162 lines
5.7 KiB
JavaScript
162 lines
5.7 KiB
JavaScript
|
const { Command } = require('../../../../interfaces/');
|
||
|
|
||
|
const { stripIndents } = require('common-tags');
|
||
|
|
||
|
class GrantCommand extends Command {
|
||
|
|
||
|
constructor(client) {
|
||
|
|
||
|
super(client, {
|
||
|
name: 'grant',
|
||
|
module: 'administration',
|
||
|
usage: "<role|user> <permissions..>",
|
||
|
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))));
|
||
|
};
|