mirror of
https://github.com/Hessenuk/DiscordTickets.git
synced 2024-12-23 08:13:09 +02:00
Giving up on encryption
and life
This commit is contained in:
parent
28f1e85759
commit
5786c3598d
@ -53,13 +53,13 @@ model ArchivedUser {
|
|||||||
bot Boolean @default(false)
|
bot Boolean @default(false)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
discriminator String @db.Char(4)
|
discriminator String @db.Char(4)
|
||||||
displayName String @db.VarChar(512)
|
displayName String @db.Text
|
||||||
role ArchivedRole @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
role ArchivedRole @relation(fields: [ticketId, roleId], references: [ticketId, roleId], onDelete: Cascade)
|
||||||
roleId String @db.VarChar(19)
|
roleId String @db.VarChar(19)
|
||||||
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||||
ticketId String @db.VarChar(19)
|
ticketId String @db.VarChar(19)
|
||||||
userId String @db.VarChar(19)
|
userId String @db.VarChar(19)
|
||||||
username String @db.VarChar(512)
|
username String @db.Text
|
||||||
|
|
||||||
@@id([ticketId, userId])
|
@@id([ticketId, userId])
|
||||||
@@unique([ticketId, userId])
|
@@unique([ticketId, userId])
|
||||||
@ -70,7 +70,7 @@ model Category {
|
|||||||
channelName String
|
channelName String
|
||||||
claiming Boolean @default(false)
|
claiming Boolean @default(false)
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
description String @db.VarChar(512)
|
description String
|
||||||
discordCategory String @db.VarChar(19)
|
discordCategory String @db.VarChar(19)
|
||||||
emoji String
|
emoji String
|
||||||
enableFeedback Boolean @default(false)
|
enableFeedback Boolean @default(false)
|
||||||
@ -79,7 +79,7 @@ model Category {
|
|||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
image String?
|
image String?
|
||||||
memberLimit Int @default(1)
|
memberLimit Int @default(1)
|
||||||
name String @db.VarChar(512)
|
name String
|
||||||
openingMessage String @db.Text
|
openingMessage String @db.Text
|
||||||
pingRoles Json @default("[]")
|
pingRoles Json @default("[]")
|
||||||
questions Question[]
|
questions Question[]
|
||||||
@ -134,14 +134,14 @@ model Guild {
|
|||||||
model Question {
|
model Question {
|
||||||
answers QuestionAnswer[]
|
answers QuestionAnswer[]
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
id Int @id @default(autoincrement())
|
id String @id @default(uuid())
|
||||||
category Category? @relation(fields: [categoryId], references: [id])
|
category Category @relation(fields: [categoryId], references: [id], onDelete: Cascade)
|
||||||
categoryId Int?
|
categoryId Int
|
||||||
label String @db.VarChar(512)
|
label String
|
||||||
maxLength Int? @default(4000)
|
maxLength Int? @default(4000)
|
||||||
minLength Int? @default(0)
|
minLength Int? @default(0)
|
||||||
order Int
|
order Int
|
||||||
placeholder String? @db.VarChar(512)
|
placeholder String?
|
||||||
required Boolean @default(true)
|
required Boolean @default(true)
|
||||||
style Int @default(2)
|
style Int @default(2)
|
||||||
value String? @db.Text
|
value String? @db.Text
|
||||||
@ -152,11 +152,11 @@ model Question {
|
|||||||
model QuestionAnswer {
|
model QuestionAnswer {
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
ticket Ticket @relation(fields: [ticketId], references: [id])
|
ticket Ticket @relation(fields: [ticketId], references: [id], onDelete: Cascade)
|
||||||
ticketId String @db.VarChar(19)
|
ticketId String @db.VarChar(19)
|
||||||
question Question @relation(fields: [questionId], references: [id])
|
question Question @relation(fields: [questionId], references: [id], onDelete: Cascade)
|
||||||
questionId Int
|
questionId String
|
||||||
user User @relation(fields: [userId], references: [id])
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||||
userId String @db.VarChar(19)
|
userId String @db.VarChar(19)
|
||||||
value String? @db.Text
|
value String? @db.Text
|
||||||
|
|
||||||
@ -164,13 +164,13 @@ model QuestionAnswer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
model Tag {
|
model Tag {
|
||||||
content String @db.Text()
|
content String @db.Text
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
guild Guild @relation(fields: [guildId], references: [id], onDelete: Cascade)
|
||||||
guildId String @db.VarChar(19)
|
guildId String @db.VarChar(19)
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
name String @db.VarChar(512)
|
name String
|
||||||
regex String? @db.VarChar(512)
|
regex String?
|
||||||
|
|
||||||
@@unique([guildId, name])
|
@@unique([guildId, name])
|
||||||
@@map("tags")
|
@@map("tags")
|
||||||
@ -188,7 +188,7 @@ model Ticket {
|
|||||||
closedAt DateTime?
|
closedAt DateTime?
|
||||||
closedBy User @relation(name: "TicketsClosedByUser", fields: [closedById], references: [id])
|
closedBy User @relation(name: "TicketsClosedByUser", fields: [closedById], references: [id])
|
||||||
closedById String @db.VarChar(19)
|
closedById String @db.VarChar(19)
|
||||||
closedReason String? @db.VarChar(512)
|
closedReason String?
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
createdBy User @relation(name: "TicketsCreatedByUser", fields: [createdById], references: [id])
|
createdBy User @relation(name: "TicketsCreatedByUser", fields: [createdById], references: [id])
|
||||||
createdById String @db.VarChar(19)
|
createdById String @db.VarChar(19)
|
||||||
@ -210,7 +210,7 @@ model Ticket {
|
|||||||
referencesMessageId String @db.VarChar(19)
|
referencesMessageId String @db.VarChar(19)
|
||||||
referencesTicket Ticket? @relation(name: "TicketsReferencedByTicket", fields: [referencesTicketId], references: [id], onDelete: SetNull)
|
referencesTicket Ticket? @relation(name: "TicketsReferencedByTicket", fields: [referencesTicketId], references: [id], onDelete: SetNull)
|
||||||
referencesTicketId String? @db.VarChar(19)
|
referencesTicketId String? @db.VarChar(19)
|
||||||
topic String? @db.VarChar(512)
|
topic String?
|
||||||
questionAnswers QuestionAnswer[]
|
questionAnswers QuestionAnswer[]
|
||||||
|
|
||||||
@@unique([guildId, number])
|
@@unique([guildId, number])
|
||||||
|
@ -6,7 +6,6 @@ const I18n = require('@eartharoid/i18n');
|
|||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const { join } = require('path');
|
const { join } = require('path');
|
||||||
const YAML = require('yaml');
|
const YAML = require('yaml');
|
||||||
const middleware = require('./lib/prisma');
|
|
||||||
|
|
||||||
module.exports = class Client extends FrameworkClient {
|
module.exports = class Client extends FrameworkClient {
|
||||||
constructor(config, log) {
|
constructor(config, log) {
|
||||||
@ -37,7 +36,6 @@ module.exports = class Client extends FrameworkClient {
|
|||||||
async login(token) {
|
async login(token) {
|
||||||
/** @type {PrismaClient} */
|
/** @type {PrismaClient} */
|
||||||
this.prisma = new PrismaClient();
|
this.prisma = new PrismaClient();
|
||||||
this.prisma.$use(middleware(this.log));
|
|
||||||
this.keyv = new Keyv();
|
this.keyv = new Keyv();
|
||||||
return super.login(token);
|
return super.login(token);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
const { EmbedBuilder } = require('discord.js');
|
const {
|
||||||
|
cleanCodeBlockContent,
|
||||||
|
EmbedBuilder,
|
||||||
|
} = require('discord.js');
|
||||||
const { diff: getDiff } = require('object-diffy');
|
const { diff: getDiff } = require('object-diffy');
|
||||||
|
|
||||||
function makeDiff({
|
function makeDiff({
|
||||||
@ -8,12 +11,12 @@ function makeDiff({
|
|||||||
const fields = [];
|
const fields = [];
|
||||||
for (const key in diff) {
|
for (const key in diff) {
|
||||||
if (key === 'createdAt') continue; // object-diffy doesn't like dates
|
if (key === 'createdAt') continue; // object-diffy doesn't like dates
|
||||||
const from = diff[key].from === null ? '' : `- ${diff[key].from}\n`;
|
const from = diff[key].from === null ? '' : `- ${diff[key].from.toString().replace(/\n/g, '\\n')}\n`;
|
||||||
const to = diff[key].to === null ? '' : `+ ${diff[key].to}\n`;
|
const to = diff[key].to === null ? '' : `+ ${diff[key].to.toString().replace(/\n/g, '\\n')}\n`;
|
||||||
fields.push({
|
fields.push({
|
||||||
inline: true,
|
inline: true,
|
||||||
name: key,
|
name: key,
|
||||||
value: `\`\`\`diff\n${from + to}\n\`\`\``,
|
value: `\`\`\`diff\n${cleanCodeBlockContent(from + to)}\n\`\`\``,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return fields;
|
return fields;
|
||||||
|
@ -1,69 +0,0 @@
|
|||||||
const Cryptr = require('cryptr');
|
|
||||||
const cryptr = new Cryptr(process.env.ENCRYPTION_KEY);
|
|
||||||
const fields = [
|
|
||||||
'name',
|
|
||||||
'content',
|
|
||||||
'username',
|
|
||||||
'displayName',
|
|
||||||
// 'channelName',
|
|
||||||
'openingMessage',
|
|
||||||
'description',
|
|
||||||
'value',
|
|
||||||
'placeholder',
|
|
||||||
'closedReason',
|
|
||||||
'topic',
|
|
||||||
'comment',
|
|
||||||
'label',
|
|
||||||
'regex',
|
|
||||||
];
|
|
||||||
const shouldEncrypt = ['create', 'createMany', 'update', 'updateMany', 'upsert'];
|
|
||||||
// const shouldDecrypt = ['findUnique', 'findFirst', 'findMany'];
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module.exports = log => {
|
|
||||||
const encrypt = obj => {
|
|
||||||
for (const prop in obj) {
|
|
||||||
if (obj.hasOwnProperty(prop)) {
|
|
||||||
if (typeof obj[prop] === 'object') {
|
|
||||||
obj[prop] = encrypt(obj[prop]);
|
|
||||||
} else if (typeof obj[prop] === 'string' && obj[prop].length !== 0 && fields.includes(prop)) {
|
|
||||||
try {
|
|
||||||
obj[prop] = cryptr.encrypt(obj[prop]);
|
|
||||||
} catch (error) {
|
|
||||||
log.warn(`Failed to encrypt ${prop}`);
|
|
||||||
log.debug(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
const decrypt = obj => {
|
|
||||||
for (const prop in obj) {
|
|
||||||
if (obj.hasOwnProperty(prop)) {
|
|
||||||
if (typeof obj[prop] === 'object') {
|
|
||||||
obj[prop] = decrypt(obj[prop]);
|
|
||||||
} else if (typeof obj[prop] === 'string' && obj[prop].length !== 0 && fields.includes(prop)) {
|
|
||||||
try {
|
|
||||||
obj[prop] = cryptr.decrypt(obj[prop]);
|
|
||||||
} catch (error) {
|
|
||||||
log.warn(`Failed to decrypt ${prop}`);
|
|
||||||
log.debug(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
};
|
|
||||||
|
|
||||||
return async (params, next) => {
|
|
||||||
if (params.args.data && shouldEncrypt.includes(params.action)) params.args = encrypt(params.args);
|
|
||||||
let result = await next(params);
|
|
||||||
// if (result && shouldDecrypt.includes(params.action)) result = decrypt(result);
|
|
||||||
if (result) result = decrypt(result);
|
|
||||||
return result;
|
|
||||||
};
|
|
||||||
};
|
|
@ -1,10 +1,14 @@
|
|||||||
const { logAdminEvent } = require('../../../../../../lib/logging');
|
const { logAdminEvent } = require('../../../../../../lib/logging');
|
||||||
|
const { randomUUID } = require('crypto');
|
||||||
|
|
||||||
module.exports.delete = fastify => ({
|
module.exports.delete = fastify => ({
|
||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
/** @type {import('client')} */
|
/** @type {import('client')} */
|
||||||
const client = res.context.config.client;
|
const client = res.context.config.client;
|
||||||
|
const guildId = req.params.guild;
|
||||||
const categoryId = Number(req.params.category);
|
const categoryId = Number(req.params.category);
|
||||||
|
const original = req.params.category && await client.prisma.category.findUnique({ where: { id: categoryId } });
|
||||||
|
if (!original || original.guildId !== guildId) return res.status(404).send(new Error('Not Found'));
|
||||||
const category = await client.prisma.category.delete({ where: { id: categoryId } });
|
const category = await client.prisma.category.delete({ where: { id: categoryId } });
|
||||||
|
|
||||||
logAdminEvent(client, {
|
logAdminEvent(client, {
|
||||||
@ -27,12 +31,13 @@ module.exports.get = fastify => ({
|
|||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
/** @type {import('client')} */
|
/** @type {import('client')} */
|
||||||
const client = res.context.config.client;
|
const client = res.context.config.client;
|
||||||
|
const guildId = req.params.guild;
|
||||||
const categoryId = Number(req.params.category);
|
const categoryId = Number(req.params.category);
|
||||||
const category = await client.prisma.category.findUnique({
|
const category = await client.prisma.category.findUnique({
|
||||||
include: {
|
include: {
|
||||||
questions: {
|
questions: {
|
||||||
select: {
|
select: {
|
||||||
createdAt: true,
|
// createdAt: true,
|
||||||
id: true,
|
id: true,
|
||||||
label: true,
|
label: true,
|
||||||
maxLength: true,
|
maxLength: true,
|
||||||
@ -48,6 +53,8 @@ module.exports.get = fastify => ({
|
|||||||
where: { id: categoryId },
|
where: { id: categoryId },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!category || category.guildId !== guildId) return res.status(404).send(new Error('Not Found'));
|
||||||
|
|
||||||
return category;
|
return category;
|
||||||
},
|
},
|
||||||
onRequest: [fastify.authenticate, fastify.isAdmin],
|
onRequest: [fastify.authenticate, fastify.isAdmin],
|
||||||
@ -57,11 +64,13 @@ module.exports.patch = fastify => ({
|
|||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
/** @type {import('client')} */
|
/** @type {import('client')} */
|
||||||
const client = res.context.config.client;
|
const client = res.context.config.client;
|
||||||
|
const guildId = req.params.guild;
|
||||||
const categoryId = Number(req.params.category);
|
const categoryId = Number(req.params.category);
|
||||||
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 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 || original.guildId !== guildId) return res.status(404).send(new Error('Not Found'));
|
||||||
|
|
||||||
|
|
||||||
if (data.hasOwnProperty('id')) delete data.id;
|
if (data.hasOwnProperty('id')) delete data.id;
|
||||||
if (data.hasOwnProperty('createdAt')) delete data.createdAt;
|
if (data.hasOwnProperty('createdAt')) delete data.createdAt;
|
||||||
@ -70,11 +79,14 @@ module.exports.patch = fastify => ({
|
|||||||
data: {
|
data: {
|
||||||
...data,
|
...data,
|
||||||
questions: {
|
questions: {
|
||||||
upsert: data.questions?.map(q => ({
|
upsert: data.questions?.map(q => {
|
||||||
|
if (!q.id) q.id = randomUUID();
|
||||||
|
return {
|
||||||
create: q,
|
create: q,
|
||||||
update: q,
|
update: q,
|
||||||
where: { id: q.id },
|
where: { id: q.id },
|
||||||
})),
|
};
|
||||||
|
}),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
where: { id: categoryId },
|
where: { id: categoryId },
|
||||||
|
@ -8,29 +8,27 @@ module.exports.get = fastify => ({
|
|||||||
const client = res.context.config.client;
|
const client = res.context.config.client;
|
||||||
|
|
||||||
const { categories } = await client.prisma.guild.findUnique({
|
const { categories } = await client.prisma.guild.findUnique({
|
||||||
select: {
|
select: { categories: true },
|
||||||
categories: {
|
|
||||||
include: {
|
|
||||||
questions: {
|
|
||||||
select: {
|
|
||||||
createdAt: true,
|
|
||||||
id: true,
|
|
||||||
label: true,
|
|
||||||
maxLength: true,
|
|
||||||
minLength: true,
|
|
||||||
order: true,
|
|
||||||
placeholder: true,
|
|
||||||
required: true,
|
|
||||||
style: true,
|
|
||||||
value: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
where: { id: req.params.guild },
|
where: { id: req.params.guild },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// include: {
|
||||||
|
// questions: {
|
||||||
|
// select: {
|
||||||
|
// createdAt: true,
|
||||||
|
// id: true,
|
||||||
|
// label: true,
|
||||||
|
// maxLength: true,
|
||||||
|
// minLength: true,
|
||||||
|
// order: true,
|
||||||
|
// placeholder: true,
|
||||||
|
// required: true,
|
||||||
|
// style: true,
|
||||||
|
// value: true,
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
|
||||||
return categories;
|
return categories;
|
||||||
},
|
},
|
||||||
onRequest: [fastify.authenticate, fastify.isAdmin],
|
onRequest: [fastify.authenticate, fastify.isAdmin],
|
||||||
|
32
src/routes/api/admin/guilds/[guild]/problems.js
Normal file
32
src/routes/api/admin/guilds/[guild]/problems.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
module.exports.get = fastify => ({
|
||||||
|
handler: async (req, res) => {
|
||||||
|
/** @type {import('client')} */
|
||||||
|
const client = res.context.config.client;
|
||||||
|
const id = req.params.guild;
|
||||||
|
const guild = client.guilds.cache.get(id);
|
||||||
|
const settings = await client.prisma.guild.findUnique({ where: { id } }) ??
|
||||||
|
await client.prisma.guild.create({ data: { id } });
|
||||||
|
const problems = [];
|
||||||
|
|
||||||
|
if (settings.logChannel) {
|
||||||
|
const permissions = guild.members.me.permissionsIn(settings.logChannel);
|
||||||
|
|
||||||
|
if (!permissions.has('SendMessages')) {
|
||||||
|
problems.push({
|
||||||
|
id: 'logChannelMissingPermission',
|
||||||
|
permission: 'SendMessages',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!permissions.has('EmbedLinks')) {
|
||||||
|
problems.push({
|
||||||
|
id: 'logChannelMissingPermission',
|
||||||
|
permission: 'EmbedLinks',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return problems;
|
||||||
|
},
|
||||||
|
onRequest: [fastify.authenticate, fastify.isAdmin],
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user