javascriptnode.jsaxiosreset-password

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);
  }
};

Solution

  • 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!