mirror of
https://github.com/BluemediaGER/muse.git
synced 2024-11-23 09:15:29 +01:00
Add permissions system
This commit is contained in:
parent
8e00726dc2
commit
1621b2c281
19
migrations/20220129010359_remove_channel/migration.sql
Normal file
19
migrations/20220129010359_remove_channel/migration.sql
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
Warnings:
|
||||||
|
|
||||||
|
- You are about to drop the column `channel` on the `Setting` table. All the data in the column will be lost.
|
||||||
|
|
||||||
|
*/
|
||||||
|
-- RedefineTables
|
||||||
|
PRAGMA foreign_keys=OFF;
|
||||||
|
CREATE TABLE "new_Setting" (
|
||||||
|
"guildId" TEXT NOT NULL PRIMARY KEY,
|
||||||
|
"playlistLimit" INTEGER NOT NULL DEFAULT 50,
|
||||||
|
"createdAt" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updatedAt" DATETIME NOT NULL
|
||||||
|
);
|
||||||
|
INSERT INTO "new_Setting" ("createdAt", "guildId", "playlistLimit", "updatedAt") SELECT "createdAt", "guildId", "playlistLimit", "updatedAt" FROM "Setting";
|
||||||
|
DROP TABLE "Setting";
|
||||||
|
ALTER TABLE "new_Setting" RENAME TO "Setting";
|
||||||
|
PRAGMA foreign_key_check;
|
||||||
|
PRAGMA foreign_keys=ON;
|
|
@ -0,0 +1,2 @@
|
||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Setting" ADD COLUMN "roleId" TEXT;
|
|
@ -25,8 +25,8 @@ model KeyValueCache {
|
||||||
|
|
||||||
model Setting {
|
model Setting {
|
||||||
guildId String @id
|
guildId String @id
|
||||||
channel String?
|
|
||||||
playlistLimit Int @default(50)
|
playlistLimit Int @default(50)
|
||||||
|
roleId String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import Config from './services/config.js';
|
||||||
import {generateDependencyReport} from '@discordjs/voice';
|
import {generateDependencyReport} from '@discordjs/voice';
|
||||||
import {REST} from '@discordjs/rest';
|
import {REST} from '@discordjs/rest';
|
||||||
import {Routes} from 'discord-api-types/v9';
|
import {Routes} from 'discord-api-types/v9';
|
||||||
|
import updatePermissionsForGuild from './utils/update-permissions-for-guild.js';
|
||||||
|
|
||||||
@injectable()
|
@injectable()
|
||||||
export default class {
|
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`);
|
spinner.succeed(`Ready! Invite the bot with https://discordapp.com/oauth2/authorize?client_id=${this.client.user?.id ?? ''}&scope=bot%20applications.commands&permissions=2184236096`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
103
src/commands/config.ts
Normal file
103
src/commands/config.ts
Normal file
|
@ -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');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -75,6 +75,7 @@ export default class implements Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
async handleAutocompleteInteraction(interaction: AutocompleteInteraction) {
|
async handleAutocompleteInteraction(interaction: AutocompleteInteraction) {
|
||||||
|
const subcommand = interaction.options.getSubcommand();
|
||||||
const query = interaction.options.getString('name')!.trim();
|
const query = interaction.options.getString('name')!.trim();
|
||||||
|
|
||||||
const favorites = await prisma.favoriteQuery.findMany({
|
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 => ({
|
await interaction.respond(results.map(r => ({
|
||||||
name: r,
|
name: r.name,
|
||||||
value: r,
|
value: r.name,
|
||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import GetSongs from './services/get-songs.js';
|
||||||
// Comands
|
// Comands
|
||||||
import Command from './commands';
|
import Command from './commands';
|
||||||
import Clear from './commands/clear.js';
|
import Clear from './commands/clear.js';
|
||||||
|
import Config from './commands/config.js';
|
||||||
import Disconnect from './commands/disconnect.js';
|
import Disconnect from './commands/disconnect.js';
|
||||||
import Favorites from './commands/favorites.js';
|
import Favorites from './commands/favorites.js';
|
||||||
import ForwardSeek from './commands/fseek.js';
|
import ForwardSeek from './commands/fseek.js';
|
||||||
|
@ -54,6 +55,7 @@ container.bind<AddQueryToQueue>(TYPES.Services.AddQueryToQueue).to(AddQueryToQue
|
||||||
// Commands
|
// Commands
|
||||||
[
|
[
|
||||||
Clear,
|
Clear,
|
||||||
|
Config,
|
||||||
Disconnect,
|
Disconnect,
|
||||||
Favorites,
|
Favorites,
|
||||||
ForwardSeek,
|
ForwardSeek,
|
||||||
|
|
44
src/utils/update-permissions-for-guild.ts
Normal file
44
src/utils/update-permissions-for-guild.ts
Normal file
|
@ -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;
|
Loading…
Reference in a new issue