XuqmGroup-RNSDK/packages/common/tests/crypto.test.ts
XuqmGroup 507ce3d2ee feat(update): release-set 事务制品与原生层职责拆分
- 插件包改为 .xuqm.zip 事务制品,manifest/bundle/资源/SHA-256 统一校验
- 原生层拆分为桥接编排、插件包暂存、底层存储三个单一职责类
- 状态查询改为纯读取,不再误触发安装;新增 NATIVE_BASELINE_INCOMPATIBLE 拒绝
- SemVer 解析拆分为独立原生类并补原生测试
- XWebView 收口唯一内核,错误态统一中文层与重试
- common 增加请求头/运行时契约收口与 http 测试
2026-07-20 19:31:43 +08:00

56 行
1.8 KiB
TypeScript

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/)
})