Node mongoose always returning error on findOne

841 Views Asked by At

I'm using passport.js to sign in users, and whenever my local authentication function gets to User.findOne(), it always returns with an error. I have no idea what I'm doing wrong...

my passport code with the findOne() call:

passport.serializeUser(function(user, done) {
    console.log('serialize user occurred');
    done(null, user.id);
});

// used to deserialize the user
passport.deserializeUser(function(id, done) {
    User.findById(id, function(err, user) {
        done(err, user);
    });
});




passport.use('local-signup',
    new LocalStrategy({
        // by default, local strategy uses username and password, we will override with email
        usernameField : 'email',
        passwordField : 'password'
    },
    function(email, password, done) {

        // asynchronous
        // User.findOne wont fire unless data is sent back
        process.nextTick(function() {
            // find a user whose email is the same as the forms email
            // we are checking to see if the user trying to login already exists
            User.findOne({ 'local.email' :  email }, function(err, user) {
                if (err) // An error occurred
                    console.log(err);
                    err.toString();
                    return done(err);
                if (user) { // This email is already in use
                    return done(null, false);
                } else { // Valid email to sign in wth
                    var newUser = new User();
                    newUser.local.email = email;
                    newUser.local.password = newUser.generateHash(password);

                    newUser.save(function(err) {
                        if (err)
                            throw err;
                        return done(null, newUser);
                    });
                }
            });
        });
    })
);

And my user model:

var userSchema = mongoose.Schema({
    local : {
        email : String,
        password : String
    },
    facebook : {
        id : String,
        token : String,
        email : String,
        name : String
    }
});

// methods ==============
// Generate a hash for a password
userSchema.methods.generateHash = function(password){
    return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};

// Checking if password is valid
userSchema.methods.comparePassword = function(password){
    return bcrypt.compareSync(password, this.local.password);
};

module.exports = mongoose.model('User', userSchema);

and my routes if you're interested:

app.get('/signupfail', function(req, res) {
    // render the page and pass in any flash data if it exists
    res.json({message: "failed to sign in, failure redirect"});
});

// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
    successRedirect : '/profile', // redirect to the secure profile section
    failureRedirect : '/signupfail', // redirect back to the signup page if there is an error
    falureFlash : true // allow flash messages
}));

app.get('/profile', isLoggedIn, function(req, res) {
    var user = req.user // This is the user extracted from the session
    res.json({message: "hooray it worked for: "+user.local.email});
});

I'm honestly terrible with node, but I want to learn!

2

There are 2 best solutions below

3
On BEST ANSWER
passport.use('local-signup',
 ...
    function(req, email, password, done) {

The function expect three arguments email, password,done.
change the callback function to

function( email, password, done) {
1
On

Well, I found the problem.

Listen here kids, always wrap your jimmy, and always close your if statements