fix(sso): enforce root wildcard cookie domain (.atyg.org) across all auth, join, and pass routes
This commit is contained in:
parent
9c2aa73fdd
commit
267ed4b17b
@ -201,17 +201,28 @@ export async function isSessionAdmin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes root cookie domain from RP_ID or host.
|
* Computes root wildcard cookie domain from RP_ID, COOKIE_DOMAIN, or host.
|
||||||
|
* E.g., "auth.atyg.org" -> ".atyg.org" (allowing SSO across *.atyg.org).
|
||||||
*/
|
*/
|
||||||
export function getCookieDomain(customRpId?: string): string {
|
export function getCookieDomain(customRpId?: string): string | undefined {
|
||||||
const rpId = customRpId || Deno.env.get("RP_ID");
|
const envDomain = Deno.env.get("COOKIE_DOMAIN");
|
||||||
if (rpId) {
|
if (envDomain) {
|
||||||
if (rpId.includes("localhost") || rpId.includes("127.0.0.1")) {
|
return envDomain.startsWith(".") ? envDomain : `.${envDomain}`;
|
||||||
return rpId;
|
|
||||||
}
|
}
|
||||||
return `.${rpId}`;
|
const targetId = customRpId || Deno.env.get("RP_ID") || "";
|
||||||
|
if (
|
||||||
|
!targetId ||
|
||||||
|
!targetId.includes(".") ||
|
||||||
|
targetId.includes("localhost") ||
|
||||||
|
targetId.includes("127.0.0.1")
|
||||||
|
) {
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
return "";
|
const parts = targetId.split(".").filter(Boolean);
|
||||||
|
if (parts.length >= 2) {
|
||||||
|
return `.${parts.slice(-2).join(".")}`;
|
||||||
|
}
|
||||||
|
return `.${targetId}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import type { AuthenticationResponseJSON } from "jsr:@simplewebauthn/server@13";
|
|||||||
|
|
||||||
import { valkey } from "../../core/valkey.ts";
|
import { valkey } from "../../core/valkey.ts";
|
||||||
import { getClientIp, publicRateLimiter } from "../../core/middleware.ts";
|
import { getClientIp, publicRateLimiter } from "../../core/middleware.ts";
|
||||||
import { extractAllSessionIds } from "../../core/session.ts";
|
import { extractAllSessionIds, getCookieDomain } from "../../core/session.ts";
|
||||||
import { auditWrapper } from "../../core/audit.ts";
|
import { auditWrapper } from "../../core/audit.ts";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -30,22 +30,6 @@ const rpID = Deno.env.get("RP_ID") ||
|
|||||||
const origin = Deno.env.get("ORIGIN") ||
|
const origin = Deno.env.get("ORIGIN") ||
|
||||||
(import.meta.main ? undefined : "http://localhost");
|
(import.meta.main ? undefined : "http://localhost");
|
||||||
|
|
||||||
function getCookieDomain(customRpId?: string): string | undefined {
|
|
||||||
const envDomain = Deno.env.get("COOKIE_DOMAIN");
|
|
||||||
if (envDomain) {
|
|
||||||
return envDomain.startsWith(".") ? envDomain : `.${envDomain}`;
|
|
||||||
}
|
|
||||||
const targetId = customRpId || Deno.env.get("RP_ID") || "";
|
|
||||||
if (!targetId || !targetId.includes(".") || targetId === "localhost") {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const parts = targetId.split(".").filter(Boolean);
|
|
||||||
if (parts.length >= 2) {
|
|
||||||
return `.${parts.slice(-2).join(".")}`;
|
|
||||||
}
|
|
||||||
return `.${targetId}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI Route
|
// UI Route
|
||||||
loginRoutes.get("/login", (c) => {
|
loginRoutes.get("/login", (c) => {
|
||||||
return c.html(LoginPageFragment());
|
return c.html(LoginPageFragment());
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import type { RegistrationResponseJSON } from "jsr:@simplewebauthn/server@13";
|
|||||||
import { valkey } from "../../core/valkey.ts";
|
import { valkey } from "../../core/valkey.ts";
|
||||||
import { getClientIp, publicRateLimiter } from "../../core/middleware.ts";
|
import { getClientIp, publicRateLimiter } from "../../core/middleware.ts";
|
||||||
import { auditWrapper } from "../../core/audit.ts";
|
import { auditWrapper } from "../../core/audit.ts";
|
||||||
|
import { getCookieDomain } from "../../core/session.ts";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
createPasskey,
|
createPasskey,
|
||||||
@ -28,22 +29,6 @@ const rpID = Deno.env.get("RP_ID") ||
|
|||||||
const origin = Deno.env.get("ORIGIN") ||
|
const origin = Deno.env.get("ORIGIN") ||
|
||||||
(import.meta.main ? undefined : "http://localhost");
|
(import.meta.main ? undefined : "http://localhost");
|
||||||
|
|
||||||
function getCookieDomain(customRpId?: string): string | undefined {
|
|
||||||
const envDomain = Deno.env.get("COOKIE_DOMAIN");
|
|
||||||
if (envDomain) {
|
|
||||||
return envDomain.startsWith(".") ? envDomain : `.${envDomain}`;
|
|
||||||
}
|
|
||||||
const targetId = customRpId || Deno.env.get("RP_ID") || "";
|
|
||||||
if (!targetId || !targetId.includes(".") || targetId === "localhost") {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
const parts = targetId.split(".").filter(Boolean);
|
|
||||||
if (parts.length >= 2) {
|
|
||||||
return `.${parts.slice(-2).join(".")}`;
|
|
||||||
}
|
|
||||||
return `.${targetId}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI Route
|
// UI Route
|
||||||
registerRoutes.get("/register", (c) => {
|
registerRoutes.get("/register", (c) => {
|
||||||
const code = c.req.query("code") || "";
|
const code = c.req.query("code") || "";
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user