diff options
Diffstat (limited to 'src/util/Permissions.ts')
-rw-r--r-- | src/util/Permissions.ts | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/util/Permissions.ts b/src/util/Permissions.ts index c3dcdb53..89e1d1d3 100644 --- a/src/util/Permissions.ts +++ b/src/util/Permissions.ts @@ -1,6 +1,8 @@ // https://github.com/discordjs/discord.js/blob/master/src/util/Permissions.js // Apache License Version 2.0 Copyright 2015 - 2021 Amish Shah +import { ChannelPermissionOverwrite } from "../models/Channel"; +import { Role } from "../models/Role"; import { BitField } from "./BitField"; export type PermissionResolvable = string | number | Permissions | PermissionResolvable[]; @@ -50,4 +52,49 @@ export class Permissions extends BitField { has(permission: PermissionResolvable, checkAdmin = true) { return (checkAdmin && super.has(Permissions.FLAGS.ADMINISTRATOR)) || super.has(permission); } + + static channelPermission(overwrites: ChannelPermissionOverwrite[], init?: bigint) { + // channelOverwrites.filter((x) => x.type === 1 && x.id !== user.id); + return overwrites.reduce((permission, overwrite) => { + // apply disallowed permission + // * permission: current calculated permission (e.g. 010) + // * deny contains all denied permissions (e.g. 011) + // * allow contains all explicitly allowed permisions (e.g. 100) + return (permission & ~overwrite.deny) | overwrite.allow; + // ~ operator inverts deny (e.g. 011 -> 100) + // & operator only allows 1 for both ~deny and permission (e.g. 010 & 100 -> 000) + // | operators adds both together (e.g. 000 + 100 -> 100) + }, 0n ?? init); + } + + static rolePermission(roles: Role[]) { + // adds all permissions of all roles together (Bit OR) + return roles.reduce((permission, role) => permission | role.permissions, 0n); + } + + static finalPermission({ + user, + guild, + channel, + }: { + user: { id: bigint; roles: bigint[] }; + guild: { roles: Role[] }; + channel?: { + overwrites: ChannelPermissionOverwrite[]; + }; + }) { + let roles = guild.roles.filter((x) => user.roles.includes(x.id)); + let permission = Permissions.rolePermission(roles); + + if (channel?.overwrites) { + let overwrites = channel.overwrites.filter((x) => { + if (x.type === 0 && user.roles.includes(x.id)) return true; + if (x.type === 1 && x.id == user.id) return true; + return false; + }); + permission = Permissions.channelPermission(overwrites, permission); + } + + return permission; + } } |