Gà Rù
Gà Rù

Reputation: 291

Passport-Local Mongoose - Change password?

I use Passport-Local Mongoose to encrypt the account's password. But I don't know how to change the password.

Can you give some document or example to do it? Thank you.

Upvotes: 21

Views: 24515

Answers (7)

Sophie Cheong
Sophie Cheong

Reputation: 21

With async/await method, you can improve the code of @steampowered as below:

  

    const sanitizedUser = await User.findByUsername(userName);

    try {
      await sanitizedUser.setPassword(newPassword);
      await sanitizedUser.save();
      res.status(200).json({ message: 'Successful!' });
    } 
    catch (err) {
      res.status(422).send(err);
    }
 

Upvotes: 0

Pran R.V
Pran R.V

Reputation: 1158

In passport-local-mongoose you dont have to create any methods in schema, instead you can directly use changePassword command. Here is an example

router.post('/changepassword', function(req, res) {

User.findOne({ _id: 'your id here' },(err, user) => {
  // Check if error connecting
  if (err) {
    res.json({ success: false, message: err }); // Return error
  } else {
    // Check if user was found in database
    if (!user) {
      res.json({ success: false, message: 'User not found' }); // Return error, user was not found in db
    } else {
      user.changePassword(req.body.oldpassword, req.body.newpassword, function(err) {
         if(err) {
                  if(err.name === 'IncorrectPasswordError'){
                       res.json({ success: false, message: 'Incorrect password' }); // Return error
                  }else {
                      res.json({ success: false, message: 'Something went wrong!! Please try again after sometimes.' });
                  }
        } else {
          res.json({ success: true, message: 'Your password has been changed successfully' });
         }
       })
    }
  }
});   });

If you want to change the password without using old password then use setPassword method. It is used for forgot password condition. Here is the code

 user.setPassword(req.body.password, function(err,user){
if (err) {
    res.json({success: false, message: 'Password could not be saved. 
  Please try again!'})
} else { 
  res.json({success: true, message: 'Your new password has been saved 
successfully'})
             }
             });

Upvotes: 3

EddieB
EddieB

Reputation: 5001

As stated in the other answers, you need to get a new instance of the user object from the database, which is async so you need to either user await or use the callback/Promise function like this...

User.findOne({ username: req.user.username })
.then((u) => {
    u.setPassword(req.body.newPassword,(err, u) => {
        if (err) return next(err);
        u.save();
        res.status(200).json({ message: 'password change successful' });
    });

})

Upvotes: 2

Srujal Kachhela
Srujal Kachhela

Reputation: 209

I think you can use changepassword method which was implemented in version 4.1.0

https://github.com/saintedlama/passport-local-mongoose/blob/master/CHANGELOG.md#410--2017-08-08

For implementation reference you can check the written tests at following location:

https://github.com/saintedlama/passport-local-mongoose/blob/807d9cf669f7a7c433eb0206c97574761c03b8e5/test/passport-local-mongoose.js#L217

Upvotes: 1

steampowered
steampowered

Reputation: 12062

No need to authenticate. Retrieve user from account using findByUsername() method, which was placed on the model by passport-local-mongoose, then run setPassword(), then user.save() in the callback.

userModel.findByUsername(email).then(function(sanitizedUser){
    if (sanitizedUser){
        sanitizedUser.setPassword(newPasswordString, function(){
            sanitizedUser.save();
            res.status(200).json({message: 'password reset successful'});
        });
    } else {
        res.status(500).json({message: 'This user does not exist'});
    }
},function(err){
    console.error(err);
})

I call the user sanitizedUser() because I have configured passport-local-mongoose to not return the password or salt fields using findByUsername() and the passport options in the model.

Upvotes: 17

adri14
adri14

Reputation: 151

Good answer, but for ones who come from the MEAN stack (uses passport-local, not passport-local-mongoose):

//in app/models/user.js

/**
 * Virtuals
 */
UserSchema.virtual('password').set(function(password) {
    this._password = password;
    this.salt = this.makeSalt();
    this.hashed_password = this.encryptPassword(password);
}).get(function() {
    return this._password;
});

So this would change the pass:

user.password = '12345678';//and after this setter...
user.save(function(err){ //...save
    if(err)...
});

Upvotes: 9

user1441287
user1441287

Reputation: 411

Looking at the source there is a function that is added to the schema called setPassword. I believe that after authenticating you can call it to change the password for the user.

schema.methods.setPassword = function (password, cb) {
    if (!password) {
        return cb(new BadRequestError(options.missingPasswordError));
    }

    var self = this;

    crypto.randomBytes(options.saltlen, function(err, buf) {
        if (err) {
            return cb(err);
        }

        var salt = buf.toString('hex');

        crypto.pbkdf2(password, salt, options.iterations, options.keylen, function(err, hashRaw) {
            if (err) {
                return cb(err);
            }

            self.set(options.hashField, new Buffer(hashRaw, 'binary').toString('hex'));
            self.set(options.saltField, salt);

            cb(null, self);
        });
    });
};

Upvotes: 21

Related Questions