hundred_dolla_tea
hundred_dolla_tea

Reputation: 561

Why isn't my mongoose document updated properly inside of the bcrypt functions?

I am trying to hash a password right before save is called on a document. I attempt to generate a hash (which works fine) and then update the password field of the document (a string type) with the new hashed password.

However, the user.password = hash line doesn't change anything.

I check my database and nothing has changed! Whats even weirder is that if I try to change my doc's data outside the hash/bcrypt functions, it works fine.

For example, if I initialize my document with the password "fake1" and then put user.password = "fakepassword" outside of my hashing functions, it updates it fine....

Why is that? Does the reference this change once you enter does hashing functions? Every example (I've searched for hours and hours) I've seen is exactly like mine... why does mine not work?

userSchema.pre('save', function(next) {   
    var user = this; // i reference the doc by "this"
    bcrypt.genSalt(SALT_WORK_FACTOR, function(err,salt){    
        if(err){  
            console.log("error with salt \n");  
        }  
            bcrypt.hash(user.password,salt,function(error,hash){  
                if (error){  
                    console.log("error with hash \n");  
                }  
                user.password = hash; // this line doesn't do anything!  

            });  
   });        
   return next(user);                                                                                                                                                    
}); 

Upvotes: 0

Views: 30

Answers (1)

robertklep
robertklep

Reputation: 203241

You should call next() when the asynchronous bcrypt code is done. Right now, you're calling it without waiting for the result of bcrypt.genSalt/bcrypt.hash.

Also, the argument passed to next is reserved for errors. You should call next without an argument if everything went okay.

Here's a cleaned up version of your middleware:

userSchema.pre('save', function(next) {
  var user = this;
  bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
    if (err) {
      console.log("error with salt \n");
      // Pass error back to Mongoose.
      return next(err);
    }
    bcrypt.hash(user.password, salt, function(error, hash) {
      if (error) {
        console.log("error with hash \n");
        return next(error);
      }
      user.password = hash;
      // Here are we done with the bcrypt stuff, so it's time to call `next`
      next();
    });
  });
});

Upvotes: 1

Related Questions