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

211 lines
7.8 KiB
JavaScript

const { Role, MessageAttachment } = require('discord.js');
const { Command } = require('../../../../interfaces/');
const { stripIndents } = require('common-tags');
class PermissionsCommand extends Command {
constructor(client) {
super(client, {
name: 'permissions',
module: 'administration',
usage: "<list|role-name|user-name>",
aliases: [
'perms',
'permission',
'perm'
],
examples: [
"list",
"Server Moderators",
"@nolan#2887"
],
arguments: [
{
name: 'user',
aliases: ['users'],
type: 'BOOLEAN',
types: ['VERBAL', 'FLAG'],
default: true
},
{
name: 'json',
aliases: ['raw'],
type: 'BOOLEAN',
types: ['VERBAL', 'FLAG'],
default: true
}
],
// memberPermissions: ['ADMINISTRATOR', 'MANAGE_GUILD'],
guildOnly: true
});
}
async execute(message, { params, args }) {
const permissions = await message.guild.permissions();
if(args.json) {
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;
} else {
const parameters = params.join(' ');
const resolveable = await this._parseResolveable(message, parameters);
const permission = permissions[resolveable?.id || parameters];
if(!permission) {
await message.respond(message.format('C_PERMISSIONS_NOTFOUND'), { emoji: 'failure' });
return undefined;
}
const embed = {
author: {
name: `${resolveable?.user?.tag || resolveable?.tag || resolveable?.name || parameters} Permissions`,
// icon_url: resolveable?.user?.displayAvatarURL() || resolveable?.displayAvatarURL() || message.guild.iconURL()
},
description: `${message.format('C_PERMISSIONS_GLOBAL', { permissions: permissions.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 = this.client.resolver.resolveChannels(channelId, message.guild, true)[0];
if(!channel) {
delete permission.channels[channelId];
update = true;
continue;
} else {
if(embed.fields.length === 25) {
embed.description += `\n${message.format('C_PERMISSIONS_MAXFIELDS')}`;
break;
}
embed.fields.push({
name: `#${channel.name}`,
value: this._displayNames(perms).map(p=>`\`${p}\``).join(', ')
});
}
}
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}`);
}
}
return await message.embed(embed);
}
}
async _showPermissions(message, user = false) {
const embed = {
author: {
name: message.format('C_PERMISSIONS_SHOWTITLE', { user }, true),
icon_url: message.guild.iconURL()
},
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;
const item = await this.client.resolver[user ? 'resolveMemberAndUser' : 'resolveRoles'](id, message.guild); //dont kill me
if(item instanceof Role && user) continue;
else if(!user && !(item instanceof Role)) continue;
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;
embed.fields.push({
name,
value: stripIndents`${this._displayNames(value.global).map(n=>`\`${n}\``).join('\n')}
${channels > 0 ? `\`..${channels} channel${channels === 1 ? '' : 's'}\`` : ''}`
});
}
return await message.embed(embed);
}
async _listAvailablePermissions(message) {
const components = this.client.registry.components.filter(c=>(c.type === 'command' && c.grantable) || (c.type === 'module' && c.components.some(c=>c.type === 'command' && c.grantable)))
.sort((a, b) => a - b);
return await message.respond(message.format('C_PERMISSIONS_LIST', { permissions: components.map(c => `\`${c.resolveable}\``).join(', ') }), { emoji: 'success' });
}
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) {
parsed = await this.client.resolver.resolveUsers(resolveable);
if(!parsed) return null;
}
}
return parsed[0];
}
async _displayRaw(message, permissions) {
const string = JSON.stringify(permissions);
const attachment = new MessageAttachment(Buffer.from(string), "permissions.json");
return await message.respond(message.format('C_PERMISSIONS_JSON'), { emoji: 'success', attachments: [ attachment ] })
}
_displayNames(permissions) {
const modules = this.client.registry.components.filter(c=>c.type === 'module');
let names = [];
let temp = [];
for(const module of modules.values()) {
for(const component of module.components.filter(c=>c.type === 'command').values()) {
if(permissions.includes(component.resolveable)) {
temp.push(component.resolveable);
}
}
temp.length === module.components.filter(c=>c.type === 'command').size
? names.push(module.resolveable)
: names = names.concat(temp);
temp = [];
}
return names;
}
}
module.exports = PermissionsCommand;