Fix transcript encryption and endpoints (#35)

diff --git a/src/commands/nucleus/premium.ts b/src/commands/nucleus/premium.ts
index 0b0f553..4effb23 100644
--- a/src/commands/nucleus/premium.ts
+++ b/src/commands/nucleus/premium.ts
@@ -193,8 +193,9 @@
         );
     }
 
-    let userPremiumServers;
-    if ((dbMember?.appliesTo.length ?? 0) > 0) userPremiumServers = "\nIf you want to remove premium from a server, run this command in your DMs with me.";
+    let userPremiumServers = "";
+    if ((dbMember?.appliesTo.length ?? 0) > 0)
+        userPremiumServers = "\nIf you want to remove premium from a server, run this command in your DMs with me.";
 
     interaction.editReply({
         embeds: [
@@ -223,7 +224,9 @@
                 new EmojiEmbed()
                     .setTitle("Premium")
                     .setDescription(
-                        `You have already activated premium on the maximum amount of servers!` + userPremiumServers + firstDescription
+                        `You have already activated premium on the maximum amount of servers!` +
+                            userPremiumServers +
+                            firstDescription
                     )
                     .setEmoji("NUCLEUS.PREMIUMACTIVATE")
                     .setStatus("Danger")
@@ -236,7 +239,9 @@
             embeds: [
                 new EmojiEmbed()
                     .setTitle("Premium")
-                    .setDescription(`You have activated premium on this server!` + userPremiumServers + firstDescription)
+                    .setDescription(
+                        `You have activated premium on this server!` + userPremiumServers + firstDescription
+                    )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
             ],
diff --git a/src/commands/privacy.ts b/src/commands/privacy.ts
index 0be4880..590e866 100644
--- a/src/commands/privacy.ts
+++ b/src/commands/privacy.ts
@@ -33,7 +33,7 @@
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({text: "https://clicksminuteper.github.io/policies/nucleus"})
+                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Welcome")
             .setDescription("General privacy information")
@@ -48,7 +48,7 @@
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({text: "https://clicksminuteper.github.io/policies/nucleus"})
+                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Scanners")
             .setDescription("About Unscan")
@@ -62,7 +62,7 @@
                     )
                     .setEmoji("NUCLEUS.LOGO")
                     .setStatus("Danger")
-                    .setFooter({text: "https://clicksminuteper.github.io/policies/nucleus"})
+                    .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
             )
             .setTitle("Link scanning and Transcripts")
             .setDescription("Information about how links and images are scanned, and transcripts are stored")
@@ -77,7 +77,7 @@
                               .setDescription("Below are buttons for controlling this servers privacy settings")
                               .setEmoji("NUCLEUS.LOGO")
                               .setStatus("Danger")
-                              .setFooter({text: "https://clicksminuteper.github.io/policies/nucleus"})
+                              .setFooter({ text: "https://clicksminuteper.github.io/policies/nucleus" })
                       )
                       .setTitle("Options")
                       .setDescription("Options")
