mirror of
https://github.com/arsvendg/Stirling-PDF.git
synced 2026-07-17 11:45:05 +02:00
Fix login loop on self-hosted desktop (#5022)
# Description of Changes Fix #5017 Changes the handling of jwt tokens to be stored in local storage as well as OS keyring so the rest of the app knows that you're logged in.
This commit is contained in:
@@ -126,6 +126,14 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
initializeAuth();
|
||||
|
||||
// Listen for jwt-available event (triggered by desktop auth or other sources)
|
||||
const handleJwtAvailable = () => {
|
||||
console.debug('[Auth] JWT available event received, refreshing session');
|
||||
void initializeAuth();
|
||||
};
|
||||
|
||||
window.addEventListener('jwt-available', handleJwtAvailable);
|
||||
|
||||
// Subscribe to auth state changes
|
||||
const { data: { subscription } } = springAuth.onAuthStateChange(
|
||||
async (event: AuthChangeEvent, newSession: Session | null) => {
|
||||
@@ -162,6 +170,7 @@ export function AuthProvider({ children }: { children: ReactNode }) {
|
||||
|
||||
return () => {
|
||||
mounted = false;
|
||||
window.removeEventListener('jwt-available', handleJwtAvailable);
|
||||
subscription.unsubscribe();
|
||||
};
|
||||
}, []);
|
||||
|
||||
@@ -161,8 +161,8 @@ class SpringAuthClient {
|
||||
return { data: { session: null }, error: null };
|
||||
}
|
||||
|
||||
// Clear potentially invalid token on other errors too
|
||||
localStorage.removeItem('stirling_jwt');
|
||||
// Don't clear token for other errors (e.g., backend not ready, network issues)
|
||||
// The token is still valid, just can't verify it right now
|
||||
return {
|
||||
data: { session: null },
|
||||
error: { message: getErrorMessage(error, 'Unknown error') },
|
||||
|
||||
@@ -8,6 +8,8 @@ import { useTranslation } from 'react-i18next';
|
||||
import { useDocumentMeta } from '@app/hooks/useDocumentMeta';
|
||||
import AuthLayout from '@app/routes/authShared/AuthLayout';
|
||||
import { useBackendProbe } from '@app/hooks/useBackendProbe';
|
||||
import apiClient from '@app/services/apiClient';
|
||||
import { BASE_PATH } from '@app/constants/app';
|
||||
|
||||
// Import login components
|
||||
import LoginHeader from '@app/routes/login/LoginHeader';
|
||||
@@ -16,7 +18,6 @@ import EmailPasswordForm from '@app/routes/login/EmailPasswordForm';
|
||||
import OAuthButtons, { DEBUG_SHOW_ALL_PROVIDERS, oauthProviderConfig } from '@app/routes/login/OAuthButtons';
|
||||
import DividerWithText from '@app/components/shared/DividerWithText';
|
||||
import LoggedInState from '@app/routes/login/LoggedInState';
|
||||
import { BASE_PATH } from '@app/constants/app';
|
||||
|
||||
export default function Login() {
|
||||
const navigate = useNavigate();
|
||||
@@ -85,30 +86,28 @@ export default function Login() {
|
||||
useEffect(() => {
|
||||
const fetchProviders = async () => {
|
||||
try {
|
||||
const response = await fetch(`${BASE_PATH}/api/v1/proprietary/ui-data/login`);
|
||||
if (response.ok) {
|
||||
const data = await response.json();
|
||||
const response = await apiClient.get('/api/v1/proprietary/ui-data/login');
|
||||
const data = response.data;
|
||||
|
||||
// Check if login is disabled - if so, redirect to home
|
||||
if (data.enableLogin === false) {
|
||||
console.debug('[Login] Login disabled, redirecting to home');
|
||||
navigate('/');
|
||||
return;
|
||||
}
|
||||
|
||||
setEnableLogin(data.enableLogin ?? true);
|
||||
|
||||
// Set first-time setup flags
|
||||
setIsFirstTimeSetup(data.firstTimeSetup ?? false);
|
||||
setShowDefaultCredentials(data.showDefaultCredentials ?? false);
|
||||
|
||||
// Extract provider IDs from the providerList map
|
||||
// The keys are like "/oauth2/authorization/google" - extract the last part
|
||||
const providerIds = Object.keys(data.providerList || {})
|
||||
.map(key => key.split('/').pop())
|
||||
.filter((id): id is string => id !== undefined);
|
||||
setEnabledProviders(providerIds);
|
||||
// Check if login is disabled - if so, redirect to home
|
||||
if (data.enableLogin === false) {
|
||||
console.debug('[Login] Login disabled, redirecting to home');
|
||||
navigate('/');
|
||||
return;
|
||||
}
|
||||
|
||||
setEnableLogin(data.enableLogin ?? true);
|
||||
|
||||
// Set first-time setup flags
|
||||
setIsFirstTimeSetup(data.firstTimeSetup ?? false);
|
||||
setShowDefaultCredentials(data.showDefaultCredentials ?? false);
|
||||
|
||||
// Extract provider IDs from the providerList map
|
||||
// The keys are like "/oauth2/authorization/google" - extract the last part
|
||||
const providerIds = Object.keys(data.providerList || {})
|
||||
.map(key => key.split('/').pop())
|
||||
.filter((id): id is string => id !== undefined);
|
||||
setEnabledProviders(providerIds);
|
||||
} catch (err) {
|
||||
console.error('[Login] Failed to fetch enabled providers:', err);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user