"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 { SessionManager } = require("./session-manager"); const zhulan = { pid: "ICE-GL-ZL-001", name: "铸澜" }; test("one approval creates a reusable bounded session", () => { const m = new SessionManager({ absoluteTtl: 100, idleTtl: 20 }); const { token } = m.create(zhulan, "BS-SG-001", ["code-repo"], ["sync-status"], 10); assert.equal(m.verify(token, zhulan, "BS-SG-001", "code-repo", "sync-status", 11).ok, true); assert.equal(m.verify(token, zhulan, "BS-SG-001", "code-repo", "sync-status", 12).ok, true); }); test("session is bound to identity server and scope", () => { const m = new SessionManager(); const { token } = m.create(zhulan, "BS-SG-001", ["code-repo"], ["sync-status"], 10); assert.equal(m.verify(token, { pid: "ICE-GL-ZY001" }, "BS-SG-001", "code-repo", "sync-status", 11).ok, false); assert.equal(m.verify(token, zhulan, "OTHER", "code-repo", "sync-status", 11).ok, false); assert.equal(m.verify(token, zhulan, "BS-SG-001", "system-arch", "sync-status", 11).ok, false); }); test("end signal revokes immediately", () => { const m = new SessionManager(); const { token } = m.create(zhulan, "BS-SG-001", ["code-repo"], ["sync-status"], 10); assert.equal(m.end(token, zhulan), true); assert.equal(m.verify(token, zhulan, "BS-SG-001", "code-repo", "sync-status", 11).ok, false); }); test("session survives process reload without persisting plaintext token", () => { const dir = fs.mkdtempSync(path.join(os.tmpdir(), "gatekeeper-session-")); const stateFile = path.join(dir, "sessions.json"); try { const now = Date.now() / 1000; const first = new SessionManager({ absoluteTtl: 100, idleTtl: 20, stateFile }); const created = first.create(zhulan, "BS-SG-001", ["code-repo"], ["sync-status"], now); const onDisk = fs.readFileSync(stateFile, "utf8"); assert.equal(onDisk.includes(created.token), false); const reloaded = new SessionManager({ absoluteTtl: 100, idleTtl: 20, stateFile }); assert.equal(reloaded.verify(created.token, zhulan, "BS-SG-001", "code-repo", "sync-status", now + 1).ok, true); } finally { fs.rmSync(dir, { recursive: true, force: true }); } });