/* eslint-disable no-unused-vars */ const bcrypt = require('bcryptjs') const { body, validationResult, param } = require('express-validator') const User = require('../models/GPS.User') const { _sr } = require('../plugins/serverResponses') const { SMS } = require('../plugins/SMS_Module') const { res500, checkValidations, removeWhiteSpaces, checkMobileNumber, normalizeMobileNumber, nameOptimizer, checkNationalCode, isPersian, generateRandomDigits } = require('../plugins/controllersHelperFunctions') const _faSr = _sr.fa function sendConfirmationSMS(userId) { return new Promise(async (resolve, reject) => { try { const user = await User.findById(userId) if (!user) throw new Error('invalid id') const mobileKey = generateRandomDigits(6) user.otp = mobileKey await user.save() const smsMsg = [ 'این شماره در وبسایت آسان سرویس ثبت گردیده.', ' کد تایید شماره همراه: ', mobileKey ] await SMS([user.mobile_number], smsMsg.join('')) resolve() } catch (err) { reject(err) } }) } module.exports.register_user = [ [ body('first_name') .notEmpty() .withMessage(_faSr.required.first_name) .bail() .isLength({ min: 2 }) .withMessage(_faSr.min_char.min2) .bail() .custom((value, { req }) => { if (removeWhiteSpaces(value).length < 2) return Promise.reject(_faSr.min_char.min2) if (!isPersian(value)) return Promise.reject(new Error('لطفا با حروف فارسی تایپ کنید')) else return true }), body('last_name') .notEmpty() .withMessage(_faSr.required.first_name) .bail() .isLength({ min: 2 }) .withMessage(_faSr.min_char.min2) .bail() .custom((value, { req }) => { if (removeWhiteSpaces(value).length < 2) return Promise.reject(_faSr.min_char.min2) if (!isPersian(value)) return Promise.reject(new Error('لطفا با حروف فارسی تایپ کنید')) else return true }), body('national_code') .notEmpty() .withMessage(_faSr.required.national_code) .bail() .custom((value, { req }) => { if (checkNationalCode(value)) return true else return Promise.reject(_faSr.format.national_code) }) .bail() .custom((value, { req }) => { const nationalCode = value.trim() return User.findOne({ national_code: nationalCode }).then(user => { if (user && user.national_code === nationalCode) return Promise.reject(new Error('کاربر با این کد ملی از قبل وجود دارد')) else return true }) }), body('province_name').notEmpty().withMessage(_faSr.required.province), body('city_name').notEmpty().withMessage(_faSr.required.city), body('shopName') .notEmpty() .withMessage(_faSr.required.address), body('mobile_number') .notEmpty() .withMessage(_faSr.required.phone_number) .bail() .custom((value, { req }) => { const mobileNStatus = checkMobileNumber(value) if (!mobileNStatus) return Promise.reject(_faSr.format.phone_number) else return Promise.resolve() }) .bail() .custom((value, { req }) => { const mobileNumber = value.trim() return User.findOne({ mobile_number: mobileNumber }).then(user => { if (user && user.mobile_number === mobileNumber) return Promise.reject(new Error('کاربر با این شماره موبایل از قبل وجود دارد')) else return true }) }), body('password') .isLength({ min: 4 }) .withMessage(_faSr.min_char.min4) .custom((value, { req }) => { if (value === req.body.password_confirmation) return true else return Promise.reject(_faSr.response.passwords_not_match) }) ], checkValidations(validationResult), async (req, res) => { try { const { first_name, last_name, national_code, province_name, city_name, mobile_number, password, shopName } = req.body const data = { last_name, province_name, city_name, shopName } data.first_name = nameOptimizer(first_name) data.national_code = national_code.trim() data.mobile_number = normalizeMobileNumber(mobile_number) // hash user password and done const salt = await bcrypt.genSalt(10) const hash = await bcrypt.hash(password, salt) data.password = hash const user = new User(data) await user.save() return res.json({ message: _faSr.response.success_save }) } catch (err) { const registerFailurMsg = 'مشکلی در ثبت نام پیش آمده، لطفا مجددا تلاش کنید' res500(res, registerFailurMsg) } } ] module.exports.update_user = [ [ body('first_name') .notEmpty() .withMessage(_faSr.required.first_name) .bail() .isLength({ min: 2 }) .withMessage(_faSr.min_char.min2) .bail() .custom((value, { req }) => { if (removeWhiteSpaces(value).length < 2) return Promise.reject(_faSr.min_char.min2) if (!isPersian(value)) return Promise.reject(new Error('لطفا با حروف فارسی تایپ کنید')) else return true }), body('last_name') .notEmpty() .withMessage(_faSr.required.first_name) .bail() .isLength({ min: 2 }) .withMessage(_faSr.min_char.min2) .bail() .custom((value, { req }) => { if (removeWhiteSpaces(value).length < 2) return Promise.reject(_faSr.min_char.min2) if (!isPersian(value)) return Promise.reject(new Error('لطفا با حروف فارسی تایپ کنید')) else return true }), body('province_name').notEmpty().withMessage(_faSr.required.province), body('city_name').notEmpty().withMessage(_faSr.required.city), body('shopName') .notEmpty() .withMessage(_faSr.required.field), body('address') .notEmpty() .withMessage(_faSr.required.address), body('cell_number') .notEmpty() .withMessage(_faSr.required.address), body('birthDate') .notEmpty() .withMessage(_faSr.required.address), ], checkValidations(validationResult), async (req, res) => { try { const { first_name, last_name, province_name, city_name, shopName, birthDate, address, cell_number } = req.body const data = { last_name, province_name, city_name, shopName, birthDate, address, cell_number } data.first_name = nameOptimizer(first_name) await User.findByIdAndUpdate( req.params.id, data ) return res.json({ message: _faSr.response.success_save }) } catch (err) { const registerFailurMsg = 'مشکلی در به روز رسانی پیش آمده، لطفا مجددا تلاش کنید' res500(res, registerFailurMsg) } } ] module.exports.update_user_password = [ [ body('newPassword') .isLength({ min: 4 }) .withMessage(_faSr.min_char.min4) .custom((value, { req }) => { if (value === req.body.password_confirmation) return true else return Promise.reject(_faSr.response.passwords_not_match) }), body('password') .isLength({ min: 4 }) .withMessage(_faSr.min_char.min4) ], checkValidations(validationResult), async (req, res) => { try { const { password, newPassword } = req.body const { user_id } = req const salt = await bcrypt.genSalt(10) const hash = await bcrypt.hash(newPassword, salt) const user = await User.findById(user_id) if (!user) throw new Error(_faSr.not_found.user_id) const passwordMatch = await bcrypt.compare(password, user.password) if (!passwordMatch) throw new Error('err') user.password = hash await user.save() return res.json({ message: _faSr.response.success_save }) } catch (err) { if (err) return res500(res, err) } } ] module.exports.send_otp = [ [ body('mobile_number') .notEmpty() .withMessage(_faSr.required.phone_number) ], checkValidations(validationResult), async (req, res) => { try { const { mobile_number } = req.body const user = await User.findOne({ mobile_number }) if (!user) throw new Error(_sr.fa.not_found.user_id) await sendConfirmationSMS(user.id) res.status(200).json({msg:"ok"}) } catch (err) { if (err) return res500(res, err) } } ] module.exports.check_otp = [ [ body('mobile_number') .notEmpty() .withMessage(_faSr.required.phone_number), body('otp') .notEmpty() .withMessage(_faSr.required.phone_number) ], checkValidations(validationResult), async (req, res) => { try { const { mobile_number, otp } = req.body const user = await User.findOne({ mobile_number }) if (!user) throw new Error(_sr.fa.not_found.user_id) if (user.otp !== otp) throw new Error("کد اشتباه است") if (user.otp === otp) res.status(200).json({ msg: "ok" }) } catch (err) { if (err) return res500(res, err.message) } } ] module.exports.resetpass_otp = [ [ body('mobile_number') .notEmpty() .withMessage(_faSr.required.phone_number), body('otp') .notEmpty() .withMessage(_faSr.required.phone_number), body('password') .isLength({ min: 4 }) .withMessage(_faSr.min_char.min4) .custom((value, { req }) => { if (value === req.body?.password_confirmation) return true else return Promise.reject(_faSr.response.passwords_not_match) }) ], checkValidations(validationResult), async (req, res) => { try { const { mobile_number, otp, password } = req.body const salt = await bcrypt.genSalt(10) const hash = await bcrypt.hash(password, salt) const user = await User.findOne({ mobile_number }) if (!user) throw new Error(_sr.fa.not_found.user_id) if (user.otp !== otp) throw new Error("کد اشتباه است") if (user.otp === otp) { user.password = hash user.otp = generateRandomDigits(6) user.save() res.status(200).json({ msg: _sr.fa.response.success_save }) } } catch (err) { if (err) return res500(res, err.message) } } ] module.exports.getCurrent = async (req, res) => { const user = await User.findById(req.user_id).select('-password -token -otp -seenByAdmin') if (!user || !user.active) return res.ststus(404).json({ msg: _sr.fa.not_found.user_id }) else return res.status(200).json(user) } module.exports.getUsersForAdmin = async (req, res) => { const user = await User.find({}).sort({ active: 1, created_at: -1 }).select('-password -token -otp -seenByAdmin') res.status(200).json(user) } module.exports.getUserForAdmin = async (req, res) => { const user = await User.findById(req.params.id).select('-password -token -otp -seenByAdmin') if (!user) { return res.status(404).json({ msg: _sr.fa.not_found.user_id }) }else { user.seenByAdmin = true user.save() res.status(200).json(user) } } module.exports.activeUser = [ [ param('status').notEmpty().isBoolean().withMessage('این استاتوس اشتباه است'), param('id').notEmpty().isMongoId().withMessage('این ایدی اشتباه است') ], checkValidations(validationResult), async (req, res) => { const data = await User.findByIdAndUpdate(req.params.id, { active: req.params.status }, { new: true }).select('-password -token -otp -seenByAdmin') if (!data) return res.status(404).json({ msg: _sr.fa.not_found.user_id }) res.status(200).json(data) } ]