import { describe, expect, it } from 'vitest'; import { openPasskeyKey, sealPasskeyKey } from './passkeyCrypto'; import { bytes, openJson, sealJson } from './accountCrypto'; describe('Passkey recovery key envelopes', () => { it('recovers the same non-exportable vault key without exposing plaintext to the backend', async () => { const material = crypto.getRandomValues(new Uint8Array(32)); const prf = crypto.getRandomValues(new Uint8Array(32)); const key = await crypto.subtle.importKey('raw', bytes(material), 'AES-GCM', false, ['encrypt', 'decrypt']); const vault = await sealJson({ private: 'test-private-identity' }, key); const envelope = await sealPasskeyKey(material, bytes(prf), 'alice', 'credential-a'); expect(envelope).not.toContain('test-private-identity'); const recovered = await openPasskeyKey(envelope, bytes(prf), 'alice', 'credential-a'); expect(recovered.extractable).toBe(false); expect(await openJson(vault, recovered)).toEqual({ private: 'test-private-identity' }); await expect(openPasskeyKey(envelope, bytes(prf), 'bob', 'credential-a')).rejects.toThrow(); await expect(openPasskeyKey(envelope, bytes(prf), 'alice', 'credential-b')).rejects.toThrow(); await expect(openPasskeyKey(envelope, bytes(crypto.getRandomValues(new Uint8Array(32))), 'alice', 'credential-a')).rejects.toThrow(); }); it('rejects malformed PRF outputs', async () => { await expect(sealPasskeyKey(new Uint8Array(32), new ArrayBuffer(31), 'alice', 'credential')).rejects.toThrow(); }); });