More fixes

This commit is contained in:
Isaac 2022-07-18 21:53:17 +01:00
parent 3a1c0f54bd
commit 28f1e85759
9 changed files with 62 additions and 24 deletions

View File

@ -1,7 +1,8 @@
CONFIG_PATH=./user/config.yml CONFIG_PATH=./user/config.yml
DISCORD_SECRET= DISCORD_SECRET=
DISCORD_TOKEN= DISCORD_TOKEN=
DB_CONNECTION_URL="mysql://test:password@localhost/tickets0"
ENCRYPTION_KEY= ENCRYPTION_KEY=
DB_CONNECTION_URL="" HTTP_BIND=8080
HTTP_BIND=3000 HTTP_EXTERNAL=http://localhost:8080
HTTP_EXTERNAL= SUPER=

View File

@ -30,7 +30,7 @@
"node": ">=18.0" "node": ">=18.0"
}, },
"dependencies": { "dependencies": {
"@eartharoid/dbf": "^0.2.0", "@eartharoid/dbf": "^0.2.2",
"@eartharoid/dtf": "^2.0.1", "@eartharoid/dtf": "^2.0.1",
"@eartharoid/i18n": "^1.0.4", "@eartharoid/i18n": "^1.0.4",
"@fastify/cookie": "^6.0.0", "@fastify/cookie": "^6.0.0",
@ -48,6 +48,7 @@
"leekslazylogger": "^4.1.7", "leekslazylogger": "^4.1.7",
"ms": "^2.1.3", "ms": "^2.1.3",
"node-dir": "^0.1.17", "node-dir": "^0.1.17",
"node-emoji": "^1.11.0",
"object-diffy": "^1.0.4", "object-diffy": "^1.0.4",
"prisma": "^4.0.0", "prisma": "^4.0.0",
"semver": "^7.3.7", "semver": "^7.3.7",

View File

@ -115,7 +115,7 @@ model Guild {
blocklist Json @default("[]") blocklist Json @default("[]")
categories Category[] categories Category[]
createdAt DateTime @default(now()) createdAt DateTime @default(now())
errorColour String @default("RED") errorColour String @default("Red")
feedback Feedback[] feedback Feedback[]
footer String? @default("Discord Tickets by eartharoid") footer String? @default("Discord Tickets by eartharoid")
id String @id @db.VarChar(19) id String @id @db.VarChar(19)
@ -123,7 +123,7 @@ model Guild {
logChannel String? @db.VarChar(19) logChannel String? @db.VarChar(19)
primaryColour String @default("#009999") primaryColour String @default("#009999")
staleAfter Int? staleAfter Int?
successColour String @default("GREEN") successColour String @default("Green")
tags Tag[] tags Tag[]
tickets Ticket[] tickets Ticket[]
workingHours Json @default("[\"UTC\", [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"]]") workingHours Json @default("[\"UTC\", [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"], [\"00:00\",\"23:59\"]]")
@ -141,7 +141,7 @@ model Question {
maxLength Int? @default(4000) maxLength Int? @default(4000)
minLength Int? @default(0) minLength Int? @default(0)
order Int order Int
placeholder String? @db.VarChar(100) placeholder String? @db.VarChar(512)
required Boolean @default(true) required Boolean @default(true)
style Int @default(2) style Int @default(2)
value String? @db.Text value String? @db.Text

View File

@ -31,6 +31,7 @@ module.exports = class Client extends FrameworkClient {
this.i18n = new I18n('en-GB', locales); this.i18n = new I18n('en-GB', locales);
this.config = config; this.config = config;
this.log = log; this.log = log;
this.supers = (process.env.SUPER ?? '').split(',');
} }
async login(token) { async login(token) {

View File

@ -74,8 +74,8 @@ module.exports = client => {
}); });
} }
const guildMember = await guild.members.fetch(userId); const guildMember = await guild.members.fetch(userId);
const isAdmin = guildMember?.permissions.has('MANAGE_GUILD'); const isAdmin = guildMember?.permissions.has('MANAGE_GUILD') || client.supers.includes(userId);
if (!guildMember || !isAdmin) { if (!isAdmin) {
return res.code(403).send({ return res.code(403).send({
error: 'Forbidden', error: 'Forbidden',
message: 'You are not permitted for this action.', message: 'You are not permitted for this action.',
@ -88,6 +88,18 @@ module.exports = client => {
} }
}); });
// body processing
fastify.addHook('preHandler', (req, res, done) => {
if (req.body && typeof req.body === 'object') {
for (const prop in req.body) {
if (typeof req.body[prop] === 'string') {
req.body[prop] = req.body[prop].trim();
}
}
}
done();
});
// logging // logging
fastify.addHook('onResponse', (req, res, done) => { fastify.addHook('onResponse', (req, res, done) => {
done(); done();

View File

@ -1,4 +1,4 @@
const { MessageEmbed } = require('discord.js'); const { EmbedBuilder } = require('discord.js');
const { diff: getDiff } = require('object-diffy'); const { diff: getDiff } = require('object-diffy');
function makeDiff({ function makeDiff({
@ -61,8 +61,8 @@ async function logAdminEvent(client, {
const channel = client.channels.cache.get(settings.logChannel); const channel = client.channels.cache.get(settings.logChannel);
if (!channel) return; if (!channel) return;
const embeds = [ const embeds = [
new MessageEmbed() new EmbedBuilder()
.setColor('ORANGE') .setColor('Orange')
.setAuthor({ .setAuthor({
iconURL: user.avatarURL(), iconURL: user.avatarURL(),
name: user.username, name: user.username,
@ -77,13 +77,18 @@ async function logAdminEvent(client, {
targetType: getMessage(`log.admin.description.target.${target.type}`), targetType: getMessage(`log.admin.description.target.${target.type}`),
verb: getMessage(`log.admin.verb.${action}`), verb: getMessage(`log.admin.verb.${action}`),
})) }))
.addField(getMessage(`log.admin.title.target.${target.type}`), target.name ?? target.id), .addFields([
{
name: getMessage(`log.admin.title.target.${target.type}`),
value: target.name ?? target.id,
},
]),
]; ];
if (diff && diff.original) { if (diff && diff.original) {
embeds.push( embeds.push(
new MessageEmbed() new EmbedBuilder()
.setColor('ORANGE') .setColor('Orange')
.setTitle(getMessage('log.admin.changes')) .setTitle(getMessage('log.admin.changes'))
.setFields(makeDiff(diff)), .setFields(makeDiff(diff)),
); );

View File

@ -63,6 +63,9 @@ module.exports.patch = fastify => ({
const original = req.params.category && await client.prisma.category.findUnique({ where: { id: categoryId } }); const original = req.params.category && await client.prisma.category.findUnique({ where: { id: categoryId } });
if (!original) return res.status(404); if (!original) return res.status(404);
if (data.hasOwnProperty('id')) delete data.id;
if (data.hasOwnProperty('createdAt')) delete data.createdAt;
const category = await client.prisma.category.update({ const category = await client.prisma.category.update({
data: { data: {
...data, ...data,

View File

@ -1,4 +1,6 @@
const { logAdminEvent } = require('../../../../../../lib/logging'); const { logAdminEvent } = require('../../../../../../lib/logging');
const emoji = require('node-emoji');
const { ChannelType: { GuildCategory } } = require('discord.js');
module.exports.get = fastify => ({ module.exports.get = fastify => ({
handler: async (req, res) => { handler: async (req, res) => {
@ -42,14 +44,17 @@ module.exports.post = fastify => ({
const user = await client.users.fetch(req.user.payload.id); const user = await client.users.fetch(req.user.payload.id);
const guild = client.guilds.cache.get(req.params.guild); const guild = client.guilds.cache.get(req.params.guild);
const data = req.body; const data = req.body;
const allow = ['VIEW_CHANNEL', 'READ_MESSAGE_HISTORY', 'SEND_MESSAGES', 'EMBED_LINKS', 'ATTACH_FILES']; const allow = ['ViewChannel', 'ReadMessageHistory', 'SendMessages', 'EmbedLinks', 'AttachFiles'];
if (!data.discordCategory) { if (!data.discordCategory) {
const channel = await guild.channels.create(data.name, { let name = data.name;
if (emoji.hasEmoji(data.emoji)) name = `${emoji.get(data.emoji)} ${name}`;
const channel = await guild.channels.create({
name,
permissionOverwrites: [ permissionOverwrites: [
...[ ...[
{ {
deny: ['VIEW_CHANNEL'], deny: ['ViewChannel'],
id: guild.roles.everyone, id: guild.roles.everyone,
}, },
{ {
@ -64,12 +69,12 @@ module.exports.post = fastify => ({
], ],
position: 1, position: 1,
reason: `Tickets category created by ${user.tag}`, reason: `Tickets category created by ${user.tag}`,
type: 'GUILD_CATEGORY', type: GuildCategory,
}); });
data.discordCategory = channel.id; data.discordCategory = channel.id;
} }
data.channelName ??= 'ticket-{num}'; data.channelName ||= 'ticket-{num}'; // not ??=, expect empty string
const category = await client.prisma.category.create({ const category = await client.prisma.category.create({
data: { data: {

View File

@ -1,4 +1,5 @@
const { logAdminEvent } = require('../../../../../lib/logging.js'); const { logAdminEvent } = require('../../../../../lib/logging.js');
const { Colors } = require('discord.js');
module.exports.delete = fastify => ({ module.exports.delete = fastify => ({
handler: async (req, res) => { handler: async (req, res) => {
@ -37,16 +38,25 @@ module.exports.get = fastify => ({
module.exports.patch = fastify => ({ module.exports.patch = fastify => ({
handler: async (req, res) => { handler: async (req, res) => {
if (req.body.hasOwnProperty('id')) delete req.body.id; const data = req.body;
if (req.body.hasOwnProperty('createdAt')) delete req.body.createdAt; if (data.hasOwnProperty('id')) delete data.id;
if (data.hasOwnProperty('createdAt')) delete data.createdAt;
const colours = ['errorColour', 'primaryColour', 'successColour'];
for (const c of colours) {
if (data[c] && !data[c].startsWith('#') && !(data[c] in Colors)) { // if not null/empty and not hex
throw new Error(`${data[c]} is not a valid colour. Valid colours are HEX and: ${Object.keys(Colors).join(', ')}`);
}
}
/** @type {import('client')} */ /** @type {import('client')} */
const client = res.context.config.client; const client = res.context.config.client;
const id = req.params.guild; const id = req.params.guild;
const original = await client.prisma.guild.findUnique({ where: { id } }); const original = await client.prisma.guild.findUnique({ where: { id } });
const settings = await client.prisma.guild.update({ const settings = await client.prisma.guild.update({
data: req.body, data: data,
where: { id }, where: { id },
}); });
logAdminEvent(client, { logAdminEvent(client, {
action: 'update', action: 'update',
diff: { diff: {
@ -56,7 +66,7 @@ module.exports.patch = fastify => ({
guildId: id, guildId: id,
target: { target: {
id, id,
name: client.guilds.cache.get(id), name: client.guilds.cache.get(id).name,
type: 'settings', type: 'settings',
}, },
userId: req.user.payload.id, userId: req.user.payload.id,