diff options
| author | nsfisis <nsfisis@gmail.com> | 2026-01-01 21:28:33 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2026-01-01 21:28:33 +0900 |
| commit | 1d31f2ec8921bb58d74458b057bbb31f4877c335 (patch) | |
| tree | 695e24534c9529d4271aa7ed544eaadb697c93b6 /src/client/stores/auth.tsx | |
| parent | bf286c11d3244afb5132271dac656109934150e0 (diff) | |
| download | kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.tar.gz kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.tar.zst kioku-1d31f2ec8921bb58d74458b057bbb31f4877c335.zip | |
fix(auth): redirect to login when session expires
When the refresh token fails (session expired), the ApiClient now
notifies the AuthProvider via a callback. This triggers a logout
and React state update, causing ProtectedRoute to redirect to /login.
Closes #7
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'src/client/stores/auth.tsx')
| -rw-r--r-- | src/client/stores/auth.tsx | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/client/stores/auth.tsx b/src/client/stores/auth.tsx index b34717b..3f2681b 100644 --- a/src/client/stores/auth.tsx +++ b/src/client/stores/auth.tsx @@ -31,6 +31,15 @@ export interface AuthProviderProps { export function AuthProvider({ children }: AuthProviderProps) { const [user, setUser] = useState<User | null>(null); const [isLoading, setIsLoading] = useState(true); + const [isAuthenticated, setIsAuthenticated] = useState( + apiClient.isAuthenticated(), + ); + + const logout = useCallback(() => { + apiClient.logout(); + setUser(null); + setIsAuthenticated(false); + }, []); // Check for existing auth on mount useEffect(() => { @@ -45,18 +54,19 @@ export function AuthProvider({ children }: AuthProviderProps) { } }, []); + // Subscribe to session expired events from the API client + useEffect(() => { + return apiClient.onSessionExpired(() => { + logout(); + }); + }, [logout]); + const login = useCallback(async (username: string, password: string) => { const response = await apiClient.login(username, password); setUser(response.user); + setIsAuthenticated(true); }, []); - const logout = useCallback(() => { - apiClient.logout(); - setUser(null); - }, []); - - const isAuthenticated = apiClient.isAuthenticated(); - const value = useMemo<AuthContextValue>( () => ({ user, |
