initial project setup
Fastify + Prisma backend, React + Vite frontend, Docker deployment. Multi-board feedback platform with anonymous cookie auth, passkey upgrade path, ALTCHA spam protection, plugin system, and full privacy-first architecture.
This commit is contained in:
30
packages/api/src/services/encryption.ts
Normal file
30
packages/api/src/services/encryption.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
import { createCipheriv, createDecipheriv, createHmac, createHash, randomBytes } from "node:crypto";
|
||||
|
||||
const IV_LEN = 12;
|
||||
const TAG_LEN = 16;
|
||||
|
||||
export function encrypt(plaintext: string, key: Buffer): string {
|
||||
const iv = randomBytes(IV_LEN);
|
||||
const cipher = createCipheriv("aes-256-gcm", key, iv);
|
||||
const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
|
||||
const tag = cipher.getAuthTag();
|
||||
return Buffer.concat([iv, encrypted, tag]).toString("base64");
|
||||
}
|
||||
|
||||
export function decrypt(encoded: string, key: Buffer): string {
|
||||
const buf = Buffer.from(encoded, "base64");
|
||||
const iv = buf.subarray(0, IV_LEN);
|
||||
const tag = buf.subarray(buf.length - TAG_LEN);
|
||||
const ciphertext = buf.subarray(IV_LEN, buf.length - TAG_LEN);
|
||||
const decipher = createDecipheriv("aes-256-gcm", key, iv);
|
||||
decipher.setAuthTag(tag);
|
||||
return decipher.update(ciphertext) + decipher.final("utf8");
|
||||
}
|
||||
|
||||
export function blindIndex(value: string, key: Buffer): string {
|
||||
return createHmac("sha256", key).update(value.toLowerCase()).digest("hex");
|
||||
}
|
||||
|
||||
export function hashToken(token: string): string {
|
||||
return createHash("sha256").update(token).digest("hex");
|
||||
}
|
||||
Reference in New Issue
Block a user