Moez Ben Rebah
Moez Ben Rebah

Reputation: 312

how to fetch reset password api in front-end Node js

I'm student in web development. Currently, I'm trying to build a basic project, where I'm stack in implementing reset password feature, I really need help in how fetching reset password API in front-end using Axios. In short, the reset password API that I implemented works fine on Postman, but whenever I tried to pass in front-end and fetch the API in order to enable users to enter their new password and passwordValidation I kinda lost, below I share my code snippets:

backend code reset password

resetPassword = async(req, res) => {
  try {
    // Step 1: Get user based on the token
    const validateHashedToken = crypto
                              .createHash('sha256')
                              .update(req.params.token)
                              .digest('hex');

    const user = await User.findOne(
                { 
                  passwordResetToken: validateHashedToken,
                  passwordResetExpires: { $gt: Date.now() }
                });
    
    user.password = req.body.password;
    user.passwordValidation = req.body.passwordValidation;
    user.passwordResetToken = undefined;
    user.passwordResetExpires = undefined;
    await user.save();

    // Step 3: Update the "passwordChangedAt" date
    // Step 4: Log the user in and send a JWT
    genResJWT(user, 200, res);

  } catch (error) {
    console.log('error', error)
  }
};

Routes:

router
  .route('/api/v1/users/resetpassword/:token')
  .get(viewsController.getResetPasswordUrl)
  .patch(viewsController.resetpassword);

controllers

exports.getResetPasswordUrl = async(req, res) => {
  try {
    const { token } = req.params.token;
    const validToken = await User.findOne(
      { 
        passwordResetToken: token
      }
    );

    res.status(200).render('resetPassword',
      {
    title: 'resetpassword',
    token: validToken
      });
  } catch (error) {
    console.log(error);
  }
};

exports.resetpassword = (req, res) => {
  // I'm stack here and I really need help
  res.status(200).render('profile', {
    title: 'reset password successfuly'
  });
};

front-end fetching api code:

import axios from 'axios';

export const resetPassword = async (password, passwordValidation) => {
  try {
    const res = await axios({
      method: 'PATCH',
      url:
        `http://127.0.0.1:3000/api/v1/users/resetpassword/:token`,
      data: {
        password,
        passwordValidation
      }
    });

    if (res.data.status === 'success') {
      window.setTimeout(() => {
    location.replace('/me');
      }, 500);
    }
  } catch (error) {
    console.log('error', error.response.data.message);
  }
};

Upvotes: 2

Views: 1638

Answers (2)

Moez Ben Rebah
Moez Ben Rebah

Reputation: 312

I fixed my issue with the following steps:

1- Use only GET request in my '/resetpassword/:token' route and submit the PATCH request with Axios.

2- Pass the 'token' along with the 'password' and the 'passwordValidation' as input data in the PATCH request.

3- create a hidden input within the 'resetPassword' form in order to submit the 'token' with the password and the 'passwordValidation' whenever users confirm their updated password.

Below is my code snippet in order to explain how goes the solution:

Routes:

router.get(
  '/resetpassword/:token',
  viewsController.resetPassword
  )

controllers

exports.resetPassword = (req, res) => {
  const token = req.params.token;
  res.status(200).render('/login', {
    title: 'reset password successfuly', { token }
  });
};

front-end fetching API code:

import axios from 'axios';

export const resetPassword = async (password, passwordValidation, token) => {
  try {
    const res = await axios({
      method: 'PATCH',
      url:
        `/api/v1/users/resetpassword/${token}`,
      data: {
        password,
        passwordValidation
      }
    });

    if (res.data.status === 'success') {
      window.setTimeout(() => {
        location.assign('/login');
      }, 1000);
    }
  } catch (error) {
    console.log('error', error.response.data.message);
  }
};

the resetPassword form:

extends goaheadtravel


block content
  main.main
    .resetpassword-form
      h2.heading-secondary.ma-bt-lg Please enter a new password and validate it
      form.form.resetpassword--form
        .form__group.ma-bt-md
          label.form__label(for='password') Password
          input#password.form__input(type='password' placeholder='••••••••' required='' minlength='8')
        .form__group.ma-bt-md
          label.form__label(for='passwordValidation') Confirm password
          input#passwordValidation.form__input(type='password' placeholder='••••••••' required='' minlength='8')
          input#resetToken(type='hidden' value=`${token}`)
        .form__group.right
          button.btn.btn--green Confirm new password

Hope that my solution will help other developers!

Upvotes: 0

Wowkster
Wowkster

Reputation: 195

On the front end, you are making a request to http://127.0.0.1:3000/api/v1/users/resetpassword/:token. Since token is a route parameter, you are directly passing in the string ":token" and not the actual value of the token.

Try this instead:

const res = await axios({
    method: 'PATCH',
    url:
        `http://127.0.0.1:3000/api/v1/users/resetpassword/${token}`,
    data: {
        password,
        passwordValidation
    }
  });

where token is a variable you need to define.

Assuming that you are using express, here is some documentation about parameter routing: https://expressjs.com/en/guide/routing.html#route-parameters

Upvotes: 2

Related Questions