2020-05-17 15:07:39 +02:00
|
|
|
const { Role, MessageAttachment } = require('discord.js');
|
2020-05-08 08:50:54 +02:00
|
|
|
const { Command } = require('../../../../interfaces/');
|
|
|
|
|
|
|
|
const { stripIndents } = require('common-tags');
|
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
class PermissionsCommand extends Command {
|
2020-05-08 08:50:54 +02:00
|
|
|
|
|
|
|
constructor(client) {
|
|
|
|
|
|
|
|
super(client, {
|
|
|
|
name: 'permissions',
|
|
|
|
module: 'administration',
|
2020-05-17 15:07:39 +02:00
|
|
|
usage: "<list|role-name|user-name>",
|
2020-05-08 08:50:54 +02:00
|
|
|
aliases: [
|
|
|
|
'perms',
|
|
|
|
'permission',
|
|
|
|
'perm'
|
|
|
|
],
|
|
|
|
examples: [
|
2020-05-17 15:07:39 +02:00
|
|
|
"list",
|
2020-05-08 08:50:54 +02:00
|
|
|
"Server Moderators",
|
|
|
|
"@nolan#2887"
|
|
|
|
],
|
2020-05-17 15:07:39 +02:00
|
|
|
arguments: [
|
|
|
|
{
|
|
|
|
name: 'user',
|
|
|
|
aliases: ['users'],
|
|
|
|
type: 'BOOLEAN',
|
|
|
|
types: ['VERBAL', 'FLAG'],
|
|
|
|
default: true
|
|
|
|
},
|
|
|
|
{
|
2020-05-17 15:27:35 +02:00
|
|
|
name: 'raw',
|
|
|
|
aliases: ['json'],
|
2020-05-17 15:07:39 +02:00
|
|
|
type: 'BOOLEAN',
|
|
|
|
types: ['VERBAL', 'FLAG'],
|
|
|
|
default: true
|
|
|
|
}
|
|
|
|
],
|
|
|
|
// memberPermissions: ['ADMINISTRATOR', 'MANAGE_GUILD'],
|
2020-05-08 08:50:54 +02:00
|
|
|
guildOnly: true
|
|
|
|
});
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
async execute(message, { params, args }) {
|
|
|
|
|
|
|
|
const permissions = await message.guild.permissions();
|
2020-06-02 12:09:28 +02:00
|
|
|
if(args.raw) {
|
2020-05-17 15:07:39 +02:00
|
|
|
await this._displayRaw(message, permissions);
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(params.length === 0) {
|
|
|
|
await this._showPermissions(message, Boolean(args.user));
|
|
|
|
return undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(params[0] === 'list') {
|
|
|
|
await this._listAvailablePermissions(message);
|
|
|
|
return undefined;
|
2020-07-25 08:02:22 +02:00
|
|
|
}
|
|
|
|
const parameters = params.join(' ');
|
|
|
|
let resolveable = await this._parseResolveable(message, parameters);
|
|
|
|
if(resolveable.user) resolveable = resolveable.user;
|
|
|
|
const type = resolveable.tag ? 'user' : 'role';
|
|
|
|
const permission = permissions[resolveable?.id || parameters];
|
|
|
|
if(resolveable && !permission) {
|
|
|
|
await message.respond(message.format('C_PERMISSIONS_PERMISSIONSNOTFOUND', { resolveable: resolveable.tag || resolveable.name, type, they: type === 'user' ? 'they ' : '' }), { emoji: 'failure' });
|
|
|
|
return undefined;
|
|
|
|
}
|
2020-06-02 12:09:28 +02:00
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
if(!permission) {
|
|
|
|
await message.respond(message.format('C_PERMISSIONS_NOTFOUND'), { emoji: 'failure' });
|
|
|
|
return undefined;
|
|
|
|
}
|
2020-05-17 15:07:39 +02:00
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
const embed = {
|
|
|
|
author: {
|
|
|
|
name: `${resolveable?.user?.tag || resolveable?.tag || resolveable?.name || parameters}'s Permissions`,
|
|
|
|
icon_url: resolveable.displayAvatarURL ? resolveable.displayAvatarURL() : message.guild.iconURL()
|
|
|
|
},
|
|
|
|
description: `${message.format('C_PERMISSIONS_GLOBAL', { permissions: permission.global.length > 0 ? this._displayNames(permission.global).map((p) => `\`${p}\``).join(', ') : "`N/A`" })} ${Object.values(permission.channels).length > 0 ? message.format('C_PERMISSIONS_GLOBALALT') : ''}`,
|
|
|
|
fields: []
|
|
|
|
};
|
|
|
|
|
|
|
|
let update = false;
|
|
|
|
for(const [channelId, perms] of Object.entries(permission.channels)) {
|
|
|
|
const channel = await this.client.resolver.resolveChannel(channelId, true, message.guild);
|
|
|
|
if(!channel) {
|
|
|
|
delete permission.channels[channelId];
|
|
|
|
update = true;
|
|
|
|
continue;
|
|
|
|
} else {
|
|
|
|
if(embed.fields.length === 25) {
|
|
|
|
embed.description += `\n${message.format('C_PERMISSIONS_MAXFIELDS')}`;
|
|
|
|
break;
|
2020-05-17 15:07:39 +02:00
|
|
|
}
|
2020-07-25 08:02:22 +02:00
|
|
|
embed.fields.push({
|
|
|
|
name: `#${channel.name}`,
|
|
|
|
value: this._displayNames(perms).map((p) => `\`${p}\``).join(', ')
|
|
|
|
});
|
2020-05-17 15:07:39 +02:00
|
|
|
}
|
2020-07-25 08:02:22 +02:00
|
|
|
}
|
|
|
|
if(update) {
|
|
|
|
delete permissions._id;
|
|
|
|
try {
|
|
|
|
await this.client.transactionHandler.send({
|
|
|
|
provider: 'mongodb',
|
|
|
|
request: {
|
|
|
|
type: 'updateOne',
|
|
|
|
collection: 'permissions',
|
|
|
|
query: {
|
|
|
|
guildId: message.guild.id
|
|
|
|
},
|
|
|
|
data: permissions
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} catch(error) {
|
|
|
|
this.client.logger.error(`Error removing channel permissions to ${message.guild.id}:\n${error.stack || error}`);
|
2020-05-17 15:07:39 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
return message.embed(embed);
|
|
|
|
|
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async _showPermissions(message, user = false) {
|
|
|
|
const embed = {
|
|
|
|
author: {
|
|
|
|
name: message.format('C_PERMISSIONS_SHOWTITLE', { user }, true),
|
2020-07-25 08:08:47 +02:00
|
|
|
icon_url: message.guild.iconURL() //eslint-disable-line camelcase
|
2020-05-17 15:07:39 +02:00
|
|
|
},
|
|
|
|
description: message.format('C_PERMISSIONS_SHOWDESCRIPTION', { resolve: user ? 'user' : 'role' }),
|
|
|
|
fields: []
|
|
|
|
};
|
|
|
|
|
|
|
|
const permissions = message.guild._permissions;
|
|
|
|
for(const [id, value] of Object.entries(permissions)) {
|
|
|
|
if(id === '_id' || id === 'guildId') continue;
|
2020-06-02 12:09:28 +02:00
|
|
|
const item = await this.client.resolver[user ? 'resolveUser' : 'resolveRole'](id, true, message.guild); //dont kill me
|
2020-07-25 08:02:22 +02:00
|
|
|
if(item instanceof Role && user
|
|
|
|
|| !user && !(item instanceof Role)
|
2020-06-02 12:09:28 +02:00
|
|
|
|| !item) continue;
|
2020-05-17 15:07:39 +02:00
|
|
|
if(embed.fields.length === 25) {
|
|
|
|
embed.description += `\n${message.format('C_PERMISSIONS_MAXFIELDS')}`;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
const name = item?.user?.tag || item?.tag || item?.name || id; //please dont kill me again
|
|
|
|
const channels = Object.values(value.channels).length;
|
2020-06-02 12:09:28 +02:00
|
|
|
if(channels === 0 && value.global.length === 0) {
|
|
|
|
embed.description += `\n\n${message.format('C_PERMISSIONS_NOPERMISSIONS')}`;
|
|
|
|
break;
|
|
|
|
}
|
2020-05-17 15:07:39 +02:00
|
|
|
embed.fields.push({
|
|
|
|
name,
|
2020-07-25 08:02:22 +02:00
|
|
|
value: stripIndents`${this._displayNames(value.global).map((n) => `\`${n}\``).join('\n')}
|
2020-05-17 15:07:39 +02:00
|
|
|
${channels > 0 ? `\`..${channels} channel${channels === 1 ? '' : 's'}\`` : ''}`
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-06-02 12:09:28 +02:00
|
|
|
return message.embed(embed);
|
2020-05-17 15:07:39 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
async _listAvailablePermissions(message) {
|
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
const components = this.client.registry.components.filter((c) => c.type === 'command' || c.type === 'module' && c.components.some((c) => c.type === 'command'))
|
2020-05-17 15:07:39 +02:00
|
|
|
.sort((a, b) => a - b);
|
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
return await message.respond(message.format('C_PERMISSIONS_LIST', { permissions: components.map((c) => `\`${c.resolveable}\``).join(', ') }), { emoji: 'success' });
|
2020-05-17 15:07:39 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
async _parseResolveable(message, resolveable) {
|
2020-06-02 12:09:28 +02:00
|
|
|
let parsed = await this.client.resolver.resolveRole(resolveable, false, message.guild);
|
2020-05-17 15:07:39 +02:00
|
|
|
if(!parsed) {
|
2020-06-02 12:09:28 +02:00
|
|
|
parsed = await this.client.resolver.resolveMember(resolveable, false, message.guild);
|
2020-05-17 15:07:39 +02:00
|
|
|
if(!parsed) {
|
2020-06-02 12:09:28 +02:00
|
|
|
parsed = await this.client.resolver.resolveUser(resolveable, false);
|
2020-05-17 15:07:39 +02:00
|
|
|
if(!parsed) return null;
|
|
|
|
}
|
|
|
|
}
|
2020-06-02 12:09:28 +02:00
|
|
|
return parsed;
|
2020-05-17 15:07:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
async _displayRaw(message, permissions) {
|
|
|
|
|
|
|
|
const string = JSON.stringify(permissions);
|
|
|
|
const attachment = new MessageAttachment(Buffer.from(string), "permissions.json");
|
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
return await message.respond(message.format('C_PERMISSIONS_JSON'), { emoji: 'success', attachments: [ attachment ] });
|
2020-05-17 15:07:39 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
_displayNames(permissions) {
|
|
|
|
|
2020-07-25 08:02:22 +02:00
|
|
|
const modules = this.client.registry.components.filter((c) => c.type === 'module');
|
2020-05-17 15:07:39 +02:00
|
|
|
let names = [];
|
2020-05-08 08:50:54 +02:00
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
let temp = [];
|
|
|
|
for(const module of modules.values()) {
|
2020-07-25 08:02:22 +02:00
|
|
|
for(const component of module.components.filter((c) => c.type === 'command').values()) {
|
2020-05-17 15:07:39 +02:00
|
|
|
if(permissions.includes(component.resolveable)) {
|
|
|
|
temp.push(component.resolveable);
|
|
|
|
}
|
|
|
|
}
|
2020-07-25 08:02:22 +02:00
|
|
|
temp.length === module.components.filter((c) => c.type === 'command').size
|
2020-05-17 15:07:39 +02:00
|
|
|
? names.push(module.resolveable)
|
|
|
|
: names = names.concat(temp);
|
|
|
|
temp = [];
|
|
|
|
}
|
2020-05-08 08:50:54 +02:00
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
return names;
|
2020-05-08 08:50:54 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2020-05-17 15:07:39 +02:00
|
|
|
module.exports = PermissionsCommand;
|