import React, { createContext, useState, useContext, useEffect } from 'react'; import { base44 } from '@/api/base44Client'; /** * Auth context. * * The single source of truth for "is anyone signed in", and it is not a flag * this app sets. `checkUserAuth` calls `GET /me`; the server reads its own * session table and either returns a user or answers 401. Success means there * is a session, failure means there is not, and there is no third answer this * code can manufacture. * * The context shape is unchanged from the demo's version — `isLoadingAuth`, * `isLoadingPublicSettings`, `authError`, `navigateToLogin` and the rest — so * `App.jsx`, `ProtectedRoute` and every consumer stay as they were. What * changed is where the answer comes from: a real session cookie rather than a * client that reported the seeded user as permanently signed in. */ const AuthContext = createContext(/** @type {any} */ (null)); /** @param {any} props */ export const AuthProvider = ({ children }) => { const [user, setUser] = useState(null); const [isAuthenticated, setIsAuthenticated] = useState(false); const [isLoadingAuth, setIsLoadingAuth] = useState(true); const [authChecked, setAuthChecked] = useState(false); const checkUserAuth = async () => { setIsLoadingAuth(true); try { const currentUser = await base44.auth.me(); setUser(currentUser); setIsAuthenticated(true); } catch { // A 401 is the ordinary state of a signed-out visitor, and it is also // what an expired session looks like on the first request after it // lapses. Both mean the same thing here. setUser(null); setIsAuthenticated(false); } finally { setIsLoadingAuth(false); setAuthChecked(true); } }; useEffect(() => { checkUserAuth(); }, []); /** * Signs in. * * Resolves to the user on success and throws the API's error otherwise. The * error's message is already the generic one the server chose — it does not * say whether the address exists — so callers show it as-is rather than * writing their own. */ const login = async ({ email, password, rememberMe = false }) => { const currentUser = await base44.auth.login({ email, password, rememberMe }); setUser(currentUser); setIsAuthenticated(true); setAuthChecked(true); return currentUser; }; const logout = async (redirectTo = '/admin/login') => { setUser(null); setIsAuthenticated(false); // Revokes the session server-side, expires the cookie, then redirects. await base44.auth.logout(redirectTo); }; const navigateToLogin = () => { base44.auth.redirectToLogin(); }; return ( {children} ); }; export const useAuth = () => { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within an AuthProvider'); } return context; };