diff options
| author | Max Isom <[email protected]> | 2022-01-29 11:20:40 -0500 |
|---|---|---|
| committer | Max Isom <[email protected]> | 2022-01-29 11:20:40 -0500 |
| commit | 1621b2c2815f7458df19320361a4a5a41c9cf4d3 (patch) | |
| tree | 47c7c1377243c5d91a95c0c7d9217ad3a3b9cfdb /src | |
| parent | 8e00726dc2c8179c7aa03f72e96544e78b4fb001 (diff) | |
| download | muse-1621b2c2815f7458df19320361a4a5a41c9cf4d3.tar.xz muse-1621b2c2815f7458df19320361a4a5a41c9cf4d3.zip | |
Add permissions system
Diffstat (limited to 'src')
| -rw-r--r-- | src/bot.ts | 5 | ||||
| -rw-r--r-- | src/commands/config.ts | 103 | ||||
| -rw-r--r-- | src/commands/favorites.ts | 12 | ||||
| -rw-r--r-- | src/inversify.config.ts | 2 | ||||
| -rw-r--r-- | src/utils/update-permissions-for-guild.ts | 44 |
5 files changed, 162 insertions, 4 deletions
@@ -13,6 +13,7 @@ import Config from './services/config.js'; import {generateDependencyReport} from '@discordjs/voice'; import {REST} from '@discordjs/rest'; import {Routes} from 'discord-api-types/v9'; +import updatePermissionsForGuild from './utils/update-permissions-for-guild.js'; @injectable() export default class { @@ -146,6 +147,10 @@ export default class { ); } + // Update permissions + spinner.text = '📡 updating permissions...'; + await Promise.all(this.client.guilds.cache.map(async guild => updatePermissionsForGuild(guild))); + spinner.succeed(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.client.user?.id ?? ''}&scope=bot%20applications.commands&permissions=2184236096`); }); diff --git a/src/commands/config.ts b/src/commands/config.ts new file mode 100644 index 0000000..65aa36b --- /dev/null +++ b/src/commands/config.ts @@ -0,0 +1,103 @@ +import {SlashCommandBuilder} from '@discordjs/builders'; +import {CommandInteraction, MessageEmbed} from 'discord.js'; +import {injectable} from 'inversify'; +import {prisma} from '../utils/db.js'; +import updatePermissionsForGuild from '../utils/update-permissions-for-guild.js'; +import Command from './index.js'; + +@injectable() +export default class implements Command { + public readonly slashCommand = new SlashCommandBuilder() + .setName('config') + .setDescription('configure bot settings') + .addSubcommand(subcommand => subcommand + .setName('set-playlist-limit') + .setDescription('set the maximum number of tracks that can be added from a playlist') + .addIntegerOption(option => option + .setName('limit') + .setDescription('maximum number of tracks') + .setRequired(true))) + .addSubcommand(subcommand => subcommand + .setName('set-role') + .setDescription('set the role that is allowed to use the bot') + .addRoleOption(option => option + .setName('role') + .setDescription('allowed role') + .setRequired(true))) + .addSubcommand(subcommand => subcommand + .setName('get') + .setDescription('show all settings')); + + async execute(interaction: CommandInteraction) { + switch (interaction.options.getSubcommand()) { + case 'set-playlist-limit': { + const limit = interaction.options.getInteger('limit')!; + + if (limit < 1) { + throw new Error('invalid limit'); + } + + await prisma.setting.update({ + where: { + guildId: interaction.guild!.id, + }, + data: { + playlistLimit: limit, + }, + }); + + await interaction.reply('👍 limit updated'); + + break; + } + + case 'set-role': { + const role = interaction.options.getRole('role')!; + + await prisma.setting.update({ + where: { + guildId: interaction.guild!.id, + }, + data: { + roleId: role.id, + }, + }); + + await updatePermissionsForGuild(interaction.guild!); + + await interaction.reply('👍 role updated'); + + break; + } + + case 'get': { + const embed = new MessageEmbed().setTitle('Config'); + + const config = await prisma.setting.findUnique({where: {guildId: interaction.guild!.id}}); + + if (!config) { + throw new Error('no config found'); + } + + const settingsToShow = { + 'Playlist Limit': config.playlistLimit, + Role: config.roleId ? `<@&${config.roleId}>` : 'not set', + }; + + let description = ''; + for (const [key, value] of Object.entries(settingsToShow)) { + description += `**${key}**: ${value}\n`; + } + + embed.setDescription(description); + + await interaction.reply({embeds: [embed]}); + + break; + } + + default: + throw new Error('unknown subcommand'); + } + } +} diff --git a/src/commands/favorites.ts b/src/commands/favorites.ts index b15a5c9..98f1ba9 100644 --- a/src/commands/favorites.ts +++ b/src/commands/favorites.ts @@ -75,6 +75,7 @@ export default class implements Command { } async handleAutocompleteInteraction(interaction: AutocompleteInteraction) { + const subcommand = interaction.options.getSubcommand(); const query = interaction.options.getString('name')!.trim(); const favorites = await prisma.favoriteQuery.findMany({ @@ -83,13 +84,16 @@ export default class implements Command { }, }); - const names = favorites.map(favorite => favorite.name); + let results = query === '' ? favorites : favorites.filter(f => f.name.startsWith(query)); - const results = query === '' ? names : names.filter(name => name.startsWith(query)); + if (subcommand === 'remove') { + // Only show favorites that user is allowed to remove + results = interaction.member?.user.id === interaction.guild?.ownerId ? results : results.filter(r => r.authorId === interaction.member!.user.id); + } await interaction.respond(results.map(r => ({ - name: r, - value: r, + name: r.name, + value: r.name, }))); } diff --git a/src/inversify.config.ts b/src/inversify.config.ts index f423614..d29d3de 100644 --- a/src/inversify.config.ts +++ b/src/inversify.config.ts @@ -15,6 +15,7 @@ import GetSongs from './services/get-songs.js'; // Comands import Command from './commands'; import Clear from './commands/clear.js'; +import Config from './commands/config.js'; import Disconnect from './commands/disconnect.js'; import Favorites from './commands/favorites.js'; import ForwardSeek from './commands/fseek.js'; @@ -54,6 +55,7 @@ container.bind<AddQueryToQueue>(TYPES.Services.AddQueryToQueue).to(AddQueryToQue // Commands [ Clear, + Config, Disconnect, Favorites, ForwardSeek, diff --git a/src/utils/update-permissions-for-guild.ts b/src/utils/update-permissions-for-guild.ts new file mode 100644 index 0000000..ca7c427 --- /dev/null +++ b/src/utils/update-permissions-for-guild.ts @@ -0,0 +1,44 @@ +import {ApplicationCommandPermissionData, Guild} from 'discord.js'; +import {prisma} from './db.js'; + +const COMMANDS_TO_LIMIT_TO_GUILD_OWNER = ['config']; + +const updatePermissionsForGuild = async (guild: Guild) => { + const settings = await prisma.setting.findUnique({ + where: { + guildId: guild.id, + }, + }); + + if (!settings) { + throw new Error('could not find settings for guild'); + } + + const permissions: ApplicationCommandPermissionData[] = [ + { + id: guild.ownerId, + type: 'USER', + permission: true, + }, + { + id: guild.roles.everyone.id, + type: 'ROLE', + permission: false, + }, + ]; + const commands = await guild.commands.fetch(); + + await guild.commands.permissions.set({fullPermissions: commands.map(command => ({ + id: command.id, + permissions: COMMANDS_TO_LIMIT_TO_GUILD_OWNER.includes(command.name) ? permissions : [ + ...permissions, + ...(settings.roleId ? [{ + id: settings.roleId, + type: 'ROLE' as const, + permission: true, + }] : []), + ], + }))}); +}; + +export default updatePermissionsForGuild; |
