const bcrypt = require('bcryptjs') const jwt = require('jsonwebtoken') const { body, param, validationResult } = require('express-validator') const { secretKey } = require('../authentication') const { _sr } = require('../plugins/serverResponses') const { checkValidations } = require('../plugins/controllersHelperFunctions') const User = require('../models/User') module.exports.login = [ [ body('username') .isLength({ min: 4 }) .withMessage(_sr.fa.min_char.min4) .bail() .if((value, { req }) => { return req.body.password && req.body.password.length >= 4 }) .custom((value, { req }) => { return User.findOne({ $or: [{ email: value.toLowerCase().trim() }, { national_code: value }, { username: value }] }).then(user => { if (!user) return Promise.reject(_sr.fa.not_found.password) else return true }) }), body('password') .notEmpty() .withMessage(_sr.fa.required.password) .bail() .isLength({ min: 4 }) .withMessage(_sr.fa.min_char.min4), body('remember_me') .exists() .withMessage(_sr.fa.required.remember_me) .bail() .isBoolean() .withMessage(_sr.fa.format.boolean) ], checkValidations(validationResult), async (req, res) => { try { const { username, password } = req.body const user = await User.findOne({ $or: [{ email: username.toLowerCase().trim() }, { national_code: username }, { username }] }) if (!user) throw new Error('err') const passwordMatch = await bcrypt.compare(password, user.password) if (!passwordMatch) throw new Error('err') const token = await jwt.sign({ _id: user._id }, secretKey, { expiresIn: req.body.remember_me ? '30d' : '7d' }) user.token = token await user.save() return res.status(200).json({ token }) } catch (err) { return res.status(422).json({ validation: { username: { msg: _sr.fa.not_found.password } } }) } } ]