Reputation: 201
I'm using passport.js for the authentication and handling of sessions in my project.
I use email to authenticate from passport but when the done is called on verification, I get the error done is not a function.
at Promise.<anonymous> (/Users/sultan/Desktop/too2/controllers/users.js:39:28)
at Promise.<anonymous> (/Users/sultan/Desktop/too2/node_modules/mongoose/lib/promise.js:120:8)
// LOCAL LOGIN =============================================================
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password'
//passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function( email, password, done) {
if (email)
email = email.toString().toLowerCase();
// asynchronous
process.nextTick(function() {
User.findOne({ email: email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// if no user is found, return the message
if (!user)
//(/Users/sultan/Desktop/too2/controllers/users.js:39:28)
return done(null, false, {message: 'No user found.'});
if (!user.validPassword(password))
return done(null, false, {message: 'Oops! Wrong Password'});
// all is well, return user
else
return done(null, user);
});
});
}));
What is the cause of this error and how do I resolve it?
Upvotes: 3
Views: 22500
Reputation: 201
this worked for me
passport.use('login', new LocalStrategy({
// by default, local strategy uses username
usernameField : 'email',
passwordField : 'password',
passReqToCallback : true
},
function(req, email, password, done) {
if (email) email = email.toLowerCase();
// asynchronous
process.nextTick(function() {
User.findOne({ 'email' : email }, function(err, user) {
// if there are any errors, return the error
if (err)
return done(err);
// if no user is found, return the message
if (!user)
return done(null, false, req.flash('loginMessage', 'No user found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.'));
// all is well, return user
else
return done(null, user);
});
});
}));
Upvotes: 2
Reputation: 1291
It might come from you wrapping your code into process.nextTick()
If you want to have an asynchronous call to verify your user you could use promises instead like @Damien Gold answer. I can't test it but something like the below might work.
If Users.findOne()
is not thenable you could use deferred promise or promisification (let me know I can adjust my answer with sample code)
let promise = require('bluebird'); // or any other promise library
passport.use('local-login', new LocalStrategy({
usernameField : 'email',
passwordField : 'password'
//passReqToCallback : true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function( email, password, done) {
if (email)
email = email.toString().toLowerCase();
// not sure which db driver you are using but most implement promises now
Let defer = promise.defer();
User.findOne({ email: email }, function(err, user) {
if (err) { return defer.reject(err); }
return defer.resolve(user);
});
defer.promise
.then(function(user) {
// if no user is found, return the message
if (!user)
return done(null, false, {message: 'No user found.'});
if (!user.validPassword(password))
return done(null, false, {message: 'Oops! Wrong Password'});
// all is well, return user
else
return done(null, user);
}).catch(function(err) {
// if there are any errors, return the error
return done(err);
});
});
}));
Upvotes: 0
Reputation: 1610
I am currently working on a node.js project that requires user authentication. Below is the code in my passport.js file. It should work for you. In case, you don't want to use the node package connect-flash
, you can replace req.flash
with {message:...}
.
var bCrypt = require('bcrypt-nodejs');
var db = require("../models");
module.exports = function(passport) {
var user = db.User;
var User = user;
var LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done) {
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
User.findById(id).then(function(user) {
if (user) {
done(null, user.get());
} else {
done(user.errors, null);
}
});
});
passport.use('local-signup', new LocalStrategy(
{
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
var generateHash = function(password) {
return bCrypt.hashSync(password, bCrypt.genSaltSync(8), null);
};
User.findOne({
where: {
email: email
}
}).then(function(user) {
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken'));
} else {
var userPassword = generateHash(password);
var data = {
email: email,
password: userPassword,
firstname: req.body.firstname,
lastname: req.body.lastname
};
User.create(data).then(function(newUser, created) {
if (!newUser) {
return done(null, false, req.flash('userExist', 'You are already registered. Please sign in!'));
}
if (newUser) {
return done(null, newUser, req.flash('userCreated', 'You are now registered and logged in!'));
}
});
}
});
}
));
//LOCAL SIGNIN
passport.use('local-signin', new LocalStrategy({
// by default, local strategy uses username and password, we will override with email
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true // allows us to pass back the entire request to the callback
},
function(req, email, password, done) {
var User = user;
var isValidPassword = function(userpass, password) {
return bCrypt.compareSync(password, userpass);
}
User.findOne({
where: {
email: email
}
}).then(function(user) {
if (!user) {
return done(null, false, req.flash('signinError', 'Email does not exist'));
}
if (!isValidPassword(user.password, password)) {
return done(null, false, req.flash('passwordError', 'Incorrect password.'));
}
var userinfo = user.get();
return done(null, userinfo);
}).catch(function(err) {
console.log("Error:", err);
return done(null, false, req.flash('genError', 'Something went wrong with your Signin'));
});
}
));
}
Upvotes: 1