Files
crowdlending-app/frontend/src/context/AuthContext.jsx
T

85 lines
2.6 KiB
React

import { createContext, useContext, useEffect, useState } from 'react';
import { api } from '../api.js';
const AuthCtx = createContext(null);
export function AuthProvider({ children }) {
const [token, setToken] = useState(() => localStorage.getItem('cl_token'));
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
if (!token) { setLoading(false); return; }
api.get('/auth/me')
.then(({ user }) => setUser(user))
.catch(() => logout())
.finally(() => setLoading(false));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [token]);
const login = async (email, password, deviceToken) => {
const body = { email, password, ...(deviceToken ? { deviceToken } : {}) };
const r = await api.post('/auth/login', body);
if (r.requires2FA) {
// Authentification incomplète — retourne les infos pour la page Login
return { requires2FA: true, sessionToken: r.sessionToken, email: r.email };
}
localStorage.setItem('cl_token', r.token);
setToken(r.token);
setUser(r.user);
return r.user;
};
// Appelé par Login après validation du code 2FA
const completeLogin = (token, userData) => {
localStorage.setItem('cl_token', token);
setToken(token);
setUser(userData);
};
const register = async (email, password, displayName) => {
const r = await api.post('/auth/register', { email, password, displayName });
if (r.requiresVerification) {
// Compte créé mais email non vérifié — pas de connexion automatique
return { requiresVerification: true, email: r.email };
}
localStorage.setItem('cl_token', r.token);
setToken(r.token);
setUser(r.user);
return r.user;
};
const logout = () => {
localStorage.removeItem('cl_token');
localStorage.removeItem('cl_investisseur_id');
setToken(null);
setUser(null);
};
const updateUser = async (payload) => {
const r = await api.put('/auth/me', payload);
setUser(r.user);
// If backend issued a fresh token (email changed), persist it
if (r.token) {
localStorage.setItem('cl_token', r.token);
setToken(r.token);
}
return r.user;
};
const deleteAccount = async (password) => {
await api.del('/auth/me', { password });
logout();
};
const isAdmin = user?.role === 'admin';
return (
<AuthCtx.Provider value={{ token, user, loading, login, completeLogin, register, logout, updateUser, deleteAccount, isAdmin }}>
{children}
</AuthCtx.Provider>
);
}
export const useAuth = () => useContext(AuthCtx);