feat(api): privilege levels

This commit is contained in:
Isaac 2024-04-22 03:03:33 +01:00
parent 46bd58daf6
commit 130f5dc590
No known key found for this signature in database
GPG Key ID: 0DE40AE37BBA5C33
4 changed files with 66 additions and 10 deletions

View File

@ -4,7 +4,7 @@ const { randomBytes } = require('crypto');
const { short } = require('leeks.js'); const { short } = require('leeks.js');
const { join } = require('path'); const { join } = require('path');
const { files } = require('node-dir'); const { files } = require('node-dir');
const { PermissionsBitField } = require('discord.js'); const { getPrivilegeLevel } = require('./lib/users');
process.env.ORIGIN = process.env.HTTP_INTERNAL || process.env.HTTP_EXTERNAL; process.env.ORIGIN = process.env.HTTP_INTERNAL || process.env.HTTP_EXTERNAL;
@ -65,6 +65,33 @@ module.exports = async client => {
} }
}); });
fastify.decorate('isMember', async (req, res) => {
try {
const userId = req.user.id;
const guildId = req.params.guild;
const guild = client.guilds.cache.get(guildId);
if (!guild) {
return res.code(404).send({
error: 'Not Found',
message: 'The requested resource could not be found.',
statusCode: 404,
});
}
const guildMember = await guild.members.fetch(userId);
if (!guildMember) {
return res.code(403).send({
error: 'Forbidden',
message: 'You are not permitted for this action.',
statusCode: 403,
});
}
} catch (err) {
res.send(err);
}
});
fastify.decorate('isAdmin', async (req, res) => { fastify.decorate('isAdmin', async (req, res) => {
try { try {
const userId = req.user.id; const userId = req.user.id;
@ -79,7 +106,7 @@ module.exports = async client => {
}); });
} }
const guildMember = await guild.members.fetch(userId); const guildMember = await guild.members.fetch(userId);
const isAdmin = guildMember?.permissions.has(PermissionsBitField.Flags.ManageGuild) || client.supers.includes(userId); const isAdmin = await getPrivilegeLevel(guildMember) >= 2;
if (!isAdmin) { if (!isAdmin) {
return res.code(403).send({ return res.code(403).send({
error: 'Forbidden', error: 'Forbidden',

View File

@ -46,3 +46,23 @@ module.exports.isStaff = async (guild, userId) => {
const staffRoles = await client.keyv.get(`cache/guild-staff:${guild.id}`) || await updateStaffRoles(guild); const staffRoles = await client.keyv.get(`cache/guild-staff:${guild.id}`) || await updateStaffRoles(guild);
return staffRoles.some(r => guildMember.roles.cache.has(r)); return staffRoles.some(r => guildMember.roles.cache.has(r));
}; };
/**
*
* @param {import("discord.js")} member
* @returns {Promise<number>}
* - `4` = OPERATOR (SUPER)
* - `3` = GUILD_OWNER
* - `2` = GUILD_ADMIN
* - `1` = GUILD_STAFF
* - `0` = GUILD_MEMBER
* - `-1` = NONE (NOT A MEMBER)
*/
module.exports.getPrivilegeLevel = async member => {
if (!member) return -1;
else if (member.guild.client.supers.includes(member.id)) return 4;
else if (member.guild.ownerId === member.id) return 3;
else if (member.permissions.has(PermissionsBitField.Flags.ManageGuild)) return 2;
else if (await this.isStaff(member.guild, member.id)) return 1;
else return 0;
};

View File

@ -1,3 +1,4 @@
const { getPrivilegeLevel } = require('../../../../lib/users');
const { iconURL } = require('../../../../lib/misc'); const { iconURL } = require('../../../../lib/misc');
module.exports.get = fastify => ({ module.exports.get = fastify => ({
@ -9,8 +10,9 @@ module.exports.get = fastify => ({
id: guild.id, id: guild.id,
logo: iconURL(guild), logo: iconURL(guild),
name: guild.name, name: guild.name,
privilegeLevel: await getPrivilegeLevel(await guild.members.fetch(req.user.id)),
}); });
}, },
onRequest: [fastify.authenticate], onRequest: [fastify.authenticate, fastify.isMember],
}); });

View File

@ -1,3 +1,4 @@
const { getPrivilegeLevel } = require('../../../lib/users');
const { iconURL } = require('../../../lib/misc'); const { iconURL } = require('../../../lib/misc');
module.exports.get = fastify => ({ module.exports.get = fastify => ({
@ -5,13 +6,19 @@ module.exports.get = fastify => ({
const { client } = req.routeOptions.config; const { client } = req.routeOptions.config;
const guilds = await (await fetch('https://discordapp.com/api/users/@me/guilds', { headers: { 'Authorization': `Bearer ${req.user.accessToken}` } })).json(); const guilds = await (await fetch('https://discordapp.com/api/users/@me/guilds', { headers: { 'Authorization': `Bearer ${req.user.accessToken}` } })).json();
res.send( res.send(
guilds await Promise.all(
.filter(guild => client.guilds.cache.has(guild.id)) guilds
.map(guild => ({ .filter(partialGuild => client.guilds.cache.has(partialGuild.id))
id: guild.id, .map(async partialGuild => {
logo: iconURL(client.guilds.cache.get(guild.id)), const guild = client.guilds.cache.get(partialGuild.id);
name: guild.name, return {
})), id: guild.id,
logo: iconURL(guild),
name: guild.name,
privilegeLevel: await getPrivilegeLevel(await guild.members.fetch(req.user.id)),
};
}),
),
); );
}, },
onRequest: [fastify.authenticate], onRequest: [fastify.authenticate],