fix(session): clear invalid cookies on redirect and add cache-control headers to prevent 302 caching loops

This commit is contained in:
Tyler Gillispie 2026-08-24 15:57:02 -07:00
parent 0a46e2bdfc
commit 8babb8a46e
2 changed files with 87 additions and 0 deletions

View File

@ -366,6 +366,8 @@ app.post("/api/guests/sandbox", async (c) => {
const cookieDomain = getCookieDomain(rpID); const cookieDomain = getCookieDomain(rpID);
deleteCookie(c, "session_id", { path: "/" });
setCookie(c, "session_id", sessionId, { setCookie(c, "session_id", sessionId, {
domain: cookieDomain, domain: cookieDomain,
path: "/", path: "/",
@ -832,6 +834,9 @@ app.post("/api/login/verify", async (c) => {
const cookieDomain = getCookieDomain(rpID); const cookieDomain = getCookieDomain(rpID);
// Clear any existing host-only cookie that might shadow the wildcard domain cookie
deleteCookie(c, "session_id", { path: "/" });
setCookie(c, "session_id", sessionId, { setCookie(c, "session_id", sessionId, {
domain: cookieDomain, domain: cookieDomain,
path: "/", path: "/",

View File

@ -30,6 +30,7 @@ const uiApp: Hono = new Hono();
// Explicit Side Effect: Route rendering // Explicit Side Effect: Route rendering
uiApp.get("/", (c) => { uiApp.get("/", (c) => {
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
}); });
@ -99,6 +100,7 @@ uiApp.get("/logout", async (c) => {
if (safeRedirect) { if (safeRedirect) {
return c.redirect(`/login?redirect=${encodeURIComponent(safeRedirect)}`); return c.redirect(`/login?redirect=${encodeURIComponent(safeRedirect)}`);
} }
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
}); });
@ -123,6 +125,14 @@ uiApp.get("/register", (c) => {
uiApp.get("/dashboard", async (c) => { uiApp.get("/dashboard", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -152,6 +162,14 @@ uiApp.get("/dashboard", async (c) => {
uiApp.get("/dashboard/sessions", async (c) => { uiApp.get("/dashboard/sessions", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -172,6 +190,14 @@ uiApp.get("/dashboard/sessions", async (c) => {
uiApp.get("/dashboard/passkeys", async (c) => { uiApp.get("/dashboard/passkeys", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -194,6 +220,14 @@ uiApp.get("/admin", (c) => {
uiApp.get("/admin/users", async (c) => { uiApp.get("/admin/users", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -214,6 +248,14 @@ uiApp.get("/admin/users", async (c) => {
uiApp.get("/admin/apps", async (c) => { uiApp.get("/admin/apps", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -237,6 +279,14 @@ uiApp.get("/admin/apps", async (c) => {
uiApp.get("/admin/roles", async (c) => { uiApp.get("/admin/roles", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -263,6 +313,14 @@ uiApp.get("/admin/roles", async (c) => {
uiApp.get("/admin/invites", async (c) => { uiApp.get("/admin/invites", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -295,6 +353,14 @@ uiApp.get("/admin/invites", async (c) => {
uiApp.get("/admin/aaguid", async (c) => { uiApp.get("/admin/aaguid", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -315,6 +381,14 @@ uiApp.get("/admin/aaguid", async (c) => {
uiApp.get("/admin/users/:id", async (c) => { uiApp.get("/admin/users/:id", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }
@ -378,6 +452,14 @@ uiApp.get("/admin/users/:id", async (c) => {
uiApp.get("/admin/audit-logs", async (c) => { uiApp.get("/admin/audit-logs", async (c) => {
const auth = await getAuthenticatedUser(c); const auth = await getAuthenticatedUser(c);
if (!auth) { if (!auth) {
if (getCookie(c, "session_id")) {
deleteCookie(c, "session_id", { path: "/" }); // clear host cookie
deleteCookie(c, "session_id", {
domain: getCookieDomain(Deno.env.get("RP_ID")),
path: "/",
}); // clear domain cookie
}
c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0");
return c.redirect("/login"); return c.redirect("/login");
} }