summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Magnusson <mathias@magnusson.space>2026-01-21 22:27:07 +0100
committerMathias Magnusson <mathias@magnusson.space>2026-01-21 22:27:18 +0100
commit46f3cf2fa24d2ad94b0f906e3c2d2ec07daea6b0 (patch)
tree42845eedbae9e3a645a8d34805516003e443cce4
parent3100234542982dab8c16ab489386c45ab74bd427 (diff)
downloadchalle-anka-46f3cf2fa24d2ad94b0f906e3c2d2ec07daea6b0.tar.gz
handle permissions more thoroughly
-rw-r--r--commands.ts122
-rw-r--r--index.ts1
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";
+ }
+}
diff --git a/index.ts b/index.ts
index afb43f8..2a89958 100644
--- a/index.ts
+++ b/index.ts
@@ -44,6 +44,7 @@ client.on(Events.GuildAvailable, guild => {
PermissionFlagsBits.SendMessages,
PermissionFlagsBits.SendMessagesInThreads,
PermissionFlagsBits.CreatePublicThreads,
+ PermissionFlagsBits.CreatePrivateThreads,
PermissionFlagsBits.ManageThreads,
]) {
if (!role.permissions.has(permission)) {