mirror of
https://github.com/Gimanh/taskview-community.git
synced 2026-09-11 21:38:56 +00:00
50 lines
1.8 KiB
TypeScript
50 lines
1.8 KiB
TypeScript
import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';
|
|
import { $logger } from '../modules/logget';
|
|
|
|
const ALGORITHM = 'aes-256-gcm';
|
|
const IV_LENGTH = 12;
|
|
const AUTH_TAG_LENGTH = 16;
|
|
|
|
function getKey(): Buffer {
|
|
const hex = process.env.ENCRYPTION_KEY;
|
|
if (!hex || hex.length !== 64) {
|
|
throw new Error('ENCRYPTION_KEY must be a 64-character hex string (32 bytes)');
|
|
}
|
|
return Buffer.from(hex, 'hex');
|
|
}
|
|
|
|
export function encrypt(text: string): string {
|
|
const key = getKey();
|
|
const iv = randomBytes(IV_LENGTH);
|
|
const cipher = createCipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
const encrypted = Buffer.concat([cipher.update(text, 'utf8'), cipher.final()]);
|
|
const authTag = cipher.getAuthTag();
|
|
return `${iv.toString('hex')}:${authTag.toString('hex')}:${encrypted.toString('hex')}`;
|
|
}
|
|
|
|
export function decrypt(encrypted: string): string {
|
|
const key = getKey();
|
|
const [ivHex, authTagHex, dataHex] = encrypted.split(':');
|
|
const iv = Buffer.from(ivHex, 'hex');
|
|
const authTag = Buffer.from(authTagHex, 'hex');
|
|
const data = Buffer.from(dataHex, 'hex');
|
|
const decipher = createDecipheriv(ALGORITHM, key, iv, { authTagLength: AUTH_TAG_LENGTH });
|
|
decipher.setAuthTag(authTag);
|
|
return Buffer.concat([decipher.update(data), decipher.final()]).toString('utf8');
|
|
}
|
|
|
|
export function encryptField(value: string | null | undefined): string | null {
|
|
if (!value) return null
|
|
return encrypt(value)
|
|
}
|
|
|
|
export function decryptField(value: string | null): string | null {
|
|
if (!value) return null
|
|
try {
|
|
return decrypt(value)
|
|
} catch {
|
|
$logger.warn('Failed to decrypt field — returning raw value (possible migration or key mismatch)')
|
|
return value
|
|
}
|
|
}
|