Обновлять пароль только после того, как Условие встречено в NodeJS и ExpressJS - PullRequest
1 голос
/ 15 октября 2019

Я пытаюсь создать компонент, в котором я запрашиваю у пользователя его текущий пароль и два ввода, которые должны совпадать, чтобы изменить его пароль.

Пока что я создал свой маршрут следующим образом:

// @route       POST api/profiles/edit-password
// @description Update user password
// @access      Private
// @task        ALMOST DONE - NEEDS TO AVOID PASSWORD UPDATING IF NULL
router.post(
  '/edit-password',
  [
    auth,
    [
      check('old_password', 'Old Password is required')
        .not()
        .isEmpty(),
      check('old_password', 'Old Password does not match')
        .exists(),
      check('password', 'New Password is required')
        .not()
        .isEmpty(),
      check('new_password', 'Confirm Password is required')
        .not()
        .isEmpty()
    ]
  ],
  async (req, res) => {
    const errors = validationResult(req);
    // Check for errors
    if (!errors.isEmpty()) {
      return res.status(400).json({ errors: errors.array() });
    }

    // Destructure
    const {
      old_password,
      password,
      new_password,
    } = req.body;

    // Build profile object
    const profileFields = {};
    profileFields.user = req.user.id;
    if (password === new_password) {
      // Encrypt Password
      passwordEncrypt = password;
      const salt = await bcrypt.genSalt(10);
      profileFields.password = await bcrypt.hash(passwordEncrypt, salt);
    }

    try {

      let formOldPassword = old_password; // req.body.old_password can be used as well.
      let loggedPassword = await User.findById(req.user.id).select('password');

      // Old password input with password stored in DB
      const isMatch = await bcrypt.compare(formOldPassword, loggedPassword);

      console.log(isMatch ? 'yes' : 'no');

      // In case old password input does not match with password stored in DB, prevent from updating password
      if (!isMatch) {
        return res
          .status(400)
          .json({ errors: [{ msg: 'Invalid credentials' }] });
      }

      let profile = await User.findByIdAndUpdate(req.user.id, profileFields, { new: true });

      return res.json(profile);


    } catch (err) {
      console.error(err.message);
      res.status(500).send('Server error');
    }
  }
);

Я передаю три ввода из формы, которую я имею в функциональном компоненте, это:

  • old_password
  • пароль
  • new_password

После этого я создаю пустой объект, который буду использовать для обновления указанных значений, которые соответствуют запрашивающему его пользователю. После этого я поставил условие, что если совпадают и new_password, и verify_password, он должен зашифровать пароль с помощью хэша (здесь я предполагаю, что причина ошибки; я могу ошибаться):

if (password === new_password) {
      // Encrypt Password
      passwordEncrypt = password;
      const salt = await bcrypt.genSalt(10);
      profileFields.password = await bcrypt.hash(passwordEncrypt, salt);
    }

Затем я перехожу, чтобы позвонить в базу данных, чтобы получить пароль, соответствующий пользователю вошедшего в систему, и сравнить его сохраненный пароль с данными, представленными в форме:

let formOldPassword = old_password; // req.body.old_password can be used as well.
let loggedPassword = await User.findById(req.user.id).select('password');

// Old password input with password stored in DB
const isMatch = await bcrypt.compare(formOldPassword, loggedPassword);

Теперь оба входа должнысовпадают, но в случае, если это не так, верните ошибку 400 http. Если все до сих пор было успешным, обновите данные пользователя loggedIn.

// In case old password input does not match with password stored in DB, prevent from updating password
if (!isMatch) {
  return res
    .status(400)
    .json({ errors: [{ msg: 'Invalid credentials' }] });
}

let profile = await User.findByIdAndUpdate(req.user.id, profileFields, { new: true });

return res.json(profile);

Неожиданный вывод (ошибка), который я получаю в консоли, таков:

Illegal arguments: string, object

Есть идеи как это исправить?

Ответы [ 2 ]

1 голос
/ 15 октября 2019

Вы сравниваете новый пароль строки с объектом (вместо String). Попробуйте ниже и напечатайте старый пароль

   try {
            const userObj = await User.findById(req.user.id);
            const oldPassword = userObj.password;
             console.log("OLD password" + password);
            //Then do your comparision logic
        } catch (err) {
            console.log('error occured' +err);   
        }
0 голосов
/ 15 октября 2019

Думаю, проблема в том, что вы пытаетесь

bcrypt.compare(formOldPassword, loggedPassword);

formOldPassword = req.body.old_password ----> String

loggedPassword = await User.findById(req.user.id).select('password') ---> Hash
...