galactic-bot/structure/client/components/commands/administration/Revoke.js

183 lines
7.0 KiB
JavaScript

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: "<role|user> <permissions..>",
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) {
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) {
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.resolveRoles(resolveable, message.guild)[0];
if(!parsed) {
parsed = await this.client.resolver.resolveMemberAndUser(resolveable, 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))));
};