import { createCipheriv, createDecipheriv, randomBytes, createHash } from "crypto"; const ALGORITHM = "aes-256-gcm"; function getKey(): Buffer { const secret = process.env["BETTER_AUTH_SECRET"] ?? "dev-secret-needs-32-bytes-padding!"; return createHash("sha256").update(secret).digest(); } export function encrypt(plaintext: string): string { const key = getKey(); const iv = randomBytes(12); const cipher = createCipheriv(ALGORITHM, key, iv); const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]); const authTag = (cipher as ReturnType & { getAuthTag(): Buffer }).getAuthTag(); return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted.toString("hex")}`; } export function decrypt(ciphertext: string): string { const parts = ciphertext.split(":"); if (parts.length !== 3) throw new Error("Invalid ciphertext format"); const [ivHex, authTagHex, encryptedHex] = parts as [string, string, string]; const key = getKey(); const iv = Buffer.from(ivHex, "hex"); const authTag = Buffer.from(authTagHex, "hex"); const encrypted = Buffer.from(encryptedHex, "hex"); const decipher = createDecipheriv(ALGORITHM, key, iv); (decipher as ReturnType & { setAuthTag(tag: Buffer): void }).setAuthTag(authTag); return Buffer.concat([decipher.update(encrypted), decipher.final()]).toString("utf8"); }