import fs from "node:fs/promises";
import http from "node:http";
import { spawn } from "node:child_process";
import { setTimeout as pause } from "node:timers/promises";
const owner = "12345678-1234-1234-1234-123456789abc";
const second = "12345678-1234-1234-1234-123456789def";
const child = spawn(
process.execPath,
["release/context-preview/dist-server/index.mjs"],
{
env: {
...process.env,
PORT: "4199",
CONTEXT_HOSTED: "true",
WEBSITE_SITE_NAME: "packaged-test",
CONTEXT_AUTH_PROVIDER: "azure-easyauth",
CONTEXT_ALLOWED_ORIGINS: "https://context.marmar.life",
CONTEXT_REVIEWER_IDS: owner + "," + second,
},
stdio: ["ignore", "pipe", "pipe"],
}
);
const results = [];
const base = "http://127.0.0.1:4199";
async function req(path, body, override = {}) {
return await new Promise((resolve, reject) => {
const request = http.request(
base + path,
{
method: body === undefined ? "GET" : "POST",
headers: {
host: "context.marmar.life",
origin: "https://context.marmar.life",
"x-ms-client-principal-id": owner,
...(body === undefined ? {} : { "content-type": "application/json" }),
...override,
},
},
(response) => {
let text = "";
response.on("data", (chunk) => (text += chunk));
response.on("end", () => {
let data;
try {
data = JSON.parse(text);
} catch {
data = text;
}
resolve({
status: response.statusCode,
data,
headers: new Headers(response.headers),
});
});
}
);
request.on("error", reject);
request.end(body === undefined ? undefined : JSON.stringify(body));
});
}
const check = (name, passed) => results.push({ name, passed });
try {
for (let i = 0; i < 50; i++) {
try {
await fetch(base + "/healthz");
break;
} catch {
await pause(100);
}
}
check(
"Unauthenticated application blocked",
(await req("/api/status", undefined, { "x-ms-client-principal-id": "" }))
.status === 401
);
check(
"Unapproved reviewer blocked",
(
await req("/api/status", undefined, {
"x-ms-client-principal-id": "unapproved",
})
).status === 401
);
check(
"Unrelated origin blocked",
(await req("/api/status", undefined, { origin: "https://evil.example" }))
.status === 403
);
check(
"Unapproved Host blocked",
(await req("/api/status", undefined, { host: "evil.example" })).status ===
403
);
const status = await req("/api/status");
check(
"Hosted status and administrator-managed model",
status.status === 200 &&
status.data.hosted &&
status.data.modelConnectionManaged
);
check(
"Browser model changes blocked",
(await req("/api/model", {})).status === 403
);
const index = await req("/");
check(
"Standalone frontend served",
index.status === 200 && index.data.includes('<div id="root">')
);
check(
"Security response headers",
index.headers.get("x-frame-options") === "DENY" &&
index.headers.has("strict-transport-security")
);
const caseResponse = await req("/api/cases");
if (!Array.isArray(caseResponse.data))
throw new Error(JSON.stringify({ results, caseResponse }));
const cases = caseResponse.data;
for (const item of cases) {
const sources = item.sources;
const extracted = await req("/api/extract", {
sources,
syntheticOnly: true,
useModel: false,
});
check(item.id + " extraction", extracted.status === 200);
const draft = extracted.data;
const review = Object.fromEntries(
draft.facts.map((f) => [f.id, f.problem ? "exclude" : "include"])
);
const payload = {
sources,
syntheticOnly: true,
draftId: draft.id,
review,
fingerprint: draft.fingerprint,
acknowledgeUnparsed: true,
};
const assessment = await req("/api/assess", payload);
if (item.id === "conflicting-records" || item.id === "narrative-context") {
check(
item.id + " blocked pending reconciliation or narrative model",
assessment.status === 400
);
continue;
}
check(item.id + " assessment", assessment.status === 200);
check(
item.id + " report export",
(await req("/api/reports/" + assessment.data.reportId)).status === 200
);
check(
item.id + " cross-reviewer draft denied",
(
await req("/api/assess", payload, {
"x-ms-client-principal-id": second,
})
).status === 400
);
check(
item.id + " cross-reviewer report denied",
(
await req("/api/reports/" + assessment.data.reportId, undefined, {
"x-ms-client-principal-id": second,
})
).status === 400
);
}
for (let i = 0; i < 2; i++)
await req("/api/extract", {
sources: cases[0].sources,
syntheticOnly: true,
});
check(
"Repeated extraction rate limited",
(
await req("/api/extract", {
sources: cases[0].sources,
syntheticOnly: true,
})
).status === 429
);
check(
"Evaluation succeeds under deployed package",
(await req("/api/evaluate", {})).data.passed === 14
);
await fs.writeFile(
"validation/hosted-package-smoke-2026-10-25.json",
JSON.stringify(
{
scope:
"Local packaged-server checks using simulated Azure proxy identity headers; Azure authentication and public URL not yet verified",
results,
},
null,
2
) + "\n"
);
console.log(
JSON.stringify(
{
passed: results.filter((x) => x.passed).length,
total: results.length,
failed: results.filter((x) => !x.passed),
},
null,
2
)
);
if (results.some((x) => !x.passed)) process.exitCode = 1;
} finally {
child.kill("SIGTERM");
}