From d39abe147f193303523299396e3fa8493ee5f09b Mon Sep 17 00:00:00 2001 From: LTS20050703 Date: Thu, 15 Sep 2022 22:22:52 +0700 Subject: [PATCH] plugins/permissions: check channel type and implicit permissions (#2468) * plugins/permissions: check channel type and implicit permissions * deno fmt * refactor: plugins/permissions Co-authored-by: Skillz4Killz <23035000+Skillz4Killz@users.noreply.github.com> --- .../permissions/src/channels/deleteChannel.ts | 13 ++++++++++--- .../deleteChannelPermissionOverride.ts | 11 +++++++++-- .../permissions/src/channels/editChannel.ts | 17 ++++++++++------- .../channels/editChannelPermissionOverrides.ts | 11 +++++++++-- .../src/channels/followAnnouncementChannel.ts | 18 ++++++++++++++---- .../src/channels/forums/createForumThread.ts | 7 +++++-- .../src/channels/getChannelWebhooks.ts | 10 ++++++++-- .../src/channels/stages/createStageInstance.ts | 9 ++++++--- .../channels/stages/deleteStageInstances.ts | 14 ++++++++++++-- .../src/channels/stages/editStageInstance.ts | 15 +++++++++++++-- .../permissions/src/channels/swapChannels.ts | 15 +++++++++++---- .../src/channels/threads/addThreadMember.ts | 9 +++++++-- .../threads/getPrivateArchivedThreads.ts | 14 ++++++++++++-- .../threads/getPrivateJoinedArchivedThreads.ts | 13 +++++++++++-- .../threads/getPublicArchivedThreads.ts | 13 +++++++++++-- .../src/channels/threads/joinThread.ts | 13 +++++++++++-- .../src/channels/threads/leaveThread.ts | 13 +++++++++++-- .../src/channels/threads/removeThreadMember.ts | 7 ++++++- 18 files changed, 176 insertions(+), 46 deletions(-) diff --git a/plugins/permissions/src/channels/deleteChannel.ts b/plugins/permissions/src/channels/deleteChannel.ts index 97381034b..df829c81b 100644 --- a/plugins/permissions/src/channels/deleteChannel.ts +++ b/plugins/permissions/src/channels/deleteChannel.ts @@ -1,5 +1,5 @@ -import { BotWithCache, ChannelTypes } from "../../deps.ts"; -import { requireBotGuildPermissions } from "../permissions.ts"; +import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; +import { requireBotChannelPermissions } from "../permissions.ts"; export function deleteChannel(bot: BotWithCache) { const deleteChannel = bot.helpers.deleteChannel; @@ -15,10 +15,17 @@ export function deleteChannel(bot: BotWithCache) { if (guild.publicUpdatesChannelId === channelId) throw new Error("UPDATES_CHANNEL_CANNOT_BE_DELETED"); + const perms: PermissionStrings[] = ["VIEW_CHANNEL"]; const isThread = [ChannelTypes.AnnouncementThread, ChannelTypes.PublicThread, ChannelTypes.PrivateThread] .includes(channel.type); + const isVoice = [ChannelTypes.GuildVoice, ChannelTypes.GuildStageVoice].includes(channel.type); - requireBotGuildPermissions(bot, guild, isThread ? ["MANAGE_THREADS"] : ["MANAGE_CHANNELS"]); + if (isThread) perms.push("MANAGE_THREADS"); + else perms.push("MANAGE_CHANNELS"); + + if (isVoice) perms.push("CONNECT"); + + requireBotChannelPermissions(bot, channelId, perms); } return await deleteChannel(channelId, reason); diff --git a/plugins/permissions/src/channels/deleteChannelPermissionOverride.ts b/plugins/permissions/src/channels/deleteChannelPermissionOverride.ts index 154e87211..f8ce7e224 100644 --- a/plugins/permissions/src/channels/deleteChannelPermissionOverride.ts +++ b/plugins/permissions/src/channels/deleteChannelPermissionOverride.ts @@ -1,4 +1,4 @@ -import { BotWithCache } from "../../deps.ts"; +import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; export function deleteChannelPermissionOverride(bot: BotWithCache) { @@ -7,7 +7,14 @@ export function deleteChannelPermissionOverride(bot: BotWithCache) { bot.helpers.deleteChannelPermissionOverride = async function (channelId, overwriteId) { const channel = bot.channels.get(channelId); - if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]); + if (channel?.guildId) { + const perms: PermissionStrings[] = ["VIEW_CHANNEL", "MANAGE_ROLES"]; + const isVoice = [ChannelTypes.GuildVoice, ChannelTypes.GuildStageVoice].includes(channel.type); + + if (isVoice) perms.push("CONNECT"); + + requireBotChannelPermissions(bot, channelId, perms); + } return await deleteChannelPermissionOverride(channelId, overwriteId); }; diff --git a/plugins/permissions/src/channels/editChannel.ts b/plugins/permissions/src/channels/editChannel.ts index ad5ab5dec..095e84e1e 100644 --- a/plugins/permissions/src/channels/editChannel.ts +++ b/plugins/permissions/src/channels/editChannel.ts @@ -20,10 +20,13 @@ export function editChannel(bot: BotWithCache) { } } + const perms: PermissionStrings[] = ["VIEW_CHANNEL"]; const isThread = [ChannelTypes.AnnouncementThread, ChannelTypes.PublicThread, ChannelTypes.PrivateThread] .includes(channel.type); + const isVoice = [ChannelTypes.GuildVoice, ChannelTypes.GuildStageVoice].includes(channel.type); + + if (isVoice) perms.push("CONNECT"); - const requiredPerms: PermissionStrings[] = []; if (isThread) { if (options.invitable !== undefined && channel.type !== ChannelTypes.PrivateThread) { throw new Error("Invitable option is only allowed on private threads."); @@ -31,16 +34,16 @@ export function editChannel(bot: BotWithCache) { // UNARCHIVING AN UNLOCKED CHANNEL SIMPLY REQUIRES SEND if (!channel.locked && options.archived === false) { - requiredPerms.push("SEND_MESSAGES"); + perms.push("SEND_MESSAGES"); // MORE THAN ARCHIVE WAS MODIFIED - if (Object.keys(options).length > 1) requiredPerms.push("MANAGE_THREADS"); + if (Object.keys(options).length > 1) perms.push("MANAGE_THREADS"); } else { - requiredPerms.push("MANAGE_THREADS"); + perms.push("MANAGE_THREADS"); } } else { - requiredPerms.push("MANAGE_CHANNELS"); + perms.push("MANAGE_CHANNELS"); - if (options.permissionOverwrites) requiredPerms.push("MANAGE_ROLES"); + if (options.permissionOverwrites) perms.push("MANAGE_ROLES"); if (options.type) { if ([ChannelTypes.GuildAnnouncement, ChannelTypes.GuildText].includes(options.type)) { @@ -68,7 +71,7 @@ export function editChannel(bot: BotWithCache) { } } - requireBotChannelPermissions(bot, channel, requiredPerms); + requireBotChannelPermissions(bot, channel, perms); } return await editChannel(channelId, options); diff --git a/plugins/permissions/src/channels/editChannelPermissionOverrides.ts b/plugins/permissions/src/channels/editChannelPermissionOverrides.ts index 4b6c0e12c..41b992156 100644 --- a/plugins/permissions/src/channels/editChannelPermissionOverrides.ts +++ b/plugins/permissions/src/channels/editChannelPermissionOverrides.ts @@ -1,4 +1,4 @@ -import { BotWithCache } from "../../deps.ts"; +import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; export function editChannelPermissionOverrides(bot: BotWithCache) { @@ -6,7 +6,14 @@ export function editChannelPermissionOverrides(bot: BotWithCache) { bot.helpers.editChannelPermissionOverrides = async function (channelId, overwrite) { const channel = bot.channels.get(channelId); - if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]); + if (channel?.guildId) { + const perms: PermissionStrings[] = ["VIEW_CHANNEL", "MANAGE_ROLES"]; + const isVoice = [ChannelTypes.GuildVoice, ChannelTypes.GuildStageVoice].includes(channel.type); + + if (isVoice) perms.push("CONNECT"); + + requireBotChannelPermissions(bot, channelId, perms); + } return await editChannelPermissionOverrides(channelId, overwrite); }; diff --git a/plugins/permissions/src/channels/followAnnouncementChannel.ts b/plugins/permissions/src/channels/followAnnouncementChannel.ts index 80a351e78..61acb0778 100644 --- a/plugins/permissions/src/channels/followAnnouncementChannel.ts +++ b/plugins/permissions/src/channels/followAnnouncementChannel.ts @@ -1,13 +1,23 @@ -import { BotWithCache } from "../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../deps.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; export function followAnnouncementChannel(bot: BotWithCache) { const followAnnouncementChannel = bot.helpers.followAnnouncementChannel; bot.helpers.followAnnouncementChannel = async function (sourceChannelId, targetChannelId) { - const channel = bot.channels.get(targetChannelId); - if (channel?.guildId) requireBotChannelPermissions(bot, channel, ["MANAGE_WEBHOOKS"]); - + const sourceChannel = bot.channels.get(sourceChannelId); + if (sourceChannel && sourceChannel.type !== ChannelTypes.GuildAnnouncement) { + throw new Error("Source channel must be an announcement channel"); + } + const targetChannel = bot.channels.get(targetChannelId); + if (targetChannel) { + const isWebhookParent = [ChannelTypes.GuildAnnouncement, ChannelTypes.GuildText].includes(targetChannel.type); + if (!isWebhookParent) { + throw new Error("Target channel must be a text channel or an announcement channel"); + } + } + requireBotChannelPermissions(bot, sourceChannelId, ["VIEW_CHANNEL"]); + requireBotChannelPermissions(bot, targetChannelId, ["VIEW_CHANNEL", "MANAGE_WEBHOOKS"]); return await followAnnouncementChannel(sourceChannelId, targetChannelId); }; } diff --git a/plugins/permissions/src/channels/forums/createForumThread.ts b/plugins/permissions/src/channels/forums/createForumThread.ts index 35659ddca..3fe27e76b 100644 --- a/plugins/permissions/src/channels/forums/createForumThread.ts +++ b/plugins/permissions/src/channels/forums/createForumThread.ts @@ -1,4 +1,4 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function createForumThread(bot: BotWithCache) { @@ -7,7 +7,10 @@ export function createForumThread(bot: BotWithCache) { bot.helpers.createForumThread = async function (channelId, options) { const channel = bot.channels.get(channelId); - if (channel) requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]); + if (channel && channel.type !== ChannelTypes.GuildForum) { + throw new Error("Channel must be a forum channel"); + } + requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "SEND_MESSAGES"]); return await createForumThread(channelId, options); }; diff --git a/plugins/permissions/src/channels/getChannelWebhooks.ts b/plugins/permissions/src/channels/getChannelWebhooks.ts index 666b340a7..97cc3acc9 100644 --- a/plugins/permissions/src/channels/getChannelWebhooks.ts +++ b/plugins/permissions/src/channels/getChannelWebhooks.ts @@ -1,4 +1,4 @@ -import { BotWithCache } from "../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../deps.ts"; import { requireBotChannelPermissions } from "../permissions.ts"; export function getChannelWebhooks(bot: BotWithCache) { @@ -6,7 +6,13 @@ export function getChannelWebhooks(bot: BotWithCache) { bot.helpers.getChannelWebhooks = async function (channelId) { const channel = bot.channels.get(channelId); - if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]); + if (channel) { + const isWebhookParent = [ChannelTypes.GuildAnnouncement, ChannelTypes.GuildText].includes(channel.type); + if (!isWebhookParent) { + throw new Error("Target channel must be a text channel or an announcement channel"); + } + requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "MANAGE_WEBHOOKS"]); + } return await getChannelWebhooks(channelId); }; diff --git a/plugins/permissions/src/channels/stages/createStageInstance.ts b/plugins/permissions/src/channels/stages/createStageInstance.ts index 234977ac5..627752786 100644 --- a/plugins/permissions/src/channels/stages/createStageInstance.ts +++ b/plugins/permissions/src/channels/stages/createStageInstance.ts @@ -1,14 +1,17 @@ -import { BotWithCache, PermissionStrings } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes, PermissionStrings } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function createStageInstance(bot: BotWithCache) { const createStageInstance = bot.helpers.createStageInstance; bot.helpers.createStageInstance = async function (options) { - const perms: PermissionStrings[] = ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]; + const channel = bot.channels.get(options.channelId); + if (channel && channel.type !== ChannelTypes.GuildStageVoice) { + throw new Error("Channel must be a stage voice channel"); + } + const perms: PermissionStrings[] = ["VIEW_CHANNEL", "CONNECT", "MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]; if (options.sendStartNotification) perms.push("MENTION_EVERYONE"); - requireBotChannelPermissions(bot, options.channelId, perms); return await createStageInstance(options); diff --git a/plugins/permissions/src/channels/stages/deleteStageInstances.ts b/plugins/permissions/src/channels/stages/deleteStageInstances.ts index 1692df2c7..a7a30616f 100644 --- a/plugins/permissions/src/channels/stages/deleteStageInstances.ts +++ b/plugins/permissions/src/channels/stages/deleteStageInstances.ts @@ -1,11 +1,21 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function deleteStageInstance(bot: BotWithCache) { const deleteStageInstance = bot.helpers.deleteStageInstance; bot.helpers.deleteStageInstance = async function (channelId) { - requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]); + const channel = bot.channels.get(channelId); + if (channel && channel.type !== ChannelTypes.GuildStageVoice) { + throw new Error("Channel must be a stage voice channel"); + } + requireBotChannelPermissions(bot, channelId, [ + "VIEW_CHANNEL", + "CONNECT", + "MANAGE_CHANNELS", + "MUTE_MEMBERS", + "MOVE_MEMBERS", + ]); return await deleteStageInstance(channelId); }; diff --git a/plugins/permissions/src/channels/stages/editStageInstance.ts b/plugins/permissions/src/channels/stages/editStageInstance.ts index 8b15ad0ab..f5966184e 100644 --- a/plugins/permissions/src/channels/stages/editStageInstance.ts +++ b/plugins/permissions/src/channels/stages/editStageInstance.ts @@ -1,11 +1,22 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function editStageInstance(bot: BotWithCache) { const editStageInstance = bot.helpers.editStageInstance; bot.helpers.editStageInstance = async function (channelId, data) { - requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]); + const channel = bot.channels.get(channelId); + if (channel && channel.type !== ChannelTypes.GuildStageVoice) { + throw new Error("Channel must be a stage voice channel"); + } + + requireBotChannelPermissions(bot, channelId, [ + "VIEW_CHANNEL", + "CONNECT", + "MANAGE_CHANNELS", + "MUTE_MEMBERS", + "MOVE_MEMBERS", + ]); return await editStageInstance(channelId, data); }; diff --git a/plugins/permissions/src/channels/swapChannels.ts b/plugins/permissions/src/channels/swapChannels.ts index 1c1e0a7ee..63f9d62a5 100644 --- a/plugins/permissions/src/channels/swapChannels.ts +++ b/plugins/permissions/src/channels/swapChannels.ts @@ -1,12 +1,19 @@ -import { BotWithCache } from "../../deps.ts"; -import { requireBotGuildPermissions } from "../permissions.ts"; +import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts"; +import { requireBotChannelPermissions } from "../permissions.ts"; export function swapChannels(bot: BotWithCache) { const swapChannels = bot.helpers.swapChannels; bot.helpers.swapChannels = async function (guildId, channelPositions) { - requireBotGuildPermissions(bot, guildId, ["MANAGE_CHANNELS"]); - + for (const channelPosition of channelPositions) { + const channel = bot.channels.get(BigInt(channelPosition.id)); + if (channel) { + const perms: PermissionStrings[] = ["VIEW_CHANNEL", "MANAGE_CHANNELS"]; + const isVoice = [ChannelTypes.GuildVoice, ChannelTypes.GuildStageVoice].includes(channel.type); + if (isVoice) perms.push("CONNECT"); + requireBotChannelPermissions(bot, BigInt(channelPosition.id), perms); + } + } return await swapChannels(guildId, channelPositions); }; } diff --git a/plugins/permissions/src/channels/threads/addThreadMember.ts b/plugins/permissions/src/channels/threads/addThreadMember.ts index c67526d11..290d3b0fa 100644 --- a/plugins/permissions/src/channels/threads/addThreadMember.ts +++ b/plugins/permissions/src/channels/threads/addThreadMember.ts @@ -1,4 +1,4 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function addThreadMember(bot: BotWithCache) { @@ -8,9 +8,14 @@ export function addThreadMember(bot: BotWithCache) { const channel = bot.channels.get(threadId); if (channel) { + const isThread = ![ChannelTypes.PublicThread, ChannelTypes.PrivateThread, ChannelTypes.AnnouncementThread] + .includes(channel.type); + + if (isThread) throw new Error("Channel must be a thread channel"); + if (channel.archived) throw new Error("Cannot add user to thread if thread is archived."); - requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]); + requireBotChannelPermissions(bot, channel, ["VIEW_CHANNEL", "SEND_MESSAGES"]); } return await addThreadMember(threadId, userId); diff --git a/plugins/permissions/src/channels/threads/getPrivateArchivedThreads.ts b/plugins/permissions/src/channels/threads/getPrivateArchivedThreads.ts index 69f119f94..e82d0e41f 100644 --- a/plugins/permissions/src/channels/threads/getPrivateArchivedThreads.ts +++ b/plugins/permissions/src/channels/threads/getPrivateArchivedThreads.ts @@ -1,11 +1,21 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function getPrivateArchivedThreads(bot: BotWithCache) { const getPrivateArchivedThreads = bot.helpers.getPrivateArchivedThreads; bot.helpers.getPrivateArchivedThreads = async function (channelId, options) { const channel = bot.channels.get(channelId); - if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY", "MANAGE_MESSAGES"]); + + if (channel) { + const isThreadParent = [ChannelTypes.GuildText, ChannelTypes.GuildAnnouncement, ChannelTypes.GuildForum] + .includes(channel.type); + if (!isThreadParent) { + throw new Error("Channel must be a text channel, a forum channel, or an announcement channel"); + } + } + + requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY", "MANAGE_MESSAGES"]); + return await getPrivateArchivedThreads(channelId, options); }; } diff --git a/plugins/permissions/src/channels/threads/getPrivateJoinedArchivedThreads.ts b/plugins/permissions/src/channels/threads/getPrivateJoinedArchivedThreads.ts index e16828479..c5023ffec 100644 --- a/plugins/permissions/src/channels/threads/getPrivateJoinedArchivedThreads.ts +++ b/plugins/permissions/src/channels/threads/getPrivateJoinedArchivedThreads.ts @@ -1,11 +1,20 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function getPrivateJoinedArchivedThreads(bot: BotWithCache) { const getPrivateJoinedArchivedThreads = bot.helpers.getPrivateJoinedArchivedThreads; bot.helpers.getPrivateJoinedArchivedThreads = async function (channelId, options) { const channel = bot.channels.get(channelId); - if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY"]); + + if (channel) { + const isThreadParent = [ChannelTypes.GuildText, ChannelTypes.GuildAnnouncement, ChannelTypes.GuildForum] + .includes(channel.type); + if (!isThreadParent) { + throw new Error("Channel must be a text channel, a forum channel, or an announcement channel"); + } + } + requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); + return await getPrivateJoinedArchivedThreads(channelId, options); }; } diff --git a/plugins/permissions/src/channels/threads/getPublicArchivedThreads.ts b/plugins/permissions/src/channels/threads/getPublicArchivedThreads.ts index 81cd1abb9..ff7e3ed34 100644 --- a/plugins/permissions/src/channels/threads/getPublicArchivedThreads.ts +++ b/plugins/permissions/src/channels/threads/getPublicArchivedThreads.ts @@ -1,11 +1,20 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; import { requireBotChannelPermissions } from "../../permissions.ts"; export function getPublicArchivedThreads(bot: BotWithCache) { const getPublicArchivedThreads = bot.helpers.getPublicArchivedThreads; bot.helpers.getPublicArchivedThreads = async function (channelId, options) { const channel = bot.channels.get(channelId); - if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY"]); + + if (channel) { + const isThreadParent = [ChannelTypes.GuildText, ChannelTypes.GuildAnnouncement, ChannelTypes.GuildForum] + .includes(channel.type); + if (!isThreadParent) { + throw new Error("Channel must be a text channel, a forum channel, or an announcement channel"); + } + } + requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL", "READ_MESSAGE_HISTORY"]); + return await getPublicArchivedThreads(channelId, options); }; } diff --git a/plugins/permissions/src/channels/threads/joinThread.ts b/plugins/permissions/src/channels/threads/joinThread.ts index 013ad030c..db047d707 100644 --- a/plugins/permissions/src/channels/threads/joinThread.ts +++ b/plugins/permissions/src/channels/threads/joinThread.ts @@ -1,4 +1,5 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; +import { requireBotChannelPermissions } from "../../permissions.ts"; export function joinThread(bot: BotWithCache) { const joinThread = bot.helpers.joinThread; @@ -6,7 +7,15 @@ export function joinThread(bot: BotWithCache) { bot.helpers.joinThread = async function (threadId) { const channel = bot.channels.get(threadId); - if (channel && !channel.archived) throw new Error("You can not join an archived channel."); + if (channel) { + const isThread = ![ChannelTypes.PublicThread, ChannelTypes.PrivateThread, ChannelTypes.AnnouncementThread] + .includes(channel.type); + + if (isThread) throw new Error("Channel must be a thread channel"); + + if (channel.archived) throw new Error("You can not join an archived channel."); + } + requireBotChannelPermissions(bot, threadId, ["VIEW_CHANNEL"]); return await joinThread(threadId); }; diff --git a/plugins/permissions/src/channels/threads/leaveThread.ts b/plugins/permissions/src/channels/threads/leaveThread.ts index a2d7b3ffd..f7c4f94ff 100644 --- a/plugins/permissions/src/channels/threads/leaveThread.ts +++ b/plugins/permissions/src/channels/threads/leaveThread.ts @@ -1,4 +1,5 @@ -import { BotWithCache } from "../../../deps.ts"; +import { BotWithCache, ChannelTypes } from "../../../deps.ts"; +import { requireBotChannelPermissions } from "../../permissions.ts"; export function leaveThread(bot: BotWithCache) { const leaveThread = bot.helpers.leaveThread; @@ -6,7 +7,15 @@ export function leaveThread(bot: BotWithCache) { bot.helpers.leaveThread = async function (threadId) { const channel = bot.channels.get(threadId); - if (channel && !channel.archived) throw new Error("You can not leave an archived channel."); + if (channel) { + const isThread = ![ChannelTypes.PublicThread, ChannelTypes.PrivateThread, ChannelTypes.AnnouncementThread] + .includes(channel.type); + + if (isThread) throw new Error("Channel must be a thread channel"); + + if (channel.archived) throw new Error("You can not leave an archived channel."); + } + requireBotChannelPermissions(bot, threadId, ["VIEW_CHANNEL"]); return await leaveThread(threadId); }; diff --git a/plugins/permissions/src/channels/threads/removeThreadMember.ts b/plugins/permissions/src/channels/threads/removeThreadMember.ts index 2d47df58e..3b5c5ef57 100644 --- a/plugins/permissions/src/channels/threads/removeThreadMember.ts +++ b/plugins/permissions/src/channels/threads/removeThreadMember.ts @@ -8,10 +8,15 @@ export function removeThreadMember(bot: BotWithCache) { const channel = bot.channels.get(threadId); if (channel) { + const isThread = ![ChannelTypes.PublicThread, ChannelTypes.PrivateThread, ChannelTypes.AnnouncementThread] + .includes(channel.type); + + if (isThread) throw new Error("Channel must be a thread channel"); + if (channel.archived) throw new Error("Cannot remove user from thread if thread is archived."); if (!(bot.id === channel.ownerId && channel.type === ChannelTypes.PrivateThread)) { - requireBotChannelPermissions(bot, channel, ["MANAGE_MESSAGES"]); + requireBotChannelPermissions(bot, channel, ["VIEW_CHANNEL", "MANAGE_MESSAGES"]); } }