import { createCipheriv, createDecipheriv, randomBytes, scryptSync } from "node:crypto"; const ALGORITHM = "aes-256-gcm"; const IV_LENGTH = 12; const TAG_LENGTH = 16; function getKey(): Buffer { const secret = process.env.INTEGRATION_SECRET; if (!secret) throw new Error("INTEGRATION_SECRET environment variable is required"); return scryptSync(secret, "trails-cool-integrations", 32); } export function encrypt(plaintext: string): string { const key = getKey(); const iv = randomBytes(IV_LENGTH); const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: TAG_LENGTH }); const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]); const tag = cipher.getAuthTag(); return Buffer.concat([iv, tag, encrypted]).toString("base64"); } export function decrypt(encoded: string): string { const key = getKey(); const buf = Buffer.from(encoded, "base64"); const iv = buf.subarray(0, IV_LENGTH); const tag = buf.subarray(IV_LENGTH, IV_LENGTH + TAG_LENGTH); const encrypted = buf.subarray(IV_LENGTH + TAG_LENGTH); const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: TAG_LENGTH }); decipher.setAuthTag(tag); return decipher.update(encrypted) + decipher.final("utf8"); }