diff --git a/server/src/__tests__/companies-route-path-guard.test.ts b/server/src/__tests__/companies-route-path-guard.test.ts new file mode 100644 index 00000000..ede6d024 --- /dev/null +++ b/server/src/__tests__/companies-route-path-guard.test.ts @@ -0,0 +1,49 @@ +import express from "express"; +import request from "supertest"; +import { describe, expect, it, vi } from "vitest"; +import { companyRoutes } from "../routes/companies.js"; + +vi.mock("../services/index.js", () => ({ + companyService: () => ({ + list: vi.fn(), + stats: vi.fn(), + getById: vi.fn(), + create: vi.fn(), + update: vi.fn(), + archive: vi.fn(), + remove: vi.fn(), + }), + companyPortabilityService: () => ({ + exportBundle: vi.fn(), + previewImport: vi.fn(), + importBundle: vi.fn(), + }), + accessService: () => ({ + canUser: vi.fn(), + ensureMembership: vi.fn(), + }), + logActivity: vi.fn(), +})); + +describe("company routes malformed issue path guard", () => { + it("returns a clear error when companyId is missing for issues list path", async () => { + const app = express(); + app.use((req, _res, next) => { + (req as any).actor = { + type: "agent", + agentId: "agent-1", + companyId: "company-1", + source: "agent_key", + }; + next(); + }); + app.use("/api/companies", companyRoutes({} as any)); + + const res = await request(app).get("/api/companies/issues"); + + expect(res.status).toBe(400); + expect(res.body).toEqual({ + error: "Missing companyId in path. Use /api/companies/{companyId}/issues.", + }); + }); +}); diff --git a/server/src/routes/companies.ts b/server/src/routes/companies.ts index e0505fbb..f034e402 100644 --- a/server/src/routes/companies.ts +++ b/server/src/routes/companies.ts @@ -43,6 +43,13 @@ export function companyRoutes(db: Db) { res.json(filtered); }); + // Common malformed path when companyId is empty in "/api/companies/{companyId}/issues". + router.get("/issues", (_req, res) => { + res.status(400).json({ + error: "Missing companyId in path. Use /api/companies/{companyId}/issues.", + }); + }); + router.get("/:companyId", async (req, res) => { assertBoard(req); const companyId = req.params.companyId as string;