fix(api): wrap invoice API responses with cors() helper

The order-action / order-block UI extensions are hosted on
extensions.shopifycdn.com and call our app via fetch(). Without CORS
headers the browser blocked the response. authenticate.admin already
returns a cors helper and handles OPTIONS preflight - wrap every
Response with it.
This commit is contained in:
Gerhard Scheikl
2026-05-08 15:12:52 +02:00
parent 58cfc30cd7
commit a67fc0767e
+12 -10
View File
@@ -12,7 +12,7 @@ import { cancelAndReissue } from "../services/invoice/cancelAndReissue.server";
* normalises it. * normalises it.
*/ */
export const loader = async ({ request, params }: LoaderFunctionArgs) => { export const loader = async ({ request, params }: LoaderFunctionArgs) => {
const { session } = await authenticate.admin(request); const { session, cors } = await authenticate.admin(request);
const orderId = requireOrderId(params); const orderId = requireOrderId(params);
const orderGid = orderId.startsWith("gid://") const orderGid = orderId.startsWith("gid://")
? orderId ? orderId
@@ -24,16 +24,18 @@ export const loader = async ({ request, params }: LoaderFunctionArgs) => {
}); });
const latest = invoices.find((i) => i.kind === "invoice" && !i.cancelledAt); const latest = invoices.find((i) => i.kind === "invoice" && !i.cancelledAt);
return { return cors(
latest: latest ? serialise(latest) : null, Response.json({
history: invoices.map(serialise), latest: latest ? serialise(latest) : null,
}; history: invoices.map(serialise),
}),
);
}; };
export const action = async ({ request, params }: ActionFunctionArgs) => { export const action = async ({ request, params }: ActionFunctionArgs) => {
const { admin, session } = await authenticate.admin(request); const { admin, session, cors } = await authenticate.admin(request);
if (request.method !== "POST") { if (request.method !== "POST") {
return new Response("Method Not Allowed", { status: 405 }); return cors(new Response("Method Not Allowed", { status: 405 }));
} }
const orderId = requireOrderId(params); const orderId = requireOrderId(params);
const url = new URL(request.url); const url = new URL(request.url);
@@ -55,7 +57,7 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
admin, admin,
orderId, orderId,
}); });
return { ok: true, op, ...result }; return cors(Response.json({ ok: true, op, ...result }));
} }
const result = await generateInvoice({ const result = await generateInvoice({
@@ -63,11 +65,11 @@ export const action = async ({ request, params }: ActionFunctionArgs) => {
admin, admin,
orderId, orderId,
}); });
return { ok: true, op: "generate", ...result }; return cors(Response.json({ ok: true, op: "generate", ...result }));
} catch (err) { } catch (err) {
const message = err instanceof Error ? err.message : String(err); const message = err instanceof Error ? err.message : String(err);
console.error("invoice action failed:", err); console.error("invoice action failed:", err);
return Response.json({ ok: false, error: message }, { status: 400 }); return cors(Response.json({ ok: false, error: message }, { status: 400 }));
} }
}; };