Merge branch 'development' of github.com:ClicksMinutePer/Nucleus into development
diff --git a/.eslintignore b/.eslintignore
index 45ad95d..d7b2f7f 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1 +1 @@
-ClicksMigratingProblems/**/*
+ClicksMigratingProblems/**/*
\ No newline at end of file
diff --git a/src/api/index.ts b/src/api/index.ts
index 9676194..c8b7b14 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -152,7 +152,7 @@
     app.get("/transcript/:code/human", jsonParser, async function (req: express.Request, res: express.Response) {
         const code = req.params.code;
         if (code === undefined) return res.status(400).send("No code provided");
-        const entry = await client.database.transcripts.read(code);
+        const entry = await client.database.transcripts.read(code, req.query.key as string, req.query.iv as string);
         if (entry === null) return res.status(404).send("Could not find a transcript by that code");
         // Convert to a human readable format
         const data = client.database.transcripts.toHumanReadable(entry);
@@ -164,7 +164,7 @@
     app.get("/transcript/:code", jsonParser, async function (req: express.Request, res: express.Response) {
         const code = req.params.code;
         if (code === undefined) return res.status(400).send("No code provided");
-        const entry = await client.database.transcripts.read(code);
+        const entry = await client.database.transcripts.read(code, req.query.key as string, req.query.iv as string);
         if (entry === null) return res.status(404).send("Could not find a transcript by that code");
         // Convert to a human readable format
         return res.status(200).send(entry);
diff --git a/src/commands/mod/purge.ts b/src/commands/mod/purge.ts
index 8644e26..7728e56 100644
--- a/src/commands/mod/purge.ts
+++ b/src/commands/mod/purge.ts
@@ -318,7 +318,7 @@
         )).map(message => message as Message);
         const newOut = await client.database.transcripts.createTranscript(messageArray, interaction, interaction.member as GuildMember);
 
-        const code = await client.database.transcripts.create(newOut);
+        const [code, key, iv] = await client.database.transcripts.create(newOut);
         await interaction.editReply({
             embeds: [
                 new EmojiEmbed()
@@ -329,7 +329,7 @@
             ],
             components: [
                 new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
-                    new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript?code=${code}`),
+                    new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`).setDisabled(!code),
                 ])
             ]
         });
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 46784f5..69c8980 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -179,9 +179,10 @@
                 continue;
             }
             if (confirmation.success) {
-                client.database.guilds.delete(interaction.guild!.id);
-                client.database.history.delete(interaction.guild!.id);
-                client.database.notes.delete(interaction.guild!.id);
+                await client.database.guilds.delete(interaction.guild!.id);
+                await client.database.history.delete(interaction.guild!.id);
+                await client.database.notes.delete(interaction.guild!.id);
+                await client.database.transcripts.deleteAll(interaction.guild!.id);
                 nextFooter = "All data cleared";
                 continue;
             } else {
diff --git a/src/context/messages/purgeto.ts b/src/context/messages/purgeto.ts
index aef159b..0dc84e1 100644
--- a/src/context/messages/purgeto.ts
+++ b/src/context/messages/purgeto.ts
@@ -193,7 +193,7 @@
         )
     )).map(message => message as Message);
     const transcript = await client.database.transcripts.createTranscript(messageArray, interaction, interaction.member as GuildMember);
-    const code = await client.database.transcripts.create(transcript);
+    const [code, key, iv] = await client.database.transcripts.create(transcript);
     await interaction.editReply({
         embeds: [
             new EmojiEmbed()
@@ -204,7 +204,7 @@
         ],
         components: [
             new Discord.ActionRowBuilder<ButtonBuilder>().addComponents([
-                new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript?code=${code}`),
+                new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`).setDisabled(!code),
             ])
         ]
     });
diff --git a/src/premium/createTranscript.ts b/src/premium/createTranscript.ts
index 67aed04..fa5ec84 100644
--- a/src/premium/createTranscript.ts
+++ b/src/premium/createTranscript.ts
@@ -60,7 +60,7 @@
 
     const newOut = await client.database.transcripts.createTranscript(messages, interaction, member);
 
-    const code = await client.database.transcripts.create(newOut);
+    const [code, key, iv] = await client.database.transcripts.create(newOut);
     if(!code) return await interaction.reply({
         embeds: [
             new EmojiEmbed()
@@ -86,7 +86,7 @@
         ],
         components: [
             new ActionRowBuilder<ButtonBuilder>().addComponents([
-                new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://clicks.codes/nucleus/transcript/${code}`),
+                new ButtonBuilder().setLabel("View").setStyle(ButtonStyle.Link).setURL(`https://testing.coded.codes/nucleus/transcript/${code}?key=${key}&iv=${iv}`),
                 new ButtonBuilder()
                     .setLabel("Delete")
                     .setStyle(ButtonStyle.Danger)
diff --git a/src/utils/database.ts b/src/utils/database.ts
index 2e64320..0d21979 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -21,6 +21,7 @@
 const database = mongoClient.db();
 
 const collectionOptions = { authdb: "admin" };
+const getIV = () => crypto.randomBytes(16);
 
 export class Guilds {
     guilds: Collection<GuildConfig>;
@@ -203,15 +204,39 @@
         do {
             code = crypto.randomBytes(64).toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
         } while (await this.transcripts.findOne({ code: code }));
+        const key = crypto.randomBytes(32**2).toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-").substring(0, 32);
+        const iv = getIV().toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
+        for(const message of transcript.messages) {
+            if(message.content) {
+                const encCipher = crypto.createCipheriv("AES-256-CBC", key, iv);
+                message.content = encCipher.update(message.content, "utf8", "base64") + encCipher.final("base64");
+            }
+        }
 
         const doc = await this.transcripts.insertOne(Object.assign(transcript, { code: code }), collectionOptions);
-        if(doc.acknowledged) return code;
-        else return null;
+        if(doc.acknowledged) return [code, key, iv];
+        else return [null, null, null];
     }
 
-    async read(code: string) {
+    async read(code: string, key: string, iv: string) {
         // console.log("Transcript read")
-        return await this.transcripts.findOne({ code: code });
+        const doc = await this.transcripts.findOne({ code: code });
+        if(!doc) return null;
+        for(const message of doc.messages) {
+            if(message.content) {
+                const decCipher = crypto.createDecipheriv("AES-256-CBC", key, iv);
+                message.content = decCipher.update(message.content, "base64", "utf8") + decCipher.final("utf8");
+            }
+        }
+        return doc;
+    }
+
+    async deleteAll(guild: string) {
+        // console.log("Transcript delete")
+        const filteredDocs = await this.transcripts.find({ guild: guild }).toArray();
+        for (const doc of filteredDocs) {
+            await this.transcripts.deleteOne({ code: doc.code });
+        }
     }
 
     async createTranscript(messages: Message[], interaction: MessageComponentInteraction | CommandInteraction, member: GuildMember) {