const { Inhibitor } = require('../../../interfaces/'); const safeCommands = ['command:settings', 'command:grant', 'command:revoke']; class Permissions extends Inhibitor { constructor(client) { super(client, { name: 'permissions', priority: 10, guarded: true, guild: true }); } async execute(message, command) { const { permissionType } = message.guild._settings; let missing = []; if(permissionType === 'discord') { missing = this._checkDiscord(message, command.memberPermissions); } else if(permissionType === 'grant') { // vv Prevent Softlock vv if(safeCommands.includes(command.resolveable) && (this._checkDiscord(message, ['ADMINISTRATOR']).length === 0 || this._checkDiscord(message, ['MANAGE_GUILD']).length === 0)) { return super._succeed(); } missing = await this._checkGrants(message, command.resolveable); } else { missing = this._checkDiscord(message, command.memberPermissions); missing.concat(await this._checkGrants(message, command.resolveable)); } if(missing.length > 0) { return super._fail({ missing: missing.join(', ') }); } return super._succeed(); } _checkDiscord(message, permissions) { return message.channel.permissionsFor(message.member).missing(permissions); } async _checkGrants(message, permission) { //async just incase const _permissions = await message.guild.permissions(); const roles = message.member.roles.cache.map((r) => r.id); const { channelId } = message.channel; const { userId } = message.member; let allowed = false; for(const [ id, permissions ] of Object.entries(_permissions)) { if(id === userId || roles.includes(id)) { if(permissions.global.includes(permission)) { allowed = true; break; } const channel = permissions.channels[channelId]; if(!channel) continue; if(channel.includes(permission)) allowed = true; break; } continue; } return allowed ? [] : [permission]; } } module.exports = Permissions;