feat(api): setting up

This commit is contained in:
2025-11-09 16:28:36 +02:00
parent d72f3871a4
commit 4b82a11207
35 changed files with 2280 additions and 1516 deletions
+76
View File
@@ -0,0 +1,76 @@
import crypto from "node:crypto";
import { createEnvAccessor } from "@devscast/config";
export const env = createEnvAccessor(["BASANGO_ENCRYPTION_KEY"] as const);
const ALGORITHM = "aes-256-gcm";
const IV_LENGTH = 16;
const AUTH_TAG_LENGTH = 16;
function getKey(): Buffer {
const key = env("BASANGO_ENCRYPTION_KEY");
if (Buffer.from(key, "hex").length !== 32) {
throw new Error("BASANGO_ENCRYPTION_KEY must be a 64-character hex string (32 bytes).");
}
return Buffer.from(key, "hex");
}
/**
* Encrypts a plaintext string using AES-256-GCM.
* @param text The plaintext string to encrypt.
* @returns A string containing the IV, auth tag, and encrypted text, concatenated and base64 encoded.
*/
export function encrypt(text: string): string {
const key = getKey();
const iv = crypto.randomBytes(IV_LENGTH);
const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
let encrypted = cipher.update(text, "utf8", "hex");
encrypted += cipher.final("hex");
const authTag = cipher.getAuthTag();
// Concatenate IV, auth tag, and encrypted data
const encryptedPayload = Buffer.concat([iv, authTag, Buffer.from(encrypted, "hex")]).toString(
"base64",
);
return encryptedPayload;
}
/**
* Decrypts an AES-256-GCM encrypted string.
* @param encryptedPayload The base64 encoded string containing the IV, auth tag, and encrypted text.
* @returns The original plaintext string.
*/
export function decrypt(encryptedPayload: string): string {
const key = getKey();
const dataBuffer = Buffer.from(encryptedPayload, "base64");
// Extract IV, auth tag, and encrypted data
const iv = dataBuffer.subarray(0, IV_LENGTH);
const authTag = dataBuffer.subarray(IV_LENGTH, IV_LENGTH + AUTH_TAG_LENGTH);
const encryptedText = dataBuffer.subarray(IV_LENGTH + AUTH_TAG_LENGTH);
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
decipher.setAuthTag(authTag);
let decrypted = decipher.update(encryptedText.toString("hex"), "hex", "utf8");
decrypted += decipher.final("utf8");
return decrypted;
}
export function hash(str: string): string {
return crypto.createHash("sha256").update(str).digest("hex");
}
export function md5(str: string): string {
return crypto.createHash("md5").update(str).digest("hex");
}
export function generateRandomBytes(size: number): string {
return crypto.randomBytes(size).toString("hex");
}