Files
Exchange/server/routes/auth.ts
2025-11-07 22:24:40 +01:00

998 lines
31 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as express from 'express';
export const authRoutes = express.Router()
import * as uuid4 from 'uuid4'
import * as crypto from 'crypto'
import * as mongoose from 'mongoose'
import { logger } from '../api/logger'
import { publishQueueConnection } from '../api/amqp'
import myError from '../api/myError'
import { User, VerificationCode, VerificationPhoneCode } from '../db/user'
import { userValidationRules, validate, isEmailValid, isValidMobilePhone, numbersFormatter } from '../middlewares/validation'
import successRes from '../middlewares/response'
import tryCatch from '../middlewares/tryCtach'
import { isAuthorized } from '../middlewares/auth'
import * as fetch from 'node-fetch'
import { preventBruteForce, rateLimiterMiddleware } from '../middlewares/preventBruteForce'
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////// GET ENDPOINTS /////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
// This end point check "Authentication" of users from MongoDB.
authRoutes.get('/auth',
rateLimiterMiddleware,
tryCatch((req, res, next) => {
if (!req.session.userId) {
logger.error('Unauthorized cookie')
const error = new myError(
'Unauthorized cookie',
400,
1,
'کاربر حق دسترسی ندارد!',
'خطا رخ داد'
)
next(error)
} else {
successRes(res, '', { isAuth: true })
}
}))
// This end point delete "Token" of users who want to logout from MongoDB.
authRoutes.get('/logout',
rateLimiterMiddleware,
isAuthorized,
tryCatch((req, res, next) => {
const agant = req.useragent
const userActivity = {
action: 'LOGOUT',
timestamp: Date.now(),
device: agant.source,
ip: req.ip
}
User.findOneAndUpdate({ _id: req.session.userId }, { $push: { userActivities: userActivity } })
.catch((err) => {
logger.error(`Updating user activity has some error: ${err} `)
})
req.session.destroy()
successRes(res)
}))
authRoutes.get('/verifyEmails',
rateLimiterMiddleware,
userValidationRules('query', 'string'),
validate,
tryCatch((req, res, next) => {
const id = req.query.string
VerificationCode.findOne({ name: id })
.then((doc) => {
if (!doc) {
const error = new myError(
'Verification Code is not valid!',
400,
5,
'کد راستی آزمایی معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
User.findOne({ emailVerificationString: doc._id })
.then((user) => {
if (user && user.emailVerificationString.toString() === doc._id.toString()) {
user.email.validated = true
user.emailVerificationString = undefined
user.email.address = doc.email
user.save()
.then(() => {
const data = {
email: user.email.address
}
doc.remove().catch((err)=>{
logger.error(err)
})
successRes(res, 'Email is verified', data)
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'Verification Code is not valid!',
400,
5,
'کد راستی آزمایی معتبر نیست!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
logger.error(`The query on User Collection with emailVerificationString ${id} has some errors: ${err}`)
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
authRoutes.get('/requestForPhoneCode',
rateLimiterMiddleware,
userValidationRules('query', 'phoneNumber'),
validate,
tryCatch((req, res, next) => {
const userId = req.session.userId
const phoneNumber = numbersFormatter(req.query.phoneNumber, 'en')
const code = Math.floor(Math.random() * 10000)
const data = {
pattern_code : process.env.SMS_API_PHONE_PATTERN_CODE,
originator: process.env.SMS_API_DEFINITE_SENDER_NUMBER,
recipient: phoneNumber.toString(),
values:{ "verification-code" : code.toString()}
}
const body = {
phoneNumber,
sessionId: req.cookies.sessionId,
code
}
const verificationPhoneCode = new VerificationPhoneCode({ ...body })
verificationPhoneCode.save()
.then(() => {
if (userId) {
User.findOne({ _id: userId })
.then((user) => {
if (user && user._id.toString() === userId) {
user['tempPhoneNumber'] = verificationPhoneCode._id
user.save()
.then(() => {
fetch('http://rest.ippanel.com/v1/messages/patterns/send', {
method: 'POST',
body : JSON.stringify(data),
headers: {
'Authorization' : process.env.SMS_API_ACCESS_KEY,
'Content-Type': 'application/json',
'Accept' : '*/*',
'Connection' : 'Keep-Alive'
}
})
.catch((err) => {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
throw(error)
})
.then(res => res.json())
.then((response) => {
if (response.status === 'OK') {
successRes(res, '')
} else {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
})
.catch((err) => {
next(err)
})
} else {
}
})
.catch((err) => {
next(err)
})
} else {
fetch('http://rest.ippanel.com/v1/messages/patterns/send', {
method: 'POST',
body : JSON.stringify(data),
headers: {
'Authorization' : process.env.SMS_API_ACCESS_KEY,
'Content-Type': 'application/json',
'Accept' : '*/*',
'Connection' : 'Keep-Alive'
}
})
.catch((err) => {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
throw(error)
})
.then(res => res.json())
.then((response) => {
if (response.status === 'OK') {
successRes(res, '')
} else {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
authRoutes.get('/verifyPhoneCode',
rateLimiterMiddleware,
tryCatch((req, res, next) => {
const phoneCode = req.query.phoneCode
const userId = req.session.userId
const sessionId = req.cookies.sessionId
VerificationPhoneCode.findOne({ $and: [ { sessionId: sessionId }, { code: phoneCode } ] })
.then((item) => {
if (item && item.sessionId === sessionId) {
if(item.code === phoneCode) {
let query
if (userId) {
query = { tempPhoneNumber: item._id }
} else {
query = { 'phoneNumber.number': item.phoneNumber }
}
User.findOne(query)
.then((user) => {
if (user) {
user.phoneNumber.number = item.phoneNumber
user.phoneNumber.validated = true
user['tempPhoneNumber'] = undefined
user.save()
.then(() => {
item.remove()
.catch((err) => {
logger.error(err)
})
successRes(res, '', item.phoneNumber)
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'The code is not valid!',
400,
11,
'کد وارد شده معتبر نیست!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'The code is not valid!',
400,
11,
'کد وارد شده معتبر نیست!',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'The code is not valid!',
400,
11,
'کد وارد شده معتبر نیست!',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}))
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////// POST ENDPOINTS /////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
/// ///////////////////////////////////////////////////////////////////////////////////////////////
// This end point get the users' information and save those in MongoDB.
authRoutes.post('/register',
//rateLimiterMiddleware,
userValidationRules('body', 'name'),
userValidationRules('body', 'lastName'),
userValidationRules('body', 'username'),
userValidationRules('body', 'password'),
validate,
tryCatch((req, res, next) => {
const username = req.body.username
let rand
let mailOptions
let dataSms
let code
let isEmail = false
let isPhoneNumber = false
let setNewTempPhone = () => {
return null
}
let setEmailVeificationCode = () => {
return null
}
if (isEmailValid(username)) {
isEmail = true
} else if (isValidMobilePhone(username)) {
isPhoneNumber = true
}
if (isPhoneNumber) {
code = Math.floor(Math.random() * 10000)
dataSms = {
pattern_code : process.env.SMS_API_PHONE_PATTERN_CODE,
originator: process.env.SMS_API_DEFINITE_SENDER_NUMBER,
recipient: username.toString(),
values:{ "verification-code" : code.toString()}
}
}
if (isEmail) {
//const rand = process.env.NODE_ENV === 'test' ? 'cb0059c2-5566-4967-8c9d-1126d1e9eda4' : uuid4()
rand = uuid4()
const link = `${process.env.API}/verify?type=email&string=${rand}`
mailOptions = {
from: process.env.SENDER_ADDRESS, // sender address
to: username,
subject: 'Please confirm your Email account',
html: 'Hello,<br> Please Click on the link to verify your email.<br><a href=' + link + '>Click here to verify</a>'
}
}
let body
let user
let verificationPhoneCode
if (isEmail) {
setEmailVeificationCode = () => {
const bodyEmailCode = {
name: rand
}
const newEmailCode = new VerificationCode({ ...bodyEmailCode })
return newEmailCode.save()
.then(() => {
body = {
name: req.body.name,
lastName: req.body.lastName,
email: { address : username},
password: req.body.password,
label: ['USER'],
emailVerificationString: newEmailCode._id
}
user = new User({ ...body })
})
.catch((err) => {
throw err
})
}
} else if (isPhoneNumber) {
setNewTempPhone = () => {
const bodyPhoneCode = {
phoneNumber: numbersFormatter(username, 'en'),
sessionId: req.cookies.sessionId,
code
}
verificationPhoneCode = new VerificationPhoneCode({ ...bodyPhoneCode })
return verificationPhoneCode.save()
.then(() => {
body = {
name: req.body.name,
lastName: req.body.lastName,
phoneNumber: {
number: numbersFormatter(username, 'en'),
validated: false
},
password: req.body.password,
label: ['USER']
}
user = new User({ ...body })
})
.catch((err) => {
if (err.name = 'MongoError' && err.code === 11000) {
logger.error(`The save action on Verification Collection with document ${bodyPhoneCode} has some errors: ${err}`)
const error = new myError(
'!',
400,
9,
'لطفا چند دقیقه بعد از درخواست قبلی صبر نمیایید!',
'خطا رخ داد '
)
throw (error)
}
else
throw (err)
})
}
}
Promise.all([setNewTempPhone(), setEmailVeificationCode()])
.then(() => {
user.save()
.then((usr) => {
const data = {
email: user.email.address,
tempPhoneNumber: verificationPhoneCode ? verificationPhoneCode._id : undefined,
isActive: user.isActive,
}
if (isEmail) {
const body1 = {
aUsername: username,
aPass: req.body.password,
aPassConfirm: req.body.password,
aFullname: req.body.name + req.body.lastName,
aTitle: username,
userId: usr._id,
aGrps: ["5fb38b5de54aaa00062de4cb"],//[group._id.toString()],
aEmail: username
}
const body1Json = JSON.stringify(body1)
console.log(body1Json)
fetch("http://localhost:3001/tickets/register", {
method: 'POST',
body: body1Json,
headers: {
accessToken: process.env.ACCESS_TOKEN,
'Content-Type': 'application/json'
}
})
.then((res) => res.json())
.then((response) => { console.log('response: ', response) })
.catch((err) => { console.log('err: ', err) })
successRes(res, 'Registration is done successfully', data, { isEmail })
publishQueueConnection(mailOptions)
} else if (isPhoneNumber) {
const body1 = {
aUsername: username,
aPass: req.body.password,
aPassConfirm: req.body.password,
aFullname: req.body.name + req.body.lastName,
aTitle: username,
//aGrps: [group._id.toString()],
userId: usr._id,
aEmail: username.concat("@gmail.com")
}
const body1Json = JSON.stringify(body1)
fetch("http://localhost:3001/tickets/register", {
method: 'POST',
body: body1Json,
headers: {
accessToken: process.env.ACCESS_TOKEN,
'Content-Type': 'application/json'
}
})
.then((res) => res.json())
.then((response) => {})
successRes(res, 'Registration is done successfully', data, { isPhoneNumber })
fetch('http://rest.ippanel.com/v1/messages/patterns/send',
{
method: 'POST',
body: JSON.stringify(dataSms),
headers: {
'Authorization' : process.env.SMS_API_ACCESS_KEY,
'Content-Type': 'application/json',
'Accept' : '*/*',
'Connection' : 'Keep-Alive'
}
})
.catch((err) => {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
logger.error(error.message);
})
.then(res => res.json()) // expecting a json response
.then((response) => {
if (response.status !== 'OK') {
const error = new myError(
'The Sms service is not responding!',
400,
11,
'سرویس ارسال پیامک دچار مشکل شده است. لطفا لحظاتی بعد دوباره اقدام فرمایید.',
'خطا رخ داد'
)
logger.error(error.message)
}
})
.catch((err) => {
logger.error(err)
})
}
})
.catch((err) => {
if (err.name = 'MongoError' && err.code === 11000) {
logger.error(`The save action on User Collection with document ${req.body.lastName} has some errors: ${err}`)
const error = new myError(
'The user has registered already!',
400,
9,
'شما قبلا ثبت نام کرده اید!',
'خطا رخ داد '
)
next(error)
} else {
next(err)
}
})
})
.catch((err) => {
next(err)
})
}))
authRoutes.post('/sendEmailVerificationLink',
rateLimiterMiddleware,
userValidationRules('body', 'email'),
validate,
tryCatch((req, res, next) => {
const email = req.body.email
User.findOne({ email: email })
.then((user) => {
if (!user) {
const error = new myError(
`Email address ${email} is not valid!`,
400,
12,
'آدرس ایمیل معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
// const rand = uuid4()
const rand = process.env.NODE_ENV === 'test' ? 'cb0059c2-5566-4967-8c9d-1126d1e9eda5' : uuid4()
const link = `${process.env.API}/verify?type=email&string=${rand}`
const mailOptions = {
from: process.env.SENDER_ADDRESS, // sender address
to: email,
subject: 'Please confirm your Email account',
html: 'Hello,<br> Please Click on the link to verify your email.<br><a href=' + link + '>Click here to verify</a>'
}
const bodyEmailCode = {
name: rand
}
const newEmailCode = new VerificationCode({ ...bodyEmailCode })
newEmailCode.save()
.then(() => {
user.updateOne({ $set: { emailVerificationString: newEmailCode._id } })
.then(() => {
const data = {
email: email
}
successRes(res, 'Please verify your email', data)
publishQueueConnection(mailOptions)
})
.catch((err) => {
next(err)
})
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
authRoutes.post('/sendPasswordVerificationLink',
rateLimiterMiddleware,
userValidationRules('body', 'email'),
validate,
tryCatch((req, res, next) => {
const email = req.body.email
User.findOne({ email: email })
.then((user) => {
if (!user) {
const error = new myError(
'Email address is not valid!',
400,
12,
'آدرس ایمیل معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
const rand = process.env.NODE_ENV === 'test' ? 'e39459ee-18b4-4967-aaaa-f22fb26a8beb' : uuid4()
// const rand = uuid4()
const link = `${process.env.API}/verify?type=password&string=${rand}`
const mailOptions = {
from: process.env.SENDER_ADDRESS, // sender address
to: email,
subject: 'Please confirm your Email account',
html: 'Hello,<br> Please Click on the link to verify your email.<br><a href=' + link + '>Click here to verify</a>'
}
const hash = crypto.createHmac('sha256', process.env.CRYPTO_SECRET)
.update(rand)
.digest('hex')
const verificationCode = new VerificationCode({ code: hash })
verificationCode.save()
.then(() => {
user.updateOne({ $set: { resetPasswordVerificationString: mongoose.Types.ObjectId(verificationCode._id) } })
.then(() => {
successRes(res, 'Please verify your email')
publishQueueConnection(mailOptions)
})
.catch((err) => {
next(err)
})
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
logger.error(`The find action on User Collection with email ${email} has some errors: ${err}`)
next(err)
})
}))
authRoutes.post('/resetPassword',
rateLimiterMiddleware,
userValidationRules('body', 'id'),
userValidationRules('body', 'password'),
validate,
tryCatch((req, res, next) => {
const id = req.body.id
const hash = crypto.createHmac('sha256', process.env.CRYPTO_SECRET)
.update(id)
.digest('hex')
VerificationCode.findOne({ code: hash })
.then((doc) => {
if (!doc) {
logger.warn(`ResetPasswordVerificationString ${hash} is not valid!`)
const error = new myError(
'Verification Code is not valid!',
400,
5,
'کد راستی آزمایی معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
User.findOne({ resetPasswordVerificationString: doc._id })
.then((user) => {
if (!user) {
logger.error(`The query on User Collection with resetPasswordVerificationString ${id} has response null!`)
const error = new myError(
'Verification Code is not valid!', 400,
5,
'کد راستی آزمایی معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
user.password = req.body.password
user.resetPasswordVerificationString = undefined
VerificationCode.deleteOne({ code: hash })
.catch((err) => {
logger.error(err)
})
user.save()
.then(() => {
const data = {
email: user.email.address
}
successRes(res, 'password is successfuly reset', data)
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
authRoutes.post('/resetPasswordWithPhone',
rateLimiterMiddleware,
userValidationRules('body', 'password'),
userValidationRules('body', 'passwordConfirm'),
// userValidationRules('body', 'verificationCode'),
validate,
tryCatch((req, res, next) => {
console.log(req.body)
const password = req.body.password
const passwordConfirm = req.body.passwordConfirm
const verificationCode = req.body.verificationCode
const sessionId = req.cookies.sessionId
if (password !== passwordConfirm) {
const error = new myError(
'passwords do not match!',
400,
11,
'پسورد ها باهم همخوانی ندارند',
'خطا رخ داد'
)
next(error)
} else {
VerificationPhoneCode.findOne({ $and: [ { code: verificationCode }, { sessionId: sessionId } ] })
.then((item) => {
if (item && item.code.toString() === verificationCode.toString() && item.sessionId.toString()=== sessionId.toString()) {
User.findOne({ 'phoneNumber.number': item.phoneNumber })
.then((user) => {
if (user && user.phoneNumber && user.phoneNumber.number === item.phoneNumber) {
if (user.phoneNumber.validated === true) {
user.password = password
user.save()
.then(() => {
item.remove()
.then(() => {
successRes(res, '', user.phoneNumber.number)
}).catch((err)=>{ next(err)})
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'The phoneNumber is not validated!',
400,
18,
'شماره مورد نظر هنوز راستی آزمایی نشده است!',
'خطا رخ داد'
)
next(error)
}
} else {
const error = new myError(
'The code is not valid!',
400,
11,
'کد معتبر نیست',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
} else {
const error = new myError(
'The code is not valid!',
400,
11,
'کد معتبر نیست',
'خطا رخ داد'
)
next(error)
}
})
.catch((err) => {
next(err)
})
}
}))
authRoutes.post('/changePassword',
rateLimiterMiddleware,
isAuthorized,
userValidationRules('body', 'password'),
validate,
userValidationRules('body', 'newPassword'),
validate,
tryCatch((req, res, next) => {
User.findOne({ email: req.session.email })
.then((user) => {
if (!user) {
logger.warn('Email address is not valid!')
const error = new myError(
'Email address is not valid!',
12,
400,
'آدرس ایمیل معتبر نیست!',
'خطا رخ داد'
)
next(error)
} else {
user.comparePasswordPromise(req.body.password)
.then((isMatch) => {
if (!isMatch) {
logger.warn('Password is not valid!')
const error = new myError(
'Inputs are not valid!',
400,
15,
'ورودی های درخواستی معتبر نیستند!',
'خطا رخ داد'
)
next(error)
} else {
user.password = req.body.newPassword
user.save()
.then(() => {
successRes(res, 'password is successfuly changed')
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}
})
.catch((err) => {
next(err)
})
}))
// This end point execute the following actions:
// 1. Find the document of a user who send the email.doc
// 2. Compare the Passord to hash of the password which is stored in MongoDB.
// 3. Generate a token and save it in MongoDB.
// 4. Send the tocken as a cookie to client.
authRoutes.post('/login',
//rateLimiterMiddleware,
//preventBruteForce,
userValidationRules('body', 'username'),
userValidationRules('body', 'password'),
validate,
tryCatch((req, res, next) => {
const agent = req.useragent
const username = req.body.username
let isEmail = false
let isPhoneNumber = false
let query
if (isEmailValid(username)) {
isEmail = true
query = { 'email.address' : username}
} else if (isValidMobilePhone(username)) {
isPhoneNumber = true
query = { 'phoneNumber.number': username }
}
User.findOne(query)
.then((user) => {
if (!user) {
const error = new myError(
'Email or Password are not valid!',
400,
8,
'نام کاربری یا گذرواژه معتبر نیستند!',
'خطا رخ داد'
)
next(error)
} else if (user && isEmail && user.email.validated !== true) {
const error = new myError(
'The email is not verified!',
400,
17,
'آدرس ایمیل شما هنوز راستی آزمایی نشده است!',
'خطا رخ داد'
)
next(error)
} else if (user && isPhoneNumber && user.phoneNumber.number && user.phoneNumber.validated !== true) {
const error = new myError(
'The mobile phone is not verified!',
400,
18,
'شماره موبایل شما هنوز راستی آزمایی نشده است!',
'خطا رخ داد'
)
next(error)
} else if (user && user.isActive !== true) {
const error = new myError(
'The account is not active!',
400,
18,
'حساب کاربری شما غیرفعال شده است!',
'خطا رخ داد'
)
next(error)
} else {
user.comparePasswordPromise(req.body.password)
.then((isMatch)=> {
if (!isMatch) {
logger.info('Passwords are not match')
const error = new myError(
'Username or Password are not valid!',
400,
8,
'نام کاربری یا گذرواژه معتبر نیستند!',
'خطا رخ داد'
)
next(error)
} else {
const userActivity = {
action: 'LOGIN',
timestamp: Date.now(),
device: agent.source,
ip: req.ip
}
user.userActivities.push(userActivity)
user.save()
.then(() => {
req.session.userId = user._id
const profile = {
name: user.name,
lastName: user.lastName,
userId: user._id,
userType: user.userType
}
successRes(res, '', profile)
})
.catch((err) => {
logger.error(`Adding activity has some errors: ${err}`)
const error = new myError(
'Error happened during the login!',
500,
16,
'در ورود شما مشکلی پیش آمده است!',
'خطا در سرور'
)
next(error)
})
}
})
.catch((err) => {
logger.error(`comparePassword method has some errors: ${err}`)
const error = new myError(
'Error happened during the login!',
500,
16,
'در ورود شما مشکلی پیش آمده است!',
'خطا در سرور'
)
next(error)
})
}
})
.catch((err) => {
logger.error(`The find action on User Collection with email ${req.body.email} has some errors: ${err}`)
const error = new myError(
'Error happened during the login!',
500,
16,
'در ورود شما مشکلی پیش آمده است!',
'خطا در سرور'
)
next(error)
})
}))