import { SyncEntry } from "../../db_models" import crypto from "crypto" export default class SecureSyncEntry { static get encrytionAlgorithm() { return "aes-256-cbc" } static async set(user_id, key, value) { if (!user_id) { throw new Error("Missing user_id") } if (!key) { throw new Error("Missing key") } if (!value) { throw new Error("Missing value") } let entry = await SyncEntry.findOne({ user_id, key, }).catch(() => null) const encryptionKey = Buffer.from(process.env.SYNC_ENCRIPT_SECRET, "hex") const iv = crypto.randomBytes(16) const cipher = crypto.createCipheriv(SecureSyncEntry.encrytionAlgorithm, encryptionKey, iv) let encrypted try { encrypted = cipher.update(value) } catch (error) { console.error(error) } encrypted = Buffer.concat([encrypted, cipher.final()]) if (entry) { entry.value = iv.toString("hex") + ":" + encrypted.toString("hex") await entry.save() return entry } entry = new SyncEntry({ user_id, key, value: iv.toString("hex") + ":" + encrypted.toString("hex"), }) await entry.save() return entry } static async get(user_id, key) { if (!user_id) { throw new Error("Missing user_id") } if (!key) { throw new Error("Missing key") } const entry = await SyncEntry.findOne({ user_id, key, }).catch(() => null) if (!entry) { return null } const encryptionKey = Buffer.from(process.env.SYNC_ENCRIPT_SECRET, "hex") const iv = Buffer.from(entry.value.split(":")[0], "hex") const encryptedText = Buffer.from(entry.value.split(":")[1], "hex") const decipher = crypto.createDecipheriv(SecureSyncEntry.encrytionAlgorithm, encryptionKey, iv) let decrypted = decipher.update(encryptedText) decrypted = Buffer.concat([decrypted, decipher.final()]) return decrypted.toString() } static async delete(user_id, key) { if (!user_id) { throw new Error("Missing user_id") } if (!key) { throw new Error("Missing key") } const entry = await SyncEntry.findOne({ user_id, key, }).catch(() => null) if (!entry) { return null } await entry.delete() return entry } static async has(user_id, key) { if (!user_id) { throw new Error("Missing user_id") } if (!key) { throw new Error("Missing key") } const entry = await SyncEntry.findOne({ user_id, key, }).catch(() => null) return !!entry } }