Add command permission checks
Level 0: Every user - Public commands Level 1: Guild owners or members with respective admin role - Elevated guild commands Level 2: Global admins - Every command including levels below
This commit is contained in:
@@ -13,7 +13,7 @@ module.exports = {
|
|||||||
.setDescription("The command to debug")
|
.setDescription("The command to debug")
|
||||||
.setRequired(false)
|
.setRequired(false)
|
||||||
),
|
),
|
||||||
|
permissionLevel: 2,
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
const identifier = CardUtils.generateIdentifier();
|
const identifier = CardUtils.generateIdentifier();
|
||||||
let user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
let user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
||||||
@@ -70,6 +70,13 @@ module.exports = {
|
|||||||
content: `Reset cooldowns`,
|
content: `Reset cooldowns`,
|
||||||
ephemeral: false
|
ephemeral: false
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
interaction.reply({
|
||||||
|
content: `Your permission level is ${await UserUtils.getPermissionLevel(interaction.member)}`,
|
||||||
|
ephemeral: false
|
||||||
|
});
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,7 +12,7 @@ module.exports = {
|
|||||||
.setDescription("The id of the character to drop")
|
.setDescription("The id of the character to drop")
|
||||||
.setRequired(true)
|
.setRequired(true)
|
||||||
),
|
),
|
||||||
|
permissionLevel: 2,
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
//get user id from database given the userID
|
//get user id from database given the userID
|
||||||
const user = await User.findOne({
|
const user = await User.findOne({
|
||||||
|
|||||||
61
commands/guildSettings.js
Normal file
61
commands/guildSettings.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
const { SlashCommandBuilder, ComponentType, ActionRowBuilder, ButtonBuilder, ButtonStyle, SelectMenuBuilder } = require("discord.js");
|
||||||
|
const { GeneralUtils, GuildUtils } = require("../util");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName("settings")
|
||||||
|
.setDescription("Change Guild Settings"),
|
||||||
|
permissionLevel: 1,
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
let reply = "Guild settings:\n";
|
||||||
|
const row = new ActionRowBuilder();
|
||||||
|
row.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`set-admin-role`)
|
||||||
|
.setLabel('Set Admin Role')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
);
|
||||||
|
const message = await interaction.reply({ content: reply, components: [row], fetchReply: true });
|
||||||
|
|
||||||
|
const filter = (m) => m.author.id === message.author.id;
|
||||||
|
const collector = message.createMessageComponentCollector(filter, { componentType: ComponentType.Button, time: 120000 });
|
||||||
|
|
||||||
|
//BUGBUG: end callback does not trigger
|
||||||
|
collector.on('end', collected => {
|
||||||
|
console.log(`Collected ${collected.size} interactions.`);
|
||||||
|
message.edit({ components: [] });
|
||||||
|
});
|
||||||
|
|
||||||
|
collector.on('collect', async m => {
|
||||||
|
switch (m.customId) {
|
||||||
|
case 'set-admin-role':
|
||||||
|
//Build select menu with every role in the guild
|
||||||
|
const row = new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new SelectMenuBuilder()
|
||||||
|
.setCustomId('select')
|
||||||
|
.setPlaceholder('Nothing selected')
|
||||||
|
.addOptions(
|
||||||
|
m.guild.roles.cache.map(role => ({
|
||||||
|
label: role.name,
|
||||||
|
description: role.id,
|
||||||
|
value: role.id
|
||||||
|
}))
|
||||||
|
),
|
||||||
|
);
|
||||||
|
const message = await m.reply({ content: 'Select a role', components: [row], fetchReply: true });
|
||||||
|
|
||||||
|
const filter = (m) => m.author.id === message.author.id;
|
||||||
|
const replyCollector = message.createMessageComponentCollector(filter, { componentType: ComponentType.SelectMenu, time: 25000 });
|
||||||
|
replyCollector.on('collect', async r => {
|
||||||
|
const role = m.guild.roles.cache.find(role => role.id === r.values[0]);
|
||||||
|
m.deleteReply(); //Delete select menu message
|
||||||
|
GuildUtils.setProperty(m.guild.id, 'adminRoleId', role.id);
|
||||||
|
r.reply({ content: `Selected role: ${role.name} \n(${role.id})`, components: [] });
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ module.exports = {
|
|||||||
data: new SlashCommandBuilder()
|
data: new SlashCommandBuilder()
|
||||||
.setName("ping")
|
.setName("ping")
|
||||||
.setDescription("Ping, yes"),
|
.setDescription("Ping, yes"),
|
||||||
|
permissionLevel: 1,
|
||||||
async execute(interaction) {
|
async execute(interaction) {
|
||||||
interaction.reply({
|
interaction.reply({
|
||||||
content: "Pong!",
|
content: "Pong!",
|
||||||
|
|||||||
@@ -35,8 +35,20 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const command = interaction.client.commands.get(interaction.commandName);
|
const command = interaction.client.commands.get(interaction.commandName);
|
||||||
|
|
||||||
|
//check if user has permissions to run the command
|
||||||
|
//TODO: pass down this user object to avoid duplicate queries
|
||||||
|
let user = await UserUtils.getUserByDiscordId(interaction.member.id);
|
||||||
|
let permissionLevel = await UserUtils.getPermissionLevel(interaction.member);
|
||||||
|
if (command.permissionLevel > permissionLevel) {
|
||||||
|
interaction.reply({
|
||||||
|
content: `You do not have permission to run this command`,
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!command) return;
|
if (!command) return;
|
||||||
|
|
||||||
|
|||||||
@@ -5,5 +5,11 @@ module.exports = {
|
|||||||
getBotProperty: async function(property) {
|
getBotProperty: async function(property) {
|
||||||
let bot = await Bot.findOne();
|
let bot = await Bot.findOne();
|
||||||
return property ? bot[property] : bot;
|
return property ? bot[property] : bot;
|
||||||
|
},
|
||||||
|
|
||||||
|
setBotProperty: async function(property, value) {
|
||||||
|
let bot = await Bot.findOne();
|
||||||
|
bot[property] = value;
|
||||||
|
await bot.save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
23
util/guilds.js
Normal file
23
util/guilds.js
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
const { Guild } = require("../models");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: "GuildUtils",
|
||||||
|
getProperty: async function(guildId, property) {
|
||||||
|
let guild = await Guild.findOne({
|
||||||
|
where: {
|
||||||
|
guildId: guildId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return property ? guild[property] : guild;
|
||||||
|
},
|
||||||
|
|
||||||
|
setProperty: async function(guildId, property, value) {
|
||||||
|
let guild = await Guild.findOne({
|
||||||
|
where: {
|
||||||
|
guildId: guildId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
guild[property] = value;
|
||||||
|
await guild.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
const { User } = require("../models");
|
const { User, Guild } = require("../models");
|
||||||
|
const GeneralUtils = require("./general");
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: "UserUtils",
|
name: "UserUtils",
|
||||||
@@ -65,5 +66,37 @@ module.exports = {
|
|||||||
let newCooldown = new Date(new Date().getTime() + cooldown);
|
let newCooldown = new Date(new Date().getTime() + cooldown);
|
||||||
user[`next${cooldownType[0].toUpperCase() + cooldownType.slice(1)}`] = newCooldown;
|
user[`next${cooldownType[0].toUpperCase() + cooldownType.slice(1)}`] = newCooldown;
|
||||||
await user.save();
|
await user.save();
|
||||||
|
},
|
||||||
|
|
||||||
|
getPermissionLevel: async function(user) {
|
||||||
|
/* THIS FUNCTION EXPECTS A DISCORD USER INSTANCE!
|
||||||
|
* Returns the permission level of the user
|
||||||
|
* 0 - no permissions
|
||||||
|
* 1 - guild permissions
|
||||||
|
* 2 - admin permissions
|
||||||
|
*/
|
||||||
|
let guild = await Guild.findOne({
|
||||||
|
where: {
|
||||||
|
guildId: user.guild.id
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
//Global Admin
|
||||||
|
let adminIDs = await GeneralUtils.getBotProperty("adminIDs");
|
||||||
|
if (adminIDs.includes(user.id)) {
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Guild Admin if role is present
|
||||||
|
if(user._roles.includes(String(guild.adminRoleId))) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
//or if user is owner
|
||||||
|
if(user.guild.ownerId === user.id) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Regular User
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user