diff --git a/src/domain/work-orders/api/work-order-board-documents-api.ts b/src/domain/work-orders/api/work-order-board-documents-api.ts index 99c060fd..fbd7bf77 100644 --- a/src/domain/work-orders/api/work-order-board-documents-api.ts +++ b/src/domain/work-orders/api/work-order-board-documents-api.ts @@ -216,10 +216,14 @@ export const workOrderBoardDocumentsApi = { workOrderId: string | number, mediaId: string | number, ): Promise => { + // No `credentials: "include"`: this endpoint authenticates with the bearer token the ky + // beforeRequest hook attaches, not cookies. In credentialed mode the browser rejects the + // API's `Access-Control-Allow-Origin: *` outright, so the fetch would throw and the document + // would never open. const response = await apiRequestRaw( "get", API_PATHS.workOrder.mediaContent(workOrderId, mediaId), - { credentials: "include", throwHttpErrors: false }, + { throwHttpErrors: false }, "workOrderBoardDocumentsApi.getMediaContent", ); diff --git a/src/test/domain/work-orders/api/work-orders-api.test.ts b/src/test/domain/work-orders/api/work-orders-api.test.ts index e295ed9d..cbfabfa9 100644 --- a/src/test/domain/work-orders/api/work-orders-api.test.ts +++ b/src/test/domain/work-orders/api/work-orders-api.test.ts @@ -1022,8 +1022,14 @@ describe("workOrdersApi.getMediaContent", () => { expect(result).toBe(blob); expect(apiGetFn).toHaveBeenCalledWith( API_PATHS.workOrder.mediaContent(10, 12), - expect.objectContaining({ credentials: "include", throwHttpErrors: false }), + expect.objectContaining({ throwHttpErrors: false }), ); + // Regression guard (SH-382): a credentialed cross-origin fetch is rejected by the browser + // against the API's `Access-Control-Allow-Origin: *`, so the content request must not opt + // into credentials mode — otherwise the document never opens. JSDOM cannot enforce CORS, so + // this asserts the request shape rather than reproducing the block. + const [, options] = apiGetFn.mock.calls[0] as [string, Record]; + expect(options).not.toHaveProperty("credentials"); }); it("throws ApiError on 404 without inventing a filename", async () => {