Files
ThothII/backend/test/auth-pi-management-local.test.ts
T

71 lines
2.8 KiB
TypeScript

import { expect, test, vi } from "vitest";
import type { PiManagementService } from "../src/pi/management.js";
import { createLocalAuthFixture } from "./auth-test-fixtures.js";
function fakeService(): PiManagementService {
return {
status: vi.fn(async () => ({ ready: true })),
options: vi.fn(async () => ({ providers: [], models: [], reasoning: [], checkedAt: "2026-08-17T00:00:00.000Z" })),
configure: vi.fn(async (value) => ({ ...value, updatedAt: "2026-08-17T00:00:00.000Z" })),
test: vi.fn(async () => ({ ready: true, checkedAt: "2026-08-17T00:00:00.000Z" })),
logs: vi.fn(async () => ({ lines: [] })),
};
}
test("a local HTTPS cookie session authorizes Pi writes through an untrusted internal HTTP hop", async () => {
const service = fakeService();
const fixture = await createLocalAuthFixture(
{ piManagement: service },
{ publicUrl: "HTTPS://thothii.example.test" },
);
try {
// The fixture performs the real login and /me request through the production hooks.
expect(fixture.loginStatus).toBe(200);
expect(fixture.meStatus).toBe(200);
expect(fixture.publicUrl).toBe("HTTPS://thothii.example.test");
const proxyHeaders = fixture.sessionHeaders({ host: "127.0.0.1:8080" });
const configured = await fixture.app.inject({
method: "PUT",
url: "/pi-management/config",
headers: proxyHeaders,
payload: { provider: "zai", model: "glm-5.2", reasoning: "high" },
});
const smoke = await fixture.app.inject({
method: "POST",
url: "/pi-management/test",
headers: proxyHeaders,
});
expect(configured.statusCode).toBe(200);
expect(smoke.statusCode).toBe(200);
expect(service.configure).toHaveBeenCalledTimes(1);
expect(service.test).toHaveBeenCalledTimes(1);
fixture.resetDownstreamHits();
vi.mocked(service.configure).mockClear();
vi.mocked(service.test).mockClear();
const wrongOrigin = await fixture.app.inject({
method: "PUT",
url: "/pi-management/config",
headers: fixture.sessionHeaders({ host: "127.0.0.1:8080", origin: "https://evil.example" }),
payload: { provider: "zai", model: "glm-5.2", reasoning: "high" },
});
const wrongCsrf = await fixture.app.inject({
method: "POST",
url: "/pi-management/test",
headers: fixture.sessionHeaders({ host: "127.0.0.1:8080", "x-thothii-csrf": "wrong" }),
});
for (const response of [wrongOrigin, wrongCsrf]) {
expect(response.statusCode).toBe(403);
expect(response.json()).toEqual({ code: "csrf_failed", error: "Request origin validation failed" });
}
expect(fixture.downstreamHits()).toBe(0);
expect(service.configure).not.toHaveBeenCalled();
expect(service.test).not.toHaveBeenCalled();
} finally {
await fixture.close();
}
});