logout issues # 2

This commit is contained in:
IGNY8 VPS (Salman)
2025-12-15 17:22:50 +00:00
parent 5366cc1805
commit 1887f2a665
6 changed files with 14 additions and 144 deletions

View File

@@ -158,23 +158,7 @@ const Tooltips = lazy(() => import("./pages/Settings/UiElements/Tooltips"));
const Videos = lazy(() => import("./pages/Settings/UiElements/Videos"));
export default function App() {
const isAuthenticated = useAuthStore((state) => state.isAuthenticated);
const refreshUser = useAuthStore((state) => state.refreshUser);
const logout = useAuthStore((state) => state.logout);
useEffect(() => {
const { token } = useAuthStore.getState();
if (!isAuthenticated || !token) return;
refreshUser().catch((error) => {
// Avoid log spam on auth pages when token is missing/expired
if (error?.message?.includes('Authentication credentials were not provided')) {
return;
}
console.warn('Session validation failed:', error);
logout();
});
}, [isAuthenticated, refreshUser, logout]);
// All session validation removed - API interceptor handles authentication
return (
<>

View File

@@ -48,18 +48,7 @@ export default function ProtectedRoute({ children }: ProtectedRouteProps) {
trackLoading('auth-loading', loading);
}, [loading]);
// Validate account + plan whenever auth/user changes
useEffect(() => {
if (!isAuthenticated) {
return;
}
if (!user?.account) {
setErrorMessage('This user is not linked to an account. Please contact support.');
logout();
return;
}
}, [isAuthenticated, user, logout]);
// Account/plan validation removed - backend middleware handles this on API calls
// Immediate check on mount: if loading is true, reset it immediately
useEffect(() => {

View File

@@ -68,18 +68,7 @@ export default function SiteSwitcher({ hiddenPaths }: SiteSwitcherProps) {
shouldHide = hiddenPathsToUse.some(path => location.pathname.startsWith(path));
}
// Refresh user data when component mounts or user changes
// This ensures we have latest account/plan info for proper site filtering
useEffect(() => {
if (isAuthenticated && user) {
// Refresh user data to get latest account/plan changes
// This is important so site filtering works correctly
refreshUser().catch((error) => {
// Silently fail - user might still be valid, just couldn't refresh
console.debug('SiteSwitcher: Failed to refresh user (non-critical):', error);
});
}
}, [isAuthenticated]); // Only refresh when auth state changes, not on every render
// User refresh removed - data loads on-demand from API calls
useEffect(() => {
if (shouldHide) {

View File

@@ -83,101 +83,7 @@ const LayoutContent: React.FC = () => {
checkTokenAndLoad();
}, [isAuthenticated]); // Run when authentication state changes
// Sector loading moved to PageHeader component
// This ensures sectors are only loaded when content pages (Planner/Writer/Optimizer) mount
// Account/billing pages don't use PageHeader with site/sector selector, so they won't trigger sector loading
// This prevents unnecessary 404 errors on /account/plans and similar routes
// Refresh user data on mount and when app version changes (after code updates)
// This ensures changes are reflected immediately without requiring re-login
useEffect(() => {
if (!isAuthenticated) return;
const APP_VERSION = import.meta.env.VITE_APP_VERSION || '2.0.2';
const VERSION_STORAGE_KEY = 'igny8-app-version';
const refreshUserData = async (force = false) => {
const now = Date.now();
// Throttle: only refresh if last refresh was more than 30 seconds ago (unless forced)
if (!force && now - lastUserRefresh.current < 30000) return;
// Check if token exists before making API call
const authState = useAuthStore.getState();
if (!authState?.token) {
// Token not available yet - wait a bit for Zustand persist to write it
setTimeout(() => {
const retryAuthState = useAuthStore.getState();
if (retryAuthState?.token && retryAuthState?.isAuthenticated) {
refreshUserData(force);
}
}, 100); // Wait 100ms for persist to write
return;
}
try {
lastUserRefresh.current = now;
await refreshUser();
// Store current version after successful refresh
if (force) {
localStorage.setItem(VERSION_STORAGE_KEY, APP_VERSION);
}
} catch (error) {
// Silently fail - user might still be authenticated
console.debug('User data refresh failed (non-critical):', error);
}
};
// Check if app version changed (indicates code update)
const storedVersion = localStorage.getItem(VERSION_STORAGE_KEY);
if (storedVersion !== APP_VERSION) {
// Force refresh on version change
refreshUserData(true);
} else {
// Normal refresh on mount
refreshUserData();
}
// Refresh when window becomes visible (user switches back to tab)
const handleVisibilityChange = () => {
if (document.visibilityState === 'visible') {
refreshUserData();
}
};
// Refresh on window focus
const handleFocus = () => {
refreshUserData();
};
// Proactive token refresh - refresh token every 12 minutes (before 15-minute expiry)
// This prevents 401 errors and ensures seamless user experience
const tokenRefreshInterval = setInterval(async () => {
const authState = useAuthStore.getState();
const refreshToken = authState?.refreshToken;
if (refreshToken && authState?.isAuthenticated) {
try {
await authState.refreshToken();
console.debug('Token proactively refreshed');
} catch (error) {
console.debug('Proactive token refresh failed (will retry on next API call):', error);
}
}
}, 720000); // 12 minutes = 720000ms
// Periodic user data refresh every 2 minutes
const intervalId = setInterval(() => refreshUserData(), 120000);
document.addEventListener('visibilitychange', handleVisibilityChange);
window.addEventListener('focus', handleFocus);
return () => {
clearInterval(tokenRefreshInterval);
clearInterval(intervalId);
document.removeEventListener('visibilitychange', handleVisibilityChange);
window.removeEventListener('focus', handleFocus);
};
}, [isAuthenticated, refreshUser]);
// All session refresh logic removed - API interceptor handles token refresh automatically on 401
// Load credit balance and set in header metrics
useEffect(() => {