diff --git a/commands/course.js b/commands/course.js index b55544c1..dac19ba6 100644 --- a/commands/course.js +++ b/commands/course.js @@ -1,7 +1,5 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); -const { Permissions } = require("discord.js"); -const MODERATION_REQUEST_CHANNEL = 824506830641561600; const COMMAND_JOIN = "join"; const COMMAND_LEAVE = "leave"; @@ -54,6 +52,9 @@ const is_valid_course = (course) => { ); }; +const in_overwrites = (overwrites, id) => + [1024n, 3072n].includes(overwrites.find((v, k) => k === id)?.allow?.bitfield); + module.exports = { data: new SlashCommandBuilder() .setName("course") @@ -128,8 +129,9 @@ module.exports = { }); } + // if there isn't a role that matches the name of the course return await interaction.reply({ - content: `✅ | End of command - ${course_with_alias}.`, + content: `There doesn't exist a role for \`${course_with_alias}\`. If you believe there should be, please inform a member of the Discord Bot team or staff.`, ephemeral: true, }); } else if (interaction.options.getSubcommand() === COMMAND_LEAVE) { @@ -143,24 +145,65 @@ module.exports = { }); } - // First, let's see if there's a role that matches the name of the course + // Check and fetch a channel corresponding to input + const channel = await interaction.guild.channels.cache.find( + (c) => c.name.toLowerCase() === course.toLowerCase(), + ); + + if (channel === undefined) { + return await interaction.reply({ + content: `❌ | The course chat for \`${course}\` does not exist.`, + ephemeral: true, + }); + } else if (channel.type !== "GUILD_TEXT") { + return await interaction.reply({ + content: `❌ | The course chat for \`${course}\` is not a text channel.`, + ephemeral: true, + }); + } + + const permissions = channel.permissionOverwrites.cache; + + // Then check if there's a role that matches the name of the course const role = await interaction.guild.roles.cache.find( (r) => r.name.toLowerCase() === course.toLowerCase(), ); - // If there is, let's see if the member already has that role + // Check if the role exists if (role !== undefined) { - if (!interaction.member.roles.cache.has(role.id)) { + // Check if the member has access via individual perms + if (in_overwrites(permissions, interaction.member.id)) { + // Remove the member from the channel's permission overwrites if so + await channel.permissionOverwrites.delete(interaction.member); + } + + // Check if the member has access via role + if ( + interaction.member.roles.cache.has(role.id) && + in_overwrites(permissions, role.id) + ) { + // If they do remove the role + await interaction.member.roles.remove(role); + return await interaction.reply({ + content: `✅ | Removed you from the role and chat for \`${course}\`.`, + ephemeral: true, + }); + } else { return await interaction.reply({ content: `❌ | You do not have the role for \`${course}\`.`, ephemeral: true, }); } - - // If they do, let's remove the role from them - await interaction.member.roles.remove(role); + } else if (in_overwrites(permissions, interaction.member.id)) { + // Check if the user has individual perms and removes if so + await channel.permissionOverwrites.delete(interaction.member); + return await interaction.reply({ + content: `✅ | Removed you from the chat for \`${course}\`.`, + ephemeral: true, + }); + } else { return await interaction.reply({ - content: `✅ | Removed you from the role and chat for \`${course}\`.`, + content: `❌ | You do not have access to the chat for \`${course}\`.`, ephemeral: true, }); } diff --git a/commands/rolesPermOverride.js b/commands/rolesPermOverride.js index 21e05e75..7d72d0af 100644 --- a/commands/rolesPermOverride.js +++ b/commands/rolesPermOverride.js @@ -1,7 +1,7 @@ const { SlashCommandBuilder } = require("@discordjs/builders"); const { Permissions } = require("discord.js"); -const is_valid_course = (course) => { +const is_valid_course_name = (course) => { const reg_comp_course = /^comp\d{4}$/; const reg_math_course = /^math\d{4}$/; const reg_binf_course = /^binf\d{4}$/; @@ -18,47 +18,51 @@ const is_valid_course = (course) => { ); }; -function editChannels(interaction, channels, role) { - channels.forEach((channel) => { - if ( - channel.type === "GUILD_TEXT" && - channel.name.toLowerCase() === role.name.toLowerCase() - ) { - // Remove all permissions from a role - role.setPermissions(0n) - .then((updated) => - console.log(`Updated permissions to ${updated.permissions.bitfield}`), - ) - .catch(console.error); - // Set the permissions of the role - // Add the member to the channel's permission overwrites - channel.permissionOverwrites.create(role, { - VIEW_CHANNEL: true, - SEND_MESSAGES: true, +const in_overwrites = (overwrites, id) => + [1024n, 3072n].includes(overwrites.find((v, k) => k === id)?.allow?.bitfield); + +async function editChannels(interaction, channels) { + for (const data of channels) { + const channel = data[1]; + const is_valid = is_valid_course_name(channel.name); + + if (!is_valid || channel.type !== "GUILD_TEXT") continue; + + let role = interaction.guild.roles.cache.find( + (r) => r.name.toLowerCase() === channel.name.toLowerCase(), + ); + + if (!role) { + role = await interaction.guild.roles.create({ + name: channel.name.toLowerCase(), + color: "BLUE", }); - console.log(channel.name, role.name); } - }); -} -function editRoles(interaction, roles) { - roles.forEach((role) => { - if (is_valid_course(role.name)) { - interaction.guild.channels - .fetch() - .then( - (channels) => ( - editChannels(interaction, channels, role), - console.log(`There are ${channels.size} channels.`) - ), - ) - .catch(console.error); + const permissions = channel.permissionOverwrites.cache; + + // clear every individual user permission overwrite for the channel + for (const user of channel.members) { + const userId = user[0]; + const userObj = user[1]; + + if (userObj.user.bot) continue; + + // Check if the member has access via individual perms + if (in_overwrites(permissions, userId)) { + // Remove the member from the channel's permission overwrites + await channel.permissionOverwrites.delete(userObj); + await userObj.roles.add(role); + } } - }); - interaction.reply({ - content: `✅ | found course chats and matching roles, cleared and set permission overwrites for roles.`, - ephemeral: true, - }); + + // set the permissions for the new role on a channel + // const channel = interaction.guild.channels.cache.get('CHANNEL_ID'); + await channel.permissionOverwrites.create(role, { + VIEW_CHANNEL: true, + SEND_MESSAGES: true, + }); + } } module.exports = { @@ -75,19 +79,18 @@ module.exports = { ephemeral: true, }); } + + await interaction.deferReply(); + // for all roles with name == chat name involving 4 letter prefix comp, seng, engg or binf, - // give the role the permission override to participate in the matching channel. - interaction.guild.roles - .fetch() - .then( - (roles) => ( - editRoles(interaction, roles), console.log(`There are ${roles.size} roles.`) - ), - ) - .catch(console.error); + // Get all channels and run function + const channels = await interaction.guild.channels.fetch(); + + await editChannels(interaction, channels); + await interaction.editReply("Successfully ported all user permissions to roles."); } catch (error) { - await interaction.reply("Error: " + error); + await interaction.editReply("Error: " + error); } }, };