diff --git a/src/commands/settings/tracks.ts b/src/commands/settings/tracks.ts
index 7e341c4..5215b3f 100644
--- a/src/commands/settings/tracks.ts
+++ b/src/commands/settings/tracks.ts
@@ -248,7 +248,8 @@
                     }need a role in this track\n` +
                     `${getEmojiByName("CONTROL." + (current.retainPrevious ? "TICK" : "CROSS"))} Members ${
                         current.retainPrevious ? "" : "don't "
-                    }keep all roles below their current highest\n\n` + (previousMessage ? previousMessage + "\n\n": "") +
+                    }keep all roles below their current highest\n\n` +
+                    (previousMessage ? previousMessage + "\n\n" : "") +
                     createVerticalTrack(
                         mapped.map((role) => renderRole(role)),
                         new Array(current.track.length).fill(false),
@@ -322,7 +323,7 @@
                 case "addRole": {
                     const role = out.values![0]!;
                     const roleObj = roles.get(role)!;
-                    if (roleObj.position >= (interaction.member as GuildMember).roles.highest.position){
+                    if (roleObj.position >= (interaction.member as GuildMember).roles.highest.position) {
                         previousMessage = "You can't add a role that is higher than your highest role.";
                     } else {
                         if (!current.track.includes(role)) {
diff --git a/src/events/messageCreate.ts b/src/events/messageCreate.ts
index fe2e27c..854e85c 100644
--- a/src/events/messageCreate.ts
+++ b/src/events/messageCreate.ts
@@ -20,7 +20,7 @@
         message.channel.type === ChannelType.GuildAnnouncement &&
         message.reference === null
     ) {
-        if(message.channel.permissionsFor(message.guild.members.me!)!.has("ManageMessages")) {
+        if (message.channel.permissionsFor(message.guild.members.me!)!.has("ManageMessages")) {
             await message.crosspost();
         } else {
             singleNotify(`I don't have permissions to publish in <#${message.channel.id}>`, message.guild.id, true);
diff --git a/src/index.ts b/src/index.ts
index 875bf45..50a1526 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -17,7 +17,6 @@
     }
     await client.database.premium.checkAllPremium();
     await client.database.guilds.updateAllGuilds();
-
 });
 
 process.on("unhandledRejection", (err) => {
diff --git a/src/utils/database.ts b/src/utils/database.ts
index 8f37466..89c108b 100644
--- a/src/utils/database.ts
+++ b/src/utils/database.ts
@@ -55,7 +55,7 @@
             } catch (e) {
                 guildObj = null;
             }
-            if(!guildObj) await this.delete(guild.id);
+            if (!guildObj) await this.delete(guild.id);
         }
     }
 
@@ -251,7 +251,13 @@
             .replace(/\//g, "_")
             .replace(/\+/g, "-")
             .substring(0, 32);
-        const iv = getIV().toString("base64").replace(/=/g, "").replace(/\//g, "_").replace(/\+/g, "-");
+        const iv = getIV()
+            .toString("base64")
+            .substring(0, 16)
+            .replace(/=/g, "")
+            .replace(/\//g, "_")
+            .replace(/\+/g, "-");
+        console.log(iv);
         for (const message of transcript.messages) {
             if (message.content) {
                 const encCipher = crypto.createCipheriv("AES-256-CBC", key, iv);
@@ -320,9 +326,10 @@
     }
 
     async read(code: string, key: string, iv: string) {
-        // console.log("Transcript read")
+        console.log("Transcript read");
         let doc: TranscriptSchema | null = await this.transcripts.findOne({ code: code });
         let findDoc: findDocSchema | null = null;
+        console.log(doc);
         if (!doc) findDoc = await this.messageToTranscript.findOne({ transcript: code });
         if (findDoc) {
             const message = await (
@@ -348,6 +355,7 @@
             if (!data) return null;
             doc = JSON.parse(Buffer.from(data).toString()) as TranscriptSchema;
         }
+        console.log(doc);
         if (!doc) return null;
         for (const message of doc.messages) {
             if (message.content) {
@@ -401,15 +409,15 @@
                     discriminator: parseInt(message.author.discriminator),
                     id: message.author.id,
                     topRole: {
-                        color: message.member!.roles.highest.color
+                        color: message.member ? message.member.roles.highest.color : 0x000000
                     },
-                    iconURL: message.member!.user.displayAvatarURL({ forceStatic: true }),
-                    bot: message.author.bot
+                    iconURL: (message.member?.user || message.author).displayAvatarURL({ forceStatic: true }),
+                    bot: message.author.bot || false
                 },
                 createdTimestamp: message.createdTimestamp
             };
             if (message.member?.nickname) msg.author.nickname = message.member.nickname;
-            if (message.member!.roles.icon) msg.author.topRole.badgeURL = message.member!.roles.icon.iconURL()!;
+            if (message.member?.roles.icon) msg.author.topRole.badgeURL = message.member!.roles.icon.iconURL()!;
             if (message.content) msg.content = message.content;
             if (message.embeds.length > 0)
                 msg.embeds = message.embeds.map((embed) => {
diff --git a/src/utils/log.ts b/src/utils/log.ts
index f1c03ef..b29f365 100644
--- a/src/utils/log.ts
+++ b/src/utils/log.ts
@@ -4,7 +4,7 @@
 import { promisify } from "util";
 import generateKeyValueList from "./generateKeyValueList.js";
 import client from "./client.js";
-import {DiscordAPIError} from "discord.js";
+import { DiscordAPIError } from "discord.js";
 
 const wait = promisify(setTimeout);
 
@@ -44,12 +44,12 @@
         return `${user.username} [<@${user.id}>]`;
     },
     renderTime(t: number) {
-        if(isNaN(t)) return "Unknown"
+        if (isNaN(t)) return "Unknown";
         t = Math.floor((t /= 1000));
         return `<t:${t}:D> at <t:${t}:T>`;
     },
     renderDelta(t: number) {
-        if(isNaN(t)) return "Unknown"
+        if (isNaN(t)) return "Unknown";
         t = Math.floor((t /= 1000));
         return `<t:${t}:R> (<t:${t}:D> at <t:${t}:T>)`;
     },
diff --git a/src/utils/migration/migration.ts b/src/utils/migration/migration.ts
index 0f54724..6286465 100644
--- a/src/utils/migration/migration.ts
+++ b/src/utils/migration/migration.ts
@@ -1,18 +1,20 @@
-import * as fs from 'fs';
+import * as fs from "fs";
 import client from "../client.js";
 import _ from "lodash";
 
-const dir = './data';
+const dir = "./data";
 const files = fs.readdirSync(dir);
 
 for (const file of files) {
     // eslint-disable-next-line @typescript-eslint/no-explicit-any
     let rsmData: any;
     try {
-        rsmData = JSON.parse(fs.readFileSync(`${dir}/${file}`, 'utf8'));
-    } catch { continue }
+        rsmData = JSON.parse(fs.readFileSync(`${dir}/${file}`, "utf8"));
+    } catch {
+        continue;
+    }
     if (!rsmData.version || rsmData.version < 3) continue;
-    const nucleusData = await client.database.guilds.readOld(rsmData.guild_info.id)
+    const nucleusData = await client.database.guilds.readOld(rsmData.guild_info.id);
     const rsmToNucleus = {
         id: rsmData.guild_info.id,
         version: 1,
@@ -20,54 +22,54 @@
         filters: {
             images: {
                 NSFW: rsmData.images?.nsfw,
-                size: rsmData.images?.toosmall,
+                size: rsmData.images?.toosmall
             },
             malware: null,
             wordFilter: {
                 enabled: true,
                 words: {
                     strict: rsmData.wordfilter?.strict,
-                    loose: rsmData.wordfilter?.soft,
+                    loose: rsmData.wordfilter?.soft
                 },
                 allowed: {
                     users: rsmData.wordfilter?.ignore?.members,
                     roles: rsmData.wordfilter?.ignore?.roles,
-                    channels: rsmData.wordfilter?.ignore?.channels,
-                },
+                    channels: rsmData.wordfilter?.ignore?.channels
+                }
             },
             invite: {
                 enabled: rsmData.invite?.enabled,
                 allowed: {
                     channels: rsmData.invite?.whitelist?.members,
                     roles: rsmData.invite?.whitelist?.roles,
-                    users: rsmData.invite?.whitelist?.channels,
-                },
+                    users: rsmData.invite?.whitelist?.channels
+                }
             }
         },
         welcome: {
             enabled: true,
             role: rsmData.welcome?.role,
             channel: rsmData.welcome?.message?.channel,
-            message: rsmData.welcome?.message?.text ?? null,
+            message: rsmData.welcome?.message?.text ?? null
         },
         logging: {
             logs: {
                 enabled: true,
-                channel: rsmData.log_info?.log_channel,
+                channel: rsmData.log_info?.log_channel
             },
             staff: {
-                channel: rsmData.log_info?.staff,
+                channel: rsmData.log_info?.staff
             }
         },
         verify: {
             enabled: true,
-            role: rsmData.verify_role,
+            role: rsmData.verify_role
         },
         tickets: {
             enabled: true,
             category: rsmData.modmail?.cat,
             supportRole: rsmData.modmail?.mention,
-            maxTickets: rsmData.modmail?.max,
+            maxTickets: rsmData.modmail?.max
         },
         tags: rsmData.tags
     } as Partial<ReturnType<typeof client.database.guilds.read>>;
@@ -75,5 +77,4 @@
     const merged = _.merge(nucleusData, rsmToNucleus);
     // console.log(merged)
     await client.database.guilds.write(merged.id!, merged);
-
 }