Reputation: 561
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
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