I have mongoose schema like so
var mongoose = require ('mongoose');
var bcrypt = require('bcryptjs');
var Schema = mongoose.Schema;
var SALT_WORK_FACTOR = 10;
var touristSchema = new Schema ({
local: {
email: String,
password: String
},
facebook: {
id: String,
token: String,
email: String,
name: String,
}
});
touristSchema.pre('save', function(next) {
var user = this;
console.log('bcrypt called by strategy', user);
// if user is facebook user skip the pasword thing.
if (user.facebook.token) {
next();
}
// only hash the password if it has been modified (or is new)
if (!user.isModified('password') && !user.isNew){
console.log('I am in here', user.isNew);
return next();
}
// generate a salt
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
console.log('I am in genSalt');
if (err) return next(err);
// hash the password using our new salt
bcrypt.hash(user.local.password, salt, function(err, hash) {
if (err) return next(err);
// override the cleartext password with the hashed one
user.local.password = hash;
next();
});
});
});
touristSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.local.password, function(err, isMatch) {
// console.log(this.local.password);
if (err) return cb(err);
cb(null, isMatch);
});
};
module.exports = mongoose.model('users', touristSchema);
and login strategy like this
passport.use('local-login', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done) {
process.nextTick(function() {
User.findOne({ 'local.email': email }, function(err, user) {
if(err)
return done(err);
if(!user)
return done(null, false, req.flash('loginMessage', 'No User Found'));
user.comparePassword(password, function(err, isMatch) {
if (err) throw err;
if (isMatch) {
done(null, user);
}
else
done(null, false, req.flash('loginMessage', 'Incorrect password'));
});
});
});
}
));
everything is working as expected but when I try to log in it gives me error:
TypeError: Cannot read property 'password' of undefined.
Turns out that this.local is undefined.
This is very strange as in touristSchema.pre
hook we assigned var user = this
and on logging this returned user document. When in compare method we are using touristSchema.methods.compare
then this
should must refer to the document as written in mongoose middleware docs too. I am beating my head over it for a couple of days now and have consumed every available help I could. Any help is greatly appreciated in advance. Thanks
and yes my
mongnodb version is v3.2.15
mongoose version is 4.9.7
which looks compatible to me according to mongoose docs