feat: add helpers and improve workspace auth flows
This commit is contained in:
@@ -103,6 +103,35 @@ function timingSafeEqual(a: string, b: string): boolean {
|
||||
return diff === 0;
|
||||
}
|
||||
|
||||
/** Preserve an intentional verifier redirect while keeping other failures opaque. */
|
||||
export function forwardAuthFailure(res: Response, verifierUrl: string): Response {
|
||||
const location = res.headers.get("location");
|
||||
if (res.status >= 300 && res.status < 400 && location) {
|
||||
try {
|
||||
const redirect = new URL(location, verifierUrl);
|
||||
if (redirect.protocol === "http:" || redirect.protocol === "https:") {
|
||||
return new Response(null, { status: res.status, headers: { location: redirect.href } });
|
||||
}
|
||||
} catch {
|
||||
// Malformed or unsafe redirects fail closed below.
|
||||
}
|
||||
}
|
||||
return new Response("Unauthorized", { status: res.status === 200 ? 401 : res.status });
|
||||
}
|
||||
|
||||
/** Describe the original gateway request to a forward-auth verifier. */
|
||||
export function forwardAuthHeaders(req: Request): Headers {
|
||||
const original = new URL(req.url);
|
||||
return new Headers({
|
||||
cookie: req.headers.get("cookie") ?? "",
|
||||
authorization: req.headers.get("authorization") ?? "",
|
||||
"x-forwarded-host": req.headers.get("host") ?? original.host,
|
||||
"x-forwarded-proto": original.protocol.replace(":", ""),
|
||||
"x-original-method": req.method,
|
||||
"x-original-uri": `${original.pathname}${original.search}`,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforce a per-app auth policy. Returns a Response to block, or null to allow.
|
||||
* `ip` is the client address (for the IP allowlist).
|
||||
@@ -140,16 +169,10 @@ async function checkAuth(
|
||||
if (auth.forward) {
|
||||
try {
|
||||
const res = await fetch(auth.forward.url, {
|
||||
headers: {
|
||||
cookie: req.headers.get("cookie") ?? "",
|
||||
authorization: req.headers.get("authorization") ?? "",
|
||||
"x-forwarded-host": req.headers.get("host") ?? "",
|
||||
"x-original-uri": new URL(req.url).pathname,
|
||||
},
|
||||
headers: forwardAuthHeaders(req),
|
||||
redirect: "manual",
|
||||
});
|
||||
if (!res.ok)
|
||||
return new Response("Unauthorized", { status: res.status === 200 ? 401 : res.status });
|
||||
if (!res.ok) return forwardAuthFailure(res, auth.forward.url);
|
||||
} catch {
|
||||
return new Response("Auth service unavailable", { status: 503 });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user