diff --git a/.dockerignore b/.dockerignore index 2afd11ac0f6e0fd0dc83a2d17c5692128ddaa2b5..45ec58844ba8e68ec8b99452d0fedf9466dee4f3 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,4 +3,5 @@ node_modules npm-debug.log .env .env.example -.DS_store \ No newline at end of file +.DS_store +mongo \ No newline at end of file diff --git a/.gitignore b/.gitignore index c223885c96d024932774661e7fd6c45c0685613a..8a590022d4c7d1e2fc840743ad4b0de4b55f6a0f 100644 --- a/.gitignore +++ b/.gitignore @@ -235,4 +235,5 @@ dist .pnp.* .env -.DS_store \ No newline at end of file +.DS_store +mongo \ No newline at end of file diff --git a/.idea/finf-discord-js.iml b/.idea/finf-discord-js.iml index 0c8867d7e175f46d4bcd66698ac13f4ca00cf592..161624603fdea1479a9bc92b5b67926010b59d24 100644 --- a/.idea/finf-discord-js.iml +++ b/.idea/finf-discord-js.iml @@ -5,6 +5,7 @@ <excludeFolder url="file://$MODULE_DIR$/temp" /> <excludeFolder url="file://$MODULE_DIR$/.tmp" /> <excludeFolder url="file://$MODULE_DIR$/tmp" /> + <excludeFolder url="file://$MODULE_DIR$/mongo" /> </content> <orderEntry type="inheritedJdk" /> <orderEntry type="sourceFolder" forTests="false" /> diff --git a/commands/AssignPermission.js b/commands/AssignPermission.js new file mode 100644 index 0000000000000000000000000000000000000000..b2009c4e6f1148aee033d401b6bec02e0a45d533 --- /dev/null +++ b/commands/AssignPermission.js @@ -0,0 +1,14 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = new SlashCommandBuilder() + .setName('assign_permission') + .setDescription('Assign a permission to a role') + .addStringOption(option => + option.setName('permission') + .setDescription('Permission to assign.') + .setRequired(true) + .addChoice("Role Menus", 'role_menu')) + .addRoleOption(option => + option.setName('role') + .setDescription('Role to assign permission to.') + .setRequired(true)) \ No newline at end of file diff --git a/commands/ListPermissions.js b/commands/ListPermissions.js new file mode 100644 index 0000000000000000000000000000000000000000..b6d35be5e9980fe7a2e36c9561fa4db15e8595bb --- /dev/null +++ b/commands/ListPermissions.js @@ -0,0 +1,5 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = new SlashCommandBuilder() + .setName('list_permissions') + .setDescription('List all Permissions for this Server.'); \ No newline at end of file diff --git a/commands/RevokePermission.js b/commands/RevokePermission.js new file mode 100644 index 0000000000000000000000000000000000000000..45b18c4678da1ca86380760e7107083d9a06e1c7 --- /dev/null +++ b/commands/RevokePermission.js @@ -0,0 +1,14 @@ +const { SlashCommandBuilder } = require('@discordjs/builders'); + +module.exports = new SlashCommandBuilder() + .setName('revoke_permission') + .setDescription('Revoke a permission from a role') + .addStringOption(option => + option.setName('permission') + .setDescription('Permission to revoke.') + .setRequired(true) + .addChoice("Role Menus", 'role_menu')) + .addRoleOption(option => + option.setName('role') + .setDescription('Role to revoke permission from.') + .setRequired(true)) \ No newline at end of file diff --git a/components/permConfig.js b/components/permConfig.js new file mode 100644 index 0000000000000000000000000000000000000000..42358394d978f1e81bdfc4a24a7fd8568a8866b8 --- /dev/null +++ b/components/permConfig.js @@ -0,0 +1,77 @@ +const ServerConfig = require('../models/ServerConfig'); +const {Permissions} = require('discord.js'); + +async function assignPermission(interaction) { + if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) { + const role = interaction.options.getRole('role'); + const perm = interaction.options.getString('permission'); + let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()}); + if (config == null) { + config = new ServerConfig(); + config.guildID = interaction.guild.id.toString(); + config.permissions.roleMenu = []; + } + if (perm === 'role_menu') { + if (!config.permissions.roleMenu.includes(role.id.toString())) { + config.permissions.roleMenu.push(role.id.toString()); + } + } + await config.save(); + await interaction.reply({content: `Role ${role.name} has been added to ${perm} permission.`, ephemeral: true}); + } else { + await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true}); + } +} + +async function revokePermission(interaction) { + if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) { + const role = interaction.options.getRole('role'); + const perm = interaction.options.getString('permission'); + let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()}); + if (config == null) { + config = new ServerConfig(); + config.guildID = interaction.guild.id.toString(); + config.permissions.roleMenu = []; + } + if (perm === 'role_menu') { + if (config.permissions.roleMenu.includes(role.id.toString())) { + config.permissions.roleMenu.splice(config.permissions.roleMenu.indexOf(role.id.toString()), 1); + } + } + await config.save(); + await interaction.reply({ + content: `Role ${role.name} has been removed from ${perm} permission.`, + ephemeral: true + }); + } else { + await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true}); + } +} + +async function listPermissions(interaction) { + if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) { + let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()}); + if (config == null) { + config = new ServerConfig(); + config.guildID = interaction.guild.id.toString(); + config.permissions.roleMenu = []; + } + const roles = await Promise.all(config.permissions.roleMenu.map(async (roleID) => (await interaction.guild.roles.fetch(roleID)).name)); + + await interaction.reply({content: `List of Permissions:\n\nRole Menu: ${roles.join(',')}`, ephemeral: true}); + } +} + +const slashCommandHandler = async (interaction) => { + if (interaction.commandName === 'assign_permission') { + await assignPermission(interaction); + } else if (interaction.commandName === 'revoke_permission') { + await revokePermission(interaction); + } else if (interaction.commandName === 'list_permissions') { + await listPermissions(interaction); + } +} + +module.exports = { + slashCommandHandler +} \ No newline at end of file diff --git a/components/roles.js b/components/roles.js index 6721134ce875dcfb13a14dda686edf18eff815e3..0968774fa173d00ce11931bd2cacf5e7fc173793 100644 --- a/components/roles.js +++ b/components/roles.js @@ -1,8 +1,14 @@ const RoleMenu = require('../models/RoleMenu'); const {MessageActionRow, MessageSelectMenu} = require("discord.js"); +const checkPerm = require('../util/perm'); // slashcommand handler async function addRoleMenu(interaction) { + console.log('test'); + if (!(await checkPerm(interaction.member, 'role_menu'))) { + await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true}) + return; + } const channel = interaction.options.getChannel('channel'); const messageContent = interaction.options.getString('message'); const type = interaction.options.getString('type'); @@ -32,6 +38,10 @@ async function addRoleMenu(interaction) { } async function deleteRoleMenu(interaction) { + if (!(await checkPerm(interaction.member, 'role_menu'))) { + await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true}) + return; + } const channel = interaction.options.getChannel('channel'); const messageID = interaction.options.getString('message_id'); let menu = await RoleMenu.findOne({guildID: channel.guild.id, channelID: channel.id, messageID}); @@ -58,6 +68,10 @@ async function deleteRoleMenu(interaction) { } async function addRoleToMenu(interaction) { + if (!(await checkPerm(interaction.member, 'role_menu'))) { + await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true}) + return; + } const channel = interaction.options.getChannel('channel'); const messageID = interaction.options.getString('message_id'); const role = interaction.options.getRole('role') @@ -123,6 +137,10 @@ async function addRoleToMenu(interaction) { } async function deleteRoleFromMenu(interaction) { + if (!(await checkPerm(interaction.member, 'role_menu'))) { + await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true}) + return; + } const channel = interaction.options.getChannel('channel'); const messageID = interaction.options.getString('message_id'); const role = interaction.options.getRole('role'); @@ -183,6 +201,10 @@ async function deleteRoleFromMenu(interaction) { } async function editRoleMenu(interaction) { + if (!(await checkPerm(interaction.member, 'role_menu'))) { + await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true}) + return; + } const channel = interaction.options.getChannel('channel'); const messageID = interaction.options.getString('message_id'); const messageContent = interaction.options.getString('message'); diff --git a/docker-compose.yml b/docker-compose.yml index 43cb9974e3ff467764a535291eccc96f7807007e..ae04fab87fe2cfa481aebca9c74773f7511d3e83 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -18,6 +18,8 @@ services: mongo: image: mongo + volumes: + - "./mongo:/data/db" ports: - "${MONGO_PORT}:${MONGO_PORT}" restart: always diff --git a/index.js b/index.js index 49b18419f3adcc27511c7b2d8aeab9ac79680970..65968dd8a8dc883cd9c6b574c66bfe2fcdd3b995 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -const connectDB = require('./config/db') +const connectDB = require('./util/db') const {Client, Intents, MessageActionRow, MessageButton, MessageSelectMenu, MessageEmbed} = require('discord.js'); const fs = require('fs'); const botConfig = { diff --git a/models/ServerConfig.js b/models/ServerConfig.js new file mode 100644 index 0000000000000000000000000000000000000000..1428e8af0e129875171e6f0b10d206ad9dea9f04 --- /dev/null +++ b/models/ServerConfig.js @@ -0,0 +1,16 @@ +const {Schema, model} = require('mongoose'); + +const ServerConfigSchema = new Schema({ + guildID: { + type: String, + unique: true, + required: true + }, + permissions: { + roleMenu: [{ + type: String + }]} +}); + + +module.exports = model('serverconfig', ServerConfigSchema); \ No newline at end of file diff --git a/package.json b/package.json index 420b0a1a2c6fb08e59405a1d62f0bd3685e5de91..a5d606be7114a205e7a1288f66aa2bee44179333 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "finf-discord", - "version": "0.1.0", + "version": "0.1.1", "description": "", "main": "index.ts", "scripts": { diff --git a/config/db.js b/util/db.js similarity index 100% rename from config/db.js rename to util/db.js diff --git a/util/perm.js b/util/perm.js new file mode 100644 index 0000000000000000000000000000000000000000..7cf3f0f44d43914d1dbb9c7c692b77c659133c16 --- /dev/null +++ b/util/perm.js @@ -0,0 +1,17 @@ +const ServerConfig = require('../models/ServerConfig'); +const {Permissions} = require('discord.js'); + +module.exports = async (member, permission) => { + const guildID = member.guild.id; + const config = await ServerConfig.findOne({guildID}); + if (config == null) { + return false; + } + if (permission === 'role_menu') { + console.log(member.roles.cache); + console.log(config.permissions.roleMenu); + return member.roles.cache.some((role) => config.permissions.roleMenu.some((prole) => prole == role.id.toString())) + || member.permissions.has(Permissions.FLAGS.ADMINISTRATOR); + } + return false; +} \ No newline at end of file