diff --git a/app/src/contexts/AuthContext.jsx b/app/src/contexts/AuthContext.jsx index a93d0c5..4878e05 100644 --- a/app/src/contexts/AuthContext.jsx +++ b/app/src/contexts/AuthContext.jsx @@ -19,16 +19,10 @@ export const AuthProvider = ({ children }) => { useEffect(() => { const initializeAuth = async () => { try { - const storedToken = localStorage.getItem('accessToken'); - if (storedToken) { - authApi.setAuthToken(storedToken); - const userData = await authApi.getCurrentUser(); - setUser(userData); - } + const userData = await authApi.getCurrentUser(); + setUser(userData); } catch (error) { console.error('Failed to initialize auth:', error); - localStorage.removeItem('accessToken'); - authApi.clearAuthToken(); } finally { setLoading(false); setInitialized(true); @@ -40,12 +34,7 @@ export const AuthProvider = ({ children }) => { const login = useCallback(async (email, password) => { try { - const { accessToken, user: userData } = await authApi.login( - email, - password - ); - localStorage.setItem('accessToken', accessToken); - authApi.setAuthToken(accessToken); + const { user: userData } = await authApi.login(email, password); setUser(userData); notifications.show({ title: 'Success', @@ -70,18 +59,17 @@ export const AuthProvider = ({ children }) => { } catch (error) { console.error('Logout failed:', error); } finally { - localStorage.removeItem('accessToken'); - authApi.clearAuthToken(); setUser(null); } }, []); const refreshToken = useCallback(async () => { try { - const { accessToken } = await authApi.refreshToken(); - localStorage.setItem('accessToken', accessToken); - authApi.setAuthToken(accessToken); - return true; + const success = await authApi.refreshToken(); + if (!success) { + await logout(); + } + return success; } catch (error) { console.error('Token refresh failed:', error); await logout(); diff --git a/app/src/services/authApi.js b/app/src/services/authApi.js index 1144f0c..9a65633 100644 --- a/app/src/services/authApi.js +++ b/app/src/services/authApi.js @@ -1,40 +1,32 @@ import { API_BASE_URL } from '../utils/constants'; -let authToken = null; - -export const setAuthToken = (token) => { - authToken = token; -}; - -export const clearAuthToken = () => { - authToken = null; -}; - -export const getAuthHeaders = () => { - const headers = { - 'Content-Type': 'application/json', - }; - - if (authToken) { - headers['Authorization'] = `Bearer ${authToken}`; - } - - return headers; -}; - -// Update the existing apiCall function to include auth headers export const apiCall = async (url, options = {}) => { try { const headers = { - ...getAuthHeaders(), + 'Content-Type': 'application/json', ...options.headers, }; + if (options.method && options.method !== 'GET') { + const csrfToken = document.cookie + .split('; ') + .find((row) => row.startsWith('csrf_token=')) + ?.split('=')[1]; + if (csrfToken) { + headers['X-CSRF-Token'] = csrfToken; + } + } + const response = await fetch(url, { ...options, headers, + credentials: 'include', }); + if (response.status === 429) { + throw new Error('Rate limit exceeded'); + } + // Handle 401 responses if (response.status === 401) { const isRefreshEndpoint = url.endsWith('/auth/refresh'); @@ -42,13 +34,14 @@ export const apiCall = async (url, options = {}) => { // Attempt token refresh and retry the request const refreshSuccess = await refreshToken(); if (refreshSuccess) { - // Retry the original request with the new token + // Retry the original request return apiCall(url, options); } } throw new Error('Authentication failed'); } + // Handle other error responses if (!response.ok && response.status !== 204) { const errorData = await response.json().catch(() => null); throw new Error( @@ -56,6 +49,7 @@ export const apiCall = async (url, options = {}) => { ); } + // Return null for 204 responses if (response.status === 204) { return null; } @@ -73,26 +67,29 @@ export const login = async (email, password) => { method: 'POST', body: JSON.stringify({ email, password }), }); - return response.json(); + + const data = await response.json(); + // No need to store tokens as they're in cookies now + return data; }; export const logout = async () => { - const sessionId = localStorage.getItem('sessionId'); await apiCall(`${API_BASE_URL}/auth/logout`, { method: 'POST', - headers: { - 'X-Session-ID': sessionId, - }, }); + return; }; export const refreshToken = async () => { - const refreshToken = localStorage.getItem('refreshToken'); - const response = await apiCall(`${API_BASE_URL}/auth/refresh`, { - method: 'POST', - body: JSON.stringify({ refreshToken }), - }); - return response.json(); + try { + const response = await apiCall(`${API_BASE_URL}/auth/refresh`, { + method: 'POST', + }); + return response.status === 200; + } catch (error) { + console.error('Token refresh failed:', error); + return false; + } }; export const getCurrentUser = async () => {