diff --git a/lightrag_webui/src/App.tsx b/lightrag_webui/src/App.tsx
index e6155c14..4596f684 100644
--- a/lightrag_webui/src/App.tsx
+++ b/lightrag_webui/src/App.tsx
@@ -5,11 +5,9 @@ import MessageAlert from '@/components/MessageAlert'
import ApiKeyAlert from '@/components/ApiKeyAlert'
import StatusIndicator from '@/components/graph/StatusIndicator'
import { healthCheckInterval } from '@/lib/constants'
-import { useBackendState, useAuthStore } from '@/stores/state'
+import { useBackendState } from '@/stores/state'
import { useSettingsStore } from '@/stores/settings'
import { useEffect } from 'react'
-import { useNavigate } from 'react-router-dom'
-import { navigationService } from '@/services/navigation'
import SiteHeader from '@/features/SiteHeader'
import { InvalidApiKeyError, RequireApiKeError } from '@/api/lightrag'
@@ -21,22 +19,13 @@ import ApiSite from '@/features/ApiSite'
import { Tabs, TabsContent } from '@/components/ui/Tabs'
function App() {
- const navigate = useNavigate();
const message = useBackendState.use.message()
-
- // Initialize navigation service
- useEffect(() => {
- navigationService.setNavigate(navigate);
- }, [navigate]);
const enableHealthCheck = useSettingsStore.use.enableHealthCheck()
const currentTab = useSettingsStore.use.currentTab()
const [apiKeyInvalid, setApiKeyInvalid] = useState(false)
// Health check
useEffect(() => {
- const { isAuthenticated } = useAuthStore.getState();
- if (!enableHealthCheck || !isAuthenticated) return
-
// Check immediately
useBackendState.getState().check()
diff --git a/lightrag_webui/src/AppRouter.tsx b/lightrag_webui/src/AppRouter.tsx
index 5fafd43f..a0857f67 100644
--- a/lightrag_webui/src/AppRouter.tsx
+++ b/lightrag_webui/src/AppRouter.tsx
@@ -1,4 +1,4 @@
-import { HashRouter as Router, Routes, Route, Navigate } from 'react-router-dom'
+import { HashRouter as Router, Routes, Route, useNavigate } from 'react-router-dom'
import { useEffect, useState } from 'react'
import { useAuthStore } from '@/stores/state'
import { navigationService } from '@/services/navigation'
@@ -16,6 +16,12 @@ interface ProtectedRouteProps {
const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
const { isAuthenticated } = useAuthStore()
const [isChecking, setIsChecking] = useState(true)
+ const navigate = useNavigate()
+
+ // Set navigate function for navigation service
+ useEffect(() => {
+ navigationService.setNavigate(navigate)
+ }, [navigate])
useEffect(() => {
let isMounted = true; // Flag to prevent state updates after unmount
@@ -71,29 +77,33 @@ const ProtectedRoute = ({ children }: ProtectedRouteProps) => {
// Get current path and check if it's a direct access
const currentPath = window.location.hash.slice(1); // Remove the '#' from hash
const isLoginPage = currentPath === '/login';
- const isDirectAccess = !document.referrer;
-
- // Handle direct access to root path
- if (isDirectAccess && currentPath === '/') {
- navigationService.resetAllApplicationState();
- }
-
+
// Skip redirect if already on login page
if (isLoginPage) {
return null;
}
- // Use React Router's Navigate for redirection
- console.log('Not authenticated, redirecting to login');
- return ;
+ // For non-login pages, handle state reset and navigation
+ if (!isLoginPage) {
+ // Use navigation service for redirection
+ console.log('Not authenticated, redirecting to login');
+ navigationService.navigateToLogin();
+ return null;
+ }
}
return <>{children}>
}
-const AppRouter = () => {
+const AppContent = () => {
const [initializing, setInitializing] = useState(true)
const { isAuthenticated } = useAuthStore()
+ const navigate = useNavigate()
+
+ // Set navigate function for navigation service
+ useEffect(() => {
+ navigationService.setNavigate(navigate)
+ }, [navigate])
// Check token validity and auth configuration on app initialization
useEffect(() => {
@@ -152,21 +162,27 @@ const AppRouter = () => {
return null
}
+ return (
+
+ } />
+
+
+
+ }
+ />
+
+ )
+}
+
+const AppRouter = () => {
return (
-
- } />
-
-
-
- }
- />
-
-
+
+
)
diff --git a/lightrag_webui/src/api/lightrag.ts b/lightrag_webui/src/api/lightrag.ts
index fcccf9bd..0406075a 100644
--- a/lightrag_webui/src/api/lightrag.ts
+++ b/lightrag_webui/src/api/lightrag.ts
@@ -173,9 +173,12 @@ axiosInstance.interceptors.response.use(
(error: AxiosError) => {
if (error.response) {
if (error.response?.status === 401) {
- // Use navigation service to handle redirection
+ // For login API, throw error directly
+ if (error.config?.url?.includes('/login')) {
+ throw error;
+ }
+ // For other APIs, navigate to login page
navigationService.navigateToLogin();
-
// Return a never-resolving promise to prevent further execution
return new Promise(() => {});
}
diff --git a/lightrag_webui/src/features/LoginPage.tsx b/lightrag_webui/src/features/LoginPage.tsx
index 16cff851..bc00b5c9 100644
--- a/lightrag_webui/src/features/LoginPage.tsx
+++ b/lightrag_webui/src/features/LoginPage.tsx
@@ -48,7 +48,7 @@ const LoginPage = () => {
toast.info(status.message)
}
navigate('/')
- return; // Exit early, no need to set checkingAuth to false
+ return // Exit early, no need to set checkingAuth to false
}
} catch (error) {
console.error('Failed to check auth configuration:', error)
@@ -95,11 +95,17 @@ const LoginPage = () => {
} else {
toast.success(t('login.successMessage'))
}
-
+
+ // Navigate to home page after successful login
navigate('/')
} catch (error) {
console.error('Login failed...', error)
toast.error(t('login.errorInvalidCredentials'))
+
+ // Clear any existing auth state
+ useAuthStore.getState().logout()
+ // Clear local storage
+ localStorage.removeItem('LIGHTRAG-API-TOKEN')
} finally {
setLoading(false)
}
diff --git a/lightrag_webui/src/services/navigation.ts b/lightrag_webui/src/services/navigation.ts
index cc5651bb..12019a0e 100644
--- a/lightrag_webui/src/services/navigation.ts
+++ b/lightrag_webui/src/services/navigation.ts
@@ -61,13 +61,28 @@ class NavigationService {
* @param skipReset whether to skip state reset (used for direct access scenario where reset is already handled)
*/
navigateToLogin() {
-
- this.resetAllApplicationState();
- useAuthStore.getState().logout();
-
- if (this.navigate) {
- this.navigate('/login');
+ if (!this.navigate) {
+ console.error('Navigation function not set');
+ return;
}
+
+ // First navigate to login page
+ this.navigate('/login');
+
+ // Then reset state after navigation
+ setTimeout(() => {
+ this.resetAllApplicationState();
+ useAuthStore.getState().logout();
+ }, 0);
+ }
+
+ navigateToHome() {
+ if (!this.navigate) {
+ console.error('Navigation function not set');
+ return;
+ }
+
+ this.navigate('/');
}
}