2026-07-24 10:39:10 +08:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
const test = require("node:test");
|
|
|
|
|
const assert = require("node:assert/strict");
|
|
|
|
|
const fs = require("node:fs");
|
|
|
|
|
const os = require("node:os");
|
|
|
|
|
const path = require("node:path");
|
|
|
|
|
const { createApp } = require("./server");
|
|
|
|
|
const { authorizeRepoPush } = require("./authorize-repo-push");
|
|
|
|
|
|
2026-07-26 18:13:41 +08:00
|
|
|
function response(status, body) {
|
|
|
|
|
return new Response(JSON.stringify(body), {
|
|
|
|
|
status,
|
|
|
|
|
headers: { "content-type": "application/json" },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-07-26 15:26:21 +08:00
|
|
|
test("repo-push helper stops with a server receipt when no safe transport is deployed", async () => {
|
2026-07-24 10:39:10 +08:00
|
|
|
const mail = [];
|
|
|
|
|
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "lake-lamp-repo-push-"));
|
|
|
|
|
const mapGate = {
|
|
|
|
|
read: target => ({ hash: `map-${target}`, data: { node_id: target } }),
|
|
|
|
|
ack: () => ({ ok: true }),
|
|
|
|
|
verify: () => ({ ok: true }),
|
|
|
|
|
};
|
|
|
|
|
const app = createApp({
|
|
|
|
|
ownerEmail: "owner@example.invalid",
|
|
|
|
|
publicBaseUrl: "https://example.invalid/authz",
|
|
|
|
|
targets: ["JD-FD-PRIMARY"],
|
|
|
|
|
stateFile: "",
|
|
|
|
|
repoGrantDir: directory,
|
|
|
|
|
mapGate,
|
|
|
|
|
sendEmail: async message => { mail.push(message); return true; },
|
|
|
|
|
});
|
|
|
|
|
await new Promise(resolve => app.listen(0, "127.0.0.1", resolve));
|
|
|
|
|
const base = `http://127.0.0.1:${app.address().port}`;
|
|
|
|
|
const lines = [];
|
|
|
|
|
try {
|
|
|
|
|
const grantPromise = authorizeRepoPush({
|
|
|
|
|
url: base,
|
|
|
|
|
persona: "ICE-GL-ZY001",
|
|
|
|
|
name: "铸渊",
|
|
|
|
|
repo: "bingshuo/fifth-domain",
|
|
|
|
|
poll: 1,
|
|
|
|
|
}, {
|
|
|
|
|
output: line => lines.push(line),
|
|
|
|
|
sleep: milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds)),
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
while (!lines.some(line => line.startsWith("REQUEST_URL="))) await new Promise(resolve => setTimeout(resolve, 1));
|
|
|
|
|
const requestUrl = lines.find(line => line.startsWith("REQUEST_URL=")).slice("REQUEST_URL=".length);
|
|
|
|
|
const requestPath = new URL(requestUrl).pathname.replace("/authz", "");
|
|
|
|
|
assert.equal((await fetch(`${base}${requestPath}`, { method: "POST" })).status, 200);
|
|
|
|
|
assert.equal(mail.length, 1);
|
|
|
|
|
const approvalPath = new URL(mail[0].approvalUrl).pathname.replace("/authz", "");
|
|
|
|
|
assert.equal((await fetch(`${base}${approvalPath}`, { method: "POST" })).status, 200);
|
|
|
|
|
|
2026-07-26 15:26:21 +08:00
|
|
|
await assert.rejects(grantPromise, /repo_push_transport_unavailable/);
|
|
|
|
|
assert.ok(lines.some(line => line.startsWith("[LL-REPO-PUSH-TRANSPORT-BLOCKED]")));
|
2026-07-24 10:39:10 +08:00
|
|
|
assert.ok(fs.existsSync(path.join(directory, "bingshuo__fifth-domain.json")));
|
|
|
|
|
} finally {
|
|
|
|
|
await new Promise(resolve => app.close(resolve));
|
|
|
|
|
fs.rmSync(directory, { recursive: true, force: true });
|
|
|
|
|
}
|
|
|
|
|
});
|
2026-07-26 18:13:41 +08:00
|
|
|
|
|
|
|
|
test("repo-push helper fails closed when an older server omits transport state", async () => {
|
|
|
|
|
const calls = [];
|
|
|
|
|
const grantPromise = authorizeRepoPush({
|
|
|
|
|
url: "https://example.invalid/authz",
|
|
|
|
|
persona: "ICE-GL-ZY001",
|
|
|
|
|
repo: "bingshuo/guanghu-ice-heart",
|
|
|
|
|
poll: 1,
|
|
|
|
|
}, {
|
|
|
|
|
sleep: async () => {},
|
|
|
|
|
output: line => calls.push(line),
|
|
|
|
|
fetch: async url => {
|
|
|
|
|
if (url.endsWith("/api/public/workorders")) {
|
|
|
|
|
return response(200, {
|
|
|
|
|
request_url: "https://example.invalid/authz/request/opaque",
|
|
|
|
|
workorder_id: "workorder",
|
|
|
|
|
claim_token: "claim",
|
|
|
|
|
expires_in: 60,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
if (url.endsWith("/claim")) return response(200, { session_token: "session" });
|
|
|
|
|
if (url.endsWith("/api/navigation-map/read")) return response(200, { map_hash: "map" });
|
|
|
|
|
if (url.endsWith("/api/navigation-map/ack")) return response(200, { ok: true });
|
|
|
|
|
if (url.endsWith("/api/repo-push/grant")) {
|
|
|
|
|
return response(200, {
|
|
|
|
|
ok: true,
|
|
|
|
|
repo: "bingshuo/guanghu-ice-heart",
|
|
|
|
|
receipt: { diagnostic_code: "repo_push_transport_unavailable" },
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
throw new Error(`unexpected URL: ${url}`);
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await assert.rejects(grantPromise, /repo_push_transport_unavailable/);
|
|
|
|
|
assert.ok(calls.some(line => line.includes("LL-REPO-PUSH-TRANSPORT-BLOCKED")));
|
|
|
|
|
assert.ok(calls.some(line => line.includes("禁止重试裸 git push")));
|
|
|
|
|
});
|