import test from 'node:test'; import assert from 'node:assert/strict'; import { spawn } from 'node:child_process'; import { chmod, mkdtemp, rm } from 'node:fs/promises'; import { tmpdir } from 'node:os'; import { join } from 'node:path'; import { fileURLToPath } from 'node:url'; const root = fileURLToPath(new URL('..', import.meta.url)); const hermesFixture = fileURLToPath(new URL('./fixtures/fake-hermes.mjs', import.meta.url)); let nextPort = 43100; async function startServer(t, env = {}) { const port = nextPort++; const origin = `http://127.0.0.1:${port}`; const child = spawn(process.execPath, ['server.mjs'], { cwd: root, env: { ...process.env, PORT: String(port), ...env, ...(env.TIMMY_PUBLIC_ORIGIN === '__ORIGIN__' ? { TIMMY_PUBLIC_ORIGIN: origin } : {}) }, stdio: ['ignore', 'pipe', 'pipe'], }); let stderr = ''; let stdout = ''; child.stdout.on('data', chunk => { stdout += chunk; }); child.stderr.on('data', chunk => { stderr += chunk; }); t.after(() => child.kill('SIGTERM')); const deadline = Date.now() + 10_000; const basePath = (env.TIMMY_BASE_PATH || '').replace(/\/$/, ''); while (Date.now() < deadline) { if (child.exitCode !== null) throw new Error(`server exited ${child.exitCode}: ${stderr}`); try { const response = await fetch(`${origin}${basePath}/api/healthz`); if (response.status) return { origin, child, getStdout: () => stdout }; } catch {} await new Promise(resolve => setTimeout(resolve, 40)); } throw new Error(`server did not become ready: ${stderr}`); } test('staging host can bind loopback instead of every network interface', async t => { const { getStdout } = await startServer(t, { HOST: '127.0.0.1', TIMMY_VISION_ENABLED: '0' }); assert.match(getStdout(), /http:\/\/127\.0\.0\.1:/); assert.doesNotMatch(getStdout(), /http:\/\/0\.0\.0\.0:/); }); test('health endpoint exposes only bounded staging identity and feature flags', async t => { const { origin } = await startServer(t, { TIMMY_RELEASE_TAG: 'daily-2026-08-20.3', TIMMY_RELEASE_COMMIT: 'ca31e6d38bec649407f63880504554c59f2878ae', TIMMY_VISION_ENABLED: '0', TIMMY_AGENT_ENABLED: 'false', SECRET_TOKEN: 'must-not-leak', }); const response = await fetch(`${origin}/api/healthz`); assert.equal(response.status, 200); assert.deepEqual(await response.json(), { ok: true, release: 'daily-2026-08-20.3', commit: 'ca31e6d38bec649407f63880504554c59f2878ae', visionEnabled: false, agentEnabled: false, }); assert.deepEqual([...response.headers.keys()].filter(name => /token|cookie|session|path|environment|credential/i.test(name)), []); }); test('base path contains static files and APIs without capturing sibling routes', async t => { const { origin } = await startServer(t, { TIMMY_BASE_PATH: '/timmy-staging', TIMMY_VISION_ENABLED: '0' }); const health = await fetch(`${origin}/timmy-staging/api/healthz`); assert.equal(health.status, 200); const page = await fetch(`${origin}/timmy-staging/`); assert.equal(page.status, 200); assert.match(await page.text(), /