controller_authentification_controller.js

/**
 * @fileoverview Contrôleur gérant l'authentification et l'autorisation des utilisateurs
 * @module controllers/authentification
 */

const jwt = require('jsonwebtoken');
const User = require('../models/user_model');
const sha256 = require('js-sha256');
require('dotenv').config();

/**
 * @constant {string} JWT_SECRET - Clé secrète pour signer les tokens JWT
 * @default 'your_jwt_secret_key'
 */
const JWT_SECRET = process.env.JWT_SECRET || 'your_jwt_secret_key';

/**
 * @constant {string} JWT_SALT - Sel utilisé pour le hachage des mots de passe
 * @default 'your_jwt_salt'
 */
const JWT_SALT = process.env.JWT_SALT || 'your_jwt_salt';

/**
 * @constant {string} JWT_EXPIRATION - Durée de validité par défaut des tokens JWT
 * @default '24h'
 */
const JWT_EXPIRATION = process.env.JWT_EXPIRATION || '24h';

/**
 * @constant {string} JWT_EXPIRATION_REMEMBERED - Durée de validité des tokens JWT avec "Rester connecté"
 * @default '7d'
 */
const JWT_EXPIRATION_REMEMBERED = '7d';

/**
 * Middleware vérifiant si l'utilisateur est un administrateur
 * @function isAdmin
 * @async
 * @param {Object} req - L'objet requête Express
 * @param {Object} res - L'objet réponse Express
 * @param {Function} next - La fonction middleware suivante
 * @returns {void}
 * @throws {Error} Erreur si l'authentification échoue
 */
const isAdmin = (req, res, next) => {
    try{
      const token = req.headers['authorization']?.split(' ')[1];
      if (!token) {
        return res.status(401).json({ message: 'Token manquant' });
      }
  
      jwt.verify(token, JWT_SECRET, (err, decoded) => {
        if (err) {
          return res.status(403).json({ message: 'Token invalide' });
        }
        req.user = decoded;
        if (req.user.role !== 'admin') {
          return res.status(403).json({ message: 'Accès refusé' });
        }
        next();
      });
  
    }catch (error) {
      res.status(500).json({message: error.message})
    }
  }
  
  
  /**
 * Authentifie un utilisateur et génère un token JWT
 * @function authenticateUser
 * @async
 * @param {Object} req - L'objet requête Express
 * @param {Object} req.body - Le corps de la requête
 * @param {string} req.body.email - L'email de l'utilisateur
 * @param {string} req.body.password - Le mot de passe de l'utilisateur
 * @param {boolean} [req.body.rememberMe=false] - Option "Rester connecté"
 * @param {Object} res - L'objet réponse Express
 * @returns {Object} Objet contenant le token JWT et les informations utilisateur
 * @throws {Error} Erreur si l'authentification échoue
 */
const authenticateUser = async (req, res) => {
    const { email, password, rememberMe } = req.body;
    const user = await User.findOne({ email });
  
    if(!user){
      return res.status(401).json({ message: 'Invalid credentials' });
    }
    if(user.password !== sha256(password + JWT_SALT)){ // Remplacez 'secret' par le secret réel
      return res.status(401).json({ message: 'Invalid credentials' });
    }
  
    // Utiliser une expiration de 7 jours si rememberMe est true
    const expiresIn = rememberMe ? JWT_EXPIRATION_REMEMBERED : JWT_EXPIRATION;
    
    const token = jwt.sign({
        id: user._id,
        name: user.name,
        email: user.email,
        role: user.role,
        description: user.description
    }, JWT_SECRET, { expiresIn });
    
    res.json({
        token,
        expiresIn, // Ajouter l'expiration dans la réponse pour le front
        user: {
            id: user._id,
            name: user.name,
            email: user.email,
            role: user.role,
            description: user.description
        }
    });
  }
  
  /**
 * Vérifie la validité du token JWT
 * @function verifyToken
 * @async
 * @param {Object} req - L'objet requête Express
 * @param {Object} res - L'objet réponse Express
 * @param {Function} next - La fonction middleware suivante
 * @returns {void}
 * @throws {Error} Erreur si le token est invalide ou manquant
 */
const verifyToken = (req, res, next) =>{
    const token = req.headers['authorization']?.split(' ')[1];
    if (!token) {
      return res.status(401).json({ message: 'Token manquant' });
    }
  
    jwt.verify(token, JWT_SECRET, (err, decoded) => {
      if (err) {
        return res.status(403).json({ message: 'Token invalide' });
      }
      req.user = decoded;
      next();
    });
  }
  
  
  module.exports = {isAdmin, authenticateUser, verifyToken}