diff options
| author | Mathias Magnusson <mathias@magnusson.space> | 2026-01-21 22:27:07 +0100 |
|---|---|---|
| committer | Mathias Magnusson <mathias@magnusson.space> | 2026-01-21 22:27:18 +0100 |
| commit | 46f3cf2fa24d2ad94b0f906e3c2d2ec07daea6b0 (patch) | |
| tree | 42845eedbae9e3a645a8d34805516003e443cce4 | |
| parent | 3100234542982dab8c16ab489386c45ab74bd427 (diff) | |
| download | challe-anka-46f3cf2fa24d2ad94b0f906e3c2d2ec07daea6b0.tar.gz | |
handle permissions more thoroughly
| -rw-r--r-- | commands.ts | 122 | ||||
| -rw-r--r-- | index.ts | 1 |
2 files changed, 72 insertions, 51 deletions
diff --git a/commands.ts b/commands.ts index 3a4458f..39120d2 100644 --- a/commands.ts +++ b/commands.ts @@ -10,6 +10,8 @@ import { SlashCommandStringOption, SlashCommandUserOption, ChatInputCommandInteraction, + type GuildChannel, + type PermissionResolvable, type ButtonInteraction, type GuildForumTag, type GuildBasedChannel, @@ -167,10 +169,26 @@ async function newCtf(interaction: ChatInputCommandInteraction) { } async function createButtonMessage(interaction: ChatInputCommandInteraction) { + if (!interaction.guild) { + await interaction.reply({ + content: "This command can only be used inside a server.", + flags: "Ephemeral", + }); + return; + } + let forum = await getCtfForum(interaction); let channel = interaction.options.getChannel("channel", true, [ChannelType.GuildText]); + await checkManagementPerms(interaction); + await checkPermission({ + interaction, + channel, + permission: PermissionFlagsBits.SendMessages, + permissionName: "send messages in", + }); + await channel.send({ components: [ new ActionRowBuilder<ButtonBuilder>().addComponents( @@ -194,12 +212,13 @@ async function archiveCtf(interaction: ChatInputCommandInteraction) { return; } + await checkManagementPerms(interaction); + let forum = await getCtfForum(interaction); let everyoneRoleId = interaction.guild.roles.everyone.id; - await forum.permissionOverwrites.edit(everyoneRoleId, { - ViewChannel: true, + ViewChannel: null, SendMessages: false, SendMessagesInThreads: false, CreatePublicThreads: false, @@ -228,34 +247,12 @@ async function archiveCtf(interaction: ChatInputCommandInteraction) { } async function addToCtf(interaction: ChatInputCommandInteraction) { - if (!interaction.guild) { - await interaction.reply({ - content: "This command can only be used inside a server.", - flags: "Ephemeral", - }); - return; - } + await checkManagementPerms(interaction); let user = interaction.options.getUser("user", true); let forum = await getCtfForum(interaction); - let member = await interaction.guild.members.fetch(interaction.user.id); - let permissions = forum.permissionsFor(member); - - if (!permissions?.has(PermissionFlagsBits.ManageChannels)) { - await interaction.reply({ - content: `You don't have permission to update permissions in ${forum.name}.`, - flags: "Ephemeral", - }); - return; - } - - await forum.permissionOverwrites.edit(user, { - ViewChannel: true, - CreatePublicThreads: true, - SendMessages: true, - SendMessagesInThreads: true, - }); + await forum.permissionOverwrites.edit(user, { ViewChannel: true }); await interaction.reply({ content: `Granted ${user} access to ${forum.name}.`, @@ -264,28 +261,11 @@ async function addToCtf(interaction: ChatInputCommandInteraction) { } async function removeFromCtf(interaction: ChatInputCommandInteraction) { - if (!interaction.guild) { - await interaction.reply({ - content: "This command can only be used inside a server.", - flags: "Ephemeral", - }); - return; - } + await checkManagementPerms(interaction); let user = interaction.options.getUser("user", true); let forum = await getCtfForum(interaction); - let member = await interaction.guild.members.fetch(interaction.user.id); - let permissions = forum.permissionsFor(member); - - if (!permissions?.has(PermissionFlagsBits.ManageChannels)) { - await interaction.reply({ - content: `You don't have permission to update permissions in ${forum.name}.`, - flags: "Ephemeral", - }); - return; - } - await forum.permissionOverwrites.delete(user.id); await interaction.reply({ @@ -340,7 +320,13 @@ async function handleJoinCtfButton(interaction: ButtonInteraction, forumId: stri return; } - if (forumChannel.permissionsFor(interaction.guild.roles.everyone).has(PermissionFlagsBits.ViewChannel)) { + // We're specifically checking for the override on this channel, because @everyone may not be + // able to read even an archived channel (but then, most people in the server probably has + // another role that lets them read). + if (!forumChannel.permissionOverwrites + .cache.get(interaction.guild.roles.everyone.id) + ?.deny.has(PermissionFlagsBits.ViewChannel) + ) { await interaction.reply({ content: `The CTF has been archived so you can already view it: https://discord.com/channels/${interaction.guild.id}/${forumChannel.id}`, flags: "Ephemeral", @@ -348,12 +334,7 @@ async function handleJoinCtfButton(interaction: ButtonInteraction, forumId: stri return; } - await forumChannel.permissionOverwrites.edit(interaction.user.id, { - ViewChannel: true, - CreatePublicThreads: true, - SendMessages: true, - SendMessagesInThreads: true, - }); + await forumChannel.permissionOverwrites.edit(interaction.user.id, { ViewChannel: true }); await interaction.reply({ content: `Granted you access to https://discord.com/channels/${interaction.guild.id}/${forumChannel.id}`, @@ -428,3 +409,42 @@ export async function ensureUnsolvedTag(forum: ForumChannel): Promise<GuildForum return updated; } + +async function checkManagementPerms(interaction: ChatInputCommandInteraction) { + let forum = await getCtfForum(interaction); + + await checkPermission({ + interaction, + channel: forum, + permission: PermissionFlagsBits.ManageRoles, + permissionName: "manage", + }); +} + +async function checkPermission({ + interaction, channel, permission, permissionName, +}: { + interaction: ChatInputCommandInteraction, + channel: GuildChannel, + permission: PermissionResolvable, + permissionName: string +}) { + if (!interaction.guild) { + await interaction.reply({ + content: "This command can only be used inside a server.", + flags: "Ephemeral", + }); + throw "done"; + } + + let member = await interaction.guild.members.fetch(interaction.user.id); + let permissions = channel.permissionsFor(member); + + if (!permissions?.has(permission)) { + await interaction.reply({ + content: `You don't have permission to ${permissionName} ${channel.name}.`, + flags: "Ephemeral", + }); + throw "done"; + } +} @@ -44,6 +44,7 @@ client.on(Events.GuildAvailable, guild => { PermissionFlagsBits.SendMessages, PermissionFlagsBits.SendMessagesInThreads, PermissionFlagsBits.CreatePublicThreads, + PermissionFlagsBits.CreatePrivateThreads, PermissionFlagsBits.ManageThreads, ]) { if (!role.permissions.has(permission)) { |
