From ac98abc23ed9a566820c9e40e08e9c93d5a48415 Mon Sep 17 00:00:00 2001 From: viviannTam Date: Tue, 30 Jan 2024 13:03:58 +0800 Subject: [PATCH] a --- consumerWebsite/controller/user_controller.js | 110 ++++++++++++++++++ consumerWebsite/routes/user.js | 4 + consumerWebsite/utils/error.js | 13 +++ consumerWebsite/utils/errorHandler.js | 0 consumerWebsite/utils/object_isEmpty.js | 8 ++ 5 files changed, 135 insertions(+) create mode 100644 consumerWebsite/controller/user_controller.js create mode 100644 consumerWebsite/utils/error.js create mode 100644 consumerWebsite/utils/errorHandler.js create mode 100644 consumerWebsite/utils/object_isEmpty.js diff --git a/consumerWebsite/controller/user_controller.js b/consumerWebsite/controller/user_controller.js new file mode 100644 index 0000000..5cc49e1 --- /dev/null +++ b/consumerWebsite/controller/user_controller.js @@ -0,0 +1,110 @@ +const connection = require('../database/mySQL'); +const { isEmpty } = require('../utils/object_isEmpty'); +const AppError = require('../utils/error'); +const bcrypt = require('bcryptjs'); +const { USER_MODEL, USER_LOGIN_MODEL, FORGOT_PASSWORD_MODEL, RESET_PASSWORD_MODEL } = require('../database/model/userModel'); +const nodemailer = require('nodemailer'); + +exports.user_forgotPassword = (req, res, next) => { + + //Check the form data is found or not + if (isEmpty(req.body)) return next(new AppError('form data not found', 400)); + + try { + + //Check the form data is valid or not + const { error } = FORGOT_PASSWORD_MODEL.validate(req.body); + + if (error) return next(new AppError(error.details[0].message, 400)); + + connection.query("SELECT * FROM user WHERE email = ?", [[req.body.email]], async (err, data1, fields) => { + if (err) return next(new AppError(err, 500)); + + if (data1.length == 0) { + return next(new AppError("user not exist", 400)) + } + + const otp = Math.floor(1000 + Math.random() * 9000); + + const otpExpier = new Date(); + otpExpier.setMinutes(otpExpier.getMinutes() + 1); + + connection.query("UPDATE user SET otp = ?, otpExpire = ? WHERE email = ?", [otp, otpExpier, req.body.email], (err, data2, fields) => { + if (err) return next(new AppError(err, 500)); + + const transporter = nodemailer.createTransport({ + service: 'Gmail', + auth: { + user: 'ecosavertp@gmail.com', + pass: 'Ecosaver1234!', + }, + }); + + const mailOptions = { + from: 'ecosavertp@gmail.com', + to: req.body.email, + subject: 'Password reset OTP', + text: `Your OTP (It is expired after 1 min) : ${otp}`, + }; + + transporter.sendMail(mailOptions, (error, info) => { + if (error) { + return next(new AppError(error, 500)); + } else { + res.json({ + data: "Your OTP send to the email" + }) + } + }); + + }) + + }) + + } + catch (err) { + return next(new AppError(err, 500)); + } +} + +exports.user_resetPassword = (req, res, next) => { + + const body = req.body; + const password = body.password; + const confirmPassword = body.confirmPassword; + + if (isEmpty(body)) return next(new AppError('form data not found', 400)); + + try { + + const { error } = RESET_PASSWORD_MODEL.validate(body); + + if (error) return next(new AppError(error.details[0].message, 400)); + + if (password.localeCompare(confirmPassword) != 0) return next(new AppError('passwords are not equal', 400)); + + connection.query("SELECT * FROM user WHERE otp = ? AND otpExpire > NOW()", [[body.otp]], async (err, data, fields) => { + if (err) return next(new AppError(err, 500)); + + if (data.length == 0) return next(new AppError('Invalid or expired OTP', 400)); + + const solt = await bcrypt.genSalt(10); + const hashedPassword = await bcrypt.hash(password, solt); + + connection.query("UPDATE user SET password = ?, otp = null, otpExpire = null WHERE otp = ?", [hashedPassword, body.otp], async (err, data, fields) => { + if (err) return next(new AppError(err, 500)); + + res.json({ + data: 'Password reset successful' + }) + + }) + + }) + + } + catch (err) { + return next(new AppError(err, 500)); + } + +} \ No newline at end of file diff --git a/consumerWebsite/routes/user.js b/consumerWebsite/routes/user.js index e81ac90..001d27b 100644 --- a/consumerWebsite/routes/user.js +++ b/consumerWebsite/routes/user.js @@ -76,4 +76,8 @@ router.delete("/delete", async function (req, res, next) { }); }); +const { user_register, user_login, user_forgotPassword, user_resetPassword } = require('../controller/user_controller'); +router.route("/forgotPassword").post(user_forgotPassword); +router.route("/resetPassword").post(user_resetPassword); + module.exports = router; diff --git a/consumerWebsite/utils/error.js b/consumerWebsite/utils/error.js new file mode 100644 index 0000000..a4ad20c --- /dev/null +++ b/consumerWebsite/utils/error.js @@ -0,0 +1,13 @@ +class AppError extends Error { + constructor(msg, statusCode) { + super(msg); + + this.statusCode = statusCode; + this.error = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; + this.isOperational = true; + + Error.captureStackTrace(this, this.constructor); + } +} + +module.exports = AppError; \ No newline at end of file diff --git a/consumerWebsite/utils/errorHandler.js b/consumerWebsite/utils/errorHandler.js new file mode 100644 index 0000000..e69de29 diff --git a/consumerWebsite/utils/object_isEmpty.js b/consumerWebsite/utils/object_isEmpty.js new file mode 100644 index 0000000..c4099a8 --- /dev/null +++ b/consumerWebsite/utils/object_isEmpty.js @@ -0,0 +1,8 @@ +//Checking that the request body is empty +exports.isEmpty = function (obj) { + for(var prop in obj) { + if(obj.hasOwnProperty(prop)) + return false; + } + return JSON.stringify(obj) === JSON.stringify({}); +} \ No newline at end of file