Add helper for permission calculations
This commit is contained in:
parent
2fb68900c7
commit
bf3d219716
4 changed files with 50 additions and 6 deletions
|
@ -12,7 +12,7 @@ const utils = sync.require("../../m2d/converters/utils")
|
|||
* @typedef ReactionRemoveRequest
|
||||
* @prop {string} eventID
|
||||
* @prop {string | null} mxid
|
||||
* @prop {BigInt} [hash]
|
||||
* @prop {bigint} [hash]
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -115,8 +115,7 @@ module.exports = {
|
|||
if (!member) return
|
||||
if (!("permission_overwrites" in channel)) continue
|
||||
const permissions = dUtils.getPermissions(member.roles, guild.roles, client.user.id, channel.permission_overwrites)
|
||||
const wants = BigInt(1 << 10) | BigInt(1 << 16) // VIEW_CHANNEL + READ_MESSAGE_HISTORY
|
||||
if ((permissions & wants) !== wants) continue // We don't have permission to look back in this channel
|
||||
if (!dUtils.hasAllPermissions(permissions, ["ViewChannel", "ReadMessageHistory"])) continue // We don't have permission to look back in this channel
|
||||
|
||||
/** More recent messages come first. */
|
||||
// console.log(`[check missed messages] in ${channel.id} (${guild.name} / ${channel.name}) because its last message ${channel.last_message_id} is not in the database`)
|
||||
|
@ -164,8 +163,7 @@ module.exports = {
|
|||
|
||||
// Permissions check
|
||||
const permissions = dUtils.getPermissions(member.roles, guild.roles, client.user.id, channel.permission_overwrites)
|
||||
const wants = BigInt(1 << 10) | BigInt(1 << 16) // VIEW_CHANNEL + READ_MESSAGE_HISTORY
|
||||
if ((permissions & wants) !== wants) continue // We don't have permission to look up the pins in this channel
|
||||
if (!dUtils.hasAllPermissions(permissions, ["ViewChannel", "ReadMessageHistory"])) continue // We don't have permission to look up the pins in this channel
|
||||
|
||||
const row = select("channel_room", ["room_id", "last_bridged_pin_timestamp"], {channel_id: channel.id}).get()
|
||||
if (!row) continue // Only care about already bridged channels
|
||||
|
|
|
@ -137,7 +137,7 @@ const commands = [{
|
|||
// Check CREATE_INSTANT_INVITE permission
|
||||
assert(message.member)
|
||||
const guildPermissions = utils.getPermissions(message.member.roles, guild.roles)
|
||||
if (!(guildPermissions & BigInt(1))) {
|
||||
if (!(guildPermissions & DiscordTypes.PermissionFlagsBits.CreateInstantInvite)) {
|
||||
return discord.snow.channel.createMessage(channel.id, {
|
||||
...ctx,
|
||||
content: "You don't have permission to invite people to this Discord server."
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @ts-check
|
||||
|
||||
const DiscordTypes = require("discord-api-types/v10")
|
||||
const assert = require("assert").strict
|
||||
|
||||
const EPOCH = 1420070400000
|
||||
|
||||
|
@ -49,6 +50,48 @@ function getPermissions(userRoles, guildRoles, userID, channelOverwrites) {
|
|||
return allowed
|
||||
}
|
||||
|
||||
/**
|
||||
* Note: You can only provide one permission bit to permissionToCheckFor. To check multiple permissions, call `hasAllPermissions` or `hasSomePermissions`.
|
||||
* It is designed like this to avoid developer error with bit manipulations.
|
||||
*
|
||||
* @param {bigint} resolvedPermissions
|
||||
* @param {bigint} permissionToCheckFor
|
||||
* @returns {boolean} whether the user has the requested permission
|
||||
* @example
|
||||
* const permissions = getPermissions(userRoles, guildRoles, userID, channelOverwrites)
|
||||
* hasPermission(permissions, DiscordTypes.PermissionFlagsBits.ViewChannel)
|
||||
*/
|
||||
function hasPermission(resolvedPermissions, permissionToCheckFor) {
|
||||
// Make sure permissionToCheckFor has exactly one permission in it
|
||||
assert.equal(permissionToCheckFor.toString(2).match(/1/g), 1)
|
||||
// Do the actual calculation
|
||||
return (resolvedPermissions & permissionToCheckFor) === permissionToCheckFor
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {bigint} resolvedPermissions
|
||||
* @param {(keyof DiscordTypes.PermissionFlagsBits)[]} permissionsToCheckFor
|
||||
* @returns {boolean} whether the user has any of the requested permissions
|
||||
* @example
|
||||
* const permissions = getPermissions(userRoles, guildRoles, userID, channelOverwrites)
|
||||
* hasSomePermissions(permissions, ["ViewChannel", "ReadMessageHistory"])
|
||||
*/
|
||||
function hasSomePermissions(resolvedPermissions, permissionsToCheckFor) {
|
||||
return permissionsToCheckFor.some(x => hasPermission(resolvedPermissions, DiscordTypes.PermissionFlagsBits[x]))
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {bigint} resolvedPermissions
|
||||
* @param {(keyof DiscordTypes.PermissionFlagsBits)[]} permissionsToCheckFor
|
||||
* @returns {boolean} whether the user has all of the requested permissions
|
||||
* @example
|
||||
* const permissions = getPermissions(userRoles, guildRoles, userID, channelOverwrites)
|
||||
* hasAllPermissions(permissions, ["ViewChannel", "ReadMessageHistory"])
|
||||
*/
|
||||
function hasAllPermissions(resolvedPermissions, permissionsToCheckFor) {
|
||||
return permissionsToCheckFor.every(x => hasPermission(resolvedPermissions, DiscordTypes.PermissionFlagsBits[x]))
|
||||
}
|
||||
|
||||
/**
|
||||
* Command interaction responses have a webhook_id for some reason, but still have real author info of a real bot user in the server.
|
||||
* @param {DiscordTypes.APIMessage} message
|
||||
|
@ -69,6 +112,9 @@ function timestampToSnowflakeInexact(timestamp) {
|
|||
}
|
||||
|
||||
module.exports.getPermissions = getPermissions
|
||||
module.exports.hasPermission = hasPermission
|
||||
module.exports.hasSomePermissions = hasSomePermissions
|
||||
module.exports.hasAllPermissions = hasAllPermissions
|
||||
module.exports.isWebhookMessage = isWebhookMessage
|
||||
module.exports.snowflakeToTimestampExact = snowflakeToTimestampExact
|
||||
module.exports.timestampToSnowflakeInexact = timestampToSnowflakeInexact
|
||||
|
|
Loading…
Reference in a new issue