From 11be52a419803dc9fb72cc58ed1ff46c3d93b08e Mon Sep 17 00:00:00 2001 From: Paperclip Date: Fri, 27 Mar 2026 21:31:59 +0000 Subject: [PATCH] feat(web): use Better-Auth session state in App.tsx (GRO-126) Add useSession hook to check Better-Auth session for production auth. Redirect to Authentik sign-in when no session in production mode. Dev mode flow (DevLoginSelector) preserved. Co-Authored-By: Paperclip --- apps/web/src/App.tsx | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/apps/web/src/App.tsx b/apps/web/src/App.tsx index cdf9d1f..d65ce36 100644 --- a/apps/web/src/App.tsx +++ b/apps/web/src/App.tsx @@ -17,6 +17,7 @@ import { DevLoginSelector, getDevUser } from "./pages/DevLoginSelector.js"; import { DevSessionIndicator } from "./components/DevSessionIndicator.js"; import { BrandingProvider, useBranding } from "./BrandingContext.js"; import { GlobalSearch } from "./components/GlobalSearch.js"; +import { useSession, signIn } from "./lib/auth-client.js"; const NAV_LINKS = [ { to: "/admin", label: "Appointments" }, @@ -133,6 +134,7 @@ function AdminLayout() { export function App() { const location = useLocation(); const [authDisabled, setAuthDisabled] = useState(null); + const { data: session, isPending: sessionLoading } = useSession(); useEffect(() => { fetch("/api/dev/config") @@ -141,19 +143,11 @@ export function App() { .catch(() => setAuthDisabled(false)); }, []); - // Show login selector page - if (location.pathname === "/login") { + // Show login selector page (only in development) + if (import.meta.env.DEV && location.pathname === "/login") { return ; } - // While checking auth config, render nothing briefly - if (authDisabled === null) return null; - - // If auth is disabled and no dev user is selected, redirect to login selector - if (authDisabled && !getDevUser() && location.pathname !== "/login") { - return ; - } - // Public booking redirect pages — no auth or portal chrome needed if (location.pathname === "/booking/confirmed") { return ; @@ -165,6 +159,20 @@ export function App() { return ; } + // Still loading auth state + if (authDisabled === null || sessionLoading) return null; + + // Dev mode: use dev login selector + if (authDisabled && !getDevUser() && location.pathname !== "/login") { + return ; + } + + // Production mode: if no session, redirect to Authentik sign-in + if (!authDisabled && !session) { + signIn.social({ provider: "authentik" }); + return null; + } + return ( {location.pathname.startsWith("/admin") ? (