feat: Validation Plugin (#2451)

* Plugins/Permissions: FIX PARITY ISSUES
What is parity issues? Parity issues are files that exist but structured one way in the base/vanilla discordeno library, and structured another way in the permisison plugin.

* deno fmt

* plugins/permissions: nuke validations

* plugins/permissions VALIDATIONS -> plugins/validations

* plugins/validations: slash commands max 4000 chars

* fix module not found
This commit is contained in:
LTS20050703
2022-09-12 08:57:59 -05:00
committed by GitHub
parent 16f109ad43
commit b4a823aba1
155 changed files with 1794 additions and 1704 deletions
+18 -30
View File
@@ -1,49 +1,37 @@
import { Bot, BotWithCache } from "./deps.ts";
import setupChannelPermChecks from "./src/channels/mod.ts";
import { BotWithCache } from "./deps.ts";
import { channels } from "./src/channels/mod.ts";
import setupDiscoveryPermChecks from "./src/discovery.ts";
import setupEditMember from "./src/editMember.ts";
import setupEmojiPermChecks from "./src/emojis.ts";
import setupGuildPermChecks from "./src/guilds/mod.ts";
import setupIntegrationPermChecks from "./src/integrations.ts";
import setupInteractionPermChecks from "./src/interactions/mod.ts";
import setupInvitesPermChecks from "./src/invites.ts";
import setupMemberPermChecks from "./src/members/mod.ts";
import setupMessagePermChecks from "./src/messages/mod.ts";
import setupMiscPermChecks from "./src/misc/mod.ts";
import setupRolePermChecks from "./src/roles/mod.ts";
import setupWebhooksPermChecks from "./src/webhooks/mod.ts";
import { emojis } from "./src/emojis/mod.ts";
import { guilds } from "./src/guilds/mod.ts";
import { integrations } from "./src/integrations/mod.ts";
import { members } from "./src/members/mod.ts";
import { messages } from "./src/messages/mod.ts";
import { roles } from "./src/roles/mod.ts";
import { webhooks } from "./src/webhooks/mod.ts";
// PLUGINS MUST TAKE A BOT ARGUMENT WHICH WILL BE MODIFIED
export function enablePermissionsPlugin<B extends BotWithCache = BotWithCache>(bot: B): B {
// PERM CHECKS REQUIRE CACHE DUH!
if (!bot.enabledPlugins?.has("CACHE")) {
throw new Error("The PERMISSIONS plugin requires the CACHE plugin first.");
}
if (!bot.enabledPlugins?.has("CACHE")) throw new Error("The PERMISSIONS plugin requires the CACHE plugin first.");
// MARK THIS PLUGIN BEING USED
bot.enabledPlugins.add("PERMISSIONS");
// BEGIN OVERRIDING HELPER FUNCTIONS
setupChannelPermChecks(bot);
setupDiscoveryPermChecks(bot);
setupEmojiPermChecks(bot);
setupEditMember(bot);
setupGuildPermChecks(bot);
setupIntegrationPermChecks(bot);
setupInteractionPermChecks(bot);
setupInvitesPermChecks(bot);
setupMemberPermChecks(bot);
setupMessagePermChecks(bot);
setupMiscPermChecks(bot);
setupRolePermChecks(bot);
setupWebhooksPermChecks(bot);
channels(bot);
emojis(bot);
guilds(bot);
integrations(bot);
members(bot);
messages(bot);
roles(bot);
webhooks(bot);
// PLUGINS MUST RETURN THE BOT
return bot;
}
// EXPORT ALL UTIL FUNCTIONS
export * from "./src/permissions.ts";
export * from "./src/components.ts";
// DEFAULT MAKES IT SLIGHTLY EASIER TO USE
export default enablePermissionsPlugin;
-9
View File
@@ -1,9 +0,0 @@
import { Attachment, Bot } from "../deps.ts";
export function validateAttachments(bot: Bot, attachments: Attachment[]) {
attachments.forEach((attachment) => {
if (attachment.description && !bot.utils.validateLength(attachment.description, { min: 0, max: 1024 })) {
throw new Error("Attachment description length must be less than 1024 characters");
}
});
}
@@ -1,8 +1,8 @@
import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function createChannel(bot: BotWithCache) {
const createChannelOld = bot.helpers.createChannel;
export function createChannel(bot: BotWithCache) {
const createChannel = bot.helpers.createChannel;
bot.helpers.createChannel = async function (guildId, options, reason) {
const guild = bot.guilds.get(guildId);
@@ -35,9 +35,7 @@ export default function createChannel(bot: BotWithCache) {
throw new Error("The topic length must be between 1 and 1024 (4096 if forum)");
}
if (options?.userLimit && options.userLimit > 99) {
throw new Error("The user limit must be less than 99.");
}
if (options?.userLimit && options.userLimit > 99) throw new Error("The user limit must be less than 99.");
if (options?.parentId) {
const category = bot.channels.get(options.parentId);
@@ -49,6 +47,6 @@ export default function createChannel(bot: BotWithCache) {
requireBotGuildPermissions(bot, guild, requiredPerms);
}
return await createChannelOld(guildId, options, reason);
return await createChannel(guildId, options, reason);
};
}
@@ -1,8 +1,8 @@
import { BotWithCache, ChannelTypes } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function deleteChannel(bot: BotWithCache) {
const deleteChannelOld = bot.helpers.deleteChannel;
export function deleteChannel(bot: BotWithCache) {
const deleteChannel = bot.helpers.deleteChannel;
bot.helpers.deleteChannel = async function (channelId, reason) {
const channel = bot.channels.get(channelId);
@@ -11,13 +11,9 @@ export default function deleteChannel(bot: BotWithCache) {
const guild = bot.guilds.get(channel.guildId);
if (!guild) throw new Error("GUILD_NOT_FOUND");
if (guild.rulesChannelId === channelId) {
throw new Error("RULES_CHANNEL_CANNOT_BE_DELETED");
}
if (guild.rulesChannelId === channelId) throw new Error("RULES_CHANNEL_CANNOT_BE_DELETED");
if (guild.publicUpdatesChannelId === channelId) {
throw new Error("UPDATES_CHANNEL_CANNOT_BE_DELETED");
}
if (guild.publicUpdatesChannelId === channelId) throw new Error("UPDATES_CHANNEL_CANNOT_BE_DELETED");
const isThread = [ChannelTypes.AnnouncementThread, ChannelTypes.PublicThread, ChannelTypes.PrivateThread]
.includes(channel.type);
@@ -25,6 +21,6 @@ export default function deleteChannel(bot: BotWithCache) {
requireBotGuildPermissions(bot, guild, isThread ? ["MANAGE_THREADS"] : ["MANAGE_CHANNELS"]);
}
return await deleteChannelOld(channelId, reason);
return await deleteChannel(channelId, reason);
};
}
@@ -1,16 +1,14 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export default function deleteChannelPermissionOverride(bot: BotWithCache) {
const deleteChannelPermissionOverrideOld = bot.helpers.deleteChannelPermissionOverride;
export function deleteChannelPermissionOverride(bot: BotWithCache) {
const deleteChannelPermissionOverride = bot.helpers.deleteChannelPermissionOverride;
bot.helpers.deleteChannelPermissionOverride = async function (channelId, overwriteId) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]);
}
if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]);
return await deleteChannelPermissionOverrideOld(channelId, overwriteId);
return await deleteChannelPermissionOverride(channelId, overwriteId);
};
}
@@ -1,8 +1,8 @@
import { BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export default function editChannel(bot: BotWithCache) {
const editChannelOld = bot.helpers.editChannel;
export function editChannel(bot: BotWithCache) {
const editChannel = bot.helpers.editChannel;
bot.helpers.editChannel = async function (channelId, options, reason) {
const channel = bot.channels.get(channelId);
@@ -33,18 +33,14 @@ export default function editChannel(bot: BotWithCache) {
if (!channel.locked && options.archived === false) {
requiredPerms.push("SEND_MESSAGES");
// MORE THAN ARCHIVE WAS MODIFIED
if (Object.keys(options).length > 1) {
requiredPerms.push("MANAGE_THREADS");
}
if (Object.keys(options).length > 1) requiredPerms.push("MANAGE_THREADS");
} else {
requiredPerms.push("MANAGE_THREADS");
}
} else {
requiredPerms.push("MANAGE_CHANNELS");
if (options.permissionOverwrites) {
requiredPerms.push("MANAGE_ROLES");
}
if (options.permissionOverwrites) requiredPerms.push("MANAGE_ROLES");
if (options.type) {
if ([ChannelTypes.GuildAnnouncement, ChannelTypes.GuildText].includes(options.type)) {
@@ -62,9 +58,7 @@ export default function editChannel(bot: BotWithCache) {
}
}
if (options.userLimit && options.userLimit > 99) {
throw new Error("The user limit must be less than 99.");
}
if (options.userLimit && options.userLimit > 99) throw new Error("The user limit must be less than 99.");
if (options.parentId) {
const category = bot.channels.get(options.parentId);
@@ -77,6 +71,6 @@ export default function editChannel(bot: BotWithCache) {
requireBotChannelPermissions(bot, channel, requiredPerms);
}
return await editChannelOld(channelId, options, reason);
return await editChannel(channelId, options, reason);
};
}
@@ -1,15 +1,13 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export default function editChannelPermissionOverrides(bot: BotWithCache) {
const editChannelPermissionOverridesOld = bot.helpers.editChannelPermissionOverrides;
export function editChannelPermissionOverrides(bot: BotWithCache) {
const editChannelPermissionOverrides = bot.helpers.editChannelPermissionOverrides;
bot.helpers.editChannelPermissionOverrides = async function (channelId, overwrite) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]);
}
if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_ROLES"]);
return await editChannelPermissionOverridesOld(channelId, overwrite);
return await editChannelPermissionOverrides(channelId, overwrite);
};
}
@@ -1,15 +1,13 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export default function followAnnouncementChannel(bot: BotWithCache) {
const followAnnouncementChannelOld = bot.helpers.followAnnouncementChannel;
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"]);
}
if (channel?.guildId) requireBotChannelPermissions(bot, channel, ["MANAGE_WEBHOOKS"]);
return await followAnnouncementChannelOld(sourceChannelId, targetChannelId);
return await followAnnouncementChannel(sourceChannelId, targetChannelId);
};
}
@@ -1,16 +1,14 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export default function createForumThread(bot: BotWithCache) {
const createForumThreadOld = bot.helpers.createForumThread;
export function createForumThread(bot: BotWithCache) {
const createForumThread = bot.helpers.createForumThread;
bot.helpers.createForumThread = async function (channelId, options) {
const channel = bot.channels.get(channelId);
if (channel) {
requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
}
if (channel) requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
return await createForumThreadOld(channelId, options);
return await createForumThread(channelId, options);
};
}
@@ -1,6 +1,6 @@
import { BotWithCache } from "../../../deps.ts";
import createForumThread from "./createForumThread.ts";
import { createForumThread } from "./createForumThread.ts";
export default function setupThreadPermChecks(bot: BotWithCache) {
export function forums(bot: BotWithCache) {
createForumThread(bot);
}
@@ -1,15 +1,13 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export default function getChannelWebhooks(bot: BotWithCache) {
const getChannelWebhooksOld = bot.helpers.getChannelWebhooks;
export function getChannelWebhooks(bot: BotWithCache) {
const getChannelWebhooks = bot.helpers.getChannelWebhooks;
bot.helpers.getChannelWebhooks = async function (channelId) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
}
if (channel?.guildId) requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
return await getChannelWebhooksOld(channelId);
return await getChannelWebhooks(channelId);
};
}
+16 -15
View File
@@ -1,21 +1,22 @@
import { BotWithCache } from "../../deps.ts";
import createChannel from "./createChannel.ts";
import deleteChannel from "./deleteChannel.ts";
import deleteChannelPermissionOverride from "./deleteChannelPermissionOverride.ts";
import editChannel from "./editChannel.ts";
import editChannelPermissionOverrides from "./editChannelPermissionOverrides.ts";
import followAnnouncementChannel from "./followAnnouncementChannel.ts";
import setupForumPermChecks from "./forums/mod.ts";
import getChannelWebhooks from "./getChannelWebhooks.ts";
import setupStagePermChecks from "./stage.ts";
import swapChannels from "./swapChannels.ts";
import setupThreadPermChecks from "./threads/mod.ts";
import { createChannel } from "./createChannel.ts";
import { deleteChannel } from "./deleteChannel.ts";
import { deleteChannelPermissionOverride } from "./deleteChannelPermissionOverride.ts";
import { editChannel } from "./editChannel.ts";
import { editChannelPermissionOverrides } from "./editChannelPermissionOverrides.ts";
import { followAnnouncementChannel } from "./followAnnouncementChannel.ts";
import { forums } from "./forums/mod.ts";
import { getChannelWebhooks } from "./getChannelWebhooks.ts";
import { stages } from "./stages/mod.ts";
import { swapChannels } from "./swapChannels.ts";
import { threads } from "./threads/mod.ts";
export function channels(bot: BotWithCache) {
forums(bot);
stages(bot);
threads(bot);
export default function setupChannelPermChecks(bot: BotWithCache) {
createChannel(bot);
setupThreadPermChecks(bot);
setupForumPermChecks(bot);
setupStagePermChecks(bot);
deleteChannel(bot);
deleteChannelPermissionOverride(bot);
editChannel(bot);
-48
View File
@@ -1,48 +0,0 @@
import { BotWithCache, PermissionStrings } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function createStageInstance(bot: BotWithCache) {
const createStageInstanceOld = bot.helpers.createStageInstance;
bot.helpers.createStageInstance = async function (options) {
if (!bot.utils.validateLength(options.topic, { max: 120, min: 1 })) {
throw new Error("The topic length for creating a stage instance must be between 1-120.");
}
const perms = new Set<PermissionStrings>(["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]);
if (options.sendStartNotification) {
perms.add("MENTION_EVERYONE");
}
requireBotChannelPermissions(bot, options.channelId, [...perms.values()]);
return await createStageInstanceOld(options);
};
}
export function deleteStageInstance(bot: BotWithCache) {
const deleteStageInstanceOld = bot.helpers.deleteStageInstance;
bot.helpers.deleteStageInstance = async function (channelId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]);
return await deleteStageInstanceOld(channelId);
};
}
export function editStageInstance(bot: BotWithCache) {
const editStageInstanceOld = bot.helpers.editStageInstance;
bot.helpers.editStageInstance = async function (channelId, data) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]);
return await editStageInstanceOld(channelId, data);
};
}
export default function setupStagePermChecks(bot: BotWithCache) {
createStageInstance(bot);
deleteStageInstance(bot);
editStageInstance(bot);
}
@@ -0,0 +1,16 @@
import { BotWithCache, 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"];
if (options.sendStartNotification) perms.push("MENTION_EVERYONE");
requireBotChannelPermissions(bot, options.channelId, perms);
return await createStageInstance(options);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } 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"]);
return await deleteStageInstance(channelId);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } 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"]);
return await editStageInstance(channelId, data);
};
}
@@ -0,0 +1,10 @@
import { BotWithCache } from "../../../deps.ts";
import { createStageInstance } from "./createStageInstance.ts";
import { deleteStageInstance } from "./deleteStageInstances.ts";
import { editStageInstance } from "./editStageInstance.ts";
export function stages(bot: BotWithCache) {
createStageInstance(bot);
deleteStageInstance(bot);
editStageInstance(bot);
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function swapChannels(bot: BotWithCache) {
const swapChannelsOld = bot.helpers.swapChannels;
export function swapChannels(bot: BotWithCache) {
const swapChannels = bot.helpers.swapChannels;
bot.helpers.swapChannels = async function (guildId, channelPositions) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_CHANNELS"]);
return await swapChannelsOld(guildId, channelPositions);
return await swapChannels(guildId, channelPositions);
};
}
@@ -1,24 +1,18 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export default function addThreadMember(bot: BotWithCache) {
const addThreadMemberOld = bot.helpers.addThreadMember;
export function addThreadMember(bot: BotWithCache) {
const addThreadMember = bot.helpers.addThreadMember;
bot.helpers.addThreadMember = async function (threadId, userId) {
if (userId === bot.id) {
throw new Error("To add the bot to a thread, you must use bot.helpers.joinThread()");
}
const channel = bot.channels.get(threadId);
if (channel) {
if (channel.archived) {
throw new Error("Cannot add user to thread if thread is archived.");
}
if (channel.archived) throw new Error("Cannot add user to thread if thread is archived.");
requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
}
return await addThreadMemberOld(threadId, userId);
return await addThreadMember(threadId, userId);
};
}
@@ -2,12 +2,10 @@ import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function getPrivateArchivedThreads(bot: BotWithCache) {
const getPrivateArchivedThreadsOld = bot.helpers.getPrivateArchivedThreads;
bot.helpers.getPublicArchivedThreads = async function (channelId, options) {
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"]);
}
return await getPrivateArchivedThreadsOld(channelId, options);
if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY", "MANAGE_MESSAGES"]);
return await getPrivateArchivedThreads(channelId, options);
};
}
@@ -2,12 +2,10 @@ import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function getPrivateJoinedArchivedThreads(bot: BotWithCache) {
const getPrivateJoinedArchivedThreadsOld = bot.helpers.getPrivateJoinedArchivedThreads;
bot.helpers.getPublicArchivedThreads = async function (channelId, options) {
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"]);
}
return await getPrivateJoinedArchivedThreadsOld(channelId, options);
if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY"]);
return await getPrivateJoinedArchivedThreads(channelId, options);
};
}
@@ -2,12 +2,10 @@ import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function getPublicArchivedThreads(bot: BotWithCache) {
const getPublicArchivedThreadsOld = bot.helpers.getPublicArchivedThreads;
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"]);
}
return await getPublicArchivedThreadsOld(channelId, options);
if (channel) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY"]);
return await getPublicArchivedThreads(channelId, options);
};
}
@@ -1,16 +0,0 @@
import { BotWithCache, GatewayIntents } from "../../../deps.ts";
export default function getThreadMembers(bot: BotWithCache) {
const getThreadMembersOld = bot.helpers.getThreadMembers;
bot.helpers.getThreadMembers = async function (threadId) {
const hasIntent = bot.intents & GatewayIntents.GuildMembers;
if (!hasIntent) {
throw new Error(
"The get thread members endpoint requires GuildMembers intent.",
);
}
return await getThreadMembersOld(threadId);
};
}
@@ -1,15 +1,13 @@
import { BotWithCache } from "../../../deps.ts";
export default function joinThread(bot: BotWithCache) {
const joinThreadOld = bot.helpers.joinThread;
export function joinThread(bot: BotWithCache) {
const joinThread = bot.helpers.joinThread;
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 && !channel.archived) throw new Error("You can not join an archived channel.");
return await joinThreadOld(threadId);
return await joinThread(threadId);
};
}
@@ -1,15 +1,13 @@
import { BotWithCache } from "../../../deps.ts";
export default function leaveThread(bot: BotWithCache) {
const leaveThreadOld = bot.helpers.leaveThread;
export function leaveThread(bot: BotWithCache) {
const leaveThread = bot.helpers.leaveThread;
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 && !channel.archived) throw new Error("You can not leave an archived channel.");
return await leaveThreadOld(threadId);
return await leaveThread(threadId);
};
}
@@ -1,19 +1,17 @@
import { BotWithCache } from "../../../deps.ts";
import addThreadMember from "./addThreadMember.ts";
import { addThreadMember } from "./addThreadMember.ts";
import { getPrivateArchivedThreads } from "./getPrivateArchivedThreads.ts";
import { getPrivateJoinedArchivedThreads } from "./getPrivateJoinedArchivedThreads.ts";
import { getPublicArchivedThreads } from "./getPublicArchivedThreads.ts";
import getThreadMembers from "./getThreadMembers.ts";
import joinThread from "./joinThread.ts";
import leaveThread from "./leaveThread.ts";
import removeThreadMember from "./removeThreadMember.ts";
import { joinThread } from "./joinThread.ts";
import { leaveThread } from "./leaveThread.ts";
import { removeThreadMember } from "./removeThreadMember.ts";
export default function setupThreadPermChecks(bot: BotWithCache) {
export function threads(bot: BotWithCache) {
addThreadMember(bot);
getPublicArchivedThreads(bot);
getPrivateArchivedThreads(bot);
getPrivateJoinedArchivedThreads(bot);
getThreadMembers(bot);
joinThread(bot);
leaveThread(bot);
removeThreadMember(bot);
@@ -1,26 +1,20 @@
import { BotWithCache, ChannelTypes } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export default function removeThreadMember(bot: BotWithCache) {
const removeThreadMemberOld = bot.helpers.removeThreadMember;
export function removeThreadMember(bot: BotWithCache) {
const removeThreadMember = bot.helpers.removeThreadMember;
bot.helpers.removeThreadMember = async function (threadId, userId) {
if (userId === bot.id) {
throw new Error("To remove the bot from a thread, you must use bot.helpers.leaveThread()");
}
const channel = bot.channels.get(threadId);
if (channel) {
if (channel.archived) {
throw new Error("Cannot remove user from thread if thread is archived.");
}
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"]);
}
}
return await removeThreadMemberOld(threadId, userId);
return await removeThreadMember(threadId, userId);
};
}
-228
View File
@@ -1,228 +0,0 @@
import { Bot, ButtonStyles, Emoji, MessageComponents, MessageComponentTypes } from "../deps.ts";
export function validateComponents(bot: Bot, components: MessageComponents) {
if (!components?.length) return;
let actionRowCounter = 0;
for (const component of components) {
actionRowCounter++;
// Max of 5 ActionRows per message
if (actionRowCounter > 5) throw new Error("Too many action rows.");
// Max of 5 Buttons (or any component type) within an ActionRow
if (component.components?.length > 5) {
throw new Error("Too many components.");
} else if (
component.components?.length > 1 &&
component.components.some((subComponent) => subComponent.type === MessageComponentTypes.SelectMenu)
) {
throw new Error("Select component must be alone.");
}
for (const subComponent of component.components) {
if (
subComponent.customId &&
!bot.utils.validateLength(subComponent.customId, { max: 100 })
) {
throw new Error("The custom id in the component is too big.");
}
// 5 Link buttons can not have a customId
if (subComponent.type === MessageComponentTypes.Button) {
if (subComponent.style === ButtonStyles.Link && subComponent.customId) {
throw new Error("Link buttons can not have custom ids.");
}
// Other buttons must have a customId
if (
!subComponent.customId && subComponent.style !== ButtonStyles.Link
) {
throw new Error(
"The button requires a custom id if it is not a link button.",
);
}
if (!bot.utils.validateLength(subComponent.label, { max: 80 })) {
throw new Error("The label can not be longer than 80 characters.");
}
subComponent.emoji = makeEmojiFromString(subComponent.emoji);
}
if (subComponent.type === MessageComponentTypes.SelectMenu) {
if (
subComponent.placeholder &&
!bot.utils.validateLength(subComponent.placeholder, { max: 150 })
) {
throw new Error(
"The component placeholder can not be longer than 150 characters.",
);
}
if (subComponent.minValues) {
if (subComponent.minValues < 1) {
throw new Error(
"The min values must be more than 1 in a select component.",
);
}
if (subComponent.minValues > 25) {
throw new Error(
"The min values must be less than 25 in a select component.",
);
}
if (!subComponent.maxValues) {
subComponent.maxValues = subComponent.minValues;
}
if (subComponent.minValues > subComponent.maxValues) {
throw new Error(
"The select component can not have a min values higher than a max values.",
);
}
}
if (subComponent.maxValues) {
if (subComponent.maxValues < 1) {
throw new Error(
"The max values must be more than 1 in a select component.",
);
}
if (subComponent.maxValues > 25) {
throw new Error(
"The max values must be less than 25 in a select component.",
);
}
}
if (subComponent.options.length < 1) {
throw new Error("You need at least 1 option in the select component.");
}
if (subComponent.options.length > 25) {
throw new Error(
"You can not have more than 25 options in the select component.",
);
}
let defaults = 0;
for (const option of subComponent.options) {
if (option.default) {
defaults++;
if (defaults > (subComponent.maxValues || 25)) {
throw new Error("You chose too many default options.");
}
}
if (!bot.utils.validateLength(option.label, { max: 25 })) {
throw new Error(
"The select component label can not exceed 25 characters.",
);
}
if (!bot.utils.validateLength(option.value, { max: 100 })) {
throw new Error(
"The select component value can not exceed 100 characters.",
);
}
if (
option.description &&
!bot.utils.validateLength(option.description, { max: 50 })
) {
throw new Error(
"The select option description can not exceed 50 characters.",
);
}
option.emoji = makeEmojiFromString(option.emoji);
}
}
if (subComponent.type === MessageComponentTypes.InputText) {
// Other buttons must have a customId
if (
!subComponent.customId
) {
throw new Error(
"The text input requires a custom id",
);
}
if (!bot.utils.validateLength(subComponent.label, { max: 45 })) {
throw new Error("The label can not be longer than 45 characters.");
}
if (subComponent.minLength) {
if (subComponent.minLength < 0) {
throw new Error(
"The min length must be more than 0 in a text input component.",
);
}
if (subComponent.minLength > 4000) {
throw new Error(
"The min length must be less than 4000 in a text input component.",
);
}
if (subComponent.maxLength && subComponent.minLength > subComponent.maxLength) {
throw new Error(
"The text input component can not have a higher min length than the max length.",
);
}
}
if (subComponent.maxLength) {
if (subComponent.maxLength < 1) {
throw new Error(
"The max length must be more than 1 in a text input component.",
);
}
if (subComponent.maxLength > 4000) {
throw new Error(
"The max length must be less than 4000 in a text input component.",
);
}
}
}
}
}
}
function makeEmojiFromString(
emoji?:
| string
| {
id?: string | bigint | undefined;
name?: string | undefined;
animated?: boolean | undefined;
},
) {
if (!emoji) return;
if (typeof emoji !== "string") {
return {
id: emoji.id ? BigInt(emoji.id) : undefined,
name: emoji.name,
animated: emoji.animated,
};
}
// A snowflake id was provided
if (/^[0-9]+$/.test(emoji)) {
emoji = {
id: BigInt(emoji),
};
} else {
// A unicode emoji was provided
emoji = {
name: emoji,
};
}
return emoji as Emoji;
}
-64
View File
@@ -1,64 +0,0 @@
import { BotWithCache, PermissionStrings } from "../deps.ts";
import { requireBotChannelPermissions, requireBotGuildPermissions } from "./permissions.ts";
export default function editMember(bot: BotWithCache) {
const editMemberOld = bot.helpers.editMember;
bot.helpers.editMember = async function (guildId, memberId, options) {
const requiredPerms: Set<PermissionStrings> = new Set();
if (options.nick) {
if (options.nick.length > 32) {
throw new Error("NICKNAMES_MAX_LENGTH");
}
requiredPerms.add("MANAGE_NICKNAMES");
}
if (options.roles) requiredPerms.add("MANAGE_ROLES");
if (
options.mute !== undefined || options.deaf !== undefined ||
options.channelId !== undefined
) {
const memberVoiceState = (await bot.guilds.get(guildId))
?.voiceStates.get(memberId);
if (!memberVoiceState?.channelId) {
throw new Error("MEMBER_NOT_IN_VOICE_CHANNEL");
}
if (options.mute !== undefined) {
requiredPerms.add("MUTE_MEMBERS");
}
if (options.deaf !== undefined) {
requiredPerms.add("DEAFEN_MEMBERS");
}
if (options.channelId) {
const requiredVoicePerms: Set<PermissionStrings> = new Set([
"CONNECT",
"MOVE_MEMBERS",
]);
if (memberVoiceState) {
await requireBotChannelPermissions(
bot,
memberVoiceState?.channelId,
[
...requiredVoicePerms,
],
);
}
await requireBotChannelPermissions(bot, options.channelId, [
...requiredVoicePerms,
]);
}
}
await requireBotGuildPermissions(bot, guildId, [
...requiredPerms,
]);
return await editMemberOld(guildId, memberId, options);
};
}
-38
View File
@@ -1,38 +0,0 @@
import { BotWithCache } from "../deps.ts";
import { requireBotGuildPermissions } from "./permissions.ts";
export function createEmoji(bot: BotWithCache) {
const createEmojiOld = bot.helpers.createEmoji;
bot.helpers.createEmoji = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await createEmojiOld(guildId, id);
};
}
export function deleteEmoji(bot: BotWithCache) {
const deleteEmojiOld = bot.helpers.deleteEmoji;
bot.helpers.deleteEmoji = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await deleteEmojiOld(guildId, id);
};
}
export function editEmoji(bot: BotWithCache) {
const editEmojiOld = bot.helpers.editEmoji;
bot.helpers.editEmoji = async function (guildId, id, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await editEmojiOld(guildId, id, options);
};
}
export default function setupEmojiPermChecks(bot: BotWithCache) {
createEmoji(bot);
deleteEmoji(bot);
editEmoji(bot);
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function createEmoji(bot: BotWithCache) {
const createEmoji = bot.helpers.createEmoji;
bot.helpers.createEmoji = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await createEmoji(guildId, id);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function deleteEmoji(bot: BotWithCache) {
const deleteEmoji = bot.helpers.deleteEmoji;
bot.helpers.deleteEmoji = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await deleteEmoji(guildId, id);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function editEmoji(bot: BotWithCache) {
const editEmoji = bot.helpers.editEmoji;
bot.helpers.editEmoji = async function (guildId, id, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_EMOJIS"]);
return await editEmoji(guildId, id, options);
};
}
+10
View File
@@ -0,0 +1,10 @@
import { BotWithCache } from "../../deps.ts";
import { createEmoji } from "./createEmoji.ts";
import { deleteEmoji } from "./deleteEmoji.ts";
import { editEmoji } from "./editEmoji.ts";
export function emojis(bot: BotWithCache) {
createEmoji(bot);
deleteEmoji(bot);
editEmoji(bot);
}
-92
View File
@@ -1,92 +0,0 @@
import { AutoModerationActionType, BotWithCache, PermissionStrings } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function getAutomodRule(bot: BotWithCache) {
const getAutomodRuleOld = bot.helpers.getAutomodRule;
bot.helpers.getAutomodRule = async function (guildId, ruleId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getAutomodRuleOld(guildId, ruleId);
};
}
export function getAutomodRules(bot: BotWithCache) {
const getAutomodRulesOld = bot.helpers.getAutomodRules;
bot.helpers.getAutomodRules = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getAutomodRulesOld(guildId);
};
}
export function createAutomodRule(bot: BotWithCache) {
const createAutomodRuleOld = bot.helpers.createAutomodRule;
bot.helpers.createAutomodRule = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
for (const action of options.actions) {
// Check for maximum duration seconds
if (action.metadata?.durationSeconds && action.metadata.durationSeconds > 2419200) {
console.log(
`[Warning] Automod action duration seconds is too high: ${action.metadata.durationSeconds}. Setting to Discord's allowed maximum.`,
);
// Discords max is 4 weeks
action.metadata.durationSeconds = 2419200;
}
// Timeout actions require perm check
if (action.type === AutoModerationActionType.Timeout) {
requireBotGuildPermissions(bot, guildId, ["MODERATE_MEMBERS"]);
}
}
return await createAutomodRuleOld(guildId, options);
};
}
export function editAutomodRule(bot: BotWithCache) {
const editAutomodRuleOld = bot.helpers.editAutomodRule;
bot.helpers.editAutomodRule = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
for (const action of options.actions ?? []) {
// Check for maximum duration seconds
if (action.metadata?.durationSeconds && action.metadata.durationSeconds > 2419200) {
console.log(
`[Warning] Automod action duration seconds is too high: ${action.metadata.durationSeconds}. Setting to Discord's allowed maximum.`,
);
// Discords max is 4 weeks
action.metadata.durationSeconds = 2419200;
}
// Timeout actions require perm check
if (action.type === AutoModerationActionType.Timeout) {
requireBotGuildPermissions(bot, guildId, ["MODERATE_MEMBERS"]);
}
}
return await editAutomodRuleOld(guildId, options);
};
}
export function deleteAutomodRule(bot: BotWithCache) {
const deleteAutomodRuleOld = bot.helpers.deleteAutomodRule;
bot.helpers.deleteAutomodRule = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await deleteAutomodRuleOld(guildId, options);
};
}
export default function setupAutoModerationPermChecks(bot: BotWithCache) {
getAutomodRule(bot);
getAutomodRules(bot);
createAutomodRule(bot);
editAutomodRule(bot);
deleteAutomodRule(bot);
}
@@ -0,0 +1,28 @@
import { AutoModerationActionType, BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function createAutomodRule(bot: BotWithCache) {
const createAutomodRule = bot.helpers.createAutomodRule;
bot.helpers.createAutomodRule = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
for (const action of options.actions) {
// Check for maximum duration seconds
if (action.metadata?.durationSeconds && action.metadata.durationSeconds > 2419200) {
console.log(
`[Warning] Automod action duration seconds is too high: ${action.metadata.durationSeconds}. Setting to Discord's allowed maximum.`,
);
// Discords max is 4 weeks
action.metadata.durationSeconds = 2419200;
}
// Timeout actions require perm check
if (action.type === AutoModerationActionType.Timeout) {
requireBotGuildPermissions(bot, guildId, ["MODERATE_MEMBERS"]);
}
}
return await createAutomodRule(guildId, options);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function deleteAutomodRule(bot: BotWithCache) {
const deleteAutomodRule = bot.helpers.deleteAutomodRule;
bot.helpers.deleteAutomodRule = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await deleteAutomodRule(guildId, options);
};
}
@@ -0,0 +1,28 @@
import { AutoModerationActionType, BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function editAutomodRule(bot: BotWithCache) {
const editAutomodRule = bot.helpers.editAutomodRule;
bot.helpers.editAutomodRule = async function (guildId, ruleId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
for (const action of options.actions ?? []) {
// Check for maximum duration seconds
if (action.metadata?.durationSeconds && action.metadata.durationSeconds > 2419200) {
console.log(
`[Warning] Automod action duration seconds is too high: ${action.metadata.durationSeconds}. Setting to Discord's allowed maximum.`,
);
// Discords max is 4 weeks
action.metadata.durationSeconds = 2419200;
}
// Timeout actions require perm check
if (action.type === AutoModerationActionType.Timeout) {
requireBotGuildPermissions(bot, guildId, ["MODERATE_MEMBERS"]);
}
}
return await editAutomodRule(guildId, ruleId, options);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function getAutomodRule(bot: BotWithCache) {
const getAutomodRule = bot.helpers.getAutomodRule;
bot.helpers.getAutomodRule = async function (guildId, ruleId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getAutomodRule(guildId, ruleId);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function getAutomodRules(bot: BotWithCache) {
const getAutomodRules = bot.helpers.getAutomodRules;
bot.helpers.getAutomodRules = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getAutomodRules(guildId);
};
}
@@ -0,0 +1,14 @@
import { BotWithCache } from "../../../deps.ts";
import { createAutomodRule } from "./createAutomodRule.ts";
import { deleteAutomodRule } from "./deleteAutomodRule.ts";
import { editAutomodRule } from "./editAutomodRule.ts";
import { getAutomodRule } from "./getAutomodRule.ts";
import { getAutomodRules } from "./getAutomodRules.ts";
export function automod(bot: BotWithCache) {
createAutomodRule(bot);
deleteAutomodRule(bot);
editAutomodRule(bot);
getAutomodRule(bot);
getAutomodRules(bot);
}
+4 -15
View File
@@ -1,22 +1,11 @@
import { BotWithCache } from "../../deps.ts";
export default function createGuild(bot: BotWithCache) {
const createGuildOld = bot.helpers.createGuild;
export function createGuild(bot: BotWithCache) {
const createGuild = bot.helpers.createGuild;
bot.helpers.createGuild = async function (options) {
if (bot.guilds.size > 10) {
throw new Error(
"A bot can not create a guild if it is already in 10 guilds.",
);
}
if (bot.guilds.size > 10) throw new Error("A bot can not create a guild if it is already in 10 guilds.");
if (
options.name &&
!bot.utils.validateLength(options.name, { min: 2, max: 100 })
) {
throw new Error("The guild name must be between 2 and 100 characters.");
}
return await createGuildOld(options);
return await createGuild(options);
};
}
@@ -1,14 +1,12 @@
import { BotWithCache } from "../../deps.ts";
export default function deleteGuild(bot: BotWithCache) {
const deleteGuildOld = bot.helpers.deleteGuild;
export function deleteGuild(bot: BotWithCache) {
const deleteGuild = bot.helpers.deleteGuild;
bot.helpers.deleteGuild = async function (guildId) {
const guild = bot.guilds.get(guildId);
if (guild && guild.ownerId !== bot.id) {
throw new Error("A bot can only delete a guild it owns.");
}
if (guild && guild.ownerId !== bot.id) throw new Error("A bot can only delete a guild it owns.");
return await deleteGuildOld(guildId);
return await deleteGuild(guildId);
};
}
+4 -6
View File
@@ -1,16 +1,14 @@
import { BotWithCache, GuildFeatures } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function editGuild(bot: BotWithCache) {
const editGuildOld = bot.helpers.editGuild;
export function editGuild(bot: BotWithCache) {
const editGuild = bot.helpers.editGuild;
bot.helpers.editGuild = async function (guildId, options, shardId) {
if (options.features?.includes(GuildFeatures.Community)) {
requireBotGuildPermissions(bot, guildId, ["ADMINISTRATOR"]);
} else {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
}
} else requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await editGuildOld(guildId, options, shardId);
return await editGuild(guildId, options, shardId);
};
}
@@ -1,11 +1,11 @@
import { BotWithCache } from "../../deps.ts";
export default function editGuildMfaLevel(bot: BotWithCache) {
const editGuildMfaLevelOld = bot.helpers.editGuildMfaLevel;
export function editGuildMfaLevel(bot: BotWithCache) {
const editGuildMfaLevel = bot.helpers.editGuildMfaLevel;
bot.helpers.editGuildMfaLevel = async function (guildId, mfaLevel, reason) {
const guild = bot.guilds.get(guildId);
if (guild?.ownerId !== bot.id) throw new Error("The bot is not the owner of the guild");
return await editGuildMfaLevelOld(guildId, mfaLevel, reason);
return await editGuildMfaLevel(guildId, mfaLevel, reason);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function editWelcomeScreen(bot: BotWithCache) {
const editWelcomeScreen = bot.helpers.editWelcomeScreen;
bot.helpers.editWelcomeScreen = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await editWelcomeScreen(guildId, options);
};
}
@@ -1,16 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function editWidgetSettings(bot: BotWithCache) {
const editWidgetSettingsOld = bot.helpers.editWidgetSettings;
bot.helpers.editWidgetSettings = async function (guildId, enabled, channelId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await editWidgetSettingsOld(guildId, enabled, channelId);
};
}
export default function (bot: BotWithCache) {
editWidgetSettings(bot);
}
-141
View File
@@ -1,141 +0,0 @@
import { BotWithCache, ScheduledEventEntityType } from "../../deps.ts";
import { requireBotChannelPermissions, requireBotGuildPermissions } from "../permissions.ts";
export function createScheduledEvent(bot: BotWithCache) {
const createScheduledEventOld = bot.helpers.createScheduledEvent;
bot.helpers.createScheduledEvent = async function (guildId, options) {
if (options.entityType === ScheduledEventEntityType.StageInstance) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a stage scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_CHANNELS",
"MUTE_MEMBERS",
"MOVE_MEMBERS",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return createScheduledEventOld(guildId, options);
}
if (options.entityType === ScheduledEventEntityType.Voice) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a voice scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"VIEW_CHANNEL",
"CONNECT",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return createScheduledEventOld(guildId, options);
}
// EXTERNAL EVENTS
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
return await createScheduledEventOld(guildId, options);
};
}
export function editScheduledEvent(bot: BotWithCache) {
const editScheduledEventOld = bot.helpers.editScheduledEvent;
bot.helpers.editScheduledEvent = async function (guildId, eventId, options) {
if (options.entityType === ScheduledEventEntityType.StageInstance) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a stage scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_CHANNELS",
"MUTE_MEMBERS",
"MOVE_MEMBERS",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return editScheduledEventOld(guildId, eventId, options);
}
if (options.entityType === ScheduledEventEntityType.Voice) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a voice scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"VIEW_CHANNEL",
"CONNECT",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return editScheduledEventOld(guildId, eventId, options);
}
// EXTERNAL EVENTS
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
return await editScheduledEventOld(guildId, eventId, options);
};
}
export default function setupEventsPermChecks(bot: BotWithCache) {
createScheduledEvent(bot);
editScheduledEvent(bot);
}
@@ -0,0 +1,69 @@
import { BotWithCache, ScheduledEventEntityType } from "../../../deps.ts";
import { requireBotChannelPermissions, requireBotGuildPermissions } from "../../permissions.ts";
export function createScheduledEvent(bot: BotWithCache) {
const createScheduledEvent = bot.helpers.createScheduledEvent;
bot.helpers.createScheduledEvent = async function (guildId, options) {
if (options.entityType === ScheduledEventEntityType.StageInstance) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a stage scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_CHANNELS",
"MUTE_MEMBERS",
"MOVE_MEMBERS",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return createScheduledEvent(guildId, options);
}
if (options.entityType === ScheduledEventEntityType.Voice) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a voice scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"VIEW_CHANNEL",
"CONNECT",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return createScheduledEvent(guildId, options);
}
// EXTERNAL EVENTS
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
return await createScheduledEvent(guildId, options);
};
}
@@ -0,0 +1,69 @@
import { BotWithCache, ScheduledEventEntityType } from "../../../deps.ts";
import { requireBotChannelPermissions, requireBotGuildPermissions } from "../../permissions.ts";
export function editScheduledEvent(bot: BotWithCache) {
const editScheduledEvent = bot.helpers.editScheduledEvent;
bot.helpers.editScheduledEvent = async function (guildId, eventId, options) {
if (options.entityType === ScheduledEventEntityType.StageInstance) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a stage scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_CHANNELS",
"MUTE_MEMBERS",
"MOVE_MEMBERS",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return editScheduledEvent(guildId, eventId, options);
}
if (options.entityType === ScheduledEventEntityType.Voice) {
if (!options.channelId) {
throw new Error(
"A channel id is required for creating a voice scheduled event.",
);
}
requireBotChannelPermissions(bot, options.channelId, [
"VIEW_CHANNEL",
"CONNECT",
]);
// MANAGE_EVENTS at the guild level or at least MANAGE_EVENTS for the channel_id associated with the event
try {
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
} catch {
requireBotChannelPermissions(bot, options.channelId, [
"MANAGE_EVENTS",
]);
}
return editScheduledEvent(guildId, eventId, options);
}
// EXTERNAL EVENTS
requireBotGuildPermissions(bot, guildId, [
"MANAGE_EVENTS",
]);
return await editScheduledEvent(guildId, eventId, options);
};
}
@@ -0,0 +1,8 @@
import { BotWithCache } from "../../../deps.ts";
import { createScheduledEvent } from "./createScheduledEvent.ts";
import { editScheduledEvent } from "./editScheduledEvent.ts";
export function events(bot: BotWithCache) {
createScheduledEvent(bot);
editScheduledEvent(bot);
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function getAuditLog(bot: BotWithCache) {
const getAuditLogOld = bot.helpers.getAuditLog;
export function getAuditLog(bot: BotWithCache) {
const getAuditLog = bot.helpers.getAuditLog;
bot.helpers.getAuditLog = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["VIEW_AUDIT_LOG"]);
return await getAuditLogOld(guildId, options);
return await getAuditLog(guildId, options);
};
}
+3 -3
View File
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function getBan(bot: BotWithCache) {
const getBanOld = bot.helpers.getBan;
export function getBan(bot: BotWithCache) {
const getBan = bot.helpers.getBan;
bot.helpers.getBan = async function (guildId, memberId) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await getBanOld(guildId, memberId);
return await getBan(guildId, memberId);
};
}
+3 -3
View File
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function getBans(bot: BotWithCache) {
const getBansOld = bot.helpers.getBans;
export function getBans(bot: BotWithCache) {
const getBans = bot.helpers.getBans;
bot.helpers.getBans = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await getBansOld(guildId);
return await getBans(guildId);
};
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function getPruneCount(bot: BotWithCache) {
const getPruneCountOld = bot.helpers.getPruneCount;
export function getPruneCount(bot: BotWithCache) {
const getPruneCount = bot.helpers.getPruneCount;
bot.helpers.getPruneCount = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]);
return await getPruneCountOld(guildId, options);
return await getPruneCount(guildId, options);
};
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function getVanityUrl(bot: BotWithCache) {
const getVanityUrlOld = bot.helpers.getVanityUrl;
export function getVanityUrl(bot: BotWithCache) {
const getVanityUrl = bot.helpers.getVanityUrl;
bot.helpers.getVanityUrl = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getVanityUrlOld(guildId);
return await getVanityUrl(guildId);
};
}
@@ -0,0 +1,13 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function getWelcomeScreen(bot: BotWithCache) {
const getWelcomeScreen = bot.helpers.getWelcomeScreen;
bot.helpers.getWelcomeScreen = async function (guildId) {
const guild = bot.guilds.get(guildId);
if (!guild?.welcomeScreen) requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getWelcomeScreen(guildId);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function createInvite(bot: BotWithCache) {
const createInvite = bot.helpers.createInvite;
bot.helpers.createInvite = async function (channelId, options = {}) {
requireBotChannelPermissions(bot, channelId, ["CREATE_INSTANT_INVITE"]);
return await createInvite(channelId, options);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function getChannelInvites(bot: BotWithCache) {
const getChannelInvites = bot.helpers.getChannelInvites;
bot.helpers.getChannelInvites = async function (channelId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS"]);
return await getChannelInvites(channelId);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function getInvites(bot: BotWithCache) {
const getInvites = bot.helpers.getInvites;
bot.helpers.getInvites = async function (guildId) {
requireBotChannelPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getInvites(guildId);
};
}
+24 -15
View File
@@ -1,26 +1,35 @@
import { BotWithCache } from "../../deps.ts";
import createGuild from "./createGuild.ts";
import deleteGuild from "./deleteGuild.ts";
import editGuild from "./editGuild.ts";
import editWidgetSettings from "./editWidgetSettings.ts";
import setupEventsPermChecks from "./events.ts";
import getAuditLog from "./getAuditLog.ts";
import getBan from "./getBan.ts";
import getBans from "./getBans.ts";
import getPruneCount from "./getPruneCount.ts";
import getVanityUrl from "./getVanityUrl.ts";
import setupWelcomeScreenPermChecks from "./welcomeScreen.ts";
import { automod } from "./automod/mod.ts";
import { createGuild } from "./createGuild.ts";
import { deleteGuild } from "./deleteGuild.ts";
import { editGuild } from "./editGuild.ts";
import { editGuildMfaLevel } from "./editGuildMfaLevel.ts";
import { editWelcomeScreen } from "./editWelcomeScreen.ts";
import { events } from "./events/mod.ts";
import { getAuditLog } from "./getAuditLog.ts";
import { getBan } from "./getBan.ts";
import { getBans } from "./getBans.ts";
import { getPruneCount } from "./getPruneCount.ts";
import { getVanityUrl } from "./getVanityUrl.ts";
import { getWelcomeScreen } from "./getWelcomeScreen.ts";
import { voice } from "./voice/mod.ts";
import { widgets } from "./widgets/mod.ts";
export function guilds(bot: BotWithCache) {
automod(bot);
events(bot);
voice(bot);
widgets(bot);
export default function setupGuildPermChecks(bot: BotWithCache) {
createGuild(bot);
deleteGuild(bot);
editGuild(bot);
editWidgetSettings(bot);
setupEventsPermChecks(bot);
editGuildMfaLevel(bot);
editWelcomeScreen(bot);
getAuditLog(bot);
getBan(bot);
getBans(bot);
getPruneCount(bot);
getVanityUrl(bot);
setupWelcomeScreenPermChecks(bot);
getWelcomeScreen(bot);
}
@@ -1,14 +1,10 @@
import { BotWithCache, ChannelTypes, PermissionStrings } from "../deps.ts";
import { requireBotChannelPermissions } from "./permissions.ts";
import { BotWithCache, ChannelTypes, PermissionStrings } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export default function connectToVoiceChannel(bot: BotWithCache) {
const connectToVoiceChannelOld = bot.helpers.connectToVoiceChannel;
export function connectToVoiceChannel(bot: BotWithCache) {
const connectToVoiceChannel = bot.helpers.connectToVoiceChannel;
bot.helpers.connectToVoiceChannel = async function (
guildId,
channelId,
options,
) {
bot.helpers.connectToVoiceChannel = async function (guildId, channelId, options) {
const channel = bot.channels.get(channelId);
if (!channel) throw new Error("CHANNEL_NOT_FOUND");
@@ -40,6 +36,6 @@ export default function connectToVoiceChannel(bot: BotWithCache) {
requireBotChannelPermissions(bot, channel, permsNeeded);
return await connectToVoiceChannelOld(guildId, channelId, options);
return await connectToVoiceChannel(guildId, channelId, options);
};
}
@@ -0,0 +1,6 @@
import { BotWithCache } from "../../../deps.ts";
import { connectToVoiceChannel } from "./connectToVoiceChannels.ts";
export function voice(bot: BotWithCache) {
connectToVoiceChannel(bot);
}
@@ -1,30 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function getWelcomeScreen(bot: BotWithCache) {
const getWelcomeScreenOld = bot.helpers.getWelcomeScreen;
bot.helpers.getWelcomeScreen = async function (guildId) {
const guild = bot.guilds.get(guildId);
if (!guild?.welcomeScreen) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
}
return await getWelcomeScreenOld(guildId);
};
}
export function editWelcomeScreen(bot: BotWithCache) {
const editWelcomeScreenOld = bot.helpers.editWelcomeScreen;
bot.helpers.editWelcomeScreen = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await editWelcomeScreenOld(guildId, options);
};
}
export default function setupWelcomeScreenPermChecks(bot: BotWithCache) {
getWelcomeScreen(bot);
editWelcomeScreen(bot);
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotGuildPermissions } from "../../permissions.ts";
export function editWidgetSettings(bot: BotWithCache) {
const editWidgetSettings = bot.helpers.editWidgetSettings;
bot.helpers.editWidgetSettings = async function (guildId, enabled, channelId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await editWidgetSettings(guildId, enabled, channelId);
};
}
@@ -0,0 +1,6 @@
import { BotWithCache } from "../../../deps.ts";
import { editWidgetSettings } from "./editWidgetSettings.ts";
export function widgets(bot: BotWithCache) {
editWidgetSettings(bot);
}
-27
View File
@@ -1,27 +0,0 @@
import { BotWithCache } from "../deps.ts";
import { requireBotGuildPermissions } from "./permissions.ts";
export function deleteIntegration(bot: BotWithCache) {
const deleteIntegrationOld = bot.helpers.deleteIntegration;
bot.helpers.deleteIntegration = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await deleteIntegrationOld(guildId, id);
};
}
export function getIntegrations(bot: BotWithCache) {
const getIntegrationsOld = bot.helpers.getIntegrations;
bot.helpers.getIntegrations = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getIntegrationsOld(guildId);
};
}
export default function setupIntegrationPermChecks(bot: BotWithCache) {
deleteIntegration(bot);
getIntegrations(bot);
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function deleteIntegration(bot: BotWithCache) {
const deleteIntegration = bot.helpers.deleteIntegration;
bot.helpers.deleteIntegration = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await deleteIntegration(guildId, id);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function getIntegrations(bot: BotWithCache) {
const getIntegrations = bot.helpers.getIntegrations;
bot.helpers.getIntegrations = async function (guildId) {
requireBotGuildPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getIntegrations(guildId);
};
}
@@ -0,0 +1,8 @@
import { BotWithCache } from "../../deps.ts";
import { deleteIntegration } from "./deleteIntegrations.ts";
import { getIntegrations } from "./getIntegrations.ts";
export function integrations(bot: BotWithCache) {
deleteIntegration(bot);
getIntegrations(bot);
}
@@ -1,192 +0,0 @@
import {
AllowedMentionsTypes,
ApplicationCommandOption,
ApplicationCommandOptionTypes,
ApplicationCommandTypes,
BotWithCache,
CONTEXT_MENU_COMMANDS_NAME_REGEX,
SLASH_COMMANDS_NAME_REGEX,
} from "../../deps.ts";
export function validateApplicationCommandOptions(bot: BotWithCache, options: ApplicationCommandOption[]) {
const requiredOptions: ApplicationCommandOption[] = [];
const optionalOptions: ApplicationCommandOption[] = [];
for (const option of options) {
option.name = option.name.toLowerCase();
if (option.choices?.length) {
if (option.choices.length > 25) {
throw new Error("Too many application command options provided.");
}
if (
option.type !== ApplicationCommandOptionTypes.String && option.type !== ApplicationCommandOptionTypes.Integer
) {
throw new Error("Only string or integer options can have choices.");
}
}
if (!bot.utils.validateLength(option.name, { min: 1, max: 32 })) {
throw new Error("Invalid application command option name.");
}
if (!bot.utils.validateLength(option.description, { min: 1, max: 100 })) {
throw new Error("Invalid application command description.");
}
option.choices?.every((choice) => {
if (!bot.utils.validateLength(choice.name, { min: 1, max: 100 })) {
throw new Error("Invalid application command option choice name. Must be between 1-100 characters long.");
}
if (
option.type === ApplicationCommandOptionTypes.String &&
(typeof choice.value !== "string" || choice.value.length < 1 || choice.value.length > 100)
) {
throw new Error("Invalid slash options choice value type.");
}
if (option.type === ApplicationCommandOptionTypes.Integer && typeof choice.value !== "number") {
throw new Error("A number must be set for Integer types.");
}
});
if (option.required) {
requiredOptions.push(option);
continue;
}
optionalOptions.push(option);
}
return [...requiredOptions, ...optionalOptions];
}
export function createGuildApplicationCommand(bot: BotWithCache) {
const createGuildApplicationCommandOld = bot.helpers.createGuildApplicationCommand;
bot.helpers.createGuildApplicationCommand = async function (options, guildId) {
const isChatInput = !options.type || options.type === ApplicationCommandTypes.ChatInput;
if (!options.name) {
throw new Error("A name is required to create a options.");
}
if (isChatInput) {
if (!SLASH_COMMANDS_NAME_REGEX.test(options.name)) {
throw new Error("The name of the slash command did not match the required regex.");
}
// Only slash need to be lowercase
options.name = options.name.toLowerCase();
// Slash commands require description
if (!options.description) {
throw new Error("Slash commands require some form of a description be provided.");
} else if (!bot.utils.validateLength(options.description, { min: 1, max: 100 })) {
throw new Error("Application command descriptions must be between 1 and 100 characters.");
}
if (options.options?.length) {
if (options.options.length > 25) {
throw new Error("Only 25 options are allowed to be provided.");
}
options.options = validateApplicationCommandOptions(bot, options.options);
}
} else {
if (!CONTEXT_MENU_COMMANDS_NAME_REGEX.test(options.name)) {
throw new Error("The name of the context menu did not match the required regex.");
}
}
return await createGuildApplicationCommandOld(options, guildId);
};
}
export function createGlobalApplicationCommand(bot: BotWithCache) {
const createGlobalApplicationCommandOld = bot.helpers.createGlobalApplicationCommand;
bot.helpers.createGlobalApplicationCommand = async function (options) {
const isChatInput = !options.type || options.type === ApplicationCommandTypes.ChatInput;
if (!options.name) {
throw new Error("A name is required to create a options.");
}
if (isChatInput) {
if (!SLASH_COMMANDS_NAME_REGEX.test(options.name)) {
throw new Error("The name of the slash command did not match the required regex.");
}
// Only slash need to be lowercase
options.name = options.name.toLowerCase();
// Slash commands require description
if (!options.description) {
throw new Error("Slash commands require some form of a description be provided.");
} else if (!bot.utils.validateLength(options.description, { min: 1, max: 100 })) {
throw new Error("Application command descriptions must be between 1 and 100 characters.");
}
if (options.options?.length) {
if (options.options.length > 25) {
throw new Error("Only 25 options are allowed to be provided.");
}
options.options = validateApplicationCommandOptions(bot, options.options);
}
} else {
if (!CONTEXT_MENU_COMMANDS_NAME_REGEX.test(options.name)) {
throw new Error("The name of the context menu did not match the required regex.");
}
}
return await createGlobalApplicationCommandOld(options);
};
}
export function editOriginalInteractionResponse(bot: BotWithCache) {
const editOriginalInteractionResponseOld = bot.helpers.editOriginalInteractionResponse;
bot.helpers.editOriginalInteractionResponse = async function (token, options) {
if (options.content && options.content.length > 2000) {
throw Error(bot.constants.Errors.MESSAGE_MAX_LENGTH);
}
if (options.embeds && options.embeds.length > 10) {
options.embeds.splice(10);
}
if (options.allowedMentions) {
if (options.allowedMentions.users?.length) {
if (options.allowedMentions.parse?.includes(AllowedMentionsTypes.UserMentions)) {
options.allowedMentions.parse = options.allowedMentions.parse.filter((p) => p !== "users");
}
if (options.allowedMentions.users.length > 100) {
options.allowedMentions.users = options.allowedMentions.users.slice(0, 100);
}
}
if (options.allowedMentions.roles?.length) {
if (options.allowedMentions.parse?.includes(AllowedMentionsTypes.RoleMentions)) {
options.allowedMentions.parse = options.allowedMentions.parse.filter((p) => p !== "roles");
}
if (options.allowedMentions.roles.length > 100) {
options.allowedMentions.roles = options.allowedMentions.roles.slice(0, 100);
}
}
}
return await editOriginalInteractionResponseOld(token, options);
};
}
export default function setupInteractionCommandPermChecks(bot: BotWithCache) {
createGlobalApplicationCommand(bot);
createGuildApplicationCommand(bot);
editOriginalInteractionResponse(bot);
}
@@ -1,39 +0,0 @@
import { AllowedMentionsTypes, BotWithCache } from "../../deps.ts";
export default function editFollowupMessage(bot: BotWithCache) {
const editFollowupMessageOld = bot.helpers.editFollowupMessage;
bot.helpers.editFollowupMessage = async function (token, messageId, options) {
if (options.content && options.content.length > 2000) {
throw Error("MESSAGE_MAX_LENGTH");
}
if (options.embeds && options.embeds.length > 10) {
options.embeds.splice(10);
}
if (options.allowedMentions) {
if (options.allowedMentions.users?.length) {
if (options.allowedMentions.parse?.includes(AllowedMentionsTypes.UserMentions)) {
options.allowedMentions.parse = options.allowedMentions.parse.filter((p) => p !== "users");
}
if (options.allowedMentions.users.length > 100) {
options.allowedMentions.users = options.allowedMentions.users.slice(0, 100);
}
}
if (options.allowedMentions.roles?.length) {
if (options.allowedMentions.parse?.includes(AllowedMentionsTypes.RoleMentions)) {
options.allowedMentions.parse = options.allowedMentions.parse.filter((p) => p !== "roles");
}
if (options.allowedMentions.roles.length > 100) {
options.allowedMentions.roles = options.allowedMentions.roles.slice(0, 100);
}
}
}
return await editFollowupMessageOld(token, messageId, options);
};
}
@@ -1,39 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import setupInteractionCommandPermChecks from "./commands.ts";
import editFollowupMessage from "./editFollowupMessage.ts";
export function sendInteractionResponse(bot: BotWithCache) {
const sendInteractionResponseOld = bot.helpers.sendInteractionResponse;
bot.helpers.sendInteractionResponse = function (id, token, options) {
if (options.data?.title !== undefined) {
if (!bot.utils.validateLength(options.data.title, { min: 1, max: 45 })) {
throw new Error(
"Invalid modal title. Must be between 1-45 characters long.",
);
}
}
options.data?.choices?.every((choice) => {
if (!bot.utils.validateLength(choice.name, { min: 1, max: 100 })) {
throw new Error(
"Invalid application command option choice name. Must be between 1-100 characters long.",
);
}
if (
typeof choice.value === "string" && (choice.value.length < 1 ||
choice.value.length > 100)
) {
throw new Error("Invalid slash options choice value type.");
}
});
return sendInteractionResponseOld(id, token, options);
};
}
export default function setupInteractionPermChecks(bot: BotWithCache) {
setupInteractionCommandPermChecks(bot);
editFollowupMessage(bot);
}
-47
View File
@@ -1,47 +0,0 @@
import { BotWithCache } from "../deps.ts";
import { requireBotChannelPermissions } from "./permissions.ts";
export function createInvite(bot: BotWithCache) {
const createInviteOld = bot.helpers.createInvite;
bot.helpers.createInvite = async function (channelId, options = {}) {
if (options.maxAge && (options.maxAge < 0 || options.maxAge > 604800)) {
throw new Error(
"The max age for an invite must be between 0 and 604800.",
);
}
if (options.maxUses && (options.maxUses < 0 || options.maxUses > 100)) {
throw new Error("The max uses for an invite must be between 0 and 100.");
}
requireBotChannelPermissions(bot, channelId, ["CREATE_INSTANT_INVITE"]);
return await createInviteOld(channelId, options);
};
}
export function getChannelInvites(bot: BotWithCache) {
const getChannelInvitesOld = bot.helpers.getChannelInvites;
bot.helpers.getChannelInvites = async function (channelId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_CHANNELS"]);
return await getChannelInvitesOld(channelId);
};
}
export function getInvites(bot: BotWithCache) {
const getInvitesOld = bot.helpers.getInvites;
bot.helpers.getInvites = async function (guildId) {
requireBotChannelPermissions(bot, guildId, ["MANAGE_GUILD"]);
return await getInvitesOld(guildId);
};
}
export default function setupInvitesPermChecks(bot: BotWithCache) {
createInvite(bot);
getChannelInvites(bot);
getInvites(bot);
}
-27
View File
@@ -1,27 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function banMember(bot: BotWithCache) {
const banMemberOld = bot.helpers.banMember;
bot.helpers.banMember = async function (guildId, id, options) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await banMemberOld(guildId, id, options);
};
}
export function unbanMember(bot: BotWithCache) {
const unbanMemberOld = bot.helpers.unbanMember;
bot.helpers.unbanMember = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await unbanMemberOld(guildId, id);
};
}
export default function setupBanPermChecks(bot: BotWithCache) {
banMember(bot);
unbanMember(bot);
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function banMember(bot: BotWithCache) {
const banMember = bot.helpers.banMember;
bot.helpers.banMember = async function (guildId, id, options) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await banMember(guildId, id, options);
};
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function editBotMember(bot: BotWithCache) {
const editBotMemberOld = bot.helpers.editBotMember;
export function editBotMember(bot: BotWithCache) {
const editBotMember = bot.helpers.editBotMember;
bot.helpers.editBotMember = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["CHANGE_NICKNAME"]);
return await editBotMemberOld(guildId, options);
return await editBotMember(guildId, options);
};
}
+24 -19
View File
@@ -1,33 +1,38 @@
import { BotWithCache, PermissionStrings } from "../../deps.ts";
import { hasGuildPermissions, requireBotGuildPermissions, requireGuildPermissions } from "../permissions.ts";
import { requireBotChannelPermissions, requireBotGuildPermissions } from "../permissions.ts";
export default function editMember(bot: BotWithCache) {
const editMemberOld = bot.helpers.editMember;
export function editMember(bot: BotWithCache) {
const editMember = bot.helpers.editMember;
bot.helpers.editMember = async function (guildId, memberId, options) {
const requiredPerms: PermissionStrings[] = [];
if (options.nick) requiredPerms.push("MANAGE_NICKNAMES");
if (options.roles) requiredPerms.push("MANAGE_ROLES");
// NULL IS ALLOWED
if (options.nick !== undefined) requiredPerms.push("MANAGE_NICKNAMES");
if (options.channelId !== undefined) requiredPerms.push("MOVE_MEMBERS");
if (options.mute !== undefined) requiredPerms.push("MUTE_MEMBERS");
if (options.deaf !== undefined) requiredPerms.push("DEAFEN_MEMBERS");
if (options.communicationDisabledUntil) {
const guild = bot.guilds.get(guildId);
if (guild) {
if (guild.ownerId === memberId) throw new Error("You can not timeout the servers owner.");
}
if (
options.mute !== undefined || options.deaf !== undefined ||
options.channelId !== undefined
) {
const memberVoiceState = (bot.guilds.get(guildId))
?.voiceStates.get(memberId);
if (hasGuildPermissions(bot, guildId, memberId, ["ADMINISTRATOR"])) {
throw new Error("You can not timeout a server administrator.");
if (!memberVoiceState?.channelId) throw new Error("MEMBER_NOT_IN_VOICE_CHANNEL");
if (options.mute !== undefined) requiredPerms.push("MUTE_MEMBERS");
if (options.deaf !== undefined) requiredPerms.push("DEAFEN_MEMBERS");
if (options.channelId) {
const requiredVoicePerms: PermissionStrings[] = ["CONNECT", "MOVE_MEMBERS"];
if (memberVoiceState) requireBotChannelPermissions(bot, memberVoiceState?.channelId, requiredVoicePerms);
requireBotChannelPermissions(bot, options.channelId, requiredVoicePerms);
}
}
if (requiredPerms.length) {
requireBotGuildPermissions(bot, guildId, requiredPerms);
}
requireBotGuildPermissions(bot, guildId, requiredPerms);
return await editMemberOld(guildId, memberId, options);
return await editMember(guildId, memberId, options);
};
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function kickMember(bot: BotWithCache) {
const editMemberOld = bot.helpers.kickMember;
export function kickMember(bot: BotWithCache) {
const kickMember = bot.helpers.kickMember;
bot.helpers.kickMember = async function (guildId, memberId, reason) {
requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]);
return await editMemberOld(guildId, memberId, reason);
return await kickMember(guildId, memberId, reason);
};
}
+9 -7
View File
@@ -1,14 +1,16 @@
import { BotWithCache } from "../../deps.ts";
import setupBanPermChecks from "./ban.ts";
import editBotMember from "./editBotMember.ts";
import editMember from "./editMember.ts";
import kickMember from "./kickMember.ts";
import pruneMembers from "./pruneMembers.ts";
import { banMember } from "./banMember.ts";
import { editBotMember } from "./editBotMember.ts";
import { editMember } from "./editMember.ts";
import { kickMember } from "./kickMember.ts";
import { pruneMembers } from "./pruneMembers.ts";
import { unbanMember } from "./unbanMember.ts";
export default function setupMemberPermChecks(bot: BotWithCache) {
setupBanPermChecks(bot);
export function members(bot: BotWithCache) {
banMember(bot);
editBotMember(bot);
editMember(bot);
kickMember(bot);
pruneMembers(bot);
unbanMember(bot);
}
@@ -1,12 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export default function pruneMembers(bot: BotWithCache) {
const pruneMembersOld = bot.helpers.pruneMembers;
export function pruneMembers(bot: BotWithCache) {
const pruneMembers = bot.helpers.pruneMembers;
bot.helpers.pruneMembers = async function (guildId, options) {
requireBotGuildPermissions(bot, guildId, ["KICK_MEMBERS"]);
return await pruneMembersOld(guildId, options);
return await pruneMembers(guildId, options);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotGuildPermissions } from "../permissions.ts";
export function unbanMember(bot: BotWithCache) {
const unbanMember = bot.helpers.unbanMember;
bot.helpers.unbanMember = async function (guildId, id) {
requireBotGuildPermissions(bot, guildId, ["BAN_MEMBERS"]);
return await unbanMember(guildId, id);
};
}
-198
View File
@@ -1,198 +0,0 @@
import { AllowedMentionsTypes, BotWithCache, ChannelTypes, PermissionStrings } from "../../deps.ts";
import { validateAttachments } from "../attachments.ts";
import { validateComponents } from "../components.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function sendMessage(bot: BotWithCache) {
const sendMessageOld = bot.helpers.sendMessage;
bot.helpers.sendMessage = async function (
channelId,
content,
) {
if (typeof content === "string") {
throw new Error("TODO");
}
const channel = bot.channels.get(channelId);
if (
channel &&
[
ChannelTypes.GuildCategory,
ChannelTypes.GuildStageVoice,
ChannelTypes.GuildForum,
].includes(channel.type)
) {
throw new Error(
`Can not send message to a channel of this type. Channel ID: ${channelId}`,
);
}
if (
content.content &&
!bot.utils.validateLength(content.content, { max: 2000 })
) {
throw new Error("The content should not exceed 2000 characters.");
}
if (content.allowedMentions) {
if (content.allowedMentions.users?.length) {
if (
content.allowedMentions.parse?.includes(
AllowedMentionsTypes.UserMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter((
p,
) => p !== "users");
}
if (content.allowedMentions.users.length > 100) {
content.allowedMentions.users = content.allowedMentions.users.slice(
0,
100,
);
}
}
if (content.allowedMentions.roles?.length) {
if (
content.allowedMentions.parse?.includes(
AllowedMentionsTypes.RoleMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter((
p,
) => p !== "roles");
}
if (content.allowedMentions.roles.length > 100) {
content.allowedMentions.roles = content.allowedMentions.roles.slice(
0,
100,
);
}
}
}
if (content.components) {
validateComponents(bot, content.components);
}
if (channel) {
const requiredPerms: PermissionStrings[] = [];
if (channel.guildId) {
requiredPerms.push("SEND_MESSAGES");
}
if (content.tts) requiredPerms.push("SEND_TTS_MESSAGES");
if (content.messageReference) requiredPerms.push("READ_MESSAGE_HISTORY");
if (requiredPerms.length) {
requireBotChannelPermissions(bot, channel, requiredPerms);
}
}
return await sendMessageOld(channelId, content);
};
}
export function editMessage(bot: BotWithCache) {
const editMessageOld = bot.helpers.editMessage;
bot.helpers.editMessage = function (
channelId,
messageId,
content,
) {
if (typeof content === "string") {
throw new Error("TODO");
}
const message = bot.messages.get(messageId);
if (message) {
if (message.authorId !== bot.id) {
content = { flags: content.flags };
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
}
}
if (content.allowedMentions) {
if (content.allowedMentions.users?.length) {
if (
content.allowedMentions.parse?.includes(
AllowedMentionsTypes.UserMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter((
p,
) => p !== "users");
}
if (content.allowedMentions.users.length > 100) {
content.allowedMentions.users = content.allowedMentions.users.slice(
0,
100,
);
}
}
if (content.allowedMentions.roles?.length) {
if (
content.allowedMentions.parse?.includes(
AllowedMentionsTypes.RoleMentions,
)
) {
content.allowedMentions.parse = content.allowedMentions.parse.filter((
p,
) => p !== "roles");
}
if (content.allowedMentions.roles.length > 100) {
content.allowedMentions.roles = content.allowedMentions.roles.slice(
0,
100,
);
}
}
}
content.embeds?.splice(10);
if (
content.content &&
!bot.utils.validateLength(content.content, { max: 2000 })
) {
throw new Error(
"A message content can not contain more than 2000 characters.",
);
}
if (content.attachments) validateAttachments(bot, content.attachments);
return editMessageOld(channelId, messageId, content);
};
}
export function publishMessage(bot: BotWithCache) {
const publishMessageOld = bot.helpers.publishMessage;
bot.helpers.publishMessage = function (
channelId,
messageId,
) {
const message = bot.messages.get(messageId);
requireBotChannelPermissions(
bot,
channelId,
message?.authorId === bot.id ? ["SEND_MESSAGES"] : ["MANAGE_MESSAGES"],
);
return publishMessageOld(channelId, messageId);
};
}
export default function setupCreateMessagePermChecks(bot: BotWithCache) {
sendMessage(bot);
editMessage(bot);
publishMessage(bot);
}
@@ -1,80 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function deleteMessage(bot: BotWithCache) {
const deleteMessageOld = bot.helpers.deleteMessage;
bot.helpers.deleteMessage = async function (
channelId,
messageId,
reason,
milliseconds,
) {
const message = bot.messages.get(messageId);
// DELETING SELF MESSAGES IS ALWAYS ALLOWED
if (message?.authorId === bot.id) {
return deleteMessageOld(channelId, messageId, reason, milliseconds);
}
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channel, [
"MANAGE_MESSAGES",
]);
} else {
throw new Error(
`You can only delete messages in a channel which has a guild id. Channel ID: ${channelId} Message Id: ${messageId}`,
);
}
return await deleteMessageOld(channelId, messageId, reason, milliseconds);
};
}
export function deleteMessages(bot: BotWithCache) {
const deleteMessagesOld = bot.helpers.deleteMessages;
bot.helpers.deleteMessages = async function (
channelId,
ids,
reason,
) {
const channel = bot.channels.get(channelId);
if (!channel?.guildId) {
throw new Error(
`Bulk deleting messages is only allowed in channels which has a guild id. Channel ID: ${channelId} IDS: ${
ids.join(" ")
}`,
);
}
// 2 WEEKS
const oldestAllowed = Date.now() - 1209600000;
ids = ids.filter((id) => {
const createdAt = Number(id / 4194304n + 1420070400000n);
// IF MESSAGE IS OLDER THAN 2 WEEKS
if (createdAt > oldestAllowed) return true;
console.log(
`[Permission Plugin] Skipping bulk message delete of ID ${id} because it is older than 2 weeks.`,
);
return false;
});
if (ids.length < 2) {
throw new Error("Bulk message delete requires at least 2 messages.");
}
requireBotChannelPermissions(bot, channel, [
"MANAGE_MESSAGES",
]);
return await deleteMessagesOld(channelId, ids, reason);
};
}
export default function setupDeleteMessagePermChecks(bot: BotWithCache) {
deleteMessage(bot);
deleteMessages(bot);
}
@@ -0,0 +1,25 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function deleteMessage(bot: BotWithCache) {
const deleteMessage = bot.helpers.deleteMessage;
bot.helpers.deleteMessage = async function (channelId, messageId, reason, milliseconds) {
const message = bot.messages.get(messageId);
// DELETING SELF MESSAGES IS ALWAYS ALLOWED
if (message?.authorId === bot.id) return deleteMessage(channelId, messageId, reason, milliseconds);
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channel, [
"MANAGE_MESSAGES",
]);
} else {
throw new Error(
`You can only delete messages in a channel which has a guild id. Channel ID: ${channelId} Message Id: ${messageId}`,
);
}
return await deleteMessage(channelId, messageId, reason, milliseconds);
};
}
@@ -0,0 +1,21 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function deleteMessages(bot: BotWithCache) {
const deleteMessages = bot.helpers.deleteMessages;
bot.helpers.deleteMessages = async function (channelId, ids, reason) {
const channel = bot.channels.get(channelId);
if (!channel?.guildId) {
throw new Error(
`Bulk deleting messages is only allowed in channels which has a guild id. Channel ID: ${channelId} IDS: ${
ids.join(" ")
}`,
);
}
requireBotChannelPermissions(bot, channel, ["MANAGE_MESSAGES"]);
return await deleteMessages(channelId, ids, reason);
};
}
@@ -0,0 +1,18 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function editMessage(bot: BotWithCache) {
const editMessage = bot.helpers.editMessage;
bot.helpers.editMessage = function (channelId, messageId, content) {
const message = bot.messages.get(messageId);
if (message) {
if (message.authorId !== bot.id) {
content = { flags: content.flags };
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
}
}
return editMessage(channelId, messageId, content);
};
}
-44
View File
@@ -1,44 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function getMessage(bot: BotWithCache) {
const getMessageOld = bot.helpers.getMessage;
bot.helpers.getMessage = async function (
channelId,
messageId,
) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channel, [
"READ_MESSAGE_HISTORY",
]);
}
return await getMessageOld(channelId, messageId);
};
}
export function getMessages(bot: BotWithCache) {
const getMessagesOld = bot.helpers.getMessages;
bot.helpers.getMessages = async function (
channelId,
options,
) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channel, [
"READ_MESSAGE_HISTORY",
"VIEW_CHANNEL",
]);
}
return await getMessagesOld(channelId, options);
};
}
export default function setupGetMessagePermChecks(bot: BotWithCache) {
getMessage(bot);
getMessages(bot);
}
@@ -0,0 +1,13 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function getMessage(bot: BotWithCache) {
const getMessage = bot.helpers.getMessage;
bot.helpers.getMessage = async function (channelId, messageId) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) requireBotChannelPermissions(bot, channel, ["READ_MESSAGE_HISTORY"]);
return await getMessage(channelId, messageId);
};
}
@@ -0,0 +1,18 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function getMessages(bot: BotWithCache) {
const getMessages = bot.helpers.getMessages;
bot.helpers.getMessages = async function (channelId, options) {
const channel = bot.channels.get(channelId);
if (channel?.guildId) {
requireBotChannelPermissions(bot, channel, [
"READ_MESSAGE_HISTORY",
"VIEW_CHANNEL",
]);
}
return await getMessages(channelId, options);
};
}
+17 -11
View File
@@ -1,14 +1,20 @@
import { BotWithCache } from "../../deps.ts";
import setupCreateMessagePermChecks from "./create.ts";
import setupDeleteMessagePermChecks from "./delete.ts";
import setupGetMessagePermChecks from "./get.ts";
import setupPinMessagePermChecks from "./pin.ts";
import setupReactionsPermChecks from "./reactions.ts";
import { deleteMessage } from "./deleteMessage.ts";
import { deleteMessages } from "./deleteMessages.ts";
import { getMessage } from "./getMessage.ts";
import { getMessages } from "./getMessages.ts";
import { pinMessage } from "./pinMessage.ts";
import { reactions } from "./reactions/mod.ts";
import { sendMessage } from "./sendMessage.ts";
import { unpinMessage } from "./unpinMessage.ts";
export default function setupMessagesPermChecks(bot: BotWithCache) {
setupReactionsPermChecks(bot);
setupDeleteMessagePermChecks(bot);
setupGetMessagePermChecks(bot);
setupPinMessagePermChecks(bot);
setupCreateMessagePermChecks(bot);
export function messages(bot: BotWithCache) {
reactions(bot);
deleteMessage(bot);
deleteMessages(bot);
getMessage(bot);
getMessages(bot);
pinMessage(bot);
sendMessage(bot);
unpinMessage(bot);
}
-37
View File
@@ -1,37 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function pinMessage(bot: BotWithCache) {
const pinMessageOld = bot.helpers.pinMessage;
bot.helpers.pinMessage = async function (
channelId,
messageId,
) {
requireBotChannelPermissions(bot, channelId, [
"MANAGE_MESSAGES",
]);
return await pinMessageOld(channelId, messageId);
};
}
export function unpinMessage(bot: BotWithCache) {
const unpinMessageOld = bot.helpers.unpinMessage;
bot.helpers.unpinMessage = async function (
channelId,
messageId,
) {
requireBotChannelPermissions(bot, channelId, [
"MANAGE_MESSAGES",
]);
return await unpinMessageOld(channelId, messageId);
};
}
export default function setupPinMessagePermChecks(bot: BotWithCache) {
pinMessage(bot);
unpinMessage(bot);
}
@@ -0,0 +1,17 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function pinMessage(bot: BotWithCache) {
const pinMessage = bot.helpers.pinMessage;
bot.helpers.pinMessage = async function (
channelId,
messageId,
) {
requireBotChannelPermissions(bot, channelId, [
"MANAGE_MESSAGES",
]);
return await pinMessage(channelId, messageId);
};
}
@@ -0,0 +1,18 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function publishMessage(bot: BotWithCache) {
const publishMessage = bot.helpers.publishMessage;
bot.helpers.publishMessage = function (channelId, messageId) {
const message = bot.messages.get(messageId);
requireBotChannelPermissions(
bot,
channelId,
message?.authorId === bot.id ? ["SEND_MESSAGES"] : ["MANAGE_MESSAGES"],
);
return publishMessage(channelId, messageId);
};
}
@@ -1,60 +0,0 @@
import { BotWithCache } from "../../deps.ts";
import { requireBotChannelPermissions } from "../permissions.ts";
export function addReaction(bot: BotWithCache) {
const addReactionOld = bot.helpers.addReaction;
bot.helpers.addReaction = async function (channelId, messageId, reaction) {
requireBotChannelPermissions(bot, channelId, ["READ_MESSAGE_HISTORY", "ADD_REACTIONS"]);
return await addReactionOld(channelId, messageId, reaction);
};
}
export function addReactions(bot: BotWithCache) {
const addReactionsOld = bot.helpers.addReactions;
bot.helpers.addReactions = async function (channelId, messageId, reactions, ordered) {
requireBotChannelPermissions(bot, channelId, ["READ_MESSAGE_HISTORY", "ADD_REACTIONS"]);
return await addReactionsOld(channelId, messageId, reactions, ordered);
};
}
export function deleteUserReaction(bot: BotWithCache) {
const deleteUserReactionOld = bot.helpers.deleteUserReaction;
bot.helpers.deleteUserReaction = async function (channelId, messageId, userId, reaction) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await deleteUserReactionOld(channelId, messageId, userId, reaction);
};
}
export function deleteReactionsAll(bot: BotWithCache) {
const DeleteReactionsAllOld = bot.helpers.deleteReactionsAll;
bot.helpers.deleteReactionsAll = async function (channelId, messageId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await DeleteReactionsAllOld(channelId, messageId);
};
}
export function deleteReactionsEmoji(bot: BotWithCache) {
const deleteReactionsEmojiOld = bot.helpers.deleteReactionsEmoji;
bot.helpers.deleteReactionsEmoji = async function (channelId, messageId, reaction) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await deleteReactionsEmojiOld(channelId, messageId, reaction);
};
}
export default function setupReactionsPermChecks(bot: BotWithCache) {
addReaction(bot);
addReactions(bot);
deleteUserReaction(bot);
deleteReactionsAll(bot);
deleteReactionsEmoji(bot);
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function addReaction(bot: BotWithCache) {
const addReaction = bot.helpers.addReaction;
bot.helpers.addReaction = async function (channelId, messageId, reaction) {
requireBotChannelPermissions(bot, channelId, ["READ_MESSAGE_HISTORY", "ADD_REACTIONS"]);
return await addReaction(channelId, messageId, reaction);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function addReactions(bot: BotWithCache) {
const addReactions = bot.helpers.addReactions;
bot.helpers.addReactions = async function (channelId, messageId, reactions, ordered) {
requireBotChannelPermissions(bot, channelId, ["READ_MESSAGE_HISTORY", "ADD_REACTIONS"]);
return await addReactions(channelId, messageId, reactions, ordered);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function deleteReactionsAll(bot: BotWithCache) {
const deleteReactionsAll = bot.helpers.deleteReactionsAll;
bot.helpers.deleteReactionsAll = async function (channelId, messageId) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await deleteReactionsAll(channelId, messageId);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function deleteReactionsEmoji(bot: BotWithCache) {
const deleteReactionsEmoji = bot.helpers.deleteReactionsEmoji;
bot.helpers.deleteReactionsEmoji = async function (channelId, messageId, reaction) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await deleteReactionsEmoji(channelId, messageId, reaction);
};
}
@@ -0,0 +1,12 @@
import { BotWithCache } from "../../../deps.ts";
import { requireBotChannelPermissions } from "../../permissions.ts";
export function deleteUserReaction(bot: BotWithCache) {
const deleteUserReaction = bot.helpers.deleteUserReaction;
bot.helpers.deleteUserReaction = async function (channelId, messageId, userId, reaction) {
requireBotChannelPermissions(bot, channelId, ["MANAGE_MESSAGES"]);
return await deleteUserReaction(channelId, messageId, userId, reaction);
};
}

Some files were not shown because too many files have changed in this diff Show More