philippebeck/nens

View on GitHub
controller/AuthCtrl.js

Summary

Maintainability
A
1 hr
Test Coverage
"use strict";

const bcrypt      = require("bcrypt");
const formidable  = require("formidable");
const Recaptcha   = require("google-recaptcha");
const db          = require("../model");

require("dotenv").config();

const { checkEmail, getMailer, getMessage, getPassword, setAuth } = require("../app/middlewares");
const { USER_NOT_FOUND } = process.env;

const form      = formidable();
const recaptcha = new Recaptcha({ secret: process.env.RECAPTCHA_SECRET });

const User = db.user;

//! ******************** PUBLIC ********************

/**
 * ? READ AVATAR
 * * Retrieves the avatar information for a specific user.
 *
 * @param {object} req - The request object.
 * @param {object} res - The response object.
 * @return {object} The avatar information for the user.
 * @throws {Error} If the user is not found in the database.
 */
exports.readAvatar = async (req, res) => {
  try {
    const ID    = parseInt(req.params.id, 10);
    const user  = await User.findByPk(ID);

    const { name, image, role } = user;
    const avatar = { name, image, role };

    res.status(200).json(avatar);

  } catch (error) {
    res.status(404).json({ message: USER_NOT_FOUND });
  }
}

/**
 * ? CHECK RECAPTCHA
 * * Checks the validity of a recaptcha response.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @param {Function} next - The next middleware function.
 * @return {Object} The validity of the recaptcha response.
 * @throws {Error} If the recaptcha response is invalid.
 */
exports.checkRecaptcha = (req, res, next) => {
  form.parse(req, (err, fields) => {
    if (err) { next(err); return }

    const response = fields.response;
    const remoteIp = req.connection.remoteAddress;

    recaptcha.verify({ response, remoteIp }, (err, data) => {
      if (!err) res.send(data);
      else res.status(500).send(err);
    });
  })
}

/**
 * ? LOGIN USER
 * * Login a user.
 *
 * @param {Object} req - the request object
 * @param {Object} res - the response object
 * @param {Function} next - the next middleware function
 * @throws {Error} If the user is not found in the database.
 */
exports.loginUser = async (req, res, next) => {
  const { AUTH_LOGIN }  = process.env;

  form.parse(req, async (err, fields) => {
    if (err) { next(err); return }

    const { email, pass } = fields;

    try {
      const user = await User.findOne({ where: { email: email }});

      if (!user) {
        return res.status(404).json({ message: USER_NOT_FOUND });
      }

      await setAuth(pass, user, res);

    } catch (error) {
      res.status(401).json({ message: AUTH_LOGIN });
    }
  })
}

/**
 * ? FORGOT PASSWORD
 * * Handles the forgot password functionality.
 *
 * @param {Object} req - The request object.
 * @param {Object} res - The response object.
 * @param {Function} next - The next middleware function.
 * @return {Object} A message indicating that the password was sent.
 * @throws {Error} If the user is not found in the database.
 */
exports.forgotPass = async (req, res, next) => {
  const { AUTH_MESSAGE, CHECK_EMAIL, DISPO_EMAIL_REF, USER_NOT_PASS, USER_NOT_UPDATED } = process.env;

  form.parse(req, async (err, fields) => {
    if (err) { next(err); return }

    const { email, html } = fields;
    const pass  = getPassword();
    fields.html = `<p>${html}</p><b>${pass}</b>`;

    if (!checkEmail(email)) return res.status(403).json({ message: CHECK_EMAIL });

    const mailer  = getMailer();
    const mail    = getMessage(fields);

    try {
      const user = await User.findOne({ where: { email: email }});
      if (!user) return res.status(403).json({ message: DISPO_EMAIL_REF });
    
      const hash    = await bcrypt.hash(pass, 10);
      const newUser = { ...user, pass: hash };
    
      await User.update(newUser, { where: { id: user.id }});
    
      await mailer.sendMail(mail);
      res.status(202).json({ message: AUTH_MESSAGE });

    } catch (err) {
      if (err.name === 'SequelizeEmptyResultError') {
        res.status(404).json({ message: USER_NOT_FOUND });
      } else if (err.name === 'SequelizeValidationError') {
        res.status(400).json({ message: USER_NOT_UPDATED });
      } else {
        res.status(400).json({ message: USER_NOT_PASS });
      }
    }
  })
}