From 46f3cf2fa24d2ad94b0f906e3c2d2ec07daea6b0 Mon Sep 17 00:00:00 2001 From: Mathias Magnusson Date: Wed, 21 Jan 2026 22:27:07 +0100 Subject: handle permissions more thoroughly --- commands.ts | 122 +++++++++++++++++++++++++++++++++++------------------------- 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().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 { PermissionFlagsBits.SendMessages, PermissionFlagsBits.SendMessagesInThreads, PermissionFlagsBits.CreatePublicThreads, + PermissionFlagsBits.CreatePrivateThreads, PermissionFlagsBits.ManageThreads, ]) { if (!role.permissions.has(permission)) { -- cgit v1.2.3