import { describe, it, expect, beforeEach } from 'bun:test'; import { detectEncryptionMode } from './../lib/seedpgp'; import { encryptJsonToBlob, decryptBlobToJson, destroySessionKey, getSessionKey, } from './../lib/sessionCrypto'; describe('Security Fixes Verification', () => { describe('F-02: Regex Fix for SeedQR detection', () => { it('should correctly detect a standard numeric SeedQR', () => { // A 48-digit string, representing 12 words const numericSeedQR = '000011112222333344445555666677778888999901234567'; const mode = detectEncryptionMode(numericSeedQR); expect(mode).toBe('seedqr'); }); it('should not detect a short numeric string as SeedQR', () => { const shortNumeric = '1234567890'; // 10 digits - too short for SeedQR const mode = detectEncryptionMode(shortNumeric); // ✅ FIXED: Short numeric strings should NOT be detected as SeedQR // (They may be detected as 'krux' if they match Base43 charset, which is fine) expect(mode).not.toBe('seedqr'); }); it('should not detect a mixed-character string as numeric SeedQR', () => { const mixedString = '00001111222233334444555566667777888899990123456a'; const mode = detectEncryptionMode(mixedString); expect(mode).not.toBe('seedqr'); }); }); describe('F-01: Session Key Rotation Data Loss Fix', () => { beforeEach(() => { destroySessionKey(); }); it('should include a keyId in the encrypted blob', async () => { const data = { secret: 'hello world' }; const blob = await encryptJsonToBlob(data); expect(blob.keyId).toBeDefined(); expect(typeof blob.keyId).toBe('string'); expect(blob.keyId.length).toBeGreaterThan(0); // Additional check }); it('should successfully decrypt a blob with the correct keyId', async () => { const data = { secret: 'this is a test' }; const blob = await encryptJsonToBlob(data); const decrypted = await decryptBlobToJson(blob); expect(decrypted).toEqual(data); }); it('should throw an error if the key is rotated before decryption', async () => { const data = { secret: 'will be lost' }; const blob = await encryptJsonToBlob(data); // Force key rotation by destroying the current one and getting a new one destroySessionKey(); await getSessionKey(); // Generates a new key with a new keyId // Decryption should now fail because the keyId in the blob does not match await expect(decryptBlobToJson(blob)).rejects.toThrow( 'Session expired. The encryption key has rotated. Please re-enter your seed phrase.' ); }); }); });