From 57bb342303e25dc8748eba52c12516650ad7228d Mon Sep 17 00:00:00 2001 From: Tarrgon <61888458+Tarrgon@users.noreply.github.com> Date: Mon, 6 Jul 2026 21:47:47 -0400 Subject: [PATCH] Add author id hash to database --- scripts/add-author-id-hash.js | 51 ++++++++++++++++++++++ sql/migrations/0004-add-author-id-hash.sql | 10 +++++ src/shared/Database.ts | 6 ++- src/types/database-types.d.ts | 3 +- 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 scripts/add-author-id-hash.js create mode 100644 sql/migrations/0004-add-author-id-hash.sql diff --git a/scripts/add-author-id-hash.js b/scripts/add-author-id-hash.js new file mode 100644 index 0000000..1fb619e --- /dev/null +++ b/scripts/add-author-id-hash.js @@ -0,0 +1,51 @@ +import crypto from 'crypto'; +import dotenv from 'dotenv'; +import { open } from 'sqlite'; +import sqlite3 from 'sqlite3'; + +dotenv.config(); + +async function main() { + Encrypter.initialize(process.env.DATABASE_SECRET); + + const db = await open({ + filename: './data/discord-main.db', + driver: sqlite3.Database + }); + + const messages = await db.all('SELECT * FROM messages'); + + db.exec('BEGIN TRANSACTION'); + for (const message of messages) { + db.run('UPDATE messages SET author_id_hash = ? WHERE id = ?', Encrypter.hash(Encrypter.decrypt(message.author_id)), message.id); + } + db.exec('COMMIT'); +} + +class Encrypter { + static initialize(encryptionKey) { + this.key = crypto.scryptSync(encryptionKey, 'salt', 32); + } + static encrypt(clearText) { + const iv = crypto.randomBytes(16); + const cipher = crypto.createCipheriv(this.algorithm, this.key, iv); + const encrypted = cipher.update(clearText, 'utf8', 'hex'); + return [ + encrypted + cipher.final('hex'), + Buffer.from(iv).toString('hex'), + ].join('|'); + } + static decrypt(encryptedText) { + const [encrypted, iv] = encryptedText.split('|'); + if (!iv) + throw new Error('IV not found'); + const decipher = crypto.createDecipheriv(this.algorithm, this.key, Buffer.from(iv, 'hex')); + return decipher.update(encrypted, 'hex', 'utf8') + decipher.final('utf8'); + } + static hash(clearText) { + return crypto.createHmac('sha256', this.key).update(clearText).digest('base64'); + } +} +Encrypter.algorithm = 'aes-256-cbc'; + +main(); diff --git a/sql/migrations/0004-add-author-id-hash.sql b/sql/migrations/0004-add-author-id-hash.sql new file mode 100644 index 0000000..3b20eef --- /dev/null +++ b/sql/migrations/0004-add-author-id-hash.sql @@ -0,0 +1,10 @@ +-------------------------------------------------------------------------------- +-- Up +-------------------------------------------------------------------------------- +ALTER TABLE messages ADD author_id_hash TEXT NOT NULL DEFAULT ''; +CREATE INDEX IF NOT EXISTS index_author_id_hash ON messages (author_id_hash); + +-------------------------------------------------------------------------------- +-- Down +-------------------------------------------------------------------------------- +ALTER TABLE messages DROP COLUMN author_id_hash; \ No newline at end of file diff --git a/src/shared/Database.ts b/src/shared/Database.ts index b4ee77a..1a9b3f5 100644 --- a/src/shared/Database.ts +++ b/src/shared/Database.ts @@ -131,7 +131,7 @@ export class Database { const serializedMessage = serializeMessage(message); await Database.db.run(` - INSERT INTO messages (id, id_hash, author_id, author_name, channel_id, attachments, stickers, content) VALUES + INSERT INTO messages (id, id_hash, author_id, author_id_hash, author_name, channel_id, attachments, stickers, content) VALUES (:id, :id_hash, :author_id, :author_name, :channel_id, :attachments, :stickers, :content) `, ...serializedMessage); @@ -172,6 +172,10 @@ export class Database { await Database.db.run('DELETE from messages WHERE datetime(timestamp) < datetime("now", "-28 days")'); } + static async purgeMessagesFrom(id: string) { + await Database.db.run('DELETE from messages WHERE '); + } + //#endregion //#region Tickets diff --git a/src/types/database-types.d.ts b/src/types/database-types.d.ts index 1fecb34..00b202c 100644 --- a/src/types/database-types.d.ts +++ b/src/types/database-types.d.ts @@ -1,7 +1,8 @@ export type LoggedMessage = { id: string - id_encrypted: string + id_hash: string author_id: string + author_id_hash: string author_name: string channel_id: string attachments: string