import assert from 'node:assert/strict'; import test from 'node:test'; import { Hono } from 'hono'; import type { Principal } from '../src/lib/auth'; import type { ApiEnv } from '../src/lib/mutation'; import { createPiggyChatRoutes } from '../src/routes/piggy-chat'; const principal: Principal = { userId: '10000000-0000-4000-8000-000000000001', email: 'member@example.com', name: 'Member', isPlatformAdmin: false, teams: [{ team: 'demand', role: 'member' }], via: 'jwt', scopes: ['read', 'write'], }; function appFor(fetchImpl: typeof fetch, identity: Principal = principal) { const app = new Hono(); app.use('*', async (context, next) => { context.set('principal', identity); await next(); }); app.route( '/', createPiggyChatRoutes({ enabled: true, internalUrl: 'http://127.0.0.1:8931', internalToken: 'internal-token-with-at-least-32-characters', fetchImpl, }), ); return app; } test('the authenticated proxy forwards bounded identity and relays NDJSON unchanged', async () => { let forwarded: Record | undefined; const fetchImpl: typeof fetch = async (input, init) => { assert.equal(String(input), 'http://127.0.0.1:8931/internal/chat'); assert.equal( new Headers(init?.headers).get('authorization'), 'Bearer internal-token-with-at-least-32-characters', ); forwarded = JSON.parse(String(init?.body)) as Record; return new Response( `${JSON.stringify({ type: 'content_delta', delta: 'Scoped answer' })}\n` + `${JSON.stringify({ type: 'done', inputTokens: 2, outputTokens: 3 })}\n`, { status: 200, headers: { 'content-type': 'application/x-ndjson' } }, ); }; const app = appFor(fetchImpl); const response = await app.request('/api/piggy/chat', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ message: 'Summarise this contract.', context: { type: 'contract', id: '20000000-0000-4000-8000-000000000002', label: 'Order form', }, }), }); assert.equal(response.status, 200); assert.match(response.headers.get('content-type') ?? '', /application\/x-ndjson/); assert.deepEqual(forwarded, { principalUserId: principal.userId, message: 'Summarise this contract.', context: { type: 'contract', id: '20000000-0000-4000-8000-000000000002', label: 'Order form', }, }); assert.equal( await response.text(), `${JSON.stringify({ type: 'content_delta', delta: 'Scoped answer' })}\n` + `${JSON.stringify({ type: 'done', inputTokens: 2, outputTokens: 3 })}\n`, ); }); test('a credential without read scope never reaches the internal service', async () => { let fetched = false; const app = appFor( async () => { fetched = true; return new Response(); }, { ...principal, scopes: ['write'] }, ); const response = await app.request('/api/piggy/chat', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ message: 'Read the book.' }), }); assert.equal(response.status, 403); assert.equal(fetched, false); });