2026-07-26 23:47:30 +08:00
|
|
|
import assert from 'node:assert/strict'
|
|
|
|
|
import test from 'node:test'
|
|
|
|
|
|
2026-07-28 20:29:06 +08:00
|
|
|
import { openLocalCache, sealLocalCache, secureRandomBytes } from '../src/secureCache'
|
2026-07-26 23:47:30 +08:00
|
|
|
|
2026-07-28 20:29:06 +08:00
|
|
|
test('secure random bytes never fall back to a weak random source', () => {
|
|
|
|
|
assert.equal(secureRandomBytes(32).length, 32)
|
|
|
|
|
assert.throws(() => secureRandomBytes(0), /positive integer/)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
test('device-local cache round-trips with context-bound authenticated encryption', () => {
|
|
|
|
|
const encrypted = sealLocalCache('{"enabled":true}', 'device-key', 'bugcollect|app')
|
|
|
|
|
assert.equal(openLocalCache(encrypted, 'device-key', 'bugcollect|app'), '{"enabled":true}')
|
2026-07-26 23:47:30 +08:00
|
|
|
assert.equal(encrypted.includes('enabled'), false)
|
|
|
|
|
})
|
|
|
|
|
|
2026-07-28 20:29:06 +08:00
|
|
|
test('device-local cache rejects tampering and a different application context', () => {
|
|
|
|
|
const encrypted = sealLocalCache('payload', 'device-key', 'bugcollect|app')
|
2026-07-26 23:47:30 +08:00
|
|
|
const parts = encrypted.split('.')
|
|
|
|
|
parts[2] = `${parts[2][0] === 'A' ? 'B' : 'A'}${parts[2].slice(1)}`
|
2026-07-28 20:29:06 +08:00
|
|
|
assert.throws(() => openLocalCache(parts.join('.'), 'device-key', 'bugcollect|app'))
|
|
|
|
|
assert.throws(() => openLocalCache(encrypted, 'device-key', 'bugcollect|other'))
|
2026-07-26 23:47:30 +08:00
|
|
|
})
|