import { describe, expect, it } from 'vitest'; import { randomBytes } from 'node:crypto'; import { SecretBox } from '../src/core/secret-box.js'; const box = (): SecretBox => new SecretBox(randomBytes(32)); describe('SecretBox', () => { it('chiffre puis déchiffre (round-trip)', () => { const b = box(); const secret = 'deadbeef'.repeat(8); const enc = b.encrypt(secret); expect(enc.startsWith('v1:')).toBe(true); expect(enc).not.toContain(secret); // le clair n'apparaît pas expect(b.decrypt(enc)).toBe(secret); }); it('produit un chiffré différent à chaque fois (IV aléatoire)', () => { const b = box(); expect(b.encrypt('x')).not.toBe(b.encrypt('x')); }); it('retourne tel quel une valeur en clair (legacy) et la détecte', () => { const b = box(); expect(b.isEncrypted('plain-secret')).toBe(false); expect(b.decrypt('plain-secret')).toBe('plain-secret'); expect(b.isEncrypted(b.encrypt('x'))).toBe(true); }); it('échoue si la clé ne correspond pas (GCM authentifié)', () => { const enc = box().encrypt('secret'); expect(() => box().decrypt(enc)).toThrow(); }); it('échoue sur un format chiffré corrompu', () => { expect(() => box().decrypt('v1:zzz')).toThrow(); }); });