import test, { type TestContext } from 'node:test'; import assert from 'node:assert/strict'; import { mkdtemp, mkdir, writeFile, rm, symlink } from 'node:fs/promises'; import { join, resolve } from 'node:path'; import { tmpdir } from 'node:os'; import { randomUUID } from 'node:crypto'; import { createApp, type AppOptions } from '../../apps/api/src/app.js'; import { loadConfig } from '../../apps/api/src/config.js'; import { htmlRoutes, animationJsonPaths } from '../../apps/api/src/static.js'; import type { MailMessage, MailTransport } from '../../apps/api/src/mail.js'; const origin = 'https://thatstupidcomputer.com'; const configured = { NODE_ENV: 'production', PUBLIC_ORIGIN: origin, SMTP_HOST: 'smtp.example.test', SMTP_PORT: '587', SMTP_SECURE: 'false', SMTP_USER: 'protected-user', SMTP_PASS: 'synthetic-secret-not-real', SMTP_FROM: 'sender@example.test', SMTP_TO: 'owner@example.test' }; const input = () => ({ name: 'Synthetic Visitor', email: 'visitor@example.test', business: 'Synthetic Business', website: 'https://example.test', projectType: 'design', message: 'A synthetic request for a website demo.', consent: true, companyWebsite: '', submissionId: randomUUID() }); const headers = { origin, 'content-type': 'application/json', accept: 'application/json' }; const accepted: MailTransport = { async sendMail() { return { accepted: [configured.SMTP_TO], rejected: [] }; } }; async function appFor(t: TestContext, options: AppOptions = {}) { const app = await createApp({ env: configured, mailTransport: accepted, logger: false, ...options }); t.after(() => app.close()); return app; } async function fixture(t: TestContext) { const root = await mkdtemp(join(tmpdir(), 'tsc-api-test-')); t.after(() => rm(root, { recursive: true, force: true })); for (const route of htmlRoutes) { const path = join(root, route, 'index.html'); await mkdir(join(root, route), { recursive: true }); await writeFile(path, `${route}

${route}

`); } await mkdir(join(root, 'assets')); await writeFile(join(root, 'assets', 'main-AbCd1234.js'), 'export const safe = true;'); await writeFile(join(root, 'assets', 'renderer.wasm'), Buffer.from([0, 97, 115, 109, 1, 0, 0, 0])); await writeFile(join(root, 'robots.txt'), 'User-agent: *\nAllow: /\n'); await writeFile(join(root, 'assets', 'private.json'), '{"secret":"DO_NOT_SERVE"}'); await writeFile(join(root, 'assets', 'bundle.js.map'), 'DO_NOT_SERVE'); await writeFile(join(root, '.env'), 'DO_NOT_SERVE'); return root; } test('mail acceptance is truthful, goes to the single configured recipient, and returns a generated ID', async t => { const messages: MailMessage[] = []; const app = await appFor(t, { mailTransport: { async sendMail(message) { messages.push(message); return { accepted: [configured.SMTP_TO], rejected: [] }; } } }); const res = await app.inject({ method: 'POST', url: '/api/demo', headers: { ...headers, 'x-request-id': 'visitor-controlled' }, payload: input() }); assert.equal(res.statusCode, 200); assert.equal(res.json().status, 'accepted'); assert.equal(res.json().ok, true); assert.match(res.json().requestId, /^[\da-f-]{36}$/); assert.notEqual(res.json().requestId, 'visitor-controlled'); assert.equal(messages.length, 1); assert.deepEqual(messages[0].envelope, { from: configured.SMTP_FROM, to: [configured.SMTP_TO] }); assert.equal(messages[0].from, configured.SMTP_FROM); assert.equal(messages[0].replyTo.address, 'visitor@example.test'); assert.equal(messages[0].disableFileAccess, true); assert.equal(messages[0].disableUrlAccess, true); assert.equal(res.headers['cache-control'], 'no-store'); assert.doesNotMatch(res.body, /delivered|received|synthetic-secret|owner@example/); }); test('unconfigured SMTP never sends or reports success and readiness is separate from liveness', async t => { let sent = 0; const app = await appFor(t, { env: { NODE_ENV: 'production', PUBLIC_ORIGIN: origin }, mailTransport: { async sendMail() { sent++; return { accepted: [] }; } } }); const res = await app.inject({ method: 'POST', url: '/api/demo', headers, payload: input() }); assert.equal(res.statusCode, 503); assert.equal(res.json().code, 'service_unavailable'); assert.match(res.json().message, /not been sent/); assert.equal(sent, 0); assert.equal((await app.inject('/api/health')).statusCode, 200); const ready = await app.inject('/api/ready'); assert.equal(ready.statusCode, 503); assert.equal(ready.json().checks.mail, 'unconfigured'); assert.equal(ready.json().delivery, 'not_checked'); }); test('complete runtime and static configuration reports ready without calling mail', async t => { const root = await fixture(t); let sent = 0; const app = await appFor(t, { staticRoot: root, mailTransport: { async sendMail() { sent++; return { accepted: [] }; } } }); const ready = await app.inject('/api/ready'); assert.equal(ready.statusCode, 200); assert.deepEqual(ready.json(), { ok: true, status: 'ready', checks: { mail: 'configured', site: 'available' }, delivery: 'not_checked' }); assert.equal(sent, 0); assert.doesNotMatch(ready.body, /protected-user|synthetic-secret|smtp.example|owner@example/); }); test('Origin enforcement rejects cross-site, null, suffix spoof, missing metadata, and contradictory fetch metadata', async t => { let sent = 0; const app = await appFor(t, { mailTransport: { async sendMail() { sent++; return { accepted: [] }; } } }); for (const extra of [{ origin: 'https://evil.test' }, { origin: 'null' }, { origin: `${origin}.evil.test` }, { origin, 'sec-fetch-site': 'cross-site' }, { origin: undefined }]) { const requestHeaders = Object.fromEntries(Object.entries({ ...headers, ...extra }).filter(([, value]) => value !== undefined)) as Record; const res = await app.inject({ method: 'POST', url: '/api/demo', headers: requestHeaders, payload: input() }); assert.equal(res.statusCode, 403); assert.equal(res.json().code, 'invalid_origin'); } assert.equal(sent, 0); }); test('authoritative validation rejects abusive and malformed fields without invoking SMTP', async t => { let sent = 0; const app = await appFor(t, { limits: { demoMax: 50 }, mailTransport: { async sendMail() { sent++; return { accepted: [] }; } } }); const invalid = [ { name: 'A' }, { name: 'X\r\nBcc: injected@example.test' }, { email: 'a@example.test\nBcc: bad@example.test' }, { consent: false }, { consent: 'true' }, { companyWebsite: 'https://bot.example.test' }, { message: 'short' }, { message: 'a'.repeat(4001) }, { business: 'x'.repeat(161) }, { website: 'javascript:alert(1)' }, { website: 'https://[credentials removed]@example.test/' }, { to: 'injected@example.test' }, { submissionId: 'fake-id' }, { name: ['A', 'B'] }, { projectType: 'invented' }, ]; for (const payload of invalid) { const res = await app.inject({ method: 'POST', url: '/api/demo', headers, payload: { ...input(), ...payload } }); assert.equal(res.statusCode, 400, JSON.stringify(payload)); assert.equal(res.json().code, 'invalid_request'); } assert.equal(sent, 0); }); test('parsing, body size and method failures retain actual HTTP status and safe bodies', async t => { const app = await appFor(t, { limits: { demoMax: 50 } }); const malformed = await app.inject({ method: 'POST', url: '/api/demo', headers, payload: '{"name":' }); assert.equal(malformed.statusCode, 400); const oversized = await app.inject({ method: 'POST', url: '/api/demo', headers, payload: { ...input(), message: 'x'.repeat(18000) } }); assert.equal(oversized.statusCode, 413); assert.equal(oversized.json().code, 'body_too_large'); const wrongType = await app.inject({ method: 'POST', url: '/api/demo', headers: { ...headers, 'content-type': 'text/plain' }, payload: 'private message' }); assert.equal(wrongType.statusCode, 415); const unsupported = await app.inject({ method: 'POST', url: '/api/demo', headers: { ...headers, 'content-type': 'application/xml' }, payload: 'private' }); assert.equal(unsupported.statusCode, 415); const method = await app.inject('/api/demo'); assert.equal(method.statusCode, 405); assert.equal(method.headers.allow, 'POST'); }); test('native HTML form works without JS and reflects no submitted content into error pages', async t => { const app = await appFor(t); const payload = new URLSearchParams({ ...input(), consent: 'on', submissionId: '' }); const res = await app.inject({ method: 'POST', url: '/api/demo', headers: { origin, accept: 'text/html', 'content-type': 'application/x-www-form-urlencoded' }, payload: payload.toString() }); assert.equal(res.statusCode, 200); assert.match(res.headers['content-type'] || '', /text\/html/); assert.match(res.body, /role="status"/); assert.match(res.body, /accepted for sending/); payload.set('name', ''); payload.set('email', 'not-an-email'); const invalid = await app.inject({ method: 'POST', url: '/api/demo', headers: { origin, accept: 'text/html', 'content-type': 'application/x-www-form-urlencoded' }, payload: payload.toString() }); assert.equal(invalid.statusCode, 400); assert.match(invalid.body, /role="alert"/); assert.doesNotMatch(invalid.body, /