From 7b9becba58be3f7ffc953487cecacf7701e3f7c8 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 23 May 2021 20:27:55 +0200 Subject: [PATCH 1/5] fix: role.permissions should be bigint --- src/structures/role.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/structures/role.ts b/src/structures/role.ts index 377eaa729..d99c8ee17 100644 --- a/src/structures/role.ts +++ b/src/structures/role.ts @@ -129,6 +129,7 @@ export async function createDiscordenoRole( const role: DiscordenoRole = Object.create(baseRole, { ...props, + permissions: createNewProp(snowflakeToBigint(rest.permissions)), botId: createNewProp(tags.botId ? snowflakeToBigint(tags.botId) : undefined), isNitroBoostRole: createNewProp("premiumSubscriber" in tags), integrationId: createNewProp(tags.integrationId ? snowflakeToBigint(tags.integrationId) : undefined), @@ -138,7 +139,7 @@ export async function createDiscordenoRole( return role; } -export interface DiscordenoRole extends Omit { +export interface DiscordenoRole extends Omit { /** The role id */ id: bigint; /** The bot id that is associated with this role. */ @@ -149,6 +150,8 @@ export interface DiscordenoRole extends Omit { integrationId: bigint; /** The roles guildId */ guildId: bigint; + /** Permission bit set */ + permissions: bigint; /** Holds all the boolean toggles. */ bitfield: bigint; From d737f2ac413c9819801e4613303fb76f817e7f85 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 23 May 2021 20:28:06 +0200 Subject: [PATCH 2/5] idk why ts so strange --- src/util/permissions.ts | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/util/permissions.ts b/src/util/permissions.ts index 71c7d890e..a92b9b099 100644 --- a/src/util/permissions.ts +++ b/src/util/permissions.ts @@ -37,14 +37,15 @@ export async function calculateBasePermissions( let permissions = 0n; // Calculate the role permissions bits, @everyone role is not in memberRoleIds so we need to pass guildId manualy - permissions |= [...(member.guilds.get(guild.id)?.roles || []), guild.id] - .map((id) => guild.roles.get(id)?.permissions) - // Removes any edge case undefined - .filter((perm) => perm) - .reduce((bits, perms) => { - bits |= BigInt(perms); - return bits; - }, 0n); + permissions |= + [...(member.guilds.get(guild.id)?.roles || []), guild.id] + .map((id) => guild.roles.get(id)?.permissions) + // Removes any edge case undefined + .filter((perm) => perm) + .reduce((bits, perms) => { + bits! |= perms!; + return bits; + }, 0n) || 0n; // If the memberId is equal to the guild ownerId he automatically has every permission so we add ADMINISTRATOR permission if (guild.ownerId === member.id) permissions |= 8n; From 4b3d2d97591d586d82715b14db3cd273e991707c Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 23 May 2021 20:31:14 +0200 Subject: [PATCH 3/5] remove unnecessary gotten BigInt conversion --- src/util/permissions.ts | 42 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/util/permissions.ts b/src/util/permissions.ts index a92b9b099..0a159bd0f 100644 --- a/src/util/permissions.ts +++ b/src/util/permissions.ts @@ -33,7 +33,7 @@ export async function calculateBasePermissions( const guild = await getCached("guilds", guildOrId); const member = await getCached("members", memberOrId); - if (!guild || !member) return "8"; + if (!guild || !member) return 8n; let permissions = 0n; // Calculate the role permissions bits, @everyone role is not in memberRoleIds so we need to pass guildId manualy @@ -50,7 +50,7 @@ export async function calculateBasePermissions( // If the memberId is equal to the guild ownerId he automatically has every permission so we add ADMINISTRATOR permission if (guild.ownerId === member.id) permissions |= 8n; // Return the members permission bits as a string - return permissions.toString(); + return permissions; } /** Calculates the permissions this member has for the given Channel */ @@ -61,21 +61,21 @@ export async function calculateChannelOverwrites( const channel = await getCached("channels", channelOrId); // This is a DM channel so return ADMINISTRATOR permission - if (!channel?.guildId) return "8"; + if (!channel?.guildId) return 8n; const member = await getCached("members", memberOrId); - if (!channel || !member) return "8"; + if (!channel || !member) return 8n; // Get all the role permissions this member already has - let permissions = BigInt(await calculateBasePermissions(channel.guildId, member)); + let permissions = await calculateBasePermissions(channel.guildId, member); // First calculate @everyone overwrites since these have the lowest priority const overwriteEveryone = channel.permissionOverwrites?.find((overwrite) => overwrite.id === channel.guildId); if (overwriteEveryone) { // First remove denied permissions since denied < allowed - permissions &= ~BigInt(overwriteEveryone.deny); - permissions |= BigInt(overwriteEveryone.allow); + permissions &= ~overwriteEveryone.deny; + permissions |= overwriteEveryone.allow; } const overwrites = channel.permissionOverwrites; @@ -88,8 +88,8 @@ export async function calculateChannelOverwrites( for (const overwrite of overwrites || []) { if (!memberRoles.includes(overwrite.id)) continue; - deny |= BigInt(overwrite.deny); - allow |= BigInt(overwrite.allow); + deny |= overwrite.deny; + allow |= overwrite.allow; } // After role overwrite calculate save allowed permissions first we remove denied permissions since "denied < allowed" permissions &= ~deny; @@ -98,21 +98,21 @@ export async function calculateChannelOverwrites( // Third calculate member specific overwrites since these have the highest priority const overwriteMember = overwrites?.find((overwrite) => overwrite.id === member.id); if (overwriteMember) { - permissions &= ~BigInt(overwriteMember.deny); - permissions |= BigInt(overwriteMember.allow); + permissions &= ~overwriteMember.deny; + permissions |= overwriteMember.allow; } - return permissions.toString(); + return permissions; } /** Checks if the given permission bits are matching the given permissions. `ADMINISTRATOR` always returns `true` */ -export function validatePermissions(permissionBits: string, permissions: PermissionStrings[]) { - if (BigInt(permissionBits) & 8n) return true; +export function validatePermissions(permissionBits: bigint, permissions: PermissionStrings[]) { + if (permissionBits & 8n) return true; return permissions.every( (permission) => // Check if permission is in permissionBits - BigInt(permissionBits) & BigInt(DiscordBitwisePermissionFlags[permission]) + permissionBits & BigInt(DiscordBitwisePermissionFlags[permission]) ); } @@ -153,12 +153,10 @@ export function botHasChannelPermissions(channel: bigint | DiscordenoChannel, pe } /** Returns the permissions that are not in the given permissionBits */ -export function missingPermissions(permissionBits: string, permissions: PermissionStrings[]) { - if (BigInt(permissionBits) & 8n) return []; +export function missingPermissions(permissionBits: bigint, permissions: PermissionStrings[]) { + if (permissionBits & 8n) return []; - return permissions.filter( - (permission) => !(BigInt(permissionBits) & BigInt(DiscordBitwisePermissionFlags[permission])) - ); + return permissions.filter((permission) => !(permissionBits & BigInt(DiscordBitwisePermissionFlags[permission]))); } /** Get the missing Guild permissions this member has */ @@ -224,12 +222,12 @@ export function requireBotChannelPermissions(channel: bigint | DiscordenoChannel } /** This function converts a bitwise string to permission strings */ -export function calculatePermissions(permissionBits: string) { +export function calculatePermissions(permissionBits: bigint) { return Object.keys(DiscordBitwisePermissionFlags).filter((permission) => { // Since Object.keys() not only returns the permission names but also the bit values we need to return false if it is a Number if (Number(permission)) return false; // Check if permissionBits has this permission - return BigInt(permissionBits) & BigInt(DiscordBitwisePermissionFlags[permission as PermissionStrings]); + return permissionBits & BigInt(DiscordBitwisePermissionFlags[permission as PermissionStrings]); }) as PermissionStrings[]; } From 62b6426d1d9662e28810a76ffe03ff099433b01e Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 23 May 2021 20:33:01 +0200 Subject: [PATCH 4/5] Update clone_channel.ts --- src/helpers/channels/clone_channel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/channels/clone_channel.ts b/src/helpers/channels/clone_channel.ts index 52ec7c145..70c2d41a6 100644 --- a/src/helpers/channels/clone_channel.ts +++ b/src/helpers/channels/clone_channel.ts @@ -22,8 +22,8 @@ export async function cloneChannel(channelId: bigint, reason?: string) { permissionOverwrites: channelToClone.permissionOverwrites.map((overwrite) => ({ id: overwrite.id.toString(), type: overwrite.type, - allow: calculatePermissions(overwrite.allow.toString()), - deny: calculatePermissions(overwrite.deny.toString()), + allow: calculatePermissions(overwrite.allow), + deny: calculatePermissions(overwrite.deny), })), }; From 20a3e8a0295ffb71b10d0d1048665b1f624e2d55 Mon Sep 17 00:00:00 2001 From: ITOH Date: Sun, 23 May 2021 21:09:42 +0200 Subject: [PATCH 5/5] Update src/structures/role.ts Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> --- src/structures/role.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/structures/role.ts b/src/structures/role.ts index d99c8ee17..8d6d7d88c 100644 --- a/src/structures/role.ts +++ b/src/structures/role.ts @@ -129,7 +129,7 @@ export async function createDiscordenoRole( const role: DiscordenoRole = Object.create(baseRole, { ...props, - permissions: createNewProp(snowflakeToBigint(rest.permissions)), + permissions: createNewProp(BigInt(rest.permissions)), botId: createNewProp(tags.botId ? snowflakeToBigint(tags.botId) : undefined), isNitroBoostRole: createNewProp("premiumSubscriber" in tags), integrationId: createNewProp(tags.integrationId ? snowflakeToBigint(tags.integrationId) : undefined),