import test from 'node:test';import assert from 'node:assert/strict';import * as ed from '../web/vendor/ed25519.js';import { hex } from '../web/lib/near.js';import { decodeRecovery, deriveSigner, encodeRecovery, newRoot, openSession } from '../web/lib/session.js';import { fromUrlKey, openDocument, sealDocument, toUrlKey, unwrapContentKey } from '../web/lib/doc.js';test('the same root always gives the same account', async () => { const root = new Uint8Array(32).fill(1); assert.equal((await openSession(root)).account, (await openSession(root.slice())).account);});test('accounts are implicit, and jars get their own key', async () => { const root = newRoot(); const main = await deriveSigner(root); const tax = await deriveSigner(root, 'jar/tax'); assert.equal(main.account, hex(main.publicKey)); assert.match(main.account, /^[0-9a-f]{64}$/); assert.notEqual(main.account, tax.account);});test('signatures verify against the derived key', async () => { const s = await deriveSigner(newRoot()); const msg = new Uint8Array(32).fill(4); assert.ok(await ed.verifyAsync(await s.sign(msg), msg, s.publicKey));});test('recovery key round trips and catches typos', async () => { const root = newRoot(); const text = await encodeRecovery(root); assert.deepEqual([...(await decodeRecovery(text))], [...root]); const flip = text.slice(0, 10) + (text[10] === 'a' ? 'b' : 'a') + text.slice(11); await assert.rejects(decodeRecovery(flip)); await assert.rejects(decodeRecovery('nonsense'));});const doc = { v: 1, to: { name: 'Acme' }, items: [{ d: 'Design', q: '1', p: '100' }] };test('a document opens with the link key and matches its hash', async () => { const docKey = new Uint8Array(32).fill(2); const s = await sealDocument(doc, docKey); assert.deepEqual(await openDocument(s.ct, s.contentKey, s.hash), doc); assert.deepEqual(await openDocument(s.ct, fromUrlKey(toUrlKey(s.contentKey)), s.hash), doc);});test('the merchant can reopen a document with only their key', async () => { const docKey = new Uint8Array(32).fill(2); const s = await sealDocument(doc, docKey); assert.deepEqual(await openDocument(s.ct, await unwrapContentKey(s.wrap, docKey), s.hash), doc); await assert.rejects(unwrapContentKey(s.wrap, new Uint8Array(32).fill(3)));});test('the wrong key and a swapped document are both refused', async () => { const docKey = new Uint8Array(32).fill(2); const a = await sealDocument(doc, docKey); const b = await sealDocument({ ...doc, to: { name: 'Attacker' } }, docKey); await assert.rejects(openDocument(a.ct, new Uint8Array(32).fill(9))); await assert.rejects(openDocument(b.ct, b.contentKey, a.hash), /does not match/);});test('ciphertext contains no plaintext', async () => { const s = await sealDocument(doc, new Uint8Array(32).fill(2)); assert.ok(!Buffer.from(s.ct, 'base64').toString('latin1').includes('Acme'));});test('link keys must be well formed', () => { assert.throws(() => fromUrlKey('short')); assert.throws(() => fromUrlKey('<script>alert(1)</script>'.padEnd(43, 'x')));});