2026-07-24 10:39:10 +08:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
const test = require("node:test");
|
|
|
|
|
const assert = require("node:assert/strict");
|
|
|
|
|
const crypto = require("node:crypto");
|
|
|
|
|
const fs = require("node:fs");
|
|
|
|
|
const os = require("node:os");
|
|
|
|
|
const path = require("node:path");
|
|
|
|
|
const { createApp } = require("./server");
|
2026-07-29 23:37:26 +08:00
|
|
|
const {
|
|
|
|
|
canonicalApproval,
|
|
|
|
|
canonicalConnect,
|
|
|
|
|
} = require("./guanghu-router");
|
2026-07-24 10:39:10 +08:00
|
|
|
|
|
|
|
|
async function withServer(run, extra = {}) {
|
|
|
|
|
const mail = [];
|
|
|
|
|
const app = createApp({
|
|
|
|
|
requestToken: "request-only-secret",
|
|
|
|
|
ownerEmail: "owner@example.invalid",
|
|
|
|
|
publicBaseUrl: "https://example.invalid/authz",
|
|
|
|
|
targets: ["JD-FD-PRIMARY", "BS-GZ-006"],
|
|
|
|
|
actions: { "server-login": ["read-navigation-map", "inspect-services"], "server-ops": ["read-navigation-map", "inspect-services"], "repo-push": ["read-navigation-map", "push-repository"] },
|
|
|
|
|
stateFile: "",
|
|
|
|
|
sendEmail: async (message) => { mail.push(message); return true; },
|
|
|
|
|
...extra,
|
|
|
|
|
});
|
|
|
|
|
await new Promise((resolve) => app.listen(0, "127.0.0.1", resolve));
|
|
|
|
|
const base = `http://127.0.0.1:${app.address().port}`;
|
2026-07-29 23:37:26 +08:00
|
|
|
try {
|
|
|
|
|
await run({ base, mail });
|
|
|
|
|
} finally {
|
|
|
|
|
app.closeAllConnections?.();
|
|
|
|
|
await new Promise((resolve) => app.close(resolve));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function ownerForm(email = "owner@example.invalid", headers = {}) {
|
|
|
|
|
return {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/x-www-form-urlencoded", ...headers },
|
|
|
|
|
body: new URLSearchParams({ email }).toString(),
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function routerDevice() {
|
|
|
|
|
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");
|
|
|
|
|
const publicJwk = publicKey.export({ format: "jwk" });
|
|
|
|
|
return {
|
|
|
|
|
device: {
|
|
|
|
|
device_id: "HL-BS-MAC-001",
|
|
|
|
|
owner_id: "ICE-GL∞",
|
|
|
|
|
label: "冰朔的 HoloLake",
|
|
|
|
|
public_key: publicJwk.x,
|
|
|
|
|
enabled: true,
|
|
|
|
|
},
|
|
|
|
|
privateKey,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async function readSseEvent(reader) {
|
|
|
|
|
const decoder = new TextDecoder();
|
|
|
|
|
let text = "";
|
|
|
|
|
while (!text.includes("\n\n")) {
|
|
|
|
|
const chunk = await reader.read();
|
|
|
|
|
if (chunk.done) throw new Error("光湖路由连接在回执抵达前关闭");
|
|
|
|
|
text += decoder.decode(chunk.value, { stream: true });
|
|
|
|
|
}
|
|
|
|
|
const block = text.slice(0, text.indexOf("\n\n"));
|
|
|
|
|
const data = block.split("\n").find(line => line.startsWith("data:"));
|
|
|
|
|
if (!data) throw new Error(`光湖路由回执缺少 data: ${block}`);
|
|
|
|
|
return JSON.parse(data.slice(5).trim());
|
2026-07-24 10:39:10 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
test("work order sends an opaque approval link and can be claimed once", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const recipientFingerprint = crypto.createHash("sha256").update("owner@example.invalid").digest("hex");
|
|
|
|
|
const requested = await fetch(`${base}/api/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", persona_name: "铸渊", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map", recipient_fingerprint: recipientFingerprint }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(requested.status, 201);
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
assert.equal(mail.length, 1);
|
|
|
|
|
assert.equal(mail[0].to, "owner@example.invalid");
|
|
|
|
|
assert.doesNotMatch(JSON.stringify(order), /approvalToken/i);
|
|
|
|
|
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
const page = await fetch(`${base}${approvalPath}`);
|
|
|
|
|
assert.equal(page.status, 200);
|
|
|
|
|
assert.match(await page.text(), /JD-FD-PRIMARY/);
|
|
|
|
|
|
|
|
|
|
const approved = await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
assert.equal(approved.status, 200);
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${order.claim_token}` },
|
|
|
|
|
});
|
|
|
|
|
assert.equal(claimed.status, 200);
|
|
|
|
|
const session = await claimed.json();
|
|
|
|
|
assert.equal(session.expires_in, 3 * 60 * 60);
|
|
|
|
|
|
|
|
|
|
const secondClaim = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
assert.equal(secondClaim.status, 403);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("cross-device request is powerless until the owner asks for an email and approves it", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const capabilities = await (await fetch(`${base}/api/public/capabilities`)).json();
|
|
|
|
|
assert.deepEqual(capabilities.required_fields, ["persona_id", "target", "scope", "action"]);
|
|
|
|
|
assert.ok(capabilities.scopes["repo-push"].includes("push-repository"));
|
|
|
|
|
assert.equal(capabilities.limits.create_per_network_per_hour, 24);
|
|
|
|
|
assert.equal(capabilities.limits.email_per_network_per_hour, 12);
|
|
|
|
|
assert.doesNotMatch(JSON.stringify(capabilities), /owner@example\.invalid/);
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json", "x-forwarded-for": "198.51.100.8" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", persona_name: "铸渊", target: "JD-FD-PRIMARY", scope: "repo-push", action: "push-repository", description: "mobile handoff" }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(requested.status, 201);
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
assert.equal(order.status, "waiting_for_owner_handoff");
|
2026-07-26 15:26:21 +08:00
|
|
|
assert.equal(order.receipt.diagnostic_code, "owner_handoff_required");
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.equal(mail.length, 0);
|
|
|
|
|
assert.match(order.request_url, /\/request\//);
|
|
|
|
|
assert.doesNotMatch(JSON.stringify(order), /approve\//);
|
|
|
|
|
|
|
|
|
|
const requestPath = new URL(order.request_url).pathname.replace("/authz", "");
|
|
|
|
|
const handoffPage = await fetch(`${base}${requestPath}`);
|
|
|
|
|
assert.equal(handoffPage.status, 200);
|
|
|
|
|
assert.match(await handoffPage.text(), /无权限申请单/);
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.match(await (await fetch(`${base}${requestPath}`)).text(), /type="email"/);
|
2026-07-24 10:39:10 +08:00
|
|
|
|
|
|
|
|
const prematureClaim = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
assert.equal(prematureClaim.status, 202);
|
|
|
|
|
|
2026-07-29 23:37:26 +08:00
|
|
|
const wrongEmail = await fetch(`${base}${requestPath}`, ownerForm("someone-else@example.invalid", { "x-forwarded-for": "203.0.113.8" }));
|
|
|
|
|
assert.equal(wrongEmail.status, 200);
|
|
|
|
|
assert.equal(mail.length, 0);
|
|
|
|
|
const wrongPage = await wrongEmail.text();
|
|
|
|
|
assert.match(wrongPage, /如果信息匹配/);
|
|
|
|
|
|
|
|
|
|
const sendMail = await fetch(`${base}${requestPath}`, ownerForm("Owner@Example.Invalid", { "x-forwarded-for": "203.0.113.9" }));
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.equal(sendMail.status, 200);
|
|
|
|
|
assert.equal(mail.length, 1);
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.equal(await sendMail.text(), wrongPage);
|
2026-07-24 10:39:10 +08:00
|
|
|
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
const approved = await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
assert.equal(approved.status, 200);
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
assert.equal(claimed.status, 200);
|
|
|
|
|
assert.equal((await claimed.json()).expires_in, 3 * 60 * 60);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-29 23:37:26 +08:00
|
|
|
test("an online HoloLake receives and approves a workorder through the Guanghu Router", async () => {
|
|
|
|
|
const { device, privateKey } = routerDevice();
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const challengeResponse = await fetch(`${base}/api/guanghu-router/challenge`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ device_id: device.device_id }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(challengeResponse.status, 200);
|
|
|
|
|
const challenge = await challengeResponse.json();
|
|
|
|
|
const clientTimestamp = challenge.server_time;
|
|
|
|
|
const connectSignature = crypto.sign(
|
|
|
|
|
null,
|
|
|
|
|
Buffer.from(canonicalConnect({
|
|
|
|
|
deviceId: device.device_id,
|
|
|
|
|
challengeId: challenge.challenge_id,
|
|
|
|
|
nonce: challenge.nonce,
|
|
|
|
|
clientTimestamp,
|
|
|
|
|
})),
|
|
|
|
|
privateKey,
|
|
|
|
|
).toString("base64url");
|
|
|
|
|
const connectResponse = await fetch(`${base}/api/guanghu-router/connect`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
device_id: device.device_id,
|
|
|
|
|
challenge_id: challenge.challenge_id,
|
|
|
|
|
client_timestamp: clientTimestamp,
|
|
|
|
|
signature: connectSignature,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(connectResponse.status, 200);
|
|
|
|
|
const connection = await connectResponse.json();
|
|
|
|
|
|
|
|
|
|
const controller = new AbortController();
|
|
|
|
|
const streamResponse = await fetch(`${base}/api/guanghu-router/stream`, {
|
|
|
|
|
headers: { authorization: `Bearer ${connection.route_token}` },
|
|
|
|
|
signal: controller.signal,
|
|
|
|
|
});
|
|
|
|
|
assert.equal(streamResponse.status, 200);
|
|
|
|
|
const reader = streamResponse.body.getReader();
|
|
|
|
|
const connected = await readSseEvent(reader);
|
|
|
|
|
assert.equal(connected.type, "router.connected");
|
|
|
|
|
assert.equal(connected.receipt.state, "online");
|
|
|
|
|
assert.equal(connected.receipt.node_id, "JD-FD-PRIMARY");
|
|
|
|
|
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
persona_name: "铸渊",
|
|
|
|
|
target: "JD-FD-PRIMARY",
|
|
|
|
|
scope: "server-login",
|
|
|
|
|
action: "read-navigation-map",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
assert.equal(order.status, "waiting_for_broadcast_console");
|
|
|
|
|
assert.equal(order.delivery.channel, "guanghu_router");
|
|
|
|
|
assert.equal(mail.length, 0);
|
|
|
|
|
|
|
|
|
|
const card = await readSseEvent(reader);
|
|
|
|
|
assert.equal(card.type, "authorization.requested");
|
|
|
|
|
assert.equal(card.workorder.id, order.workorder_id);
|
|
|
|
|
const approvalSignature = crypto.sign(
|
|
|
|
|
null,
|
|
|
|
|
Buffer.from(canonicalApproval({
|
|
|
|
|
deviceId: device.device_id,
|
|
|
|
|
workorderId: order.workorder_id,
|
|
|
|
|
digest: card.digest,
|
|
|
|
|
})),
|
|
|
|
|
privateKey,
|
|
|
|
|
).toString("base64url");
|
|
|
|
|
const approved = await fetch(
|
|
|
|
|
`${base}/api/guanghu-router/authorizations/${order.workorder_id}/approve`,
|
|
|
|
|
{
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
device_id: device.device_id,
|
|
|
|
|
signature: approvalSignature,
|
|
|
|
|
}),
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
assert.equal(approved.status, 200);
|
|
|
|
|
assert.equal((await approved.json()).receipt.state, "approved");
|
|
|
|
|
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${order.claim_token}` },
|
|
|
|
|
});
|
|
|
|
|
assert.equal(claimed.status, 200);
|
|
|
|
|
assert.equal((await claimed.json()).expires_in, 3 * 60 * 60);
|
|
|
|
|
|
|
|
|
|
controller.abort();
|
|
|
|
|
}, { devices: [device] });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("declared Work/mobile instance cannot auto-email and must hand off to the owner page", async () => {
|
2026-07-26 15:36:14 +08:00
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST", headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ system_entry: "光湖语言人格系统当前实例", origin_software: "Work", origin_model: "语言模型", origin_instance: "mobile-1", owner_notify: true, persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops", action: "dispatch-approved-deployment", resource: `GLS-0239-DEPLOY@${"a".repeat(40)}` }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(requested.status, 201);
|
|
|
|
|
const order = await requested.json();
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.equal(order.status, "waiting_for_owner_handoff");
|
|
|
|
|
assert.equal(order.email_status, "owner_input_required");
|
|
|
|
|
assert.equal(order.public_auto_email, false);
|
|
|
|
|
assert.equal(mail.length, 0);
|
|
|
|
|
assert.match(order.request_url, /\/request\//);
|
2026-07-26 15:36:14 +08:00
|
|
|
}, { actions: { "server-ops": ["read-navigation-map", "dispatch-approved-deployment"] } });
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-24 10:39:10 +08:00
|
|
|
test("cross-device request creation is rate limited without revealing owner identity", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const payload = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map" };
|
|
|
|
|
for (let i = 0; i < 3; i += 1) {
|
|
|
|
|
const response = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json", "x-forwarded-for": "spoofed, 198.51.100.20" }, body: JSON.stringify(payload) });
|
|
|
|
|
assert.equal(response.status, 201);
|
|
|
|
|
assert.doesNotMatch(await response.text(), /owner@example\.invalid/);
|
|
|
|
|
}
|
|
|
|
|
const blocked = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json", "x-forwarded-for": "different-spoof, 198.51.100.20" }, body: JSON.stringify(payload) });
|
|
|
|
|
assert.equal(blocked.status, 429);
|
|
|
|
|
assert.equal(mail.length, 0);
|
|
|
|
|
}, { publicCreateLimit: 1, publicCreateGlobalLimit: 10 });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("one server-ops approval exposes the full registered three-hour operation scope", async () => {
|
|
|
|
|
const app = createApp({
|
|
|
|
|
requestToken: "request-only-secret",
|
|
|
|
|
ownerEmail: "owner@example.invalid",
|
|
|
|
|
publicBaseUrl: "https://example.invalid/authz",
|
|
|
|
|
stateFile: "",
|
|
|
|
|
sendEmail: async () => true,
|
|
|
|
|
});
|
|
|
|
|
await new Promise(resolve => app.listen(0, "127.0.0.1", resolve));
|
|
|
|
|
try {
|
|
|
|
|
const base = `http://127.0.0.1:${app.address().port}`;
|
|
|
|
|
const capabilities = await (await fetch(`${base}/api/public/capabilities`)).json();
|
|
|
|
|
assert.deepEqual(capabilities.scopes["server-ops"], [
|
|
|
|
|
"read-navigation-map",
|
|
|
|
|
"inspect-services",
|
|
|
|
|
"pull-registered-repo",
|
|
|
|
|
"deploy-registered-service",
|
|
|
|
|
"restart-registered-service",
|
|
|
|
|
"health-check",
|
|
|
|
|
"rollback-registered-service",
|
|
|
|
|
"provision-approved-architecture",
|
|
|
|
|
"push-repository",
|
2026-07-27 14:33:03 +08:00
|
|
|
"inspect-owner-ssh-login",
|
|
|
|
|
"disable-owner-password-login",
|
2026-07-24 10:39:10 +08:00
|
|
|
"restore-owner-password-login",
|
2026-07-26 15:02:01 +08:00
|
|
|
"restore-code-channel-owner-login",
|
2026-07-26 15:36:14 +08:00
|
|
|
"dispatch-approved-deployment",
|
2026-07-24 10:39:10 +08:00
|
|
|
]);
|
|
|
|
|
} finally {
|
|
|
|
|
await new Promise(resolve => app.close(resolve));
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-29 23:37:26 +08:00
|
|
|
test("registered repositories resolve and an approved session can upload one bounded bundle", async () => {
|
|
|
|
|
const uploadDir = fs.mkdtempSync(path.join(os.tmpdir(), "guanghu-router-upload-"));
|
|
|
|
|
const received = [];
|
|
|
|
|
const registry = {
|
|
|
|
|
"bingshuo/hololake-platform": {
|
|
|
|
|
branches: ["main", "feat/hldp-runtime-browser"],
|
|
|
|
|
remote: "file:///srv/forgejo/hololake-platform.git",
|
|
|
|
|
source_urls: [
|
|
|
|
|
"https://guanghulab.com/fifth-domain/bingshuo/hololake-platform.git",
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
const mapGate = {
|
|
|
|
|
read: target => ({ hash: `map-${target}`, data: { node_id: target } }),
|
|
|
|
|
ack: () => ({ ok: true }),
|
|
|
|
|
verify: () => ({ ok: true }),
|
|
|
|
|
};
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const registered = await fetch(`${base}/api/repositories/resolve`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
remote_url: "https://guanghulab.com/fifth-domain/bingshuo/hololake-platform.git",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(registered.status, 200);
|
|
|
|
|
assert.equal((await registered.json()).repo, "bingshuo/hololake-platform");
|
|
|
|
|
|
|
|
|
|
const unregistered = await fetch(`${base}/api/repositories/resolve`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ remote_url: "" }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(unregistered.status, 404);
|
|
|
|
|
assert.equal((await unregistered.json()).diagnostic_code, "local_repository_remote_missing");
|
|
|
|
|
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
persona_name: "铸渊",
|
|
|
|
|
target: "JD-FD-PRIMARY",
|
|
|
|
|
scope: "repo-push",
|
|
|
|
|
action: "push-repository",
|
|
|
|
|
resource: "bingshuo/hololake-platform@feat/hldp-runtime-browser",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const requestPath = new URL(order.request_url).pathname.replace("/authz", "");
|
|
|
|
|
await fetch(`${base}${requestPath}`, ownerForm());
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(
|
|
|
|
|
`${base}/api/workorders/${order.workorder_id}/claim`,
|
|
|
|
|
{ method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } },
|
|
|
|
|
)).json();
|
|
|
|
|
const common = {
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
target: "JD-FD-PRIMARY",
|
|
|
|
|
scope: "repo-push",
|
|
|
|
|
};
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
authorization: `Bearer ${session.session_token}`,
|
|
|
|
|
"content-type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify(common),
|
|
|
|
|
})).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: {
|
|
|
|
|
authorization: `Bearer ${session.session_token}`,
|
|
|
|
|
"content-type": "application/json",
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify({ ...common, map_hash: map.map_hash }),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const bundle = Buffer.from("test-bundle-payload");
|
|
|
|
|
const uploadId = "11111111-1111-4111-8111-111111111111";
|
|
|
|
|
const firstChunk = bundle.subarray(0, 5);
|
|
|
|
|
const partial = await fetch(
|
|
|
|
|
`${base}/api/repo-push/bundle?repo=bingshuo%2Fhololake-platform&branch=feat%2Fhldp-runtime-browser&expected_head=${"0".repeat(40)}&persona_id=ICE-GL-ZY001&target=JD-FD-PRIMARY&scope=repo-push`,
|
|
|
|
|
{
|
|
|
|
|
method: "PUT",
|
|
|
|
|
headers: {
|
|
|
|
|
authorization: `Bearer ${session.session_token}`,
|
|
|
|
|
"content-length": String(firstChunk.length),
|
|
|
|
|
"content-type": "application/octet-stream",
|
|
|
|
|
"x-guanghu-upload-id": uploadId,
|
|
|
|
|
"x-guanghu-chunk-index": "0",
|
|
|
|
|
"x-guanghu-chunk-count": "2",
|
|
|
|
|
"x-guanghu-chunk-offset": "0",
|
|
|
|
|
},
|
|
|
|
|
body: firstChunk,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
assert.equal(partial.status, 202);
|
|
|
|
|
assert.equal((await partial.json()).upload.received_bytes, firstChunk.length);
|
|
|
|
|
const lastChunk = bundle.subarray(5);
|
|
|
|
|
const uploaded = await fetch(
|
|
|
|
|
`${base}/api/repo-push/bundle?repo=bingshuo%2Fhololake-platform&branch=feat%2Fhldp-runtime-browser&expected_head=${"0".repeat(40)}&persona_id=ICE-GL-ZY001&target=JD-FD-PRIMARY&scope=repo-push`,
|
|
|
|
|
{
|
|
|
|
|
method: "PUT",
|
|
|
|
|
headers: {
|
|
|
|
|
authorization: `Bearer ${session.session_token}`,
|
|
|
|
|
"content-length": String(lastChunk.length),
|
|
|
|
|
"content-type": "application/octet-stream",
|
|
|
|
|
"x-guanghu-upload-id": uploadId,
|
|
|
|
|
"x-guanghu-chunk-index": "1",
|
|
|
|
|
"x-guanghu-chunk-count": "2",
|
|
|
|
|
"x-guanghu-chunk-offset": String(firstChunk.length),
|
|
|
|
|
},
|
|
|
|
|
body: lastChunk,
|
|
|
|
|
},
|
|
|
|
|
);
|
|
|
|
|
assert.equal(uploaded.status, 200);
|
|
|
|
|
const result = await uploaded.json();
|
|
|
|
|
assert.equal(result.receipt.diagnostic_code, "repo_push_succeeded");
|
|
|
|
|
assert.equal(received.length, 1);
|
|
|
|
|
assert.equal(received[0].bundle_bytes, "test-bundle-payload");
|
|
|
|
|
}, {
|
|
|
|
|
mapGate,
|
|
|
|
|
repoPushRegistry: registry,
|
|
|
|
|
repoUploadDir: uploadDir,
|
|
|
|
|
receiveRepoBundle: async request => {
|
|
|
|
|
received.push({
|
|
|
|
|
...request,
|
|
|
|
|
bundle_bytes: fs.readFileSync(request.bundle_path, "utf8"),
|
|
|
|
|
});
|
|
|
|
|
return {
|
|
|
|
|
ok: true,
|
|
|
|
|
repo: request.repo,
|
|
|
|
|
branch: request.branch,
|
|
|
|
|
commit_sha: "b".repeat(40),
|
|
|
|
|
diagnostic_code: "repo_push_succeeded",
|
|
|
|
|
verification_url: "https://example.invalid/commit/" + "b".repeat(40),
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
fs.rmSync(uploadDir, { recursive: true, force: true });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-24 10:39:10 +08:00
|
|
|
test("mail handoff allows at least three requests per network and refresh does not consume quota", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const source = { "x-forwarded-for": "198.51.100.42" };
|
|
|
|
|
for (let i = 0; i < 3; i += 1) {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST", headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "repo-push", action: "push-repository" }),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const requestPath = new URL(order.request_url).pathname.replace("/authz", "");
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.equal((await fetch(`${base}${requestPath}`, ownerForm("owner@example.invalid", source))).status, 200);
|
|
|
|
|
assert.equal((await fetch(`${base}${requestPath}`, ownerForm("owner@example.invalid", source))).status, 200);
|
2026-07-24 10:39:10 +08:00
|
|
|
}
|
|
|
|
|
assert.equal(mail.length, 3);
|
|
|
|
|
const fourth = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST", headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "repo-push", action: "push-repository" }),
|
|
|
|
|
});
|
|
|
|
|
const fourthOrder = await fourth.json();
|
|
|
|
|
const fourthPath = new URL(fourthOrder.request_url).pathname.replace("/authz", "");
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.equal((await fetch(`${base}${fourthPath}`, ownerForm("owner@example.invalid", source))).status, 429);
|
2026-07-24 10:39:10 +08:00
|
|
|
}, { publicMailLimit: 1 });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("navigation map acknowledgement is mandatory before other registered actions", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-server-map-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY", modules: [{ code: "JD-GTW-01" }] }));
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const fingerprint = crypto.createHash("sha256").update("owner@example.invalid").digest("hex");
|
|
|
|
|
const requested = await fetch(`${base}/api/workorders`, { method: "POST", headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map", recipient_fingerprint: fingerprint }) });
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
const session = await claimed.json();
|
|
|
|
|
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" };
|
|
|
|
|
const locked = await fetch(`${base}/api/session/verify`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, action: "inspect-services" }) });
|
|
|
|
|
assert.equal(locked.status, 423);
|
|
|
|
|
const mapResponse = await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
|
|
|
|
|
const map = await mapResponse.json();
|
|
|
|
|
const ack = await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
|
|
|
|
|
assert.equal(ack.status, 200);
|
|
|
|
|
const unlocked = await fetch(`${base}/api/session/verify`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, action: "inspect-services" }) });
|
|
|
|
|
assert.equal(unlocked.status, 200);
|
|
|
|
|
}, { mapsDir, mapStateFile: path.join(dir, "acks.json") });
|
|
|
|
|
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("active session renewal preserves target and scope and extends the map acknowledgement", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-renew-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY" }));
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map" }) });
|
|
|
|
|
const order = await requested.json();
|
2026-07-29 23:37:26 +08:00
|
|
|
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, ownerForm());
|
2026-07-24 10:39:10 +08:00
|
|
|
await fetch(`${base}${new URL(mail[0].approvalUrl).pathname.replace("/authz", "")}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } })).json();
|
|
|
|
|
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" };
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) })).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
|
|
|
|
|
const expanded = await fetch(`${base}/api/session/renew`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, action: "health-check" }) });
|
|
|
|
|
assert.equal(expanded.status, 400);
|
|
|
|
|
const renewed = await fetch(`${base}/api/session/renew`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
|
|
|
|
|
assert.equal(renewed.status, 200);
|
|
|
|
|
assert.equal((await renewed.json()).authority_expanded, false);
|
|
|
|
|
}, { mapsDir, mapStateFile: path.join(dir, "acks.json"), sessionTtl: 100, maxSessionLifetime: 500 });
|
|
|
|
|
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("registered action bridge executes only after session and map checks", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-action-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY" }));
|
|
|
|
|
const calls = [];
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map" }) });
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const requestPath = new URL(order.request_url).pathname.replace("/authz", "");
|
2026-07-29 23:37:26 +08:00
|
|
|
await fetch(`${base}${requestPath}`, ownerForm());
|
2026-07-24 10:39:10 +08:00
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
const session = await claimed.json();
|
2026-07-26 15:26:21 +08:00
|
|
|
const initialStatus = await fetch(`${base}/api/session/status`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" }) });
|
|
|
|
|
assert.equal((await initialStatus.json()).state, "map_ack_required");
|
2026-07-24 10:39:10 +08:00
|
|
|
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "inspect-services" };
|
|
|
|
|
const beforeAck = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
|
|
|
|
|
assert.equal(beforeAck.status, 423);
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) })).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
|
|
|
|
|
const forbidden = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, cmd: "id" }) });
|
|
|
|
|
assert.equal(forbidden.status, 400);
|
|
|
|
|
const executed = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) });
|
|
|
|
|
assert.equal(executed.status, 200);
|
2026-07-26 15:26:21 +08:00
|
|
|
assert.equal((await executed.clone().json()).receipt.state, "succeeded");
|
|
|
|
|
const finalStatus = await fetch(`${base}/api/session/status`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" }) });
|
|
|
|
|
const finalPayload = await finalStatus.json();
|
|
|
|
|
assert.equal(finalPayload.state, "ready_to_execute");
|
|
|
|
|
assert.equal(finalPayload.last_receipt.diagnostic_code, "action_succeeded");
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.deepEqual(calls, [{ action: "inspect-services", target: "JD-FD-PRIMARY" }]);
|
|
|
|
|
}, { mapsDir, mapStateFile: path.join(dir, "acks.json"), executeAction: async request => { calls.push(request); return { ok: true, stdout: "healthy" }; } });
|
|
|
|
|
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-26 15:26:21 +08:00
|
|
|
test("failed server actions return a durable diagnosis instead of making a persona guess", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-action-failure-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY" }));
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map" }) });
|
|
|
|
|
const order = await requested.json();
|
2026-07-29 23:37:26 +08:00
|
|
|
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, ownerForm());
|
2026-07-26 15:26:21 +08:00
|
|
|
await fetch(`${base}${new URL(mail[0].approvalUrl).pathname.replace("/authz", "")}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } })).json();
|
|
|
|
|
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login" };
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) })).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
|
|
|
|
|
const failed = await fetch(`${base}/api/actions/execute`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, action: "inspect-services" }) });
|
|
|
|
|
assert.equal(failed.status, 502);
|
|
|
|
|
const payload = await failed.json();
|
|
|
|
|
assert.equal(payload.receipt.state, "failed");
|
|
|
|
|
assert.equal(payload.receipt.diagnostic_code, "agent_socket_unavailable");
|
|
|
|
|
assert.match(payload.receipt.next_step, /diagnostic_code/);
|
|
|
|
|
}, { mapsDir, mapStateFile: path.join(dir, "acks.json"), executeAction: async () => ({ ok: false, error: "agent_socket_unavailable", stderr: "socket offline" }) });
|
|
|
|
|
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
|
|
|
});
|
|
|
|
|
|
2026-08-02 23:41:48 +08:00
|
|
|
test("GHDR double signing is email-authorized and bound to one canonical layout digest", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-ghdr-sign-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "GH-CVM-MAIN-PROD-01.json"), JSON.stringify({
|
|
|
|
|
node_id: "GH-CVM-MAIN-PROD-01",
|
|
|
|
|
}));
|
|
|
|
|
const now = Math.floor(Date.now() / 1000);
|
|
|
|
|
const plan = {
|
|
|
|
|
schema: "guanghu.ghdr-signed-layout-plan/v1",
|
|
|
|
|
payload: {
|
|
|
|
|
node_id: "GH-CVM-MAIN-PROD-01",
|
|
|
|
|
provider: "tencent_cloud",
|
|
|
|
|
region: "ap-guangzhou",
|
|
|
|
|
target_probe_sha256: "11".repeat(32),
|
|
|
|
|
system_disk: "/dev/vda",
|
|
|
|
|
disk_sectors: 104857600,
|
|
|
|
|
logical_sector_bytes: 512,
|
|
|
|
|
disk_identity_sha256: "22".repeat(32),
|
|
|
|
|
recovery_evidence_sha256: "55".repeat(32),
|
|
|
|
|
first_partition_lba: 2048,
|
|
|
|
|
generation: 1,
|
|
|
|
|
operation: "install_native_ab",
|
|
|
|
|
issued_at_unix: now,
|
|
|
|
|
expires_at_unix: now + 300,
|
|
|
|
|
slots: [
|
|
|
|
|
{ name: "A", lba_start: 34, sector_count: 29, image_sha256: "33".repeat(32) },
|
|
|
|
|
{ name: "B", lba_start: 73, sector_count: 29, image_sha256: "44".repeat(32) },
|
|
|
|
|
],
|
|
|
|
|
},
|
|
|
|
|
signatures: [],
|
|
|
|
|
};
|
|
|
|
|
const digest = crypto.createHash("sha256").update(JSON.stringify(plan.payload)).digest("hex");
|
|
|
|
|
const resource = `GH-CVM-MAIN-PROD-01:${digest}:1`;
|
|
|
|
|
const signatures = [
|
|
|
|
|
{ node_id: "GH-CTRL-GZ-01", failure_domain: "tencent/ap-guangzhou/BS-GZ-006", public_key_hex: "aa".repeat(32), signature_hex: "bb".repeat(64) },
|
|
|
|
|
{ node_id: "GH-CTRL-SG-01", failure_domain: "tencent/ap-singapore/ZY-SG-006", public_key_hex: "cc".repeat(32), signature_hex: "dd".repeat(64) },
|
|
|
|
|
];
|
|
|
|
|
const calls = [];
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const malformed = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
target: "GH-CVM-MAIN-PROD-01",
|
|
|
|
|
scope: "native-recovery",
|
|
|
|
|
action: "sign-native-layout-plan",
|
|
|
|
|
resource: "GH-CVM-MAIN-PROD-01:not-a-digest:1",
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(malformed.status, 400);
|
|
|
|
|
assert.equal((await malformed.json()).error, "ghdr_layout_resource_required");
|
|
|
|
|
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
target: "GH-CVM-MAIN-PROD-01",
|
|
|
|
|
scope: "native-recovery",
|
|
|
|
|
action: "sign-native-layout-plan",
|
|
|
|
|
resource,
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, ownerForm());
|
|
|
|
|
await fetch(`${base}${new URL(mail[0].approvalUrl).pathname.replace("/authz", "")}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${order.claim_token}` },
|
|
|
|
|
})).json();
|
|
|
|
|
const common = {
|
|
|
|
|
persona_id: "ICE-GL-ZY001",
|
|
|
|
|
target: "GH-CVM-MAIN-PROD-01",
|
|
|
|
|
scope: "native-recovery",
|
|
|
|
|
};
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify(common),
|
|
|
|
|
})).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ ...common, map_hash: map.map_hash }),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const changed = structuredClone(plan);
|
|
|
|
|
changed.payload.generation = 2;
|
|
|
|
|
const refused = await fetch(`${base}/api/ghdr/sign-layout`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ ...common, resource, plan: changed }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(refused.status, 400);
|
|
|
|
|
assert.equal((await refused.json()).error, "ghdr_layout_resource_mismatch");
|
|
|
|
|
|
|
|
|
|
const signed = await fetch(`${base}/api/ghdr/sign-layout`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ ...common, resource, plan }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(signed.status, 200);
|
|
|
|
|
const payload = await signed.json();
|
|
|
|
|
assert.equal(payload.signatures.length, 2);
|
|
|
|
|
assert.equal(payload.receipt.diagnostic_code, "ghdr_layout_double_signature_succeeded");
|
|
|
|
|
assert.deepEqual(calls, [{
|
|
|
|
|
plan,
|
|
|
|
|
binding: {
|
|
|
|
|
ok: true,
|
|
|
|
|
payload_sha256: digest,
|
|
|
|
|
generation: 1,
|
|
|
|
|
resource,
|
|
|
|
|
},
|
|
|
|
|
workorderId: order.workorder_id,
|
|
|
|
|
authorizer: "test-authorizer",
|
|
|
|
|
}]);
|
|
|
|
|
}, {
|
|
|
|
|
mapsDir,
|
|
|
|
|
mapStateFile: path.join(dir, "acks.json"),
|
|
|
|
|
targets: ["GH-CVM-MAIN-PROD-01"],
|
|
|
|
|
actions: { "native-recovery": ["read-navigation-map", "sign-native-layout-plan"] },
|
|
|
|
|
getGhdrAuthorizer: () => "test-authorizer",
|
|
|
|
|
signGhdrPlan: async request => {
|
|
|
|
|
calls.push(request);
|
|
|
|
|
return { ok: true, signatures };
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} finally {
|
|
|
|
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2026-08-02 23:53:10 +08:00
|
|
|
test("GHDR controller transport endpoints expose jobs and public authority without private keys", async () => {
|
|
|
|
|
const calls = [];
|
|
|
|
|
await withServer(async ({ base }) => {
|
|
|
|
|
const publicResponse = await fetch(`${base}/api/ghdr/authorizer-public-key`);
|
|
|
|
|
assert.equal(publicResponse.status, 200);
|
|
|
|
|
const publicPayload = await publicResponse.json();
|
|
|
|
|
assert.equal(publicPayload.binding.algorithm, "Ed25519");
|
|
|
|
|
assert.equal(publicPayload.binding.public_key_sha256, "ab".repeat(32));
|
|
|
|
|
assert.doesNotMatch(JSON.stringify(publicPayload), /PRIVATE KEY/);
|
|
|
|
|
|
|
|
|
|
const pollBody = { request: { schema: "poll" }, request_signature_hex: "11" };
|
|
|
|
|
const poll = await fetch(`${base}/api/ghdr/controllers/poll`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify(pollBody),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(poll.status, 200);
|
|
|
|
|
assert.equal((await poll.json()).job.job_id, "job-1");
|
|
|
|
|
|
|
|
|
|
const resultBody = {
|
|
|
|
|
request: { schema: "result" },
|
|
|
|
|
request_signature_hex: "22",
|
|
|
|
|
signature: { signature_hex: "33" },
|
|
|
|
|
};
|
|
|
|
|
const result = await fetch(`${base}/api/ghdr/controllers/result`, {
|
|
|
|
|
method: "POST",
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify(resultBody),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(result.status, 403);
|
|
|
|
|
assert.equal((await result.json()).error, "controller_result_refused");
|
|
|
|
|
assert.deepEqual(calls, [
|
|
|
|
|
["poll", pollBody],
|
|
|
|
|
["submit", resultBody],
|
|
|
|
|
]);
|
|
|
|
|
}, {
|
|
|
|
|
getGhdrAuthorizer: () => ({
|
|
|
|
|
publicBinding: () => ({
|
|
|
|
|
schema: "guanghu.ghdr-authorizer-public-binding/v1",
|
|
|
|
|
authorizer_id: "JD-FD-PRIMARY-LAKE-LAMP",
|
|
|
|
|
algorithm: "Ed25519",
|
|
|
|
|
public_key_pem: "-----BEGIN PUBLIC KEY-----\nTEST\n-----END PUBLIC KEY-----\n",
|
|
|
|
|
public_key_sha256: "ab".repeat(32),
|
|
|
|
|
}),
|
|
|
|
|
}),
|
|
|
|
|
getGhdrControllerBroker: () => ({
|
|
|
|
|
poll: body => {
|
|
|
|
|
calls.push(["poll", body]);
|
|
|
|
|
return { ok: true, job: { job_id: "job-1" } };
|
|
|
|
|
},
|
|
|
|
|
submit: body => {
|
|
|
|
|
calls.push(["submit", body]);
|
|
|
|
|
return { ok: false, error: "controller_result_refused" };
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-26 15:36:14 +08:00
|
|
|
test("deployment is dispatched only by an explicit approved second signal", async () => {
|
|
|
|
|
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-deploy-dispatch-"));
|
|
|
|
|
const mapsDir = path.join(dir, "maps"); fs.mkdirSync(mapsDir);
|
|
|
|
|
fs.writeFileSync(path.join(mapsDir, "JD-FD-PRIMARY.json"), JSON.stringify({ node_id: "JD-FD-PRIMARY" }));
|
|
|
|
|
const sha = "a".repeat(40), resource = `GLS-0239-DEPLOY@${sha}`;
|
|
|
|
|
try {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops", action: "dispatch-approved-deployment", resource }) });
|
|
|
|
|
const order = await requested.json();
|
2026-07-29 23:37:26 +08:00
|
|
|
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, ownerForm());
|
2026-07-26 15:36:14 +08:00
|
|
|
await fetch(`${base}${new URL(mail[0].approvalUrl).pathname.replace("/authz", "")}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } })).json();
|
|
|
|
|
const common = { persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops" };
|
|
|
|
|
const map = await (await fetch(`${base}/api/navigation-map/read`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify(common) })).json();
|
|
|
|
|
await fetch(`${base}/api/navigation-map/ack`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, map_hash: map.map_hash }) });
|
2026-07-27 15:05:46 +08:00
|
|
|
const dispatch = await fetch(`${base}/api/deployment/dispatch`, { method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" }, body: JSON.stringify({ ...common, repo: "bingshuo/guanghu-ice-heart", branch: "main", commit_sha: sha, resource, manifest: "deployment/requests/GLS-0239-DEPLOY.json" }) });
|
2026-07-26 15:36:14 +08:00
|
|
|
assert.equal(dispatch.status, 202);
|
|
|
|
|
assert.equal((await dispatch.json()).receipt.state, "queued");
|
|
|
|
|
assert.equal(fs.readdirSync(path.join(dir, "queue")).length, 1);
|
2026-07-26 17:56:47 +08:00
|
|
|
}, {
|
|
|
|
|
mapsDir,
|
|
|
|
|
mapStateFile: path.join(dir, "acks.json"),
|
|
|
|
|
deploymentQueueDir: path.join(dir, "queue"),
|
|
|
|
|
deploymentRepositories: {
|
|
|
|
|
"bingshuo/guanghu-ice-heart": {
|
|
|
|
|
repo_url: "https://example.invalid/guanghu-ice-heart.git",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
actions: { "server-ops": ["read-navigation-map", "dispatch-approved-deployment"] },
|
|
|
|
|
});
|
2026-07-26 15:36:14 +08:00
|
|
|
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
|
|
|
|
});
|
|
|
|
|
|
2026-07-24 10:39:10 +08:00
|
|
|
test("request endpoint rejects direct email target switching and unknown actions", async () => {
|
|
|
|
|
await withServer(async ({ base }) => {
|
|
|
|
|
const common = { method: "POST", headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" } };
|
|
|
|
|
const directEmail = await fetch(`${base}/api/workorders`, { ...common, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "read-navigation-map", email: "attacker@example.invalid" }) });
|
|
|
|
|
assert.equal(directEmail.status, 400);
|
|
|
|
|
const unknown = await fetch(`${base}/api/workorders`, { ...common, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-login", action: "shell" }) });
|
|
|
|
|
assert.equal(unknown.status, 400);
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("architecture provision request is bound to one immutable manifest and commit", async () => {
|
|
|
|
|
const actions = { "server-ops": ["read-navigation-map", "provision-approved-architecture"] };
|
|
|
|
|
const resource = `GLS-0231-JD-LAN-01-INITIAL-PROVISION-20260720@${"a".repeat(40)}`;
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const missing = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops", action: "provision-approved-architecture" }) });
|
|
|
|
|
assert.equal(missing.status, 400);
|
|
|
|
|
assert.equal((await missing.json()).error, "immutable_architecture_resource_required");
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops", action: "provision-approved-architecture", resource }) });
|
|
|
|
|
const order = await requested.json();
|
2026-07-29 23:37:26 +08:00
|
|
|
await fetch(`${base}${new URL(order.request_url).pathname.replace("/authz", "")}`, ownerForm());
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.equal(mail[0].order.resource, resource);
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
assert.match(await (await fetch(`${base}${approvalPath}`)).text(), new RegExp(resource));
|
|
|
|
|
await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
const session = await (await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } })).json();
|
|
|
|
|
assert.equal(session.resource, resource);
|
|
|
|
|
}, { actions });
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("session verification rejects switching servers without new approval", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const fingerprint = crypto.createHash("sha256").update("owner@example.invalid").digest("hex");
|
|
|
|
|
const requested = await fetch(`${base}/api/workorders`, {
|
|
|
|
|
method: "POST", headers: { authorization: "Bearer request-only-secret", "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "BS-GZ-006", scope: "server-ops", action: "read-navigation-map", recipient_fingerprint: fingerprint }),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
await fetch(`${base}${approvalPath}`, { method: "POST" });
|
|
|
|
|
const claimed = await fetch(`${base}/api/workorders/${order.workorder_id}/claim`, { method: "POST", headers: { authorization: `Bearer ${order.claim_token}` } });
|
|
|
|
|
const session = await claimed.json();
|
|
|
|
|
const switched = await fetch(`${base}/api/session/verify`, {
|
|
|
|
|
method: "POST", headers: { authorization: `Bearer ${session.session_token}`, "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "ICE-GL-ZY001", target: "JD-FD-PRIMARY", scope: "server-ops", action: "read-navigation-map" }),
|
|
|
|
|
});
|
|
|
|
|
assert.equal(switched.status, 403);
|
|
|
|
|
assert.equal((await switched.json()).error, "target_mismatch");
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test("server policy selects a member mailbox by persona target and scope", async () => {
|
|
|
|
|
await withServer(async ({ base, mail }) => {
|
|
|
|
|
const requested = await fetch(`${base}/api/public/workorders`, {
|
|
|
|
|
method: "POST", headers: { "content-type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ persona_id: "AWEN-TECH", target: "JD-FD-PRIMARY", scope: "server-ops", action: "read-navigation-map" }),
|
|
|
|
|
});
|
|
|
|
|
const order = await requested.json();
|
|
|
|
|
const requestPath = new URL(order.request_url).pathname.replace("/authz", "");
|
2026-07-29 23:37:26 +08:00
|
|
|
assert.equal((await fetch(`${base}${requestPath}`, ownerForm("awen@example.invalid"))).status, 200);
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.equal(mail[0].to, "awen@example.invalid");
|
|
|
|
|
}, { approvers: [
|
|
|
|
|
{ id: "owner", email: "owner@example.invalid", default: true, persona_ids: ["ICE-GL-ZY001"], targets: ["*"], scopes: ["*"] },
|
|
|
|
|
{ id: "awen", email: "awen@example.invalid", default: false, persona_ids: ["AWEN-TECH"], targets: ["JD-FD-PRIMARY"], scopes: ["server-ops"] },
|
|
|
|
|
] });
|
|
|
|
|
});
|