Skip to content

Commit

Permalink
Permission resolving changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Larsundso committed Dec 29, 2023
1 parent b377adf commit 8ae1186
Show file tree
Hide file tree
Showing 37 changed files with 186 additions and 199 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (channel: Discord.GuildTextBasedChannel, messages: string[]) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canBulkDelete(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canBulkDelete(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(`Cannot bulk-delete messages in ${channel.name} / ${channel.id}`, [
Discord.PermissionFlagsBits.ManageMessages,
]);
Expand All @@ -34,9 +34,9 @@ export default async (channel: Discord.GuildTextBasedChannel, messages: string[]

/**
* Checks if a bulk-delete can be executed by a given user in a given channel.
* @param channel - The guild text-based channel to check.
* @param channelId - The ID of the guild text-based channel to check.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user has the necessary permissions.
*/
export const canBulkDelete = (channel: Discord.GuildTextBasedChannel, me: Discord.GuildMember) =>
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageMessages);
export const canBulkDelete = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageMessages);
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export default async (
) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canCreateForumThread(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canCreateForumThread(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(`Cannot create forum post in ${channel.name} / ${channel.id}`, [
Discord.PermissionFlagsBits.SendMessages,
]);
Expand All @@ -45,11 +45,9 @@ export default async (

/**
* Checks if the specified user has permission to create a forum thread in the given channel.
* @param channel - The channel in which the forum thread is to be created.
* @param channelId - The ID of the channel in which the forum thread is to be created.
* @param me - The guild member representing the user.
* @returns True if the user has permission to create a forum thread, false otherwise.
*/
export const canCreateForumThread = (
channel: Discord.ForumChannel | Discord.MediaChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.SendMessages);
export const canCreateForumThread = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.SendMessages);
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async (
) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canCreateInvite(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canCreateInvite(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(`Cannot create invite in ${channel.name} / ${channel.id}`, [
Discord.PermissionFlagsBits.CreateInstantInvite,
]);
Expand All @@ -41,9 +41,9 @@ export default async (

/**
* Checks if the given user has permission to create an invite in the specified channel.
* @param channel - The guild-based channel to check.
* @param channelId - The ID of the guild-based channel to check.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user can create an invite in the channel.
*/
export const canCreateInvite = (channel: Discord.GuildBasedChannel, me: Discord.GuildMember) =>
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.CreateInstantInvite);
export const canCreateInvite = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.CreateInstantInvite);
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default async (
) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canCreateThread(channel, body, await getBotMemberFromGuild(channel.guild))) {
if (!canCreateThread(channel.id, body, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(
`Cannot create ${
body.type === Discord.ChannelType.PrivateThread ? 'private' : 'public / announcement'
Expand All @@ -48,15 +48,15 @@ export default async (

/**
* Checks if the given user has permission to create a thread in the specified channel.
* @param channel - The guild text-based channel to check.
* @param channelId - The ID of the guild text-based channel to check.
* @param me - The guild member representing the user.
* @returns True if the user has permission to create a thread, false otherwise.
*/
export const canCreateThread = (
channel: Discord.GuildTextBasedChannel,
channelId: string,
body: Discord.RESTPostAPIChannelThreadsJSONBody,
me: Discord.GuildMember,
) =>
body.type === Discord.ChannelType.PublicThread
? me.permissionsIn(channel).has(Discord.PermissionFlagsBits.CreatePublicThreads)
: me.permissionsIn(channel).has(Discord.PermissionFlagsBits.CreatePrivateThreads);
? me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.CreatePublicThreads)
: me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.CreatePrivateThreads);
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,7 @@ export default async (
) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (
!canCreateWebhook(
guild.channels.cache.get(channelId) as Discord.GuildBasedChannel,
await getBotMemberFromGuild(guild),
)
) {
if (!canCreateWebhook(channelId, await getBotMemberFromGuild(guild))) {
const e = requestHandlerError(`Cannot create webhook`, [
Discord.PermissionFlagsBits.ManageWebhooks,
]);
Expand All @@ -50,9 +45,9 @@ export default async (

/**
* Checks if the user has the necessary permissions to create a webhook in a given channel.
* @param channel - The guild-based channel where the webhook will be created.
* @param channelId - The ID of the guild-based channel where the webhook will be created.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user can create a webhook in the channel.
*/
export const canCreateWebhook = (channel: Discord.GuildBasedChannel, me: Discord.GuildMember) =>
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageWebhooks);
export const canCreateWebhook = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageWebhooks);
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ export const isDeleteable = (channel: Discord.GuildBasedChannel, me: Discord.Gui
Discord.ChannelType.PublicThread,
Discord.ChannelType.AnnouncementThread,
].includes(channel.type)
? me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageThreads)
: me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageChannels);
? me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageThreads)
: me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageChannels);
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (message: Discord.Message<true>) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canDeleteAllReactions(message.channel, await getBotMemberFromGuild(message.guild))) {
if (!canDeleteAllReactions(message.channel.id, await getBotMemberFromGuild(message.guild))) {
const e = requestHandlerError(
`Cannot delete all reactions of messages in ${message.guild.name} / ${message.guild.id}`,
[Discord.PermissionFlagsBits.ManageMessages],
Expand All @@ -34,11 +34,9 @@ export default async (message: Discord.Message<true>) => {

/**
* Checks if the user has the permission to delete all reactions in a channel.
* @param channel - The guild-based channel to check.
* @param channelId - The ID of the guild-based channel to check.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user has the permission to delete all reactions.
*/
export const canDeleteAllReactions = (
channel: Discord.GuildBasedChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageMessages);
export const canDeleteAllReactions = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageMessages);
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (message: Discord.Message<true>, emoji: string) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canDeleteAllreactionsOfEmoji(message.channel, await getBotMemberFromGuild(message.guild))) {
if (!canDeleteAllreactionsOfEmoji(message.channel.id, await getBotMemberFromGuild(message.guild))) {
const e = requestHandlerError(
`Cannot delete all reactions of emoji ${emoji} in ${message.guild.name} / ${message.guild.id}`,
[Discord.PermissionFlagsBits.ManageMessages],
Expand Down Expand Up @@ -49,7 +49,12 @@ export default async (message: Discord.Message<true>, emoji: string) => {
});
};

export const canDeleteAllreactionsOfEmoji = (
channel: Discord.GuildBasedChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageMessages);
/**
* Checks if the user has the permission to delete all reactions of an emoji in a channel.
* @param channelId - The ID of the channel.
* @param me - The Discord GuildMember object representing the user.
* @returns A boolean indicating whether the user
* has the permission to delete all reactions of the emoji.
*/
export const canDeleteAllreactionsOfEmoji = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageMessages);
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (channel: Discord.GuildBasedChannel, overwriteId: string, reason?: string) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canDeletePermissionOverwrite(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canDeletePermissionOverwrite(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(
`Cannot delete permission overwrite in ${channel.name} / ${channel.id}`,
[Discord.PermissionFlagsBits.ManageRoles],
Expand All @@ -36,12 +36,10 @@ export default async (channel: Discord.GuildBasedChannel, overwriteId: string, r
};
/**
* Checks if the user has the permission to delete a permission overwrite in a channel.
* @param channel - The guild-based channel where the permission overwrite is being deleted.
* @param channelId - The ID of the guild-based channel to check.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user has the permission to
* delete the permission overwrite.
*/
export const canDeletePermissionOverwrite = (
channel: Discord.GuildBasedChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageRoles);
export const canDeletePermissionOverwrite = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageRoles);
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (message: Discord.Message<true>, userId: string, emoji: string) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canDeleteUserReaction(message.channel, await getBotMemberFromGuild(message.guild))) {
if (!canDeleteUserReaction(message.channel.id, await getBotMemberFromGuild(message.guild))) {
const e = requestHandlerError(
`Cannot delete user reaction in ${message.guild.name} / ${message.guild.id}`,
[Discord.PermissionFlagsBits.ManageMessages],
Expand Down Expand Up @@ -50,7 +50,11 @@ export default async (message: Discord.Message<true>, userId: string, emoji: str
});
};

export const canDeleteUserReaction = (
channel: Discord.GuildBasedChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageMessages);
/**
* Checks if the user has permission to delete a user's reaction in a channel.
* @param channelId - The ID of the channel.
* @param me - The Discord GuildMember object representing the user.
* @returns True if the user has permission to manage messages in the channel, false otherwise.
*/
export const canDeleteUserReaction = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageMessages);
33 changes: 18 additions & 15 deletions src/BaseClient/ClientHelperModules/requestHandler/channels/edit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,21 @@ export const canEdit = (
body: Discord.RESTPatchAPIChannelJSONBody,
me: Discord.GuildMember,
) =>
me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageChannels) &&
(body.permission_overwrites
? me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageRoles) &&
body.permission_overwrites.every(
(overwrite) =>
me
.permissionsIn(channel.id)
.has(
new Discord.PermissionsBitField(overwrite.allow ? BigInt(overwrite.allow) : 0n).bitfield,
) &&
me
.permissionsIn(channel.id)
.has(new Discord.PermissionsBitField(overwrite.deny ? BigInt(overwrite.deny) : 0n).bitfield),
)
: true);
me.guild.ownerId === me.id ||
(me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageChannels) &&
(body.permission_overwrites
? me.permissionsIn(channel.id).has(Discord.PermissionFlagsBits.ManageRoles) &&
body.permission_overwrites.every(
(overwrite) =>
me
.permissionsIn(channel.id)
.has(
new Discord.PermissionsBitField(overwrite.allow ? BigInt(overwrite.allow) : 0n).bitfield,
) &&
me
.permissionsIn(channel.id)
.has(
new Discord.PermissionsBitField(overwrite.deny ? BigInt(overwrite.deny) : 0n).bitfield,
),
)
: true));
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,5 @@ export const canEditMessage = (
) =>
msg.author.id === me.id
? true
: me.permissionsIn(msg.channel).has(Discord.PermissionFlagsBits.ManageMessages) &&
: me.permissionsIn(msg.channelId).has(Discord.PermissionFlagsBits.ManageMessages) &&
!!payload.flags;
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,15 @@ export default async (

if (
!canEditPermissionOverwrite(
channel,
channel.id,
body,
overwriteId,
await getBotMemberFromGuild(channel.guild),
)
) {
const e = requestHandlerError(
`Cannot edit message in ${channel.guild.name} / ${channel.guild.id}`,
[Discord.PermissionFlagsBits.ManageMessages],
`Cannot edit permission overwrite in ${channel.name} / ${channel.id}`,
[Discord.PermissionFlagsBits.ManageRoles],
);

return e;
Expand All @@ -47,13 +47,22 @@ export default async (
});
};

/**
* Checks if the user can edit a permission overwrite in a guild-based channel.
* @param channelId - The ID of the guild-based channel.
* @param body - The JSON body of the REST API request to edit the permission overwrite.
* @param overwriteId - The ID of the permission overwrite.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user can edit the permission overwrite.
*/
export const canEditPermissionOverwrite = (
channel: Discord.GuildBasedChannel,
channelId: string,
body: Discord.RESTPutAPIChannelPermissionJSONBody,
overwriteId: string,
me: Discord.GuildMember,
) =>
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageRoles) &&
(overwriteId === me.id
? me.permissionsIn(channel).has(body.allow ? BigInt(body.allow) : 0n)
: true);
me.guild.ownerId === me.id ||
(me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageRoles) &&
(overwriteId === me.id
? me.permissionsIn(channelId).has(body.allow ? BigInt(body.allow) : 0n)
: true));
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import requestHandlerError from '../../requestHandlerError.js';
export default async (channel: Discord.GuildTextBasedChannel, followedChannelId: string) => {
if (process.argv.includes('--silent')) return new Error('Silent mode enabled.');

if (!canFollowAnnouncements(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canFollowAnnouncements(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(`Cannot follow announcements in ${channel.name} / ${channel.id}`, [
Discord.PermissionFlagsBits.ManageWebhooks,
]);
Expand All @@ -37,11 +37,9 @@ export default async (channel: Discord.GuildTextBasedChannel, followedChannelId:

/**
* Checks if the user has the necessary permissions to follow announcements.
* @param channel - The guild text-based channel to check.
* @param channelId - The ID of the guild text-based channel to check.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user can follow announcements in the channel.
*/
export const canFollowAnnouncements = (
channel: Discord.GuildTextBasedChannel,
me: Discord.GuildMember,
) => me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageWebhooks);
export const canFollowAnnouncements = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageWebhooks);
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default async (
status: 'private' | 'public',
query: Discord.RESTGetAPIChannelThreadsArchivedQuery,
) => {
if (!canGetArchivedThreads(channel, status, await getBotMemberFromGuild(channel.guild))) {
if (!canGetArchivedThreads(channel.id, status, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(
`Cannot get archived threads in ${channel.name} / ${channel.id}`,
status === 'private'
Expand Down Expand Up @@ -52,17 +52,17 @@ export default async (

/**
* Determines whether the current user can get archived threads in a channel.
* @param channel - The channel in which the archived threads are being accessed.
* @param channelId - The ID of the channel in which the archived threads are being accessed.
* @param status - The status of the archived threads ('private' or 'public').
* @param me - The guild member representing the current user.
* @returns A boolean value indicating whether the current user can get archived threads.
*/
export const canGetArchivedThreads = (
channel: Discord.NewsChannel | Discord.TextChannel | Discord.ForumChannel,
channelId: string,
status: 'private' | 'public',
me: Discord.GuildMember,
) =>
status === 'private'
? me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageThreads) &&
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ReadMessageHistory)
? me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageThreads) &&
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ReadMessageHistory)
: true;
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import requestHandlerError from '../../requestHandlerError.js';
* @returns A promise that resolves with an array of parsed invite objects.
*/
export default async (channel: Discord.GuildBasedChannel) => {
if (!canGetInvites(channel, await getBotMemberFromGuild(channel.guild))) {
if (!canGetInvites(channel.id, await getBotMemberFromGuild(channel.guild))) {
const e = requestHandlerError(`Cannot get invites in ${channel.name} / ${channel.id}`, [
Discord.PermissionFlagsBits.ManageChannels,
]);
Expand All @@ -40,9 +40,9 @@ export default async (channel: Discord.GuildBasedChannel) => {

/**
* Checks if the user has permission to get invites in a guild-based channel.
* @param channel - The guild-based channel to check permissions in.
* @param channelId - The ID of the guild-based channel to check permissions in.
* @param me - The guild member representing the user.
* @returns A boolean indicating whether the user has permission to get invites.
*/
export const canGetInvites = (channel: Discord.GuildBasedChannel, me: Discord.GuildMember) =>
me.permissionsIn(channel).has(Discord.PermissionFlagsBits.ManageChannels);
export const canGetInvites = (channelId: string, me: Discord.GuildMember) =>
me.permissionsIn(channelId).has(Discord.PermissionFlagsBits.ManageChannels);
Loading

0 comments on commit 8ae1186

Please sign in to comment.