22 lines
1.5 KiB
TypeScript
22 lines
1.5 KiB
TypeScript
import { CmsConnection } from "@agent-studio/harness";
|
|
import { describe, expect, it } from "vitest";
|
|
import { createTestApp } from "./test-app.js";
|
|
|
|
describe("CMS API safety", () => {
|
|
it("exposes only redacted connection status and rejects cross-origin login before contacting CMS", async () => {
|
|
const cms = new CmsConnection({ publishableKey: "sb_publishable_test", fetch: () => Promise.reject(new Error("Must not reach CMS")) });
|
|
const { app } = createTestApp({ cmsForSession: () => cms });
|
|
try {
|
|
const status = await app.inject({ method: "GET", url: "/api/sessions/ses_1/cms/connection" });
|
|
expect(status.statusCode).toBe(200);
|
|
expect(status.json()).toMatchObject({ connection: { connected: false, configured: true } });
|
|
expect(status.headers["cache-control"]).toBe("no-store");
|
|
const denied = await app.inject({ method: "POST", url: "/api/sessions/ses_1/cms/connection", headers: { origin: "https://attacker.example", "sec-fetch-site": "cross-site" }, payload: { email: "fixture@example.com", password: "never-expose" } });
|
|
expect(denied.statusCode).toBe(403);
|
|
expect(denied.body).not.toContain("never-expose");
|
|
expect((await app.inject({ method: "GET", url: "/api/sessions/ses_missing/cms/connection" })).statusCode).toBe(404);
|
|
expect((await app.inject({ method: "GET", url: "/api/sessions/ses_1/cms/dramas" })).json()).toMatchObject({ error: { code: "CMS_LOGIN_REQUIRED" } });
|
|
} finally { await app.close(); }
|
|
});
|
|
});
|