Initial commit - Facturation SANTINOVA

This commit is contained in:
manus-admin
2026-04-23 04:49:21 -04:00
commit 6ab833945c
55 changed files with 12642 additions and 0 deletions

198
backend/src/routes/auth.ts Normal file
View File

@@ -0,0 +1,198 @@
import { Router, Request, Response } from 'express';
import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken';
import { getPool } from '../config/database';
import { authenticate, AuthRequest, authorize } from '../middleware/auth';
const router = Router();
// POST /api/auth/login
router.post('/login', async (req: Request, res: Response) => {
try {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: 'Email et mot de passe requis' });
}
const pool = getPool();
const [rows]: any = await pool.execute(
'SELECT * FROM users WHERE email = ? AND is_active = TRUE',
[email]
);
if (!rows.length) {
return res.status(401).json({ error: 'Identifiants incorrects' });
}
const user = rows[0];
const validPassword = await bcrypt.compare(password, user.password);
if (!validPassword) {
return res.status(401).json({ error: 'Identifiants incorrects' });
}
const secret = process.env.JWT_SECRET || 'santinova-jwt-secret';
const expiresIn = process.env.JWT_EXPIRES_IN || '24h';
const token = (jwt.sign as any)(
{
id: user.id,
email: user.email,
role: user.role,
firstName: user.first_name,
lastName: user.last_name,
},
secret,
{ expiresIn }
);
res.json({
token,
user: {
id: user.id,
email: user.email,
firstName: user.first_name,
lastName: user.last_name,
role: user.role,
},
});
} catch (error: any) {
console.error('Erreur login:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
// GET /api/auth/me
router.get('/me', authenticate, async (req: AuthRequest, res: Response) => {
try {
const pool = getPool();
const [rows]: any = await pool.execute(
'SELECT id, email, first_name, last_name, role, is_active, created_at FROM users WHERE id = ?',
[req.user!.id]
);
if (!rows.length) {
return res.status(404).json({ error: 'Utilisateur non trouvé' });
}
const user = rows[0];
res.json({
id: user.id,
email: user.email,
firstName: user.first_name,
lastName: user.last_name,
role: user.role,
isActive: user.is_active,
createdAt: user.created_at,
});
} catch (error: any) {
console.error('Erreur me:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
// GET /api/auth/users - Liste des utilisateurs (admin)
router.get('/users', authenticate, authorize('admin'), async (req: AuthRequest, res: Response) => {
try {
const pool = getPool();
const [rows]: any = await pool.execute(
'SELECT id, email, first_name, last_name, role, is_active, created_at, updated_at FROM users ORDER BY created_at DESC'
);
const users = rows.map((u: any) => ({
id: u.id,
email: u.email,
firstName: u.first_name,
lastName: u.last_name,
role: u.role,
isActive: u.is_active,
createdAt: u.created_at,
updatedAt: u.updated_at,
}));
res.json(users);
} catch (error: any) {
console.error('Erreur liste users:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
// POST /api/auth/users - Créer un utilisateur (admin)
router.post('/users', authenticate, authorize('admin'), async (req: AuthRequest, res: Response) => {
try {
const { email, password, firstName, lastName, role } = req.body;
if (!email || !password || !firstName || !lastName) {
return res.status(400).json({ error: 'Tous les champs sont requis' });
}
const hashedPassword = await bcrypt.hash(password, 12);
const pool = getPool();
const [result]: any = await pool.execute(
'INSERT INTO users (email, password, first_name, last_name, role) VALUES (?, ?, ?, ?, ?)',
[email, hashedPassword, firstName, lastName, role || 'operateur']
);
res.status(201).json({
id: result.insertId,
email,
firstName,
lastName,
role: role || 'operateur',
});
} catch (error: any) {
if (error.code === 'ER_DUP_ENTRY') {
return res.status(409).json({ error: 'Cet email est déjà utilisé' });
}
console.error('Erreur création user:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
// PUT /api/auth/users/:id - Modifier un utilisateur (admin)
router.put('/users/:id', authenticate, authorize('admin'), async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const { email, firstName, lastName, role, isActive, password } = req.body;
const pool = getPool();
let query = 'UPDATE users SET email = ?, first_name = ?, last_name = ?, role = ?, is_active = ?';
let params: any[] = [email, firstName, lastName, role, isActive !== false];
if (password) {
const hashedPassword = await bcrypt.hash(password, 12);
query += ', password = ?';
params.push(hashedPassword);
}
query += ' WHERE id = ?';
params.push(id);
await pool.execute(query, params);
res.json({ message: 'Utilisateur mis à jour' });
} catch (error: any) {
console.error('Erreur update user:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
// DELETE /api/auth/users/:id - Désactiver un utilisateur (admin)
router.delete('/users/:id', authenticate, authorize('admin'), async (req: AuthRequest, res: Response) => {
try {
const { id } = req.params;
const pool = getPool();
await pool.execute('UPDATE users SET is_active = FALSE WHERE id = ?', [id]);
res.json({ message: 'Utilisateur désactivé' });
} catch (error: any) {
console.error('Erreur delete user:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
export default router;