58 lines
2.1 KiB
TypeScript
58 lines
2.1 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 })),
|
|
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 the Pi smoke check 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 smoke = await fixture.app.inject({
|
|
method: "POST",
|
|
url: "/pi-management/test",
|
|
headers: proxyHeaders,
|
|
});
|
|
|
|
expect(smoke.statusCode).toBe(200);
|
|
expect(service.test).toHaveBeenCalledTimes(1);
|
|
|
|
fixture.resetDownstreamHits();
|
|
vi.mocked(service.test).mockClear();
|
|
const wrongOrigin = await fixture.app.inject({
|
|
method: "POST",
|
|
url: "/pi-management/test",
|
|
headers: fixture.sessionHeaders({ host: "127.0.0.1:8080", origin: "https://evil.example" }),
|
|
});
|
|
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.test).not.toHaveBeenCalled();
|
|
} finally {
|
|
await fixture.close();
|
|
}
|
|
});
|