diff options
Diffstat (limited to 'src/client/atoms')
| -rw-r--r-- | src/client/atoms/auth.ts | 27 |
1 files changed, 12 insertions, 15 deletions
diff --git a/src/client/atoms/auth.ts b/src/client/atoms/auth.ts index f618ccf..9ee69cf 100644 --- a/src/client/atoms/auth.ts +++ b/src/client/atoms/auth.ts @@ -1,17 +1,18 @@ import { atom, useSetAtom } from "jotai"; +import { atomWithStorage } from "jotai/utils"; import { useEffect } from "react"; +import { useLocation } from "wouter"; import { apiClient, type User } from "../api/client"; -// Primitive atoms -export const userAtom = atom<User | null>(null); +// userAtom is the single source of truth for auth state. Persisted to +// localStorage so that the authenticated user survives page reloads alongside +// the tokens in apiClient's token storage. +export const userAtom = atomWithStorage<User | null>("kioku_user", null); export const authLoadingAtom = atom<boolean>(true); -// Derived atom - checks if user is authenticated via apiClient -export const isAuthenticatedAtom = atom<boolean>((get) => { - // We need to trigger re-evaluation when user changes - get(userAtom); - return apiClient.isAuthenticated(); -}); +export const isAuthenticatedAtom = atom<boolean>( + (get) => get(userAtom) !== null, +); // Action atom - login export const loginAtom = atom( @@ -36,22 +37,18 @@ export const logoutAtom = atom(null, (_get, set) => { export function useAuthInit() { const setAuthLoading = useSetAtom(authLoadingAtom); const setUser = useSetAtom(userAtom); + const [, navigate] = useLocation(); useEffect(() => { - // Check for existing auth on mount - const tokens = apiClient.getTokens(); - if (tokens) { - // We have tokens stored, but we don't have user info cached - // For now, just set authenticated state. User info will be fetched when needed. - } setAuthLoading(false); // Subscribe to session expired events from the API client const unsubscribe = apiClient.onSessionExpired(() => { apiClient.logout(); setUser(null); + navigate("/login", { replace: true }); }); return unsubscribe; - }, [setAuthLoading, setUser]); + }, [setAuthLoading, setUser, navigate]); } |
