import { expect, test, vi } from "vitest"; import { buildApp } from "../src/app.js"; import { loadConfig } from "../src/config.js"; import type { PiManagementService } from "../src/pi/management.js"; import { piManagementRoutes } from "../src/routes/pi-management.js"; void piManagementRoutes; function fakeService(): PiManagementService { return { status: vi.fn(async () => ({ version: "0.80.3", ready: true, credentials: "present", config: { provider: "zai", model: "glm-5.2", reasoning: "medium" }, checkedAt: "2026-08-05T10:00:00.000Z", })), test: vi.fn(async () => ({ ready: true, checkedAt: "2026-08-05T10:00:00.000Z" })), logs: vi.fn(async () => ({ lines: ["Pi smoke check succeeded"], checkedAt: "2026-08-05T10:00:00.000Z" })), }; } function appWith(service: PiManagementService, env: Record = {}) { return buildApp(loadConfig({ THT_HARNESS_DIR: "../harness", ...env }), { thtRunner: {} as any, piManagement: service, }); } const adminHeaders = { "x-thoth-principal-issuer": "portal", "x-thoth-principal-subject": "operator", "x-thoth-is-admin": "1", }; const exposedServerEnv = { AUTH_MODE: "upstream", THOTH_PUBLIC_EXPOSURE: "true", THT_SESSION_STORAGE: "postgres", THT_SESSION_DB_HOST: "db.example.invalid", THT_SESSION_DB_NAME: "thoth_sessions", THT_SESSION_RUNTIME_USER: "thoth_runtime", THT_SESSION_RUNTIME_PASSWORD_FILE: "/run/secrets/session-password", THT_SESSION_DB_SSLMODE: "verify-full", THT_SESSION_DB_SSLROOTCERT: "/run/secrets/session-ca.pem", }; // Catches a server deployment that lets an ordinary authenticated user inspect or mutate // installation-wide Pi configuration without the trusted upstream admin claim. test("exposed upstream deployments reject Pi Management without a trusted admin identity", async () => { const service = fakeService(); const app = appWith(service, exposedServerEnv); try { const response = await app.inject({ method: "GET", url: "/pi-management/status", headers: { ...adminHeaders, "x-thoth-is-admin": "0" }, }); expect(response.statusCode).toBe(403); expect(response.json()).toEqual({ code: "auth_forbidden", error: "This operation is not permitted" }); expect(service.status).not.toHaveBeenCalled(); } finally { await app.close(); } }); test("Pi Management test requires pi.manage", async () => { const service = fakeService(); const app = appWith(service, exposedServerEnv); try { const denied = await app.inject({ method: "POST", url: "/pi-management/test", headers: { ...adminHeaders, "x-thoth-is-admin": "0" }, }); const allowed = await app.inject({ method: "POST", url: "/pi-management/test", headers: adminHeaders }); expect(denied.statusCode).toBe(403); expect(denied.json()).toEqual({ code: "auth_forbidden", error: "This operation is not permitted" }); expect(allowed.statusCode).toBe(200); } finally { await app.close(); } }); // Catches an accidental privilege regression that blocks safe loopback-only installations or // returns fields beyond the sanctioned Pi Management status contract. test("loopback-only AUTH_MODE=none may read the sanitized Pi status", async () => { const app = appWith(fakeService()); try { const response = await app.inject({ method: "GET", url: "/pi-management/status" }); expect(response.statusCode).toBe(200); expect(response.json()).toEqual({ version: "0.80.3", ready: true, credentials: "present", config: { provider: "zai", model: "glm-5.2", reasoning: "medium" }, checkedAt: "2026-08-05T10:00:00.000Z", }); } finally { await app.close(); } }); // A local implicit administrator has pi.manage, but a browser origin still cannot borrow that // authority to trigger provider work. test("loopback-only management rejects cross-origin writes for its local administrator", async () => { const service = fakeService(); const app = appWith(service); try { const smoke = await app.inject({ method: "POST", url: "/pi-management/test", headers: { host: "127.0.0.1:8080", origin: "https://evil.example" }, }); expect(smoke.statusCode).toBe(403); expect(service.test).not.toHaveBeenCalled(); } finally { await app.close(); } }); // Catches an origin guard that also blocks the same-origin Docker frontend or non-browser local // lifecycle clients that do not send Origin. test("loopback-only management preserves same-origin and origin-less smoke checks", async () => { const service = fakeService(); const app = appWith(service); try { const sameOrigin = await app.inject({ method: "POST", url: "/pi-management/test", headers: { host: "127.0.0.1:8080", origin: "http://127.0.0.1:8080" }, }); const lifecycleClient = await app.inject({ method: "POST", url: "/pi-management/test" }); expect(sameOrigin.statusCode).toBe(200); expect(lifecycleClient.statusCode).toBe(200); } finally { await app.close(); } }); // Catches a regression that reintroduces a browser-writable provider/model source. test("trusted admins receive only status, smoke, and log endpoints", async () => { const service = fakeService(); const app = appWith(service, exposedServerEnv); try { const status = await app.inject({ method: "GET", url: "/pi-management/status", headers: adminHeaders }); const smoke = await app.inject({ method: "POST", url: "/pi-management/test", headers: adminHeaders }); const logs = await app.inject({ method: "GET", url: "/pi-management/logs", headers: adminHeaders }); expect(status.statusCode).toBe(200); expect(smoke.statusCode).toBe(200); expect(logs.statusCode).toBe(200); expect((await app.inject({ method: "GET", url: "/pi-management/options", headers: adminHeaders })).statusCode).toBe(404); expect((await app.inject({ method: "PUT", url: "/pi-management/config", headers: adminHeaders })).statusCode).toBe(404); expect(app.printRoutes()).not.toContain("update"); expect(app.printRoutes()).not.toContain("rollback"); } finally { await app.close(); } });