// Runs the reference implementation's verifier over artifacts pds.js produced. // Copied into the atproto worktree by scripts/space-reference/run.sh as a // scratch file; never committed there. import { readFileSync } from 'node:fs'; import { verifySignature } from '@atproto/crypto'; import { describe, expect, it } from 'vitest'; import { verifyRepoCarFull } from '../src/index.js'; const DIR = process.env.ARTIFACTS_DIR ?? '/tmp/pdsjs-conformance'; const manifest = JSON.parse(readFileSync(`${DIR}/manifest.json`, 'utf8')); const car = new Uint8Array(readFileSync(`${DIR}/repo.car`)); const fromB64 = (s: string) => new Uint8Array(Buffer.from(s, 'base64')); describe('reference verifies pds.js output', () => { it('accepts the getRepo CAR', async () => { // This single call checks: exactly two roots, the commit block leads, the // commit's signature and MAC verify, the index follows, the index's set // hash equals the commit's hash, and every record block matches its index // entry in order. If it passes, BLAKE3, LtHash, the ctx encoding, the MAC, // the signature and the canonical block ordering all agree. const verified = await verifyRepoCarFull([car], { space: manifest.space, author: manifest.author, didKey: manifest.userDidKey, }); expect(verified.commit.rev).toBe(manifest.rev); expect(verified.records).toHaveLength(manifest.recordCount); const paths = verified.records.map((r) => `${r.collection}/${r.rkey}`); // Canonical DAG-CBOR key order: shortest first, then bytewise. expect(paths).toEqual([ 'com.e.p/x', 'com.example.post/aaa', 'com.example.post/bbb', 'com.example.reply/zz', ]); // Records round-tripped through DAG-CBOR intact, nested values included. const reply = verified.records.find( (r) => r.collection === 'com.example.reply', ); expect(reply?.record).toEqual({ $type: 'com.example.reply', deep: { nested: [1, 2, 3] }, }); }); it('rejects the CAR when told the wrong author', async () => { // The author is bound into the signed ctx, so this must fail — otherwise // the test above would pass for the wrong reason. await expect( verifyRepoCarFull([car], { space: manifest.space, author: 'did:plc:someoneelse', didKey: manifest.userDidKey, }), ).rejects.toThrow(); }); it('rejects the CAR when told the wrong space', async () => { await expect( verifyRepoCarFull([car], { space: 'at://did:plc:conformauthority/space/com.example.forum/other', author: manifest.author, didKey: manifest.userDidKey, }), ).rejects.toThrow(); }); it('verifies the getLatestCommit JSON signature', async () => { // Rebuild the ctx the way the reference does and check our wire-format // commit against the user's key. const { commit } = manifest; const enc = new TextEncoder(); const parts = [ enc.encode(manifest.space), enc.encode(manifest.author), enc.encode(commit.rev), fromB64(commit.ikm.$bytes), ]; let size = 16; for (const p of parts) size += 2 + p.length; const ctx = new Uint8Array(size); ctx.set(enc.encode('atproto-space-v1')); let off = 16; for (const p of parts) { ctx[off++] = (p.length >>> 8) & 0xff; ctx[off++] = p.length & 0xff; ctx.set(p, off); off += p.length; } const ok = await verifySignature( manifest.userDidKey, ctx, fromB64(commit.sig.$bytes), { jwtAlg: 'ES256' }, ); expect(ok).toBe(true); }); }); describe('reference verifies pds.js tokens', () => { it('accepts the delegation token', async () => { const { verifySpaceToken } = await import('../src/index.js'); const { payload } = await verifySpaceToken( 'delegation', manifest.delegationToken, { getSigningKey: () => manifest.userDidKey, aud: manifest.delegationAud, sub: manifest.space, }, ); expect(payload.iss).toBe(manifest.author); expect(payload.sub).toBe(manifest.space); }); it('accepts the space credential', async () => { const { verifySpaceToken } = await import('../src/index.js'); const { payload, header } = await verifySpaceToken( 'credential', manifest.credential, { getSigningKey: () => manifest.authorityDidKey, sub: manifest.space }, ); expect(payload.iss).toBe(manifest.authority); // The key the holder proves possession of. The reference refuses to parse a // credential without it, so reaching this line is already half the check. expect(payload.cnf?.jkt).toBe(manifest.credentialJkt); // An authority hosted on a PDS signs with the account's own key. expect(header.kid).toBe('#atproto'); }); it('rejects a delegation token presented as a credential', async () => { const { verifySpaceToken } = await import('../src/index.js'); await expect( verifySpaceToken('credential', manifest.delegationToken, { getSigningKey: () => manifest.userDidKey, }), ).rejects.toThrow(); }); });