Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131import { test } from 'node:test'import assert from 'node:assert/strict'import { createHash, generateKeyPairSync, randomUUID, sign } from 'node:crypto'import { execFileSync, spawnSync } from 'node:child_process'import http from 'node:http'import pg from 'pg'import { createPostgresBrokerStore } from '../src/server/postgres-broker-store.mjs'import { createOAuthBrokerHandler } from '../src/server/oauth-broker.mjs'
const limits = { pending: 64, storeBytes: 8192, sessions: 20, transactions: 20, grants: 20, proofs: 20 }const protocolError = code => Object.assign(new Error(code), { code, status: 401, brokerProtocolFailure: true })const docker = (...args) => execFileSync('docker', args, { encoding: 'utf8' }).trim()async function database() { const name = `reams-pg-${randomUUID()}` docker('run', '-d', '--rm', '--name', name, '-e', 'POSTGRES_PASSWORD=fixture-only', '-e', 'POSTGRES_DB=auth_test', '-p', '127.0.0.1::5432', 'postgres:17-bookworm@sha256:639ab7ceb90e13123085b741fb31ef493fba25463002f6da665352e7b534b652') const port = docker('port', name, '5432/tcp').split(':').at(-1) const connectionString = `postgres://postgres:fixture-only@127.0.0.1:${port}/auth_test` for (let attempt = 0; attempt < 100; attempt++) { const client = new pg.Client({ connectionString, connectionTimeoutMillis: 500 }) try { await client.connect(); await client.end(); return { connectionString, close: () => docker('stop', name) } } catch { await client.end().catch(() => {}); await new Promise(resolve => setTimeout(resolve, 50)) } } spawnSync('docker', ['rm', '-f', name], { stdio: 'ignore' }) throw new Error('Local PostgreSQL fixture not ready')}
test('real PostgreSQL transaction parity, cross-pool serialization, bounds, rollback and restart', { timeout: 30_000 }, async () => { const db = await database(), namespace = `test:${randomUUID()}` let a, b const inspect = new pg.Client({ connectionString: db.connectionString }) try { await inspect.connect() ;[a, b] = await Promise.all([1, 2].map(() => createPostgresBrokerStore({ connectionString: db.connectionString, namespace }))) const state = async () => (await inspect.query('SELECT state FROM reams_oauth_state WHERE namespace=$1', [namespace])).rows[0].state await assert.rejects(a.transact(s => { s.proofs = { consumed: 10 }; throw protocolError('invalid_grant') }, limits), { code: 'invalid_grant' }) assert.equal((await state()).proofs.consumed, 10) await assert.rejects(a.transact(s => { s.proofs.consumed = 99; throw new TypeError('unexpected implementation failure') }, limits), { code: 'store_unavailable', status: 503 }) assert.equal((await state()).proofs.consumed, 10) await a.transact(s => { s.transactions = { code: { used: false } } }, limits) const claim = store => store.transact(s => { if (s.transactions.code.used) throw protocolError('invalid_grant') s.transactions.code.used = true return { params: new URLSearchParams({ grant_type: 'authorization_code' }) } }, limits) const claims = await Promise.allSettled([claim(a), claim(b)]) assert.equal(claims.filter(result => result.status === 'fulfilled').length, 1) assert.equal(claims.find(result => result.status === 'fulfilled').value.params.get('grant_type'), 'authorization_code') assert.equal((await state()).transactions.code.used, true) await assert.rejects(b.transact(s => { s.transactions.code.used = false; throw protocolError('use_dpop_nonce') }, limits), { code: 'use_dpop_nonce' }) assert.equal((await state()).transactions.code.used, false) await assert.rejects(a.transact(s => { s.grants = { tooLarge: 'x'.repeat(9000) } }, limits), { code: 'store_capacity_exceeded' }) assert.deepEqual((await state()).grants, {}) await a.close() a = await createPostgresBrokerStore({ connectionString: db.connectionString, namespace }) assert.equal((await a.transact(s => s.proofs.consumed, limits)), 10) await inspect.query('BEGIN') await inspect.query('SELECT state FROM reams_oauth_state WHERE namespace=$1 FOR UPDATE', [namespace]) await assert.rejects(a.transact(s => { s.proofs.locked = 1 }, limits), { code: 'store_unavailable', status: 503 }) await inspect.query('ROLLBACK') assert.equal((await a.transact(s => s.proofs.locked, limits)), undefined) await inspect.query('UPDATE reams_oauth_state SET state=$2::jsonb WHERE namespace=$1', [namespace, '{"version":2}']) await assert.rejects(a.transact(() => undefined, limits), { code: 'store_unavailable' }) } finally { await a?.close(); await b?.close(); await inspect.end(); db.close() }})
test('two real-PG broker handlers allow one code winner, persist nonce reset, and survive process-store replacement', { timeout: 30_000 }, async () => { const db = await database(), namespace = 'https://reams.example.test/oauth-client-metadata.json' const appKeys = generateKeyPairSync('ec', { namedCurve: 'P-256' }), device = generateKeyPairSync('ec', { namedCurve: 'P-256' }) const pub = device.publicKey.export({ format: 'jwk' }) const b64 = value => Buffer.from(value).toString('base64url') const hash = value => b64(createHash('sha256').update(value).digest()) const proof = (endpoint, jti = randomUUID()) => { const input = `${b64(JSON.stringify({ typ: 'dpop+jwt', alg: 'ES256', jwk: pub }))}.${b64(JSON.stringify({ htm: 'POST', htu: endpoint, iat: Math.floor(Date.now() / 1000), jti }))}` return `${input}.${sign('sha256', Buffer.from(input), { key: device.privateKey, dsaEncoding: 'ieee-p1363' }).toString('base64url')}` } const issuer = 'https://issuer.test', did = 'did:plc:fixture' let upstreamTokens = 0, nonceOnce = true const upstream = async (url, init) => { if (url.endsWith('/par')) return Response.json({ request_uri: 'urn:fixture:request' }) upstreamTokens++ if (nonceOnce) { nonceOnce = false; return Response.json({ error: 'use_dpop_nonce' }, { status: 400, headers: { 'dpop-nonce': 'fixture-nonce' } }) } assert.equal(new URLSearchParams(init.body).get('client_id'), namespace) return Response.json({ token_type: 'DPoP', sub: did, scope: 'atproto', access_token: 'fixture-access', refresh_token: `fixture-refresh-${upstreamTokens}` }) } const base = { origin: 'https://reams.example.test', clientId: namespace, redirectUri: 'https://reams.example.test/oauth-callback.html', scope: 'atproto', signingKeyPem: appKeys.privateKey.export({ type: 'pkcs8', format: 'pem' }), kid: 'fixture', fetch: upstream, resolveAuthority: async () => ({ did, issuer, pds: issuer, parEndpoint: `${issuer}/par`, tokenEndpoint: `${issuer}/token` }) } let a, b, handlerA, handlerB, serverA, serverB async function serve(handler) { const server = http.createServer((req, res) => { void handler(req, res) }); await new Promise(resolve => server.listen(0, '127.0.0.1', resolve)); return server } let cookie, csrf async function call(server, path, fields, jti) { const headers = { origin: base.origin, ...(cookie ? { cookie } : {}), ...(csrf ? { 'x-oauth-csrf': csrf } : {}) } if (fields) { headers['content-type'] = 'application/x-www-form-urlencoded'; headers.dpop = proof(path.endsWith('/par') ? `${issuer}/par` : `${issuer}/token`, jti) } const body = fields ? new URLSearchParams({ ...fields, broker_issuer: issuer, broker_endpoint: path.endsWith('/par') ? `${issuer}/par` : `${issuer}/token` }) : undefined const response = await fetch(`http://127.0.0.1:${server.address().port}${path}`, { method: fields ? 'POST' : 'GET', headers, body }) return { status: response.status, cookie: response.headers.get('set-cookie'), nonce: response.headers.get('dpop-nonce'), body: await response.json() } } try { ;[a, b] = await Promise.all([1, 2].map(() => createPostgresBrokerStore({ connectionString: db.connectionString, namespace }))) handlerA = createOAuthBrokerHandler({ ...base, stateStore: a }); handlerB = createOAuthBrokerHandler({ ...base, stateStore: b }) serverA = await serve(handlerA); serverB = await serve(handlerB) const session = await call(serverA, '/oauth/broker/session') csrf = session.body.csrf_token; cookie = session.cookie.split(';')[0] const verifier = hash(randomUUID()), state = randomUUID() const par = await call(serverA, '/oauth/broker/par', { client_id: namespace, redirect_uri: base.redirectUri, response_type: 'code', scope: 'atproto', state, code_challenge: hash(verifier), code_challenge_method: 'S256', expected_did: did }) assert.equal(par.status, 200) const fields = { grant_type: 'authorization_code', code: 'fixture-code', code_verifier: verifier, state, broker_transaction: par.body.transaction } const challenge = await call(serverA, '/oauth/broker/token', fields) assert.equal(challenge.status, 400) assert.equal(challenge.nonce, 'fixture-nonce') const results = await Promise.all([call(serverA, '/oauth/broker/token', fields), call(serverB, '/oauth/broker/token', fields)]) assert.deepEqual(results.map(result => result.status).sort(), [200, 401]) assert.equal(upstreamTokens, 2, 'Only the initial nonce challenge and one winning code exchange may reach upstream') const token = results.find(result => result.status === 200).body await handlerA.close() a = await createPostgresBrokerStore({ connectionString: db.connectionString, namespace }) handlerA = createOAuthBrokerHandler({ ...base, stateStore: a }) await new Promise(resolve => serverA.close(resolve)); serverA = await serve(handlerA) assert.equal((await call(serverA, '/oauth/broker/session')).body.csrf_token, csrf) const refresh = { grant_type: 'refresh_token', refresh_token: token.refresh_token, broker_grant: token.broker_grant } const refreshed = await Promise.all([call(serverA, '/oauth/broker/token', refresh), call(serverB, '/oauth/broker/token', refresh)]) assert.deepEqual(refreshed.map(result => result.status).sort(), [200, 401]) assert.equal(upstreamTokens, 3) } finally { if (serverA) await new Promise(resolve => serverA.close(resolve)) if (serverB) await new Promise(resolve => serverB.close(resolve)) await handlerA?.close(); await handlerB?.close(); await a?.close(); await b?.close(); db.close() }})