Files
jiggablend/web/src/hooks/useAuth.js

89 lines
2.8 KiB
JavaScript

import { useState, useEffect, useRef } from 'react';
import { auth, setAuthErrorHandler } from '../utils/api';
export function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const userRef = useRef(user);
// Keep userRef in sync with user state
useEffect(() => {
userRef.current = user;
}, [user]);
const checkAuth = async () => {
try {
const userData = await auth.getMe();
setUser(userData);
setLoading(false);
return userData; // Return user data for verification
} catch (error) {
// If 401/403, user is not authenticated
// Check if it's an auth error
if (error.message && (error.message.includes('Unauthorized') || error.message.includes('401') || error.message.includes('403'))) {
setUser(null);
setLoading(false);
throw error; // Re-throw to allow caller to handle
} else {
// Other errors (network, etc.) - don't log out, just re-throw
// This prevents network issues from logging users out
setLoading(false);
throw error; // Re-throw to allow caller to handle
}
}
};
const logout = async () => {
try {
await auth.logout();
} catch (error) {
console.error('Logout error:', error);
} finally {
// Refresh the page to show login
window.location.reload();
}
};
useEffect(() => {
// Set up global auth error handler
setAuthErrorHandler(() => {
setUser(null);
setLoading(false);
});
// Listen for auth errors from API calls
const handleAuthErrorEvent = () => {
setUser(null);
setLoading(false);
};
window.addEventListener('auth-error', handleAuthErrorEvent);
// Initial auth check
checkAuth();
// Periodic auth check every 10 seconds
const authInterval = setInterval(() => {
// Use ref to check current user state without dependency
if (userRef.current) {
// Only check if we have a user (don't spam when logged out)
checkAuth().catch((error) => {
// Only log out if it's actually an auth error, not a network error
// Network errors shouldn't log the user out
if (error.message && (error.message.includes('Unauthorized') || error.message.includes('401') || error.message.includes('403'))) {
// This is a real auth error - user will be set to null by checkAuth
}
// For other errors (network, etc.), don't log out - just silently fail
});
}
}, 10000); // 10 seconds
return () => {
window.removeEventListener('auth-error', handleAuthErrorEvent);
clearInterval(authInterval);
};
}, []); // Empty deps - only run on mount/unmount
return { user, loading, logout, refresh: checkAuth };
}