Skip to content

Commit

Permalink
fix(🚨 security): anyone with the channel ID could read transcripts
Browse files Browse the repository at this point in the history
  • Loading branch information
eartharoid committed Aug 24, 2023
1 parent 2abd9cc commit b2790fc
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 22 deletions.
72 changes: 50 additions & 22 deletions src/commands/slash/transcript.js
Expand Up @@ -6,6 +6,8 @@ const Mustache = require('mustache');
const { AttachmentBuilder } = require('discord.js');
const Cryptr = require('cryptr');
const { decrypt } = new Cryptr(process.env.ENCRYPTION_KEY);
const { isStaff } = require('../../lib/users');
const ExtendedEmbedBuilder = require('../../lib/embed');

module.exports = class TranscriptSlashCommand extends SlashCommand {
constructor(client, options) {
Expand Down Expand Up @@ -44,29 +46,9 @@ module.exports = class TranscriptSlashCommand extends SlashCommand {
);
}

async fillTemplate(ticketId) {
async fillTemplate(ticket) {
/** @type {import("client")} */
const client = this.client;
const ticket = await client.prisma.ticket.findUnique({
include: {
archivedChannels: true,
archivedMessages: {
orderBy: { createdAt: 'asc' },
where: { external: false },
},
archivedRoles: true,
archivedUsers: true,
category: true,
claimedBy: true,
closedBy: true,
createdBy: true,
feedback: true,
guild: true,
questionAnswers: true,
},
where: { id: ticketId },
});
if (!ticket) throw new Error(`Ticket ${ticketId} does not exist`);

ticket.claimedBy = ticket.archivedUsers.find(u => u.userId === ticket.claimedById);
ticket.closedBy = ticket.archivedUsers.find(u => u.userId === ticket.closedById);
Expand Down Expand Up @@ -137,14 +119,60 @@ module.exports = class TranscriptSlashCommand extends SlashCommand {
* @param {import("discord.js").ChatInputCommandInteraction} interaction
*/
async run(interaction) {
/** @type {import("client")} */
const client = this.client;

await interaction.deferReply({ ephemeral: true });
const ticketId = interaction.options.getString('ticket', true);
const ticket = await client.prisma.ticket.findUnique({
include: {
archivedChannels: true,
archivedMessages: {
orderBy: { createdAt: 'asc' },
where: { external: false },
},
archivedRoles: true,
archivedUsers: true,
category: true,
claimedBy: true,
closedBy: true,
createdBy: true,
feedback: true,
guild: true,
questionAnswers: true,
},
where: { id: ticketId },
});

if (!ticket) throw new Error(`Ticket ${ticketId} does not exist`);

if (
ticket.createdById !== interaction.member.id &&
!(await isStaff(interaction.guild, interaction.member.id))
) {
const settings = await client.prisma.guild.findUnique({ where: { id: interaction.guild.id } });
const getMessage = client.i18n.getLocale(settings.locale);
return await interaction.editReply({
embeds: [
new ExtendedEmbedBuilder({
iconURL: interaction.guild.iconURL(),
text: ticket.guild.footer,
})
.setColor(ticket.guild.errorColour)
.setTitle(getMessage('commands.slash.transcript.not_staff.title'))
.setDescription(getMessage('commands.slash.transcript.not_staff.description')),
],
});
}

const {
fileName,
transcript,
} = await this.fillTemplate(interaction.options.getString('ticket', true));
} = await this.fillTemplate(ticket);
const attachment = new AttachmentBuilder()
.setFile(Buffer.from(transcript))
.setName(fileName);

await interaction.editReply({ files: [attachment] });
// TODO: add portal link
}
Expand Down
3 changes: 3 additions & 0 deletions src/i18n/en-GB.yml
Expand Up @@ -228,6 +228,9 @@ commands:
transcript:
description: Get the transcript of a ticket
name: transcript
not_staff:
description: Only staff members can read the transcripts of others' tickets.
title: ❌ Error
options:
member:
description: The member to search for tickets of
Expand Down

0 comments on commit b2790fc

Please sign in to comment.