From 4b78f70efde39291d5576ae0114ae7f82364d2e0 Mon Sep 17 00:00:00 2001 From: Tyler Gillispie Date: Mon, 24 Aug 2026 17:14:07 -0700 Subject: [PATCH] fix(auth): eliminate conflicting deleteCookie and add created_at to users table --- server/auth-session.ts | 2 +- server/db.ts | 4 +++- server/main.test.ts | 4 +++- server/main.ts | 15 ++++++++------- ui/components/AuthenticatedLayout.tsx | 2 +- ui/components/LoginPage.tsx | 2 +- ui/components/RegisterPage.tsx | 2 +- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/server/auth-session.ts b/server/auth-session.ts index 6eacead..37641ea 100644 --- a/server/auth-session.ts +++ b/server/auth-session.ts @@ -216,7 +216,7 @@ export async function isGlobalAdmin(userId: string): Promise { // Check 2: First registered user in system fallback const firstUser = await sqlWrapper.sql` - SELECT id FROM users ORDER BY created_at ASC LIMIT 1 + SELECT id FROM users ORDER BY created_at ASC NULLS LAST, username ASC LIMIT 1 `.then((res: any) => res[0]); if (firstUser && firstUser.id === userId) { diff --git a/server/db.ts b/server/db.ts index 35ed4c0..9bb4911 100644 --- a/server/db.ts +++ b/server/db.ts @@ -34,12 +34,14 @@ export async function initDb(): Promise { id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username TEXT UNIQUE NOT NULL, display_name TEXT, - account_status TEXT DEFAULT 'pending' + account_status TEXT DEFAULT 'pending', + created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); `; try { await sql`ALTER TABLE users ALTER COLUMN account_status SET DEFAULT 'pending'`; + await sql`ALTER TABLE users ADD COLUMN IF NOT EXISTS created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()`; } catch { // Ignore if unsupported } diff --git a/server/main.test.ts b/server/main.test.ts index 03504ca..d0aafe0 100644 --- a/server/main.test.ts +++ b/server/main.test.ts @@ -520,7 +520,9 @@ Deno.test("Tier 1 & 2: POST /api/guests/sandbox - Creates guest session", async Deno.test("Logout Return-Path Validation", async (t) => { await t.step("GET /logout preserves valid redirect", async () => { - const req = new Request("http://localhost/logout?redirect=https://ed-droid.atyg.org/"); + const req = new Request( + "http://localhost/logout?redirect=https://ed-droid.atyg.org/", + ); const res = await app.fetch(req); assertEquals(res.status, 302); assertEquals( diff --git a/server/main.ts b/server/main.ts index 13cae72..ccb642b 100644 --- a/server/main.ts +++ b/server/main.ts @@ -366,8 +366,6 @@ app.post("/api/guests/sandbox", async (c) => { const cookieDomain = getCookieDomain(rpID); - deleteCookie(c, "session_id", { path: "/" }); - setCookie(c, "session_id", sessionId, { domain: cookieDomain, path: "/", @@ -834,9 +832,6 @@ app.post("/api/login/verify", async (c) => { 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, { domain: cookieDomain, path: "/", @@ -1129,7 +1124,10 @@ app.get("/api/forward-auth", async (c) => { // If a browser is requesting a webpage on an unregistered domain, seamlessly redirect to unregistered error view if (accept.includes("text/html")) { const loginDomain = rpID || "auth.atyg.org"; - c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"); + c.header( + "Cache-Control", + "no-store, no-cache, must-revalidate, max-age=0", + ); return c.redirect( `https://${loginDomain}/errors/unregistered?host=${ encodeURIComponent(host) @@ -1192,7 +1190,10 @@ app.get("/api/forward-auth", async (c) => { // If a browser is requesting a webpage, seamlessly redirect to login if (accept.includes("text/html")) { const loginDomain = rpID || "auth.atyg.org"; - c.header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0"); + c.header( + "Cache-Control", + "no-store, no-cache, must-revalidate, max-age=0", + ); return c.redirect( `https://${loginDomain}/login?redirect=${ encodeURIComponent(originalUrl) diff --git a/ui/components/AuthenticatedLayout.tsx b/ui/components/AuthenticatedLayout.tsx index 7c25201..151a258 100644 --- a/ui/components/AuthenticatedLayout.tsx +++ b/ui/components/AuthenticatedLayout.tsx @@ -159,7 +159,7 @@ export const AuthenticatedLayout = ({ - +
diff --git a/ui/components/LoginPage.tsx b/ui/components/LoginPage.tsx index a04f9ba..85224cb 100644 --- a/ui/components/LoginPage.tsx +++ b/ui/components/LoginPage.tsx @@ -95,7 +95,7 @@ export const LoginPage = () => { - + +