const { User, GuildMember } = require('discord.js'); const { stripIndents } = require('common-tags') const { Command } = require('../../../../interfaces/'); class RevokeCommand extends Command { constructor(client) { super(client, { name: 'revoke', module: 'administration', usage: " ", examples: [ "\"Server Moderators\" module:moderation", "@nolan#2887 command:kick", "132620781791346688 moderation" ], // memberPermissions: ['ADMINISTRATOR', 'MANAGE_GUILD'], showUsage: true, guildOnly: true, arguments: [ { name: 'channel', aliases: [ 'channels' ], type: 'CHANNEL', types: ['FLAG', 'VERBAL'], infinite: true } ] }); } async execute(message, { params, args }) { const _permissions = await message.guild.permissions(); const [ parse, ...perms ] = params; const resolveable = await this._parseResolveable(message, parse); if((resolveable && !_permissions[resolveable.id] && !_permissions[parse])) { await message.respond(message.format('C_REVOKE_RESOLVEERROR', { id: resolveable.id }), { emoji: 'failure' }); return undefined; } if(perms.length === 0) { await message.respond(message.format('C_REVOKE_MISSINGPERMPARAM'), { emoji: 'failure' }); return undefined; } const permission = resolveable ? _permissions[resolveable.id] : _permissions[parse]; const permissions = this.client.registry.components.filter(c=> c.type === 'command' || c.type === 'module' ); let parsed = []; if(perms[0] === 'all') { parsed = this.client.registry.components.filter(c=>c.grantable && c.type === 'command').map(c=>c.resolveable); } else { for(const perm of perms) { const search = permissions.filter(filterInexact(perm)).first(); if(search?.type === 'module') { for(const component of search.components.values()) { if(component.type === 'command') parsed.push(component.resolveable); //add check for grantable } } else if (search?.type === 'command'){ //add check for grantable parsed.push(search.resolveable); } else { if(args.channel) { for(let channel of args.channel.value) { if(permission.channels[channel.id].includes(perm)) parsed.push(perm); } } else { if(permission.global.includes(perm)) parsed.push(perm); } } } } let removed = []; if(args.channel) { for(const channel of args.channel.value) { const existingChannel = permission.channels[channel.id]; if(existingChannel) { for(const parse of parsed) { const index = existingChannel.indexOf(parse); if(index > -1) { removed.push(parse); permission.channels[channel.id].splice(index, 1); } } if(existingChannel.length === 0) delete permission.channels[channel.id]; } else { continue; } } } else { for(const parse of parsed) { console.log(permission); const index = permission.global.indexOf(parse); if(index > -1) { removed.push(parse); permission.global.splice(index, 1); } } } delete _permissions._id; //some bullshit.. //check for deletion, saves DB space. //NOTE: DO NOT REMOVE THE _PERMISSIONS VARIABLE. if(permission.global.length === 0 && Object.keys(permission.channels).length === 0) { console.log("DELETING FOR SOME REASON WHY") try { await this.client.transactionHandler.send({ provider: 'mongodb', request: { type: 'remove', collection: 'permissions', query: { guildId: message.guild.id } } }); } catch(error) { this.client.logger.warn(`Attempted to delete collection permissions:${message.guild.id} but failed.`); } } else { try { await this.client.transactionHandler.send({ provider: 'mongodb', request: { type: 'updateOne', collection: 'permissions', query: { guildId: message.guild.id }, data: _permissions } }); } catch(error) { await message.respond(message.format('C_REVOKE_DATABASEERROR'), { emoji: 'failure' }); return undefined; } } const name = resolveable instanceof GuildMember ? resolveable?.user?.tag : resolveable instanceof User ? resolveable?.tag : resolveable?.name; if(removed.length > 0) { await message.respond(stripIndents`${message.format('C_REVOKE_SUCCESS', { removed: removed.map(r=>`\`${r}\``).join(', '), resolveable: name || parsed })}${args.channel ? ` ${message.format('C_REVOKE_SUCCESSALT', { channels: args.channel.value.map(c=>`\`#${c.name}\``).join(', ')})}` : '.'} ${removed.length < parsed.length ? message.format('C_REVOKE_SUCCESSFAILED'): ''}`, { emoji: 'success' }); } else { await message.respond(message.format('C_REVOKE_FAILED', { resolveable: name || parsed }), { emoji: 'failure' }); } } async _parseResolveable(message, resolveable) { let parsed = await this.client.resolver.resolveRole(resolveable, true, message.guild); if(!parsed) { parsed = await this.client.resolver.resolveUser(resolveable, true, message.guild); } return parsed || null; } } module.exports = RevokeCommand; const filterInexact = (search) => { return comp => comp.id.toLowerCase().includes(search) || comp.resolveable.toLowerCase().includes(search) || (comp.aliases && (comp.aliases.some(ali => `${comp.type}:${ali}`.toLowerCase().includes(search)) || comp.aliases.some(ali => ali.toLowerCase().includes(search)))); };