Spaces:
Running
Running
| import crypto from "crypto"; | |
| import { env } from "@/config/env.js"; | |
| const ALGORITHM = "aes-256-gcm"; | |
| const IV_LENGTH = 16; | |
| const AUTH_TAG_LENGTH = 16; | |
| export function encrypt(text: string): string { | |
| const iv = crypto.randomBytes(IV_LENGTH); | |
| const key = Buffer.from(env.ENCRYPTION_KEY.slice(0, 32), "utf-8"); | |
| const cipher = crypto.createCipheriv(ALGORITHM, key, iv); | |
| let encrypted = cipher.update(text, "utf8", "hex"); | |
| encrypted += cipher.final("hex"); | |
| const authTag = cipher.getAuthTag(); | |
| return `${iv.toString("hex")}:${authTag.toString("hex")}:${encrypted}`; | |
| } | |
| export function decrypt(encryptedText: string): string { | |
| const parts = encryptedText.split(":"); | |
| if (parts.length !== 3) { | |
| throw new Error("Invalid encrypted text format"); | |
| } | |
| const iv = Buffer.from(parts[0], "hex"); | |
| const authTag = Buffer.from(parts[1], "hex"); | |
| const encrypted = parts[2]; | |
| const key = Buffer.from(env.ENCRYPTION_KEY.slice(0, 32), "utf-8"); | |
| const decipher = crypto.createDecipheriv(ALGORITHM, key, iv); | |
| decipher.setAuthTag(authTag); | |
| let decrypted = decipher.update(encrypted, "hex", "utf8"); | |
| decrypted += decipher.final("utf8"); | |
| return decrypted; | |
| } | |
| export function hashApiKey(key: string): string { | |
| return crypto.createHash("sha256").update(key).digest("hex"); | |
| } | |
| export function generateWebhookSignature(payload: string, secret: string): string { | |
| return `sha256=${crypto.createHmac("sha256", secret).update(payload).digest("hex")}`; | |
| } | |
| export function verifyWebhookSignature( | |
| payload: string, | |
| signature: string, | |
| secret: string | |
| ): boolean { | |
| const expected = generateWebhookSignature(payload, secret); | |
| return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected)); | |
| } | |