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 <noreply@paperclip.ing>
This commit is contained in:
+18
-10
@@ -17,6 +17,7 @@ import { DevLoginSelector, getDevUser } from "./pages/DevLoginSelector.js";
|
|||||||
import { DevSessionIndicator } from "./components/DevSessionIndicator.js";
|
import { DevSessionIndicator } from "./components/DevSessionIndicator.js";
|
||||||
import { BrandingProvider, useBranding } from "./BrandingContext.js";
|
import { BrandingProvider, useBranding } from "./BrandingContext.js";
|
||||||
import { GlobalSearch } from "./components/GlobalSearch.js";
|
import { GlobalSearch } from "./components/GlobalSearch.js";
|
||||||
|
import { useSession, signIn } from "./lib/auth-client.js";
|
||||||
|
|
||||||
const NAV_LINKS = [
|
const NAV_LINKS = [
|
||||||
{ to: "/admin", label: "Appointments" },
|
{ to: "/admin", label: "Appointments" },
|
||||||
@@ -133,6 +134,7 @@ function AdminLayout() {
|
|||||||
export function App() {
|
export function App() {
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [authDisabled, setAuthDisabled] = useState<boolean | null>(null);
|
const [authDisabled, setAuthDisabled] = useState<boolean | null>(null);
|
||||||
|
const { data: session, isPending: sessionLoading } = useSession();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
fetch("/api/dev/config")
|
fetch("/api/dev/config")
|
||||||
@@ -141,19 +143,11 @@ export function App() {
|
|||||||
.catch(() => setAuthDisabled(false));
|
.catch(() => setAuthDisabled(false));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
// Show login selector page
|
// Show login selector page (only in development)
|
||||||
if (location.pathname === "/login") {
|
if (import.meta.env.DEV && location.pathname === "/login") {
|
||||||
return <DevLoginSelector />;
|
return <DevLoginSelector />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 <Navigate to="/login" replace />;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public booking redirect pages — no auth or portal chrome needed
|
// Public booking redirect pages — no auth or portal chrome needed
|
||||||
if (location.pathname === "/booking/confirmed") {
|
if (location.pathname === "/booking/confirmed") {
|
||||||
return <BookingConfirmedPage />;
|
return <BookingConfirmedPage />;
|
||||||
@@ -165,6 +159,20 @@ export function App() {
|
|||||||
return <BookingErrorPage />;
|
return <BookingErrorPage />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Still loading auth state
|
||||||
|
if (authDisabled === null || sessionLoading) return null;
|
||||||
|
|
||||||
|
// Dev mode: use dev login selector
|
||||||
|
if (authDisabled && !getDevUser() && location.pathname !== "/login") {
|
||||||
|
return <Navigate to="/login" replace />;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Production mode: if no session, redirect to Authentik sign-in
|
||||||
|
if (!authDisabled && !session) {
|
||||||
|
signIn.social({ provider: "authentik" });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BrandingProvider>
|
<BrandingProvider>
|
||||||
{location.pathname.startsWith("/admin") ? (
|
{location.pathname.startsWith("/admin") ? (
|
||||||
|
|||||||
Reference in New Issue
Block a user