import assert from 'node:assert/strict' import test from 'node:test' import { bytesToBase64, decryptXuqmFile, hmacSha256Base64Url } from '../src/crypto' const CONFIG_VECTOR = 'XUQM-CONFIG-V1.AAECAwQFBgcICQoLDA0ODw.EBESExQVFhcYGRob.vhdKh3AhEdeftXCdXp9KusVySkrBNAzmdaA747uf1tVWGFnAsJeCLe2mHKk0dxxez8SRTknIbk1UuRibnXY0Gbot1fmkR-jSN2ssMJO0_zQ8dUu8' test('hmacSha256Base64Url matches the standard HMAC-SHA256 vector', () => { assert.equal( hmacSha256Base64Url('key', 'The quick brown fox jumps over the lazy dog'), '97yD9DBThCSxMpjmqm-xQ-9NWaFJRhdZl0edvC0aPNg', ) }) test('bytesToBase64 supports plugin-sized byte arrays', () => { const bytes = Uint8Array.from({ length: 100_000 }, (_, index) => index % 251) assert.equal(Buffer.from(bytes).toString('base64'), bytesToBase64(bytes)) }) test('decryptXuqmFile remains compatible with existing PBKDF2 + AES-256-GCM files', async () => { await assert.doesNotReject(async () => { const result = await decryptXuqmFile(CONFIG_VECTOR) assert.deepEqual(result, { appKey: 'test-app', appName: '兼容向量', signingKey: 'secret', }) }) }) test('decryptXuqmFile does not depend on a React Native TextDecoder polyfill', async () => { const original = globalThis.TextDecoder Object.defineProperty(globalThis, 'TextDecoder', { configurable: true, value: class BrokenTextDecoder { decode(): string { return '[object Uint8Array]' } }, }) try { const result = await decryptXuqmFile(CONFIG_VECTOR) assert.equal(result.appName, '兼容向量') } finally { Object.defineProperty(globalThis, 'TextDecoder', { configurable: true, value: original, }) } }) test('decryptXuqmFile rejects invalid authentication tags', async () => { await assert.rejects(() => decryptXuqmFile(`${CONFIG_VECTOR.slice(0, -1)}A`), /decryption failed/) })