I'm using Mysql Database for my Node Js Application. Using the Passport for the Authentication. This is my Passport.js File.
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var mysql = require('mysql');
var connection = mysql.createConnection({
host : "localhost",
user : "root",
password : "",
database: "cafe"
});
connection.connect(function(err){
if(err) throw err;
else console.log("Passport Server Connected");
});
passport.serializeUser(function(user, done) {
console.log("In Serialize !"+ user.ID);
done(null, user.id);
});
// used to deserialize the user
passport.deserializeUser(function(id, done) {
connection.query("select * from user where id = "+id,function(err,rows){
console.log("Inside Deserialize ---> "+rows[0]);
done(err, rows[0]);
});
});
// https://gist.github.com/manjeshpv/84446e6aa5b3689e8b84
// Passport with mysql database
passport.use('local-signup', 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) {
connection.query("select * from user where email = '"+email+"'",function(err,rows){
console.log(rows);
console.log("above row object");
if (err)
return done(err);
if (rows.length > 0) {
// return done(null, false, req.flash('signupMessage', 'That email is already taken.')); // Not Working
return done(null, false, {message : 'Email Id Already Taken !'}); //Default Json Unauthorised
} else {
// if there is no user with that email
// create the user
var newUserMysql = new Object();
newUserMysql.email = email;
newUserMysql.password = password; // use the generateHash function in our user model
console.log(newUserMysql);
var insertQuery = "INSERT INTO user ( email,password ) VALUES ('"+ email +"','"+ password +"')";
console.log(insertQuery);
connection.query(insertQuery,function(err,rows){
newUserMysql.id = rows.insertId;
if(err) throw err;
// console.log("Error is "+ err);
// console.log(insertQuery);
return done(null, newUserMysql);
});
}
});
// connection.end();
}));
passport.use('local-login', 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) { // callback with email and password from our form
connection.query("SELECT * FROM `user` WHERE `email` = '" + email + "'",function(err,rows){
if (err)
return done(err);
if (!rows.length) {
// return done(null, false, req.flash('loginMessage', 'No user found.')); // req.flash is the way to set flashdata using connect-flash
return done(null, false, {message: 'No User Found! '});
}
// if the user is found but the password is wrong
if (!( rows[0].password == password )){
// return done(null, false, req.flash('loginMessage', 'Oops! Wrong password.')); // create the loginMessage and save it to session as flashdata
return done(null, false, {message: 'Oops! Wrong Password! '});
}
// all is well, return successful user
console.log(" Inside callback of local-login -> "+rows[0]);
return done(null, rows[0]);
});
}));
// module.exports;
As per my Application, Whenever I'm creating a new User in Signup Page, it's Successfully creating the User and the session is created by calling the Serialize and Deserialize function.
But when I try to LogIn the user, it's creating this Error.
Only Serialize is working and Deserialize function is not called in Login Process.
However if I disable the Session with session:false, it's logging me in, but without session which I don't want.
Here's my routes file.
var express = require('express');
var router = express.Router();
async = require('async');
var csrf = require('csurf');
var passport = require('passport');
var csrfProtection = csrf();
router.use(csrfProtection);
// Profile Routes
router.get('/profile',function(req,res,next){
res.render('user/profile');
});
// SIGN UP Routes
router.get('/signup',function(req,res,next){
var messages = req.flash('error');
// console.log("In Get Route "+ messages +" is the Error"); //req.flash not working.
res.render('user/signup', {csrfToken:req.csrfToken(), messages: messages , hasError: messages==undefined ?false :messages.length>0});
});
router.post('/signup',passport.authenticate('local-signup',{
successRedirect:'/user/profile',
faliureRedirect : '/user/signup',
// faliureMessage:'Not Valid',
faliureFlash:true,
// session:false
}));
//Sign In
router.get('/signin',function(req,res,next){
var messages = req.flash('error');
// console.log("In Get Route "+ messages +" is the Error"); //req.flash not working.
res.render('user/signin', {csrfToken:req.csrfToken(), messages: messages , hasError: messages==undefined ?false :messages.length>0});
});
router.post('/signin',passport.authenticate('local-login',{
successRedirect:'/user/profile',
faliureRedirect : '/user/signin',
faliureFlash:true,
// session:false,
}));
//Log Out
router.get('/logout',function(req,res,next){
req.logOut();
res.redirect('/');
});
module.exports = router;
If I may ask, my flash isn't also working. Any Help on that will be appreciated.
PS - Please note that my Sign Up is working fine, so basically the session is being created and serialize and deserialize functions are also working fine. The problem is in Login Session only
I am trying to create a simple node.js app with passport local authentication using mongoDb and express as a framework,but I'm having a problem
Whenever I try to submit the data into database using registration form,after clicking submit it appears in node terminal immediately :
here is how my user schema looks like:
var mongoose = require('mongoose');
var bcrypt = require('bcrypt-nodejs');
// define the schema for our user model
var userSchema = mongoose.Schema({
local : {
name : String,
username : String,
mobile : Number,
email : String,
gender : String,
password : String
}
});
// methods ======================
// generating a hash
userSchema.methods.generateHash = function(password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
// checking if password is valid
userSchema.methods.validPassword = function(password) {
return bcrypt.compareSync(password, this.local.password);
};
// create the model for users and expose it to our app
module.exports = mongoose.model('User', userSchema);
and my router file :
// process the signup form
app.post('/signup', passport.authenticate('local-signup', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/signup', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}));
passport configuration for sign up logic :
passport.use('local-signup', new LocalStrategy({
nameField : 'name',
usernameField : 'username',
mobileField : 'mobile',
emailField : 'email',
genderField : 'gender',
passwordField : 'password',
passReqToCallback : true // allows us to pass back the entire request to the callback
},
function(req, name, username, mobile, email, gender, 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 there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.name = name;
newUser.local.username = username;
newUser.local.mobile = mobile;
newUser.local.email = email;
newUser.local.gender = gender;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err)
throw err;
return done(null, newUser);
});
}
});
});
}));
I am new to node.js as well as in mongoDb please help me out
Thanks
Reason: reason behind this error is invalid type to store in db. Like mobile is number type but if you are passing a value which can not be convert to number then it will give the same error.
console.log(newUser); before saving the user and check the value you are passing in mobile field is convertible to Number as its data type is number in your schema.
If mobile is "" or undefined or null i.e. not convertible to number then it will not work. Remove this key from object if it's value doesn't exists. Do not pass the undefined,null or "" or string(which can not be convert to number).
I have a username field and an email field on signup and I want to check if they exist before adding the user to the database. Most examples for passport only look up one field like username and I cant figure out how to look up 2. If I do what I have below and the user enters an existing username but a non-existing email it would go through and if the user enters an existing email but a non-existing username it would go through because their is no username.
I know why that is happening. I just can't figure out how to put the 2 queries together so it saves it only after it sees that there is no username and or no email. To be clearer, there should be no duplicates of usernames and emails.
I was thinking maybe setting a variable in the else statement saying that it is ok to save the user and later in the code check to see if there are 2 of these variables and if there are those variables then save but I don't know how to do that. I think it would be hard since the queries are asynchronous. I wish I could do that method.
and how would I deal with the connect-flash messages?
passport.use("local-signup", new LocalStrategy({
usernameField : "email",
passwordField : "password",
passReqToCallback : true
},
function(req, email, password, done){
User.findOne({"email" : email}, function(err, user){
if(err) return done(err);
if(user){
return done(null, false, req.flash("signupMessage", "That email is already taken"))
}else{
var newUser = new User();
newUser.username = req.body.username;
newUser.password = password;
newUser.email = req.body.email;
newUser.save(function(err, doc){
if(err) throw err;
console.log("doc", " " , doc)
return done(null, newUser);
})
}
})
console.log("username " + req.body.username)
User.findOne({"username" : req.body.username}, function(err, user){
if(err) return done(err);
if(user){
return done(null, false, req.flash("signupMessage", "that username is taken"))
}else{
var newUser = new User();
newUser.username = req.body.username;
newUser.password = password;
newUser.email = req.body.email;
newUser.save(function(err, doc){
if(err) throw err;
console.log("doc", " " , doc)
return done(null, newUser);
})
}
})
}
))
There are many ways you can do this.
Example, you can do it the promise way; where you can simultaneously perform and async calls to check for both username and email and if both calls return an OK result and then you proceed to insert.
See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all
Since you already got some code up there, I'll do the conventional nested step by step async way.
What I got below is - first I perform a call to User.findOne() to check for the email and if the value is unique then proceed to check the username using User.findOne() again.
The code only proceeds to insert the user when the 2nd User.findOne() call reports fine.
Note: while this logic works but if you nest too many calls you will get into what the Javascript community usually describe as the callback hell.
passport.use("local-signup", new LocalStrategy({
usernameField : "email",
passwordField : "password",
passReqToCallback : true
},
function(req, email, password, done){
// register user only if the email and username is unique
// Step 1: Check email
User.findOne({"email" : email}, function(err, user){
if(err) return done(err);
if(user){
return done(null, false, req.flash("signupMessage", "That email is already taken"))
} else {
// Email is fine.
// Step 2: Check username
User.findOne({"username" : req.body.username}, function(err, user){
if(err) return done(err);
if(user){
return done(null, false, req.flash("signupMessage", "that username is taken"))
}else{
// User name is fine too
// Step 3: Create user
var newUser = new User();
newUser.username = req.body.username;
newUser.password = password;
newUser.email = req.body.email;
newUser.save(function(err, doc){
if(err) throw err;
// User created
console.log("doc", " " , doc);
return done(null, newUser);
});
}
});
}
});
};
Is there any way to allow a user to register on the local strategy with his password, email and name?
Every example I could find online only use name/password or email/password.
I also searched through the the whole passport documentation, but that documentation isn't helpful at all. It's just one bloated site full of examples.
I just need an list of functions, classes and variables passport uses with explanations what they and every parameter of them do. Every good library has something like that, why can't I find it for passport?
Here are the key parts of my code:
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
//are there other options?
//emailField did not seem to do anything
passReqToCallback: true // allows us to pass in the req from our route (lets us check if a user is logged in or not)
},
function(req, email, password, done) {
//check if email not already in database
//create new user using "email" and "password"
//I want an additional parameter here "name"
}));
So is passport really that limited? There has to be a way to do this, right?
You can be a little confused but passport doesn't implement signup methods. It's just authorisation library. So you must handle that use-case on your own.
First of all, create route that will be responsible for sign-up and your checks:
signup: function (req, res) {
User
.findOne({
or: [{username: req.param('username')}, {email: req.param('email')}]
})
.then(function(user) {
if (user) return {message: 'User already exists'};
return User.create(req.allParams());
})
.then(res.ok)
.catch(res.negotiate);
}
The example above is based on Sails framework, but you can fit it with no problems to your own case.
Next step is include passport local strategy.
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var LOCAL_STRATEGY_CONFIG = {
usernameField: 'email',
passwordField: 'password',
session: false,
passReqToCallback: true
};
function _onLocalStrategyAuth(req, email, password, next) {
User
.findOne(or: [{email: email}, {username: email}])
.then(function (user) {
if (!user) return next(null, null, {
code: 'E_USER_NOT_FOUND',
message: email + ' is not found',
status: 401
});
if (!HashService.bcrypt.compareSync(password, user.password)) return next(null, null, {
code: 'E_WRONG_PASSWORD',
message: 'Password is wrong',
status: 401
});
return next(null, user, {});
})
.catch(next);
}
passport.use(new LocalStrategy(LOCAL_STRATEGY_CONFIG), _onLocalStrategyAuth));
We have only signin task now. It's simple.
signin: function(req, res) {
passport.authenticate('local', function(error, user, info) {
if (error || !user) return res.negotiate(Object.assign(error, info));
return res.ok(user);
})(req, res);
}
This way is more suitable for passport and works great for me.
Say you have this
app.post('/login', urlencodedParser,
// so, user has been to /loginpage and clicked submit.
// /loginpage has a post form that goes to "/login".
// hence you arrive here.
passport.authenticate('my-simple-login-strategy', {
failureRedirect: '/loginagain'
}),
function(req, res) {
console.log("you are in ............")
res.redirect('/stuff');
});
Note that the .authenticate has an explicit tag.
The tags is 'my-simple-login-strategy'
That means you have this ...
passport.use(
'my-simple-login-strategy',
// !!!!!!!!!!!!!note!!!!!!!!!!, the DEFAULT there (if you have nothing)
// is 'local'. A good example of defaults being silly :/
new Strategy(
STRAT_CONFIG,
function(email, password, cb) {
// must return cb(null, false) or cb(null, the_user_struct) or cb(err)
db.findUserByEmailPass(email, password, function(err, userFoundByDB) {
if (err) { return cb(err); }
if (!userFoundByDB) { return cb(null, false); }
console.log('... ' + JSON.stringify(userFoundByDB) )
return cb(null, userFoundByDB)
})
}
)
)
!!! !!! NOTE THAT 'local' IS JUST THE DEFAULT TAG NAME !!! !!!
In passport.use, we always put in an explicit tag. It is much clearer if you do so. Put in an explicit tag in the strategy and in the app.post when you use the strategy.
So that's my-simple-login-strategy.
What is the actual db.findUserByEmailPass sql function?
We'll come back to that!
So we have my-simple-login-strategy
Next ...... we need my-simple-createaccount-strategy
Note that we are still sneakily using passport.authenticate:
So:
the strategy my-simple-createaccount-strategy will actually make an account.
However .............
you should still return a struct.
Note that my-simple-login-strategy has to return a struct.
So, my-simple-createaccount-strategy also has to return a struct - in exactly the same way.
app.post('/createaccount', urlencodedParser,
// so, user has been to /createanaccountform and clicked submit,
// that sends a post to /createaccount. So we are here:
passport.authenticate('my-simple-createaccount-strategy', {
failureRedirect: '/loginagain'
}),
function(req, res) {
console.log("you are in ............")
res.redirect('/stuff');
});
And here's the strategy ..........
passport.use(
'my-simple-createaccount-strategy',
new Strategy(
STRAT_CONFIG,
function(email, password, cb) {
// return cb(null, false), or cb(null, the_user_struct) or cb(err)
db.simpleCreate(email, password, function(err, trueOrFalse) {
if (err) { return cb(err); }
if (!trueOrFalse) { return cb(null, false); }
return cb(null, trueOrFalse)
})
}
)
)
The strategy is pretty much the same. But the db call is different.
So now let's look at the db calls.
Let's look at the db calls!
The ordinary db call for the ordinary strategy is going to look like this:
exports.findUserByEmailPass = function(email, password, cb) {
// return the struct or false via the callback
dc.query(
'select * from users where email = ? and password = ?',
[email, password],
(error, users, fields) => {
if (error) { throw error } // or something like cb(new Error('blah'));
cb(null, (users.length == 1) ? users[0] : false)
})
}
So that's exports.findUserByEmailPass, which is used by my-simple-login-strategy.
But what about exports.simpleCreate for my-simple-createaccount-strategy?
A simple toy version would
check if the username exists already - return false at this point if it does exist already, then
create it, and then
actually just return the record again.
Recall that (3) is just like in the ordinary "find" call.
Remember ... the strategy my-simple-createaccount-strategy will actually make an account. But you should still return a struct in the same way as your ordinary authenticate strategy, my-simple-login-strategy.
So exports.simpleCreate is a simple chain of three calls:
exports.simpleCreate = function(email, password, cb) {
// check if exists; insert; re-select and return it
dc.query(
'select * from users where email = ?', [email],
(error, users, fields) => {
if (error) { throw error } // or something like cb(new Error('blah'));
if (users.length > 0) {
return cb(null, false)
}
else {
return partTwo(email, password, cb)
}
})
}
partTwo = function(email, password, cb) {
dc.query(
'insert into users (email, password) values (?, ?)', [email, password],
(error, users, fields) => {
if (error) { throw error } // or something like cb(new Error('blah'));
partThree(email, password, cb)
})
}
partThree = function(email, password, cb) {
dc.query(
'select * from users where email = ? and password = ?', [email, password],
(error, users, fields) => {
if (error) { throw error } // or something like cb(new Error('blah'));
cb(null, (users.length == 1) ? users[0] : false)
})
}
And that all works.
But note that
passport has nothing to do with account creation!
In fact, you do not have to use a strategy at all.
In app.post('/createaccount' you can, if you wish, do nothing with passport.authenticate ... don't even mention it in the code. Don't use authenticate at all. Just go ahead and do the sql process of inserting a new user, right there in app.post.
However, if you "trickily" use a passport strategy - my-simple-createaccount-strategy in the example - you have the bonus that the user is then immediately logged-in with a session and everything works in the same pattern as the login post. Cool.
Here is what worked for me, the solution is based on a mongoose based odm, the first part is the passport related part, I also attached the user part from odm to who how the encryption of the password is done.
If I understood your question, you want the user to type either his email or password. In this case modify the search to try both, that is, match the provided user identifier (in your call to findOne(...) with either the username or password.
Note that I use bcrypt to avoid storing clear passwords, that's why there is a customized compare method for testing passwords. Also note 'hints' of using google auth as well, My system enabled both, if it is relevant, please lemme know and I can add the required code.
------------ Auth part (just relevant snippets) -----------
var passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
passport.serializeUser(function(user, done) {
// the values returned here will be used to deserializeUser
// this can be use for further logins
done(null, {username: user.username, _id: user.id, role: user.role});
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
passport.use(new LocalStrategy(function(username, password, done){
odm.User.findOne({username: username, authType: 'direct'}, function(err, user){
if(err){
return done(err, false);
}
if(!user){
return done(null, false);
}
if(user.role === 'new'){
console.log('can not use new user!');
return done('user not activated yet, please contact admin', false);
}
user.comparePassword(password,function(err, isMatch){
if(err){
return done(err, false);
}
if(isMatch){
return done(null, user);//{username: username});
}
return done(null, false);
});
});
}));
app.post('/login', function(req, res, next){
passport.authenticate('local', {
failureRedirect: '/logout?status=login failed'
}, function(err, user, info){
if(err){
return next(err);
}
if(!user){
return res.redirect('/login');
}
req.logIn(user, function(err){
if (req.body.rememberme) {
req.session.cookie.maxAge = 30*24*60*60*1000 ;//Rememeber 'me' for 30 days
} else {
req.session.cookie.expires = false;
}
var redirect = req.param('redirect') || '/index';
res.redirect(redirect);
});
}
)(req, res, next);
}
);
app.post('/register',function(req, res){
var user = new odm.User({username: req.body.username, password: req.body.password, email: req.body.email, authType: 'direct'});
user.save(function(err, user){
if(err){
console.log('registration err: ' , err);
} else {
res.redirect('/list');
}
});
});
--- user/odm, relevant parts ----------------
var bcrypt = require('bcrypt-nodejs');
// --------------------- User ------------------------------------------ //
var userSchema = new Schema({
name: String,
email: String,
username: {type: String, required: true, unique: true},
password: String,
role: {type: String, required: true, enum: ['new', 'admin', 'user'], default: 'new'},
authType: {type: String, enum: ['google', 'direct'], required: true}
});
userSchema.pre('save', function (next) {
var user = this;
if (!user.isModified('password')) return next();
console.log('making hash...........');
bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
if (err) return next(err);
bcrypt.hash(user.password, salt, null, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
userSchema.methods.comparePassword = function (candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function (err, isMatch) {
if (err) return cb(err);
cb(null, isMatch);
});
};
var localStrategy = require('passport-local').Strategy;
var User = require('../public/models/user');
module.exports = function(passport){
passport.serializeUser(function(user, done){
done(null, user.id);
});
passport.deserializeUser(function(id, done){
User.findById(id, function(err, user){
done(err, user);
});
});
passport.use('local-signup', new localStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
process.nextTick(function(){
User.findOne({'local.enroll': email}, function(err, user){
if(err)
return done(err);
if(user){
return done(null, false, req.flash('signupmessage', 'The email already taken'));
} else{
var newUser = new User();
newUser.local.enroll = email;
newUser.local.password = newUser.generateHash(password);
newUser.save(function(err){
if(err)
throw err
return done(null, newUser);
});
}
});
});
}));
passport.use('local-login', new localStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
function(req, email, password, done){
process.nextTick(function(){
User.findOne({'local.enroll': email}, function(err, user){
if(err)
return done(err);
if(!user){
return done(null, false, req.flash('loginmessage', 'No user found'));
}
if(!user.validPassword(password)){
return done(null, false, req.flash('loginmessage', 'Invalid password'));
}
return done(null, user);
});
});
}));
}
This has actually nothing to do with passport and is pretty simple, assuming you are using body-parser. Make sure you have an input field in your form with the attribute name="name" where you register the user's name like:
<div class="form-group">
<label for="signup-name">Name</label>
<input type="text" placeholder="Name" name="name">
</div>
In your routing, you can access this field with req.body.name:
passport.use('local-signup', new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
//are there other options?
//emailField did not seem to do anything
passReqToCallback: true
},
function(req, email, password, done) {
//check if email not already in database
//create new user using "email" and "password"
//I want an additional parameter here "name"
user.email = email;
user.password = password; // Do some hashing before storing
user.name = req.body.name;
}));
So you can add as many form input fields as you want, access them by the value of the name attribute. A Second example would be:
<input type="text" placeholder="City" name="city">
<input type="text" placeholder="Country" name="country">
// Access them by
user.city = req.body.city;
user.country = req.body.country;
UserModel.find({email: req.body.email}, function(err, user){
if(err){
res.redirect('/your sign up page');
} else {
if(user.length > 0){
res.redirect('/again your sign up page');
} else{
//YOUR REGISTRATION CODES HERE
}
}
})
In strategy options set the passReqToCallback:true and then add req as parameter into your callback function. Finally, read the extra information from req.body object for example req.body.firstName
const signup = new Strategy({
usernameField: "username",
passwordField: "password",
passReqToCallback:true
}, async (req, username, password, done) => {
try {
const user = User.create();
user.username = username;
user.password = password;
user.firstName = req.body.firstName;
user.lastName = req.body.lastName
await user.save()
return done(null, user);
} catch (error) {
return done(error, null);
}
});
I can't resolve this problem, I search a lot on th web but nothing help.
I have frontEnd(angular) running on localhost:63447 and backend on localhost:3000(nodejs).
I have a problem only when it's a new user and node have to create it before sending back the reponse. User is beeing created but I get an empty reponse on angular.
I'm sending a post via angular:
$scope.signIn = function(userToSignIn){
console.log(userToSignIn);
$http.post('http://localhost:3000/authenticate/signup',
userToSignIn)
.success(function(data, status, headers, config){
$scope.test = data;;
})
.error(function(data, status, headers, config){
console.log(data);
});
to a function in nodejs:
router.post('/signup',
function(req, res, next) {
console.log(req.body);
passport.authenticate('local-signup', function(err, user, info) {
if (err) { return next(err); }//This one is working
else if (!user) { return res.json({status: req.session.flash.signupMessage}); }//work
else if(user) {
return res.status(200).json(user._id);//this is the problem
}
})(req, res, next);}),
Here is the local-signup function:
passport.use('local-signup', 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) {
// 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 there are any errors, return the error
if (err)
return done(err);
// check to see if theres already a user with that email
if (user) {
return done(null, false, req.flash('signupMessage', 'That email is already taken.'));
} else {
// if there is no user with that email
// create the user
var newUser = new User();
// set the user's local credentials
newUser.local.email = email;
newUser.local.password = newUser.generateHash(password);
// save the user
newUser.save(function(err) {
if (err) {
console.log('error'); throw err;
}else
console.log('saved');
return done(null, newUser, req.flash('You were successly logged in'));
});
}
});