Reputation: 1432
I have been trying to create a simple Authentication app but facing this issue of .pre('save')
middleware not triggering at all when I'm trying to save the hashed password in Mongodb.
Here's my Model.js
File.
import mongoose from 'mongoose';
import bcrypt from 'bcryptjs';
const userSchema = new mongoose.Schema({
auth_method: {
type: String,
enum: ['local', 'google', 'facebook'],
required: true
},
email: {
type: String,
lowercase: true,
unique: true
},
local: {
password: {
type: String
}
},
google: {
id: {
type: String
}
},
facebook: {
id: {
type: String
}
}
},
{
collection: 'Users'
});
const userModel = module.exports = mongoose.model('Users', userSchema);
userSchema.pre('save', function (next) {
console.log("this:",this); // Nothing prints to the console here
if (this.auth_method !== 'local') {
next();
}
bcrypt.genSalt(10, function (error, salt) {
if (error) throw error;
bcrypt.hash(this.local.password, salt, function (err, hashPassword) {
if (err) throw err;
else {
this.local.password = hashPassword;
next();
}
});
});
});
const comparePassword = (candidatePassword, hashPassword) => {
return new Promise((resolve, reject) => {
bcrypt.compare(candidatePassword, hashPassword, (err, isMatch) => {
if (err) reject(err);
resolve(isMatch);
});
});
};
const saveUser = (user) => user.save();
const findUserByEmail = (email) => userModel.findOne({ email });
const findUserById = (id, cb) => { userModel.findById(id, cb); };
module.exports = {
userModel,
comparePassword,
saveUser,
findUserByEmail,
findUserById
};
Any help is appreciated, I have tried all possible solutions suggested in other threads, none worked including return next(this)
Even in the database, there's no field for local: {password: 'hashedPassword'}
Upvotes: 0
Views: 2332
Reputation: 896
You are compiling model const userModel = module.exports = mongoose.model('Users', userSchema);
before creating userSchema.pre hook.
Correct order:
...
userSchema.pre('save', function (next) {
console.log("this:",this); // Nothing prints to the console here
if (this.auth_method !== 'local') {
next();
}
bcrypt.genSalt(10, function (error, salt) {
if (error) throw error;
bcrypt.hash(this.local.password, salt, function (err, hashPassword) {
if (err) throw err;
else {
this.local.password = hashPassword;
next();
}
});
});
});
const userModel = module.exports = mongoose.model('Users', userSchema);
...
Look at this simple code: http://devsmash.com/blog/password-authentication-with-mongoose-and-bcrypt
Upvotes: 4