duly / test/session.test.mjs · raw
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')));});