44 lines
1.7 KiB
JavaScript
44 lines
1.7 KiB
JavaScript
import { readFile } from 'node:fs/promises';
|
|
import path from 'node:path';
|
|
import { fail, pass, repositoryRoot } from './lib.mjs';
|
|
|
|
const failures = [];
|
|
const route = await readFile(path.join(repositoryRoot, 'src/app/api/demo/route.ts'), 'utf8');
|
|
const service = await readFile(path.join(repositoryRoot, 'src/lib/demo/service.ts'), 'utf8');
|
|
const environment = await readFile(
|
|
path.join(repositoryRoot, 'src/lib/integrations/environment.ts'),
|
|
'utf8',
|
|
);
|
|
|
|
for (const control of [
|
|
"request.headers.get('origin')",
|
|
"request.headers.get('content-type')",
|
|
"request.headers.get('content-length')",
|
|
"request.headers.get('x-rdg-form')",
|
|
'maximumBodyBytes',
|
|
'demoSubmissionEnvelopeSchema.safeParse',
|
|
'Cache-Control',
|
|
]) {
|
|
if (!route.includes(control)) failures.push(`Submission API is missing control: ${control}`);
|
|
}
|
|
if (!service.includes('AbortController'))
|
|
failures.push('Integration orchestration has no timeout controller.');
|
|
if (!service.includes('executeIdempotent'))
|
|
failures.push('Integration orchestration bypasses idempotency.');
|
|
if (!environment.includes('DEMO_LOCAL_TEST_MODE'))
|
|
failures.push('Loopback test escape is not explicit.');
|
|
if (!environment.includes("['127.0.0.1', 'localhost']")) {
|
|
failures.push('Production-like local adapter escape is not restricted to loopback origins.');
|
|
}
|
|
|
|
const sourceFiles = [route, service];
|
|
if (sourceFiles.some((source) => /console\.(log|info|debug|warn|error)\s*\(/.test(source))) {
|
|
failures.push('Submission path writes diagnostics directly to the console.');
|
|
}
|
|
|
|
if (failures.length) fail(failures);
|
|
else
|
|
pass(
|
|
'Phase 14 API boundary includes origin, content-type, size, timeout, idempotency, and no-raw-log controls.',
|
|
);
|