DEV Community

Cover image for Reset Password
Chirag Bhardwaj
Chirag Bhardwaj

Posted on

Reset Password

Resetting a password in any login page has become so common in the applications nowadays.

this article gives you an insight of what are logics which are needed to add this feature to your react App.

This is the simple logic that we need to implement:

Image description

then, next question that probably will come to your mind:

1.how can we send OTP and how to verify OTP ?
2.how to send mail to the user with OTP ?
3.how to reset password against the DB ?
4.how many endpoints are needed to perform the whole operation?

PREQUISITE : you should have some knowledge about how to creating APIs and how to integrate in the frontend.

ENDPOINTS:
1- to generate the OTP, storing the OTP with email in the database and to send the OTP with email.(/reset)

MODEL FOR OTP:

import mongoose, { Schema } from "mongoose";



const OTPSchema = new Schema({
    email:{
        type:String,
        required:true
    },
    otp:{
        type:String,
        required:true
    }
},{timestamps:true});



const OTPmodal = mongoose.model("OTP",OTPSchema);

export default OTPmodal;
Enter fullscreen mode Exit fullscreen mode

LOGICS FOR APIs :

How to send OTPs and how to verify the OTP?

step 1 : when user click on the forgot password then user is navigate to the otp-filling page.
install through npm : nodemailer,otp-generator,bcrypt


<your Router>.post("/sendOTPMail", async (req, res) => {
  const { email } = req.body;
  const otp = "" + otpGenerator.generate(4, { digits: true, lowerCaseAlphabets: false, upperCaseAlphabets: false, specialChars: false });
  if (!email) {
    return res.status(400).json({
      message: "pls the mail properly"
    })
  }
  const emailRegex = /^([a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})$/;
  const isValid = () => {
    return emailRegex.test(email);
  }
  if (!isValid) {
    return res.status(400).json({
      message: "your mail is not valid,but enter correct email"
    })
  }
  else {
    const data = await OTPmodal.findOne({ email })
    if (data) {
      const updatedata = await OTPmodal.findOneAndUpdate({ email: email }, { otp: otp });
      if (updatedata) {
        const transport = nodemailer.createTransport({
          service: "gmail",
          auth: {
            user: "",
            pass: ""
          }
        })

        let message = {
          from: "<YOUR Gmail>",
          to: email,
          subject: "recovery password reset OTP",
          html: `<p>your OTP : ${otp}</p>`
        }
        transport.sendMail(message);
        return res.status(200).json({
          message: "recovery email sent"
        })
      }
      else{
        return res.status(500).json({
          message:"server side error"
        })
      }
    }
    else {
      const datacreate = await OTPmodal.create({
        email:email,
        otp:otp
      });
      if (datacreate) {
        const transport = nodemailer.createTransport({
          service: "gmail",
          auth: {
            user: "",
            pass: ""
          }
        })

        let message = {
          from: "<YOUR BUISNESS EMAIL>",
          to: email,
          subject: "recovery password reset OTP",
          html: `<p>your OTP : ${otp}</p>`
        }
        transport.sendMail(message);
        return res.status(200).json({
          message: "recovery email sent"
        })
      }
    }
  }
})
Enter fullscreen mode Exit fullscreen mode

so, what are we doing here?

The API endpoint, "/sendOTPMail," handles password recovery by:

1.Defining a POST route.
2.Extracting email and generating a 4-digit OTP.
3.Validating input, checking email presence and format.
4.Updating or creating records in the OTP database.
5.Using Nodemailer to email the OTP for password recovery.
6.Responding with 200 for success, 500 for server errors.

step 2: when user will enter the otp , how to verify that otp with the otp we have already stored in the DB?

<Route>.post("/verify",async(req,res)=>{
  const {userEmail,userOTP} =req.body;
 const data = await OTPmodal.findOne({email:userEmail});
 if(data.otp == userOTP){
  return res.status(200).json({
    message:"user is verified",
  })
 }
  return res.status(401).json({
    message:"incorrect password"
  })
})
Enter fullscreen mode Exit fullscreen mode

so what are we doing here?
1- we are fetching the data by finding against the email the user has written, that you can transfer through routes for payload.
2- if the otp matches with user input , it will return a successful message.

now, comes the question if user want to resend the email, then the above reset Api will again update the OTP generated recently against the email user has entered.
The user will now be forwarded to the reset Page.

step 3 : To reset the password.(we are assuming that each user have the unique email)

<Route>.patch("/reset",async (req,res)=>{
 const email = req.body.email;

 const password = bcrypt.hashSync(req.body.password, 10);

  userModal.findOneAndUpdate({email:email},{password:password}).then((data,err)=>{
    if(data){
      return res.status(201).json({
        message:"data updated"
      })
    }
    if(err){
      return res.status(201).json({
        message:"user not found"
      })
    }
  })
Enter fullscreen mode Exit fullscreen mode

How is it working?

The code defines a route handler for a PATCH request to "/reset". It retrieves an email and password from the request body, hashes the password, and updates the user's password in the database using Mongoose. The response includes a success message if the update is successful and an appropriate message if the user is not found, both with a status of 201 (Created). The code could benefit from improvements, such as using asynchronous hashing and more robust error handling.
After the data is update , user will redirected to the login page.

Thank you for reading the post.
You can comment your doubts as well.

Top comments (0)