fix: connexion par identifiant (adminItinova) ou email - conformité skill itinova-user-management

This commit is contained in:
Manus Agent
2026-04-28 11:54:01 -04:00
parent 75b80afb06
commit 33a621ba69
4 changed files with 23 additions and 18 deletions

View File

@@ -30,16 +30,20 @@ const router = Router();
// POST /api/auth/login // POST /api/auth/login
router.post('/login', async (req: Request, res: Response) => { router.post('/login', async (req: Request, res: Response) => {
try { try {
const { email, password } = req.body; // Accepter 'login' ou 'email' (compatibilité skill itinova-user-management)
const login = (req.body.login || req.body.email || '').trim();
const { password } = req.body;
if (!email || !password) { if (!login || !password) {
return res.status(400).json({ error: 'Email et mot de passe requis' }); return res.status(400).json({ error: 'Identifiant et mot de passe requis' });
} }
const pool = getPool(); const pool = getPool();
// Recherche par email exact OU par identifiant (login sans @)
// Ex: 'adminItinova' trouvera 'adminItinova@santinova-soft.org'
const [rows]: any = await pool.execute( const [rows]: any = await pool.execute(
'SELECT * FROM users WHERE email = ? AND is_active = TRUE', `SELECT * FROM users WHERE (email = ? OR email = CONCAT(?, '@santinova-soft.org')) AND is_active = TRUE`,
[email] [login, login]
); );
if (!rows.length) { if (!rows.length) {

View File

@@ -5,7 +5,7 @@ import { authAPI } from '../services/api';
interface AuthContextType { interface AuthContextType {
user: User | null; user: User | null;
token: string | null; token: string | null;
login: (email: string, password: string) => Promise<void>; login: (login: string, password: string) => Promise<void>;
logout: () => void; logout: () => void;
isLoading: boolean; isLoading: boolean;
} }
@@ -45,8 +45,8 @@ export function AuthProvider({ children }: { children: ReactNode }) {
} }
}, []); }, []);
const login = async (email: string, password: string) => { const login = async (login: string, password: string) => {
const res = await authAPI.login(email, password); const res = await authAPI.login(login, password);
const { token: newToken, user: newUser } = res.data; const { token: newToken, user: newUser } = res.data;
setToken(newToken); setToken(newToken);
setUser(newUser); setUser(newUser);

View File

@@ -4,7 +4,7 @@ import { useAuth } from '../context/AuthContext';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
export default function Login() { export default function Login() {
const [email, setEmail] = useState(''); const [loginValue, setLoginValue] = useState('');
const [password, setPassword] = useState(''); const [password, setPassword] = useState('');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const { login } = useAuth(); const { login } = useAuth();
@@ -14,7 +14,7 @@ export default function Login() {
e.preventDefault(); e.preventDefault();
setLoading(true); setLoading(true);
try { try {
await login(email, password); await login(loginValue, password);
toast.success('Connexion réussie'); toast.success('Connexion réussie');
navigate('/'); navigate('/');
} catch (error: any) { } catch (error: any) {
@@ -79,18 +79,19 @@ export default function Login() {
<div className="bg-white rounded-2xl shadow-lg p-8"> <div className="bg-white rounded-2xl shadow-lg p-8">
<form onSubmit={handleSubmit} className="space-y-5"> <form onSubmit={handleSubmit} className="space-y-5">
<div> <div>
<label htmlFor="email" className="block text-sm font-medium text-gray-700 mb-1"> <label htmlFor="login" className="block text-sm font-medium text-gray-700 mb-1">
Adresse email Identifiant ou email
</label> </label>
<input <input
id="email" id="login"
type="email" type="text"
value={email} value={loginValue}
onChange={(e) => setEmail(e.target.value)} onChange={(e) => setLoginValue(e.target.value)}
className="input-field" className="input-field"
placeholder="votre@email.com" placeholder="adminItinova ou votre@email.com"
required required
autoFocus autoFocus
autoComplete="username"
/> />
</div> </div>

View File

@@ -37,7 +37,7 @@ export default api;
// Auth // Auth
export const authAPI = { export const authAPI = {
login: (email: string, password: string) => api.post('/auth/login', { email, password }), login: (login: string, password: string) => api.post('/auth/login', { login, password }),
me: () => api.get('/auth/me'), me: () => api.get('/auth/me'),
getUsers: () => api.get('/auth/users'), getUsers: () => api.get('/auth/users'),
createUser: (data: any) => api.post('/auth/users', data), createUser: (data: any) => api.post('/auth/users', data),