const { Command } = require('../../../../interfaces/'); const { stripIndents } = require('common-tags'); class GrantCommand extends Command { constructor(client) { super(client, { name: 'grant', module: 'administration', usage: " ", examples: [ "\"Server Moderators\" module:moderation", "@nolan#2887 command:kick" ], memberPermissions: ['ADMINISTRATOR', 'MANAGE_SERVER'], showUsage: true, guildOnly: true, arguments: [ { name: 'channel', aliases: [ 'channels' ], type: 'CHANNEL', types: ['FLAG', 'VERBAL'], infinite: true } ] }); } async execute(message, { params, args }) { // console.log(args.channel); const _permissions = await message.guild.permissions(); const [ parse, ...perms ] = params; const resolveable = await this._parseResolveable(message, parse); if(!resolveable) return undefined; if(perms.length === 0) { await message.respond(message.format('C_GRANT_MISSINGPERMPARAM'), { emoji: 'failure' }); return undefined; } const permissions = this.client.registry.components.filter(c=> c.type === 'command' || c.type === 'module' ); let parsed = []; if(perms.join(' ') === '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) failed.push(perm); if(search.type === 'module') { for(const component of search.components.values()) { if(component.type === 'command') parsed.push(component.resolveable); //add check for grantable } } else { //add check for grantable parsed.push(search.resolveable); } } } if(!_permissions[resolveable.id]) { _permissions[resolveable.id] = { global: [], channels: {} }; } let existing = _permissions[resolveable.id]; let pushed = []; let failed = []; if(args.channel) { for(const channel of args.channel.value) { const existingChannel = existing.channels[channel.id]; if(existingChannel) { for(const perm of parsed) { if(existingChannel.includes(perm)) { failed.push(perm); } else { existingChannel.push(perm); pushed.push(perm); } } } else { existing.channels[channel.id] = parsed; pushed.concat(parsed) } } } else { for(const perm of parsed) { if(existing.global.includes(perm)) { failed.push(perm); } else { existing.global.push(perm); pushed.push(perm); } } } delete _permissions._id; //some bullshit.. 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_GRANT_DATABASEERROR'), { emoji: 'failure' }); return undefined; } if(pushed.length > 0) { return await message.respond(stripIndents`${message.format('C_GRANT_SUCCESS', { resolveable: resolveable.name || resolveable.user?.tag, permissions: pushed.map(p=>`\`${p}\``).join(', ') })}${args.channel ? ` ${message.format('C_GRANT_SUCCESSALT', { channels: args.channel.value.map(c=>`\`#${c.name}\``).join(', ')})}`: '.'} ${failed.length > 0 ? message.format('C_GRANT_SUCCESSFAILED', { resolveable: resolveable.user ? 'user' : 'role' }) : ''}`, { emoji: 'success' }); } else { return await message.respond(message.format('C_GRANT_FAILED', { failed: failed.map(f=>`\`${f}\``).join(', '), resolveable: resolveable.user ? 'user' : 'role' }), { emoji: 'failure' }) } } async _parseResolveable(message, resolveable) { let parsed = await this.client.resolver.resolveRoles(resolveable, message.guild); if(!parsed) { parsed = await this.client.resolver.resolveMembers(resolveable, message.guild); if(!parsed) { await message.respond(message.format('C_GRANT_RESOLVEERROR'), { emoji: 'failure' }); return null; } } return parsed[0]; } } module.exports = GrantCommand; 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)))); };