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, /