Discord: honor Administrator in permission checks

This commit is contained in:
Shadow
2026-02-12 19:52:45 -06:00
parent 22fe30c1df
commit 34c304727b
2 changed files with 45 additions and 0 deletions

View File

@@ -10,6 +10,8 @@ import { normalizeDiscordToken } from "./token.js";
const PERMISSION_ENTRIES = Object.entries(PermissionFlagsBits).filter(
([, value]) => typeof value === "bigint",
);
const ALL_PERMISSIONS = PERMISSION_ENTRIES.reduce((acc, [, value]) => acc | value, 0n);
const ADMINISTRATOR_BIT = PermissionFlagsBits.Administrator;
type DiscordClientOpts = {
token?: string;
@@ -68,6 +70,10 @@ function bitfieldToPermissions(bitfield: bigint) {
.toSorted();
}
function hasAdministrator(bitfield: bigint) {
return (bitfield & ADMINISTRATOR_BIT) === ADMINISTRATOR_BIT;
}
export function isThreadChannelType(channelType?: number) {
return (
channelType === ChannelType.GuildNewsThread ||
@@ -121,6 +127,17 @@ export async function fetchChannelPermissionsDiscord(
}
}
if (hasAdministrator(base)) {
return {
channelId,
guildId,
permissions: bitfieldToPermissions(ALL_PERMISSIONS),
raw: ALL_PERMISSIONS.toString(),
isDm: false,
channelType,
};
}
let permissions = base;
const overwrites =
"permission_overwrites" in channel ? (channel.permission_overwrites ?? []) : [];

View File

@@ -447,6 +447,34 @@ describe("fetchChannelPermissionsDiscord", () => {
expect(res.permissions).toContain("SendMessages");
expect(res.isDm).toBe(false);
});
it("treats Administrator as all permissions despite overwrites", async () => {
const { rest, getMock } = makeRest();
getMock
.mockResolvedValueOnce({
id: "chan1",
guild_id: "guild1",
permission_overwrites: [
{
id: "guild1",
deny: PermissionFlagsBits.ViewChannel.toString(),
allow: "0",
},
],
})
.mockResolvedValueOnce({ id: "bot1" })
.mockResolvedValueOnce({
id: "guild1",
roles: [{ id: "guild1", permissions: PermissionFlagsBits.Administrator.toString() }],
})
.mockResolvedValueOnce({ roles: [] });
const res = await fetchChannelPermissionsDiscord("chan1", {
rest,
token: "t",
});
expect(res.permissions).toContain("Administrator");
expect(res.permissions).toContain("ViewChannel");
});
});
describe("readMessagesDiscord", () => {