Files

44 lines
1.3 KiB
TypeScript

/** Use an explicit external origin, rather than trusting proxy-supplied schemes. */
export function studioRequest(
request: Request,
publicOrigin = process.env.STUDIO_PUBLIC_ORIGIN ??
"https://component.wrnexusjs.dev",
): Request | Response {
const incoming = new URL(request.url);
const configured = new URL(publicOrigin);
if (
configured.protocol !== "https:" ||
configured.username ||
configured.password ||
configured.pathname !== "/" ||
configured.search ||
configured.hash
)
throw Error(
"STUDIO_PUBLIC_ORIGIN must be an HTTPS origin without a path or credentials.",
);
const origin = request.headers.get("origin");
const loopback = ["localhost", "127.0.0.1", "[::1]"].includes(
incoming.hostname,
);
const expected =
loopback && (!origin || origin === incoming.origin)
? incoming.origin
: configured.origin;
if (origin && origin !== expected)
return Response.json(
{ error: "Same-origin requests only." },
{ status: 403, headers: { "cache-control": "no-store" } },
);
const normalized = new Request(
new URL(incoming.pathname + incoming.search, expected),
request,
);
normalized.headers.set(
"x-forwarded-proto",
new URL(expected).protocol.slice(0, -1),
);
normalized.headers.set("host", new URL(expected).host);
return normalized;
}