Files
zeekayandHanzo Dev 715cf40886 fix(crypto): take managedNonce from where noble 2 keeps it
@noble/ciphers 2 moved managedNonce from webcrypto.js to utils.js. The
import left behind named an export that no longer exists, so crypto.ts —
and everything that stores or reads an encrypted secret through it — could
not load: in ESM a missing named export fails the module at link time.

crypto.test.ts round-trips a secret, checks each write draws a new nonce and
that another key is refused, and decrypts a secret written by
@noble/ciphers 0.6.0 through this module's old code, since those are what
the database holds. Against the old import all four fail.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-19 04:26:16 -07:00

46 lines
1.5 KiB
TypeScript

/**
* Symmetric encryption of stored secrets.
*
* Secrets written before @noble/ciphers 2 are still in the database, so the
* fixture below was encrypted by @noble/ciphers 0.6.0 through the code this
* module had then, and has to decrypt now.
*
* Run: npx tsx --test packages/lib/__tests__/crypto.test.ts
*/
import assert from 'node:assert/strict';
import { describe, test } from 'node:test';
import { symmetricDecrypt, symmetricEncrypt } from '../universal/crypto';
const key = 'a key of any length';
const decode = (bytes: Uint8Array) => new TextDecoder().decode(bytes);
describe('symmetric encryption', () => {
test('reads back what it wrote', () => {
const data = 'a secret';
assert.equal(decode(symmetricDecrypt({ key, data: symmetricEncrypt({ key, data }) })), data);
});
test('draws a new nonce for every write', () => {
assert.notEqual(
symmetricEncrypt({ key, data: 'a secret' }),
symmetricEncrypt({ key, data: 'a secret' }),
);
});
test('reads a secret @noble/ciphers 0.6.0 wrote', () => {
const data =
'ddd5e652921b7dad9f2322aee527d4954b3e7dbfe49aecc3f989bff3fc156998fdf136b52e3b2134a0128ab8e68bab860e9d991fd03129a422261645c9c54b45531404e91e733d8d8b02b285daca';
assert.equal(decode(symmetricDecrypt({ key, data })), 'a secret kept since before the upgrade');
});
test('refuses a secret under another key', () => {
const data = symmetricEncrypt({ key, data: 'a secret' });
assert.throws(() => symmetricDecrypt({ key: 'another key', data }));
});
});