I'm trying to test my local-login. I've implemented with passport.js, following its guide and following this MEAN skeleton.
I'm pretty sure that the implementation is fine, but there is something wrong with the test that always fails authentication.
If authentication fails it should be redirect to "/signin"if authentication is correct it should be go to "/"
But when I test, the authentication always fails.
This is routes.js:
module.exports = function(app, passport, auth) {
var users = require('../app/controllers/users');
app.get('/signin', users.signin);
app.post('/users/session', passport.authenticate('local', {
failureRedirect: '/signin',
failureFlash: 'Invalid email or password.'
}), users.session);
var index = require('../app/controllers/index');
app.get('/', index.render);
passport.js:
var mongoose = require('mongoose'),
LocalStrategy = require('passport-local').Strategy,
User = mongoose.model('User'),
config = require('./config');
module.exports = function(passport) {
//Serialize sessions
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
}, '-salt -hashed_password', function(err, user) {
done(err, user);
});
});
//Use local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
User.findOne({
email: email
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Unknown user'
});
}
if (!user.authenticate(password)) {
return done(null, false, {
message: 'Invalid password'
});
}
return done(null, user);
});
}
));
}
and test: api.js:
var User, app, mongoose, request, server, should, user;
should = require("should");
app = require("../server");
mongoose = require("mongoose");
User = mongoose.model("User");
request = require("supertest");
server = request.agent("http://localhost:3000");
describe("<Unit Test>", function() {
return describe("API User:", function() {
before(function(done) {
user = new User({
email : "user#user.com",
firstName: "Full Name",
lastName : "Last Name",
password : "pass11"
});
user.save();
return done();
});
describe("Authentication", function() {
return it("Local login", function(done) {
return server.post("/users/session").send({
email : "user#user.com",
password: "pass11"
}).end(function(err, res) {
res.headers.location.should.have.equal("/");
return done();
});
});
});
return after(function(done) {
User.remove().exec();
return done();
});
});
});
This is what the terminal displays:
<Unit Test>
API User:
Authentication
1) Local login
0 passing (24ms)
1 failing
1) <Unit Test> API User: Authentication Local login:
actual expected
/signin
I'm trying using this code and work as expected
var User, app, mongoose, request, server, should, user, agent;
should = require("should");
app = require("../server");
mongoose = require("mongoose");
User = mongoose.model("User");
request = require("supertest");
agent = request.agent(app)
describe('User', function () {
before(function(done) {
user = new User({
email : "user#user.com",
firstName: "Full Name",
lastName : "Last Name",
password : "pass11"
});
user.save(done)
});
describe('Login test', function () {
it('should redirect to /', function (done) {
agent
.post('/users/session')
.field('email', 'user#user.com')
.field('password', 'pass11')
.expect('Location','/')
.end(done)
})
after(function(done) {
User.remove().exec();
return done();
});
})
})
for more reference check this test-user
here my screenshot
Related
I'm building an app in Node, using Passport and local signup and sign in strategies. I just keep running into an issue. All the required modules etc. are there. The following sign in routine works fine:
passport.use('local-signin', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqTodone : true
}, function(req, email, password, done) {
User.findOne({ 'local.email' : email }, function(err, user) {
if (err)
return done(err);
if (!user)
return done(null, false, req.flash('message', 'User not found.'));
if (!user.validPassword(password))
return done(null, false, req.flash('message', 'Wrong password.'));
return done(null, user);
});
}));
However, the following sign up routine does not:
passport.use('local-signup', new LocalStrategy({
usernameField : 'email',
passwordField : 'password',
passReqTodone : true
}, function(req, email, password, done) {
console.log("signing up")
User.findOne({ 'local.email' : email }, function(err, user) {
if (err) {
return done(err);
} else if (user) {
return done(null, false, req.flash('message', 'That email address is already registered.'));
} else {
var newUser = new User();
}
// save the user
newUser.save(function(err) {
if (err) {
console.log("Error saving new user profile: " + err);
} else {
return done(null, newUser, req.flash('message', 'User account created'));
}
});
});
}))
Both routines are called within routes.js:
// POST : SIGNUP
app.post('/signup', passport.authenticate('local-signup', {
successRedirect: '/',
failureRedirect: '/error',
failureFlash: true
}));
// POST : SIGNIN
app.post('/signin', passport.authenticate('local-signin', {
successRedirect: '/profile',
failureRedirect: '/',
failureFlash: true
}));
Any ideas where it might go wrong? As is, posting to /signup continuously results in a failureRedirect. My head is getting kinda sore from banging on the screen...
The only thing you need to change is:
if (!user.validPassword(password))
To
if (user.validPassword(password) === false)
I know, if (!user.validPassword(password)) is in examples on Passport.js official docs, but it is wrong.
I have just lost 2 hours of my life, figuring this out.
Use this code it will helps you to fix your problem
passport-authentication.js
var express=require('express');
var router = express.Router();
var passport = require('passport');
var User = require('../models/user');//user is schema
var Verify = require('./verify');//verify is a file where the user is verified
/* GET users listing. */
router.get('/', Verify.verifyOrdinaryUser,function(req, res, next) {
User.find({},function(err,user){
if(err) throw err;
res.json(user);
});
});
router.post('/register', function(req, res) {
User.register(new User({ username : req.body.username,Email:req.body.Email}),
req.body.password, function(err, user) {
if (err) {
return res.status(500).json({err: err});
}
if(req.body.firstname) {
user.firstname = req.body.firstname;
}
if(req.body.lastname) {
user.lastname = req.body.lastname;
}
user.save(function(err,user) {
passport.authenticate('local')(req, res, function () {
return res.status(200).json({status: 'Registration Successful!'});
});
});
});
});
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).json({
err: info
});
}
req.logIn(user, function(err) {
if (err) {
return res.status(500).json({
err: 'Could not log in user'
});
}
var token = Verify.getToken(user);
res.status(200).json({
status: 'Login successful!',
success: true,
token: token
});
});
})(req,res,next);
});
router.get('/logout', function(req, res) {
req.logout();
res.status(200).json({
status: 'Bye!'
});
});
module.exports = router;
verify.js
var User = require('../models/user');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('../config.js');
exports.getToken = function (user) {
return jwt.sign(user, config.secretKey, {
expiresIn: 3600
});
};
exports.verifyOrdinaryUser = function (req, res, next) {
// check header or url parameters or post parameters for token
var token = req.body.token || req.query.token || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.secretKey, function (err, decoded) {
if (err) {
var err = new Error('You are not authenticated!');
err.status = 401;
return next(err);
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
var err = new Error('No token provided!');
err.status = 403;
return next(err);
}
};
hope this helps for you...
I am currently implementing a Google login and Google calendar implementation and testing out a function when a Google user logs in it pulls their events and prints to the console. however, I am getting the following error in the console
Error: Daily Limit for Unauthenticated Use Exceeded. Continued use requires signup.
and when I console.log the calendar, it gives me a null.
I have made sure Google+ API and Google calendar API are both enabled in the console as well.
I am new to web development in general, I followed a tutorial to get me started and began trying to use the Google API's. I am using the MEAN stack for this project. Here is the relevant code.
var FacebookStrategy = require('passport-facebook').Strategy;
var User = require('../models/user');
var session = require('express-session');
var jwt = require('jsonwebtoken');
var secret = 'check123';
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var gcal = require('google-calendar');
var google = require('googleapis');
module.exports = function(app,passport, auth) {
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
passport.serializeUser(function(user, done) {
token = jwt.sign({ username: user.username, email: user.email }, secret, {expiresIn: '24h'});
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: '422080801499546',
clientSecret: '34f91021248106dea49daa111bb7ff89',
callbackURL: "http://localhost:8000/auth/facebook/callback",
profileFields: ['id', 'displayName', 'photos', 'email']
},
function(accessToken, refreshToken, profile, done) {
console.log(profile._json.email);
User.findOne({ email: profile._json.email }).select('username password email').exec(function(err, user){
if(err) done(err);
if (user && user !== null) {
done(null, user);
} else {
done(err);
}
});
//done(null, profile);
}
));
// Use the GoogleStrategy within Passport.
// Strategies in Passport require a `verify` function, which accept
// credentials (in this case, an accessToken, refreshToken, and Google
// profile), and invoke a callback with a user object.
passport.use(new GoogleStrategy({
clientID: '655984940226-ob15jvq3hvqha4969tlb3oco9tun1i9t.apps.googleusercontent.com',
clientSecret: 'hsZtBDsfiCvdPz0gT-tqdUZ_',
callbackURL: "https://frozen-woodland-75947.herokuapp.com/auth/google/callback"
},
function(accessToken, refreshToken, profile, done) {
User.findOne({ email: profile.emails[0].value }).select('username password email').exec(function(err, user){
if(err) done(err);
if (user && user !== null) {
done(null, user);
} else {
done(err);
}
});
var google_calendar = google.calendar('v3');
console.log('im here');
google_calendar.events.list({
auth: auth,
calendarId: 'primary',
timeMin: (new Date()).toISOString(),
singleEvents: true,
orderBy: 'startTime'
}, function(err, calendarList){
console.log(calendarList);
if(err){
console.log('bad list: ' + err);
return;
}
var events = calendarList.items;
if(events.length ==0){
console.log('No items found');
} else {
console.log('Upcoming events:');
console.log('%s -%s', start, event.summary);
}
})
}
Next is my authentication functions, my api.js:
var User = require('../models/user');
var jwt = require('jsonwebtoken');
var secret = 'check123';
module.exports = function(router){
//USER REGISTRATION
router.post('/users', function(req, res){
var user = new User();
user.username = req.body.username;
user.password = req.body.password;
user.email = req.body.email;
if(req.body.username == null || req.body.username == ''|| req.body.password == null || req.body.email == null || req.body.password == '' || req.body.email == ''){
res.json({ success: false, message: 'Ensure username, email, and password were provided'}); //false if the route is null empty etc.
} else {
user.save(function(err){
if(err) {
res.json({success: false, message: 'Username or email already exists'});
} else {
res.json({success: true, message: 'user created!'});
}
});
}
});
//USER LOGIN ROUTE
//http://localhost:port/api/authenticate
router.post('/authenticate', function(req,res){
User.findOne({ username: req.body.username }).select('email username password').exec(function(err,user){
if(err) throw err;
if(!user){
res.json({success: false, message: 'Could not authenticate user'});
} else if (user) {
if( req.body.password) {
var validPassword = user.comparePassword(req.body.password);
} else {
res.json({success: false, message: 'No password Provided'});
}
if(!validPassword) {
res.json({ success: false, message: ' Could not Authenticate password'});
} else {
var token = jwt.sign({ username: user.username, email: user.email }, secret, {expiresIn: '24h'}); // create json token when they successfully log in with secret encryption and expires in 24 hours
res.json({ success: true, message: ' User Authenticated!', token: token}); // respond to user with that token
}
}
});
});
router.use(function(req, res, next){
var token = req.body.token || req.body.query || req.headers['x-access-token'];
console.log(token);
if(token) {
//varify token
jwt.verify(token,secret,function(err,decoded){
if(err) {
res.json({success: false, message: 'Token invalid'});
} else {
req.decoded = decoded; //decrpyts token - user/email
next();
}
});
}else {
res.json({success: false, message: 'No token provided'});
}
});
router.post('/me', function(req, res) {
res.send(req.decoded);
});
return router;
}
Login controllers:
//controls main index - runs when main page loads
angular.module('mainController', ['authServices'])
.controller('mainCtrl', function(Auth,$timeout, $location,$rootScope, $window){
var app = this; // so we can access outside of scoper
app.loadme = false;
$rootScope.$on('$routeChangeStart', function() {
if(Auth.isLoggedIn()) {
app.isLoggedIn = true;
Auth.getUser().then(function(data){
app.username = data.data.username;
app.useremail = data.data.email;
app.loadme = true;
});
} else {
app.isLoggedIn = false;
app.username = '';
app.loadme = true;
}
});
this.google = function() {
$window.location = $window.location.protocol + '//' + $window.location.host + '/auth/google';
};
this.doLogin = function(loginData) { //when the register button is pressed controller
app.loading = true;
app.errorMsg = false;
Auth.login(app.loginData).then(function(data){
if(data.data.success){
app.loading = false;
app.successMsg = data.data.message + '...redirecting';
$timeout(function() {
$location.path('/about');
app.loginData = '';
app.successMsg = false;
}, 2000);
} else {
app.loading = false;
app.errorMsg = data.data.message;
}
});
};
this.logout = function() {
Auth.logout();
$location.path('/logout');
$timeout(function(){
$location.path('/');
}, 2000);
};
})
I'm trying to secure my sails js rest api with the help of the passport http package but at the moment I can't figure out where the error is in my code.
I used this repo and this tutorial to get an idea of how this should work. My problem is that my code always returns a 401.
I don't really know where to look for the error. If you need more information about my code just comment.
Bruno
EDIT:
I found the source of the problem (With the help of #Viktor). I just didn't really understood how HTTP-Basic authentication works. Now the problem is how do I send my auth-credentials and my data? If I just test the routes with auth(...), they work... But how do I add the data? Or do I have to authenticate me first and send the data in the second request?
passport.js
var passport = require('passport');
var BasicStrategy = require('passport-http').BasicStrategy;
var bcrypt = require('bcrypt');
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findOne({
id: id
}, function(err, user) {
done(err, user);
});
});
passport.use('user-authentication', new BasicStrategy(
function(mail, password, done) {
sails.log.error("hallo");
User.findOne({
mail: mail
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Incorrect email.'
});
}
// Make sure the password is correct
bcrypt.compare(password, user.password, function(err, isMatch) {
if (err) {
return done(err);
}
// Password did not match
if (!isMatch) {
return done(null, false, {
message: 'Invalid Password'
});
}
// Success
return done(null, user);
});
});
}
));
isAuthenticated.js
var passport = require("passport");
module.exports = function (req, res, ok) {
passport.authenticate("user-authentication", {
session: false
}, function (err, user, info) {
if (err || !user) {
res.set("WWW-Authenticate", "Basic realm=\"Restricted\"");
return res.send("You are not permitted to perform this action", 401);
}
req.session.user = user;
return ok(null, user);
})(req, res, ok);
};
policies.js
module.exports.policies = {
'*': true,
'UserController': {
update: 'isAuthenticated'
}
}
UserController.test.js
var request = require('supertest');
var async = require('async');
describe('UserController', function() {
describe('#new()', function() {
it('...', function (done) {
request(sails.hooks.http.app)
.post('/user/new')
.send({ own_number: '654122', password: 'test', mail: 'test#test.com', device_id: '1234', numbers: [1234567] })
.expect(200)
.end(done);
});
});
describe('#update()', function(){
it('...', function (done) {
async.series([
function(callback){
request(sails.hooks.http.app)
.post('/contact/update')
.send({ number: 1234, mail: "test#test.com", password: "test" })
.expect(200)
.end(callback);
},
function(callback){
request(sails.hooks.http.app)
.post('/user/update')
.send({ numbers: [1234], mail: "tet#test.com", password: "test" })
.expect(200)
.end(callback);
}
], done);
});
});
});
Works for me – I'm able to authenticate as well as access and manage the user data once there's a valid user in the database. With an empty user database, you would get 401 all the time, of course, as these policies don't allow you to create even the first user to authenticate as. Temporarily disabling the UserController policies in config/policies.js gives you the opportunity to create the first user.
Assuming you have at least one valid user in the database, let's narrow down the problem. What output do you get from logging err and user in isAuthenticated.js? If you get null and false, what happens in the different steps in passport.js - are you able to find the user by e-mail address in the database and does the password match?
Do you have custom routes and controller actions or do you use the blueprints?
EDIT: Your update test would look like this with HTTP Basic Authentication:
describe('#update()', function(){
it('...', function (done) {
async.series([
function(callback){
request(sails.hooks.http.app)
.post('/contact/update')
.auth('test#test.com', 'test')
.send({ number: 1234, mail: "test#test.com", password: "test" })
.expect(200)
.end(callback);
},
function(callback){
request(sails.hooks.http.app)
.post('/user/update')
.auth('test#test.com', 'test')
.send({ numbers: [1234], mail: "tet#test.com", password: "test" })
.expect(200)
.end(callback);
}
], done);
});
});
From the documentation here it shows you need userid and password. So looking at your code you have mail in place of userid and that is why you are getting 401 or at least where you can start looking. If you need to verify this you can look at passport-http basic strategy here.
passport.use(new BasicStrategy(
function(userid, password, done) {
User.findOne({ mail: userid, password: password }, function (err, user) {
done(err, user);
});
}
));
I know variations of this questions have been asked multiple times. My understanding is that you basically have to watch your if/else logic and make sure that done isn't being called multiple times.
Twitter and Google work fine. Facebook is giving me this error though:
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:718:10)
at ServerResponse.location (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:835:8)
at ServerResponse.redirect (/Users/azerner/code/mean-starter/node_modules/express/lib/response.js:874:8)
at complete (/Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:241:26)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:250:15
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:427:14)
at Authenticator.transformAuthInfo (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:449:5)
at /Users/azerner/code/mean-starter/node_modules/passport/lib/middleware/authenticate.js:247:22
at /Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:51:7
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:273:43)
at serialized (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:282:7)
at /Users/azerner/code/mean-starter/server/passport.js:17:5
at pass (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:290:9)
at Authenticator.serializeUser (/Users/azerner/code/mean-starter/node_modules/passport/lib/authenticator.js:295:5)
at IncomingMessage.req.login.req.logIn (/Users/azerner/code/mean-starter/node_modules/passport/lib/http/request.js:48:29)
passport.js
var LocalStrategy = require('passport-local').Strategy;
var FacebookStrategy = require('passport-facebook').Strategy;
var TwitterStrategy = require('passport-twitter').Strategy;
var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy;
var mongoose = require('mongoose');
var User = mongoose.model('User');
var Local = mongoose.model('Local');
var Facebook = mongoose.model('Facebook');
var Twitter = mongoose.model('Twitter');
var Google = mongoose.model('Google');
var bcrypt = require('bcrypt');
var config = require('./config.json');
module.exports = function(passport) {
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(id, done) {
User
.findById(id).populate('local').exec()
.then(function(user) {
console.log('deserializeUser found user: ', user);
done(null, user);
}, done)
;
});
// LOCAL
passport.use(new LocalStrategy(function(username, password, done) {
Local
.findOne({ username: username })
.select('username role hashedPassword')
.exec()
.then(function(local) {
if (!local) {
return done(null, false);
}
var validPassword = bcrypt.compareSync(password, local.hashedPassword);
if (!validPassword) {
return done(null, false);
}
else {
User
.findOne({ local: local })
.populate('local')
.exec()
.then(function(user) {
return done(null, user);
})
;
}
})
;
}));
// FACEBOOK
passport.use(new FacebookStrategy({
clientID: config.facebookAuth.clientID,
clientSecret: config.facebookAuth.clientSecret,
callbackURL: config.facebookAuth.callbackURL
}, function(token, refreshToken, profile, done) {
// asynchronous
process.nextTick(function() {
Facebook
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(facebook) {
if (facebook) {
User
.findOne({ facebook: facebook._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Facebook
.create({ id: profile.id, token: token })
.then(function(createdFacebook) {
User
.create({ facebook: createdFacebook })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(function(err) {
return done(err);
})
;
});
}));
// TWITTER
passport.use(new TwitterStrategy({
consumerKey: config.twitterAuth.consumerKey,
consumerSecret: config.twitterAuth.consumerSecret,
callbackURL: config.twitterAuth.callbackURL
}, function(token, tokenSecret, profile, done) {
process.nextTick(function() {
Twitter
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(twitter) {
if (twitter) {
User
.findOne({ twitter: twitter._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Twitter
.create({ id: profile.id, token: token })
.then(function(createdTwitter) {
User
.create({ twitter: createdTwitter })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
// GOOGLE
passport.use(new GoogleStrategy({
clientID: config.googleAuth.clientID,
clientSecret: config.googleAuth.clientSecret,
callbackURL: config.googleAuth.callbackURL
}, function(token, refreshToken, profile, done) {
process.nextTick(function() {
Google
.findOne({ id: profile.id })
.select('id token')
.exec()
.then(function(google) {
if (google) {
User
.findOne({ google: google._id }).exec()
.then(function(user) {
return done(null, user);
})
;
}
else {
Google
.create({ id: profile.id, token: token })
.then(function(createdGoogle) {
User
.create({ google: createdGoogle })
.then(function(user) {
return done(null, user);
})
;
})
;
}
})
.then(null, function(err) {
return done(err);
})
;
});
}));
};
auth.routes.js
var mongoose = require('mongoose');
var express = require('express');
var passport = require('passport');
var Auth = require('./auth.service.js');
try {
var User = mongoose.model('User');
}
catch(e) {
var User = mongoose.model('User', require('../users/user.model.js').UserSchema);
}
var router = express.Router();
// LOCAL
router.post('/login', passport.authenticate('local'), function(req, res) {
res.status(200).json(req.user);
});
router.get('/logout', Auth.isLoggedIn, function(req, res) {
req.logout();
res.status(204).end();
});
router.get('/current-user', Auth.isLoggedIn, function(req, res) {
res.status(200).json(req.user);
});
// FACEBOOK
router.get('/auth/facebook', passport.authenticate('facebook'));
router.get('/auth/facebook/callback',
passport.authenticate('facebook', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// TWITTER
router.get('/auth/twitter', passport.authenticate('twitter'));
router.get('/auth/twitter/callback',
passport.authenticate('twitter', {
successRedirect: '/',
failureRedirect: '/login'
})
);
// GOOGLE
router.get('/auth/google', passport.authenticate('google', { scope: ['profile'] }));
router.get('/auth/google/callback',
passport.authenticate('google', {
successRedirect: '/',
failureRedirect: '/login'
})
);
module.exports = router;
It's also worth noting that I have been using this to block Facebook, but I unblocked it to work on this. I did the commands, force quit Chrome and reopened it, and now I can log into facebook.com fine.
Edit: Oh, and I checked MongoHub and it shows that the User (and Facebook subdocument) have been created.
I need to write commonplace code to check a Current User Password value submitted via form to see if it matches the existing password in the database, and if so, update the password to a New Password value that was submitted via the same form.
Yet, I can't find any good examples of how to do this using Passport.js. Can anyone advise as to how I can do this in my Users controller down below, if there are any helper functions provided by passport that I should use for this, and how I do this with hashed and salted passwords?
Here is my code:
// Form Submitted
req.body = {
_id: '5294198b7b35ad2794000001',
email: 'testusera1#abc.net',
name: 'John Smith',
provider: 'local',
username: 'ab123',
current_password: 'currentpassword',
new_password: 'newpassword'
}
// Route
app.put('/users/me', users.update);
// Controller
var mongoose = require('mongoose'),
User = mongoose.model('User'),
_ = require('underscore'),
passport = require('passport'),
LocalStrategy = require('passport-local').Strategy;
exports.update = function(req, res) {
var user = req.user
user = _.extend(user, req.body);
user.save(function(err) {
if(err) { console.log(err) };
res.jsonp(user);
});
};
// Passport Config File
module.exports = function(passport) {
//Serialize sessions
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findOne({
_id: id
}, function(err, user) {
done(err, user);
});
});
//Use local strategy
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password'
},
function(email, password, done) {
User.findOne({
email: email
}, function(err, user) {
if (err) {
return done(err);
}
if (!user) {
return done(null, false, {
message: 'Unknown user'
});
}
if (!user.authenticate(password)) {
return done(null, false, {
message: 'Invalid password'
});
}
return done(null, user);
});
}
));
};
hashed and salted password
full example on github
// Bcrypt middleware
userSchema.pre('save', function(next) {
var user = this;
if(!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if(err) return next(err);
bcrypt.hash(user.password, salt, function(err, hash) {
if(err) return next(err);
user.password = hash;
next();
});
});
});
// Password verification
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if(err) return cb(err);
cb(null, isMatch);
});
};