Compare commits

...

5 commits

Author SHA1 Message Date
Alexandre Brandizzi
7fdf85fc47
Merge branch 'main' into feat/ab/sh-304-services-registry-ui 2026-09-18 19:21:21 -03:00
Alexandre Brandizzi
9bba6402e0
Merge pull request #230 from Sea-Haven-Industries/feat/ab/sh-382-extra-doc-view
fix(work-orders): view extra documents (SH-382)
2026-09-18 19:20:59 -03:00
Alexandre Brandizzi
744d7af7bb
Merge branch 'main' into feat/ab/sh-382-extra-doc-view 2026-09-18 19:09:47 -03:00
Alexandre Brandizzi
e1b03dc151
Merge branch 'main' into feat/ab/sh-382-extra-doc-view 2026-09-18 18:57:56 -03:00
Alexandre Brandizzi
1a7a4ba58f fix(work-orders): open extra documents without credentialed CORS (SH-382)
Viewing a work-order extra document called the authorized content endpoint
with `credentials: "include"`. The API replies `Access-Control-Allow-Origin: *`,
and in credentialed mode the browser rejects a wildcard origin outright, so the
fetch threw, `openExtraDocContent` fell into its catch, closed the tab and
toasted "Unable to open this document." — QA CT-03.

The endpoint authenticates with the bearer token the ky beforeRequest hook
attaches, not cookies, so credentials mode was dead weight. List, upload and
delete never set it, which is why only viewing failed. Drop the option and
guard the request shape in a test (JSDOM cannot enforce CORS).
2026-09-18 16:35:01 -03:00
2 changed files with 12 additions and 2 deletions

View file

@ -216,10 +216,14 @@ export const workOrderBoardDocumentsApi = {
workOrderId: string | number,
mediaId: string | number,
): Promise<Blob> => {
// 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",
);

View file

@ -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<string, unknown>];
expect(options).not.toHaveProperty("credentials");
});
it("throws ApiError on 404 without inventing a filename", async () => {