import { describe, expect, test } from 'bun:test'; import { deriveSecret, generateGpgPrivateKey, generateSecret } from './generators'; describe('generateGpgPrivateKey', () => { test('mints a base64-encoded ASCII-armored PGP private key', () => { const b64 = generateGpgPrivateKey('apt.celilo.computer'); const armor = Buffer.from(b64, 'base64').toString('utf-8'); expect(armor).toContain('BEGIN PGP PRIVATE KEY BLOCK'); expect(armor).toContain('END PGP PRIVATE KEY BLOCK'); }); test('mints a distinct key each call (throwaway keyring)', () => { expect(generateGpgPrivateKey('a@example.com')).not.toBe(generateGpgPrivateKey('a@example.com')); }); }); describe('generateSecret', () => { test('generates base64 secret with default length', () => { const secret = generateSecret({ format: 'base64' }); // Base64 encoding of 32 bytes = 44 characters (with padding) expect(secret).toMatch(/^[A-Za-z0-9+/]+=*$/); expect(secret.length).toBeGreaterThan(40); }); test('generates hex secret with default length', () => { const secret = generateSecret({ format: 'hex' }); // Hex encoding of 32 bytes = 64 characters expect(secret).toMatch(/^[a-f0-9]{64}$/); }); test('generates wireguard-key format (base64)', () => { const secret = generateSecret({ format: 'wireguard-key' }); // WireGuard keys are 32 bytes, base64 encoded expect(secret).toMatch(/^[A-Za-z0-9+/]+=*$/); expect(secret.length).toBeGreaterThan(40); }); test('generates tsig-key format (base64)', () => { const secret = generateSecret({ format: 'tsig-key' }); // TSIG keys are 32 bytes, base64 encoded expect(secret).toMatch(/^[A-Za-z0-9+/]+=*$/); expect(secret.length).toBeGreaterThan(40); }); test('generates secret with custom length', () => { const secret = generateSecret({ format: 'hex', length: 16 }); // Hex encoding of 16 bytes = 32 characters expect(secret).toMatch(/^[a-f0-9]{32}$/); }); test('generates different secrets on each call', () => { const secret1 = generateSecret({ format: 'base64' }); const secret2 = generateSecret({ format: 'base64' }); expect(secret1).not.toBe(secret2); }); test('throws error for unknown format', () => { expect(() => { generateSecret({ format: 'unknown-format' }); }).toThrow('Unknown secret format: unknown-format'); }); }); describe('deriveSecret', () => { test('derives wireguard public key from private key', () => { // Generate a test private key const privateKey = generateSecret({ format: 'wireguard-key' }); // Derive public key (requires wg tools installed) try { const publicKey = deriveSecret({ sourceSecret: privateKey, deriveMethod: 'wireguard-pubkey', }); // Public key should be base64 encoded expect(publicKey).toMatch(/^[A-Za-z0-9+/]+=*$/); expect(publicKey.length).toBeGreaterThan(40); // Should be different from private key expect(publicKey).not.toBe(privateKey); } catch (error) { // If wg tools not installed, skip this test if (error instanceof Error && error.message.includes('not found')) { console.warn('Skipping wireguard derivation test (wg tools not installed)'); } else { throw error; } } }); test('throws error for unknown derivation method', () => { expect(() => { deriveSecret({ sourceSecret: 'test', deriveMethod: 'unknown-method', }); }).toThrow('Unknown derivation method: unknown-method'); }); test('throws helpful error when wg tools not installed', () => { // This test might pass if wg tools ARE installed // We're mainly testing the error message structure const privateKey = 'invalid-key-to-trigger-error'; try { deriveSecret({ sourceSecret: privateKey, deriveMethod: 'wireguard-pubkey', }); } catch (error) { expect(error).toBeInstanceOf(Error); if (error instanceof Error && error.message.includes('not found')) { expect(error.message).toContain('brew install wireguard-tools'); expect(error.message).toContain('apt-get install wireguard-tools'); } } }); });