import React, { useState, createContext, useEffect } from 'react'; import { useHistory } from 'react-router-dom'; import Cookies from 'js-cookie'; import { useApi } from '@config'; const auth = { user: localStorage.getItem('user'), accessToken: null, refreshToken: null, isLogged: false, setLoading: () => {}, register: () => {}, login: () => {}, logout: () => {} }; export const AuthContext = createContext(auth); const AuthProvider = ({ children }) => { const [user, setUser] = useState(auth.user && JSON.parse(auth.user)); const [accessToken, setAccessToken] = useState(null); const [refreshToken, setRefreshToken] = useState(null); const { get, post } = useApi(); const isLoggedIn = !!accessToken; const history = useHistory(); useEffect(() => { const initAuth = async () => { try { const accessToken = window.localStorage.getItem('accessToken'); if (accessToken) { const response = await get('/auth/auth-me'); const { user, accessToken } = response.data; if (accessToken) { window.localStorage.setItem('user', JSON.stringify(user)); window.localStorage.setItem('accessToken', accessToken); } setUser(user); setAccessToken(accessToken); } } catch (err) { localStorage.removeItem('user'); localStorage.removeItem('refreshToken'); localStorage.removeItem('accessToken'); setUser(null); setAccessToken(null); setRefreshToken(null); } }; initAuth(); }, []); const handleLogin = async (params, errorCallback) => { try { const response = await post('/auth/login', params); // Extract user, accessToken, refreshToken from the response body const { user, accessToken, refreshToken } = response.data; // Store accessToken and refreshToken in state setAccessToken(accessToken); setRefreshToken(refreshToken); // Store user in state setUser(user); // Set user data in localStorage window.localStorage.setItem('user', JSON.stringify(user)); // Set accessToken in localStorage window.localStorage.setItem('accessToken', accessToken); // Set refreshToken in cookies Cookies.set('refreshToken', refreshToken, { expires: 30, secure: true, sameSite: 'strict' }); history.replace('/'); } catch (err) { if (errorCallback) errorCallback(err); } }; const handleRegister = async (params, errorCallback) => { try { const response = await post('/auth/register', params); if (response.data.error) { if (errorCallback) errorCallback(response.data.error); } else { handleLogin({ email: params.email, password: params.password }); } } catch (err) { if (errorCallback) errorCallback(err); } }; const handleLogout = () => { // Remove states setUser(null); setAccessToken(null); setRefreshToken(null); // Remove user data from localStorage window.localStorage.removeItem('user'); // Remove accessToken from localStorage window.localStorage.removeItem('accessToken'); // Remove refreshToken from cookies Cookies.remove('refreshToken', { expires: 30, secure: true, sameSite: 'strict' }); history.replace('/login'); }; const values = { user: user, accessToken: accessToken, refreshToken: refreshToken, isLogged: isLoggedIn, login: handleLogin, register: handleRegister, logout: handleLogout }; return {children}; }; export default AuthProvider;