Files

35 lines
2.0 KiB
JavaScript
Raw Permalink Normal View History

#!/usr/bin/env node
import { createHash } from 'node:crypto';
import { readFile } from 'node:fs/promises';
import { resolve } from 'node:path';
const base = (process.argv[2] || 'http://127.0.0.1:8080').replace(/\/$/, '');
const manifestPath = resolve(process.cwd(), 'asset-manifest.json');
const manifest = JSON.parse(await readFile(manifestPath, 'utf8'));
const assets = [...new Set([...(manifest.entrypoints || []), ...(manifest.publicAssets || [])])];
const failures = [];
const secretPattern = /(api[_-]?key|secret|token|password|private[_-]?key|authorization)\s*[:=]\s*["'][^"']+/i;
async function check(path, expected = {}) {
const response = await fetch(`${base}/${path}`);
const body = await response.text();
if (!response.ok) failures.push(`${path}: HTTP ${response.status}`);
if (expected.contentType && !response.headers.get('content-type')?.includes(expected.contentType)) failures.push(`${path}: unexpected content type`);
if (expected.marker && !body.includes(expected.marker)) failures.push(`${path}: missing marker ${expected.marker}`);
if (expected.integrity) {
const digest = `sha256-${createHash('sha256').update(body).digest('hex')}`;
if (digest !== expected.integrity) failures.push(`${path}: integrity mismatch`);
}
if (secretPattern.test(body)) failures.push(`${path}: possible hardcoded secret`);
console.log(`${response.ok ? 'PASS' : 'FAIL'} ${path} (${response.status})`);
}
const expectations = {
'index.html': { contentType: 'text/html', marker: 'ProspectOS' },
'health.html': { contentType: 'text/html', marker: 'Ready' },
'error.html': { contentType: 'text/html', marker: 'Something went wrong' },
healthz: { marker: 'ok' }
};
for (const asset of assets) await check(asset, { ...expectations[asset], integrity: manifest.integrity?.[asset] });
if (failures.length) { console.error(`\n${failures.length} deployment smoke check(s) failed`); for (const failure of failures) console.error(`- ${failure}`); process.exitCode = 1; } else console.log(`\nDeployment smoke checks passed for ${base}`);