nodejs passport-azure-ad redirect to failureRedirect - node.js

Hello i am trying to understand and apply "passport-azure-ad" function which i found on https://learn.microsoft.com/en-us/graph/tutorials/node?tutorial-step=1 to my own web applicaton.
Instead of "hbs"template engine what they use in the tutorial i use "jade". I registered the application in Azure. When running the web-application I and noticed that the signin function is working (redirected to the login page of Microsoft to enter my credentials). But when i leave the credentials page it returns to the http://localhost:3000/error instead of **http://localhost:3000/succes ** what i expected.
Can you please help me?
Below i put the javascript files:
app.js
require('dotenv').config();
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var session = require('express-session');
var flash = require('connect-flash');
var passport = require('passport');
var OIDCStrategy = require('passport-azure-ad').OIDCStrategy;
var graph = require('./graph');
// Configure simple-oauth2
const oauth2 = require('simple-oauth2').create({
client: {
id: process.env.OAUTH_APP_ID,
secret: process.env.OAUTH_APP_PASSWORD
},
auth: {
tokenHost: process.env.OAUTH_AUTHORITY,
authorizePath: process.env.OAUTH_AUTHORIZE_ENDPOINT,
tokenPath: process.env.OAUTH_TOKEN_ENDPOINT
}
});
// Configure passport
// In-memory storage of logged-in users
// For demo purposes only, production apps should store
// this in a reliable storage
var users = {};
// Passport calls serializeUser and deserializeUser to
// manage users
passport.serializeUser(function(user, done) {
// Use the OID property of the user as a key
users[user.profile.oid] = user;
done (null, user.profile.oid);
});
passport.deserializeUser(function(id, done) {
done(null, users[id]);
});
// Callback function called once the sign-in is complete
// and an access token has been obtained
async function signInComplete(iss, sub, profile, accessToken, refreshToken, params, done) {
if (!profile.oid) {
return done(new Error("No OID found in user profile."), null);
}
try{
const user = await graph.getUserDetails(accessToken);
if (user) {
// Add properties to profile
profile['email'] = user.mail ? user.mail : user.userPrincipalName;
console.info(users)
}
} catch (err) {
done(err, null);
}
// Create a simple-oauth2 token from raw tokens
let oauthToken = oauth2.accessToken.create(params);
// Save the profile and tokens in user storage
users[profile.oid] = { profile, oauthToken };
return done(null, users[profile.oid]);
}
// Configure OIDC strategy
passport.use(new OIDCStrategy(
{
identityMetadata: `${process.env.OAUTH_AUTHORITY}${process.env.OAUTH_ID_METADATA}`,
clientID: process.env.OAUTH_APP_ID,
responseType: 'code id_token',
responseMode: 'form_post',
redirectUrl: process.env.OAUTH_REDIRECT_URI,
allowHttpForRedirectUrl: true,
clientSecret: process.env.OAUTH_APP_PASSWORD,
validateIssuer: false,
passReqToCallback: false,
scope: process.env.OAUTH_SCOPES.split(' ')
},
signInComplete
));
//setup routes
//require('./routes/routes')(app, passport);
var indexRouter = require('./routes/index');
var authRouter = require('./routes/auth');
var app = express();
app.use(session({
secret: 'your_secret_value_here',
resave: false,
saveUninitialized: false,
unset: 'destroy'
}));
// Flash middleware
app.use(flash());
// Set up local vars for template layout
app.use(function(req, res, next) {
// Read any flashed errors and save
// in the response locals
res.locals.error = req.flash('error_msg');
// Check for simple error string and
// convert to layout's expected format
var errs = req.flash('error');
for (var i in errs){
res.locals.error.push({message: 'An error occurred', debug: errs[i]});
}
next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
// Initialize passport
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
// Set the authenticated user in the
// template locals
if (req.user) {
res.locals.user = req.user.profile;
}
next();
});
app.use('/', indexRouter);
app.use('/auth', authRouter);
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
auth.js
var express = require('express');
var passport = require('passport');
var router = express.Router();
/* GET auth callback. */
router.get('/signin',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res,
prompt: 'login',
failureRedirect: '/',
failureFlash: true,
successRedirect: '/'
}
)(req,res,next);
}
);
router.post('/callback',
function(req, res, next) {
passport.authenticate('azuread-openidconnect',
{
response: res,
failureRedirect: '/Error',
failureFlash: true,
successRedirect: '/Succes'
}
)(req,res,next);
}
);
graph.js
var graph = require('#microsoft/microsoft-graph-client');
require('isomorphic-fetch');
module.exports = {
getUserDetails: async function(accessToken) {
const client = getAuthenticatedClient(accessToken);
const user = await client.api('/me').get();
return user;
}
};
function getAuthenticatedClient(accessToken) {
// Initialize Graph client
const client = graph.Client.init({
// Use the provided access token to authenticate
// requests
authProvider: (done) => {
done(null, accessToken);
}
});
return client;
}

Related

nodejs flash message disappears from request

I am trying to post a flash message after authenticating but for some reason the req.flash() loses its value after a redirect.
The code starts when the user asks for a GET on '/'. Here's the code:
const express = require('express');
const session = require('express-session');
const cookie = require('cookie');
const methodOverride = require('method-override')
const passport = require('passport');
const localStrategy = require ('passport-local').Strategy;
const bcrypt = require('bcryptjs');
const cookieParser = require('cookie-parser');
const flash = require('express-flash');
const fs = require('fs');
const config = require('./config.js');
const db = require('./db.js');
const log = require('./logger.js');
const crypto = require('crypto');
var app = express();
const server = require('http').createServer(app);
const build_version = fs.readFileSync("minorBuild.txt").toString();
process.on('UnhandledPromiseRejectionWarning', function(err) {
log.error({ section: "UnhandledPromiseRejectionWarningr", err: err, uid: '1', orgId: '1' });
});
app.set('port', 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(cookieParser(config.cookieSecret));
app.use(flash());
app.use(express.urlencoded({extended: false}));
app.use(express.json());
app.use(session({ name: 'sid',
secret: config.sessionSecret,
cookie: { maxAge: config.sessionCookieMaxAge, domain: 'localhost:3000' },
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static('public'));
app.use(methodOverride('_method'))
app.get('/', function(req, res, next) {
if (req.isAuthenticated()) {
res.redirect('/dashboard');
} else {
res.render('index', { messages: req.flash("error") });
})
}
});
Once the user POSTS username and password, the data is sent to this function:
app.post('/login', function(req, res, next){
passport.authenticate('local', function(err, user, info){
var redirectUrl = '/';
if (!user) {
req.flash('error', info.messages);
return res.redirect('/');
}
if (req.session.redirectUrl) {
redirectUrl = req.session.redirectUrl;
req.session.redirectUrl = null;
}
req.logIn(user, function(err){
if (err) {
return next(err);
}
});
res.redirect(redirectUrl);
})(req, res, next);
});
The data is authenticated here and the message is set on incorrect auth:
async function authenticateUser (email, password, done) {
await db.getParticipantByEmail(email)
.then(async (getEmailResult) => {
if (getEmailResult === undefined) {
return done(null, false, { messages: "Incorrect Username and/or Password" });
}
});
}
Using the debugger I see the message come back to /login in the info.messages. In this line in the '/login' function:
if (!user) {
req.flash('error', info.messages); //I see the message show up here
return res.redirect('/');
}
After the redirect to '/' req.flash('error') is empty.
res.render('index', { messages: req.flash("error") }); //req.flash("error") is empty here
I have no idea why this is. What am I missing?

Node.js, Express, Passport.js - req.user undefined after login

I am aware that there are there are loads of questions already on this particular topic and I have gone through all of them and none of the solutions have help so I am aware that this may be a local issue or something very obvious that I'm missing, however any help or tips that anyone could provide would be much appreciated.
I am using passport.js to authenticate users in my express app. The authentication doesn't seem to raise any errors and seems to execute correctly as the users are stored in the session data in the db, e.g.
session: {"cookie":{"originalMaxAge":3600000,"expires":"2023-01-18T15:00:13.646Z","secure":false,"httpOnly":true,"path":"/"},"passport":{"user":"63c69e118d89ef5921231f75"}}
Despite this, if I try to access req.user in any of the controller modules, it appears undefined.
I will paste my code below:
app.js
// Declare imported packages and modules
const express = require('express');
const MongoStore = require('connect-mongo');
const passport = require('passport');
const methodOverride = require('method-override');
const session = require('express-session');
const staticDirectory = require('serve-static');
require('dotenv').config({ path: './config/config.env' });
const dbConnect = require('./config/db');
const authRouter = require('./routes/authRoutes');
const moviesRouter = require('./routes/moviesRoutes');
const userRouter = require('./routes/userRoutes');
const errorHandler = require('./middleware/errorHandler');
// Declare variables for server
const HOSTNAME = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 3000;
// Instantiate express app
const app = express();
// Add middleware to instantiated app
app.use(express.json());
app.use(staticDirectory(__dirname + '/public'));
app.use(methodOverride('_method')); // TODO: read about method override
// Add session middleware and declare session parameters
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: { maxAge: 1000 * 60 * 60 },
store: MongoStore.create({
mongoUrl: `${process.env.DB_SERVER}/${process.env.database}`,
collection: 'sessions'
})
}));
// Add passport middleware
app.use(passport.initialize());
app.use(passport.session());
// Add routes to defined endpoints
app.use('/auth', authRouter);
app.use('/user/favourites', userRouter);
app.use('/', moviesRouter);
// Add error-handling middleware
app.use(errorHandler);
// Connect the db
dbConnect();
// Run the server
app.listen({ path: HOSTNAME, port: PORT }, (error) => {
if (error) return console.log(error);
console.log(`Server is running on port ${PORT}...`);
});
passport-config.js
onst LocalStrategy = require('passport-local').Strategy;
const bcrypt = require('bcrypt');
const User = require('../models/User');
// Middleware function to initialise passport
const initialize = (passport) => {
// Defining the fields used to login
const customFields = {
usernameField: 'email',
passwordField: 'password'
};
// Function to determin how authentication is handled
const authenticateUser = async (email, password, done) => {
// Finding user in the db
const user = await User.findOne({ email: email });
if (!user) {
// No user found returns an error
return done(null, false, { message: `No user with email ${email} found` });
}
try {
// Checking password entered for user hashed against the stored hash
if (await bcrypt.compare(password, user.hash)) {
return done(null, user);
} else {
// return an error if the hashes don't match
return done(null, false, { message: 'Password incorrect' });
}
} catch (error) {
return done(error);
}
}
passport.use(new LocalStrategy(customFields, authenticateUser));
// Built-in passport.js method to add user id in session cookie info
passport.serializeUser((user, done) => {
return done(null, user.id);
});
// Built-in passport.js method to extract user id from session to obtain user info
passport.deserializeUser(async (id, done) => {
const user = await User.findOne({ _id: id });
return done(null, user);
})
}
module.exports = initialize;
In my authControllers file, I have tried a couple of options:
exports.login = (req, res, next) => {
try {
// Login using passport authenticate function
passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/'
})(req, res, next);
} catch (error) {
next(error);
}
}
and
exports.login = (req, res, next) => {
try {
// Login using passport authenticate function
passport.authenticate('local', (error, user, info) => {
if (error) return next(error);
if (!user) return res.redirect('/');
req.login(user, (err) => {
if (err) return next(err);
res.redirect('/');
})
})(req, res, next);
} catch (error) {
next(error);
}
}
I have also tried importing cors module and adding
app.use(
cors({
origin: `http://localhost:${process.env.PORT}`,
credentials: true,
})
);
and also adding
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", req.headers.origin);
res.header("Access-Control-Allow-Credentials", true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
return res.send(200);
}
next();
});
I have also tried adding { session: true } to the options for passport.authenticate(), switching from express-session to cookie-session, adding bodyParser middleware, adding cookieParser middleware. I checked the order of app.use(session({...})) and the passport functions and tried removing some of the middleware to see if it was interfering. I also tried manually saving the user in the login function and adding the user to res.locals and without results. And also importing passport-config.js after the passport functions:
app.use(passport.initialize());
app.use(passport.session());
const initializePassport = require('./config/passport-config')(passport);
All of which without results.
Sorry for the long question and as I said, any insight on what is going wrong here would be much appreciated. Thanks!

Problem with the Routing Path Express, NodeJS

I have a question about deleting data in the database using Express and NodeJS as I have a form that is deleted.pug to get the ID input from the user then used that ID to find the record in the database to delete that.
I don't know why when I clicked on the "Delete Record" button in the index.pug, I get the error "Cannot GET /delete/". Therefore, I couldn't load the form for the user to input the id.
However, in the address bar, when I typed http://localhost:3000/api/delete/5, then the city with the id is 5 was deleted in the database. Can someone help me so that I can load the delete form to get the input from the user instead of letting them directly put the id in the URL? Thank you, and I appreciate it
api.js
const express = require('express');
const mysql = require('../config/db.config');
const router = express.Router();
router.get('/delete/:id', (req, res) => {
const sql = 'DELETE FROM tblCitiesImport WHERE id=?';
mysql.query(sql, req.params.id, (err) => {
if (err) throw err;
res.render('../views/deletesuccess');
});
});
module.exports = router;
delete.pug
html
head
body
form(action='/api/delete', method='POST')
p
| ID:
input(name='ID', value='', type='text')
input(value='Submit', type='submit')
index.pug
extends layout
block layout-content
div.View.WelcomeView
h1.Banner City Database Site
div.Message
div.Title
h3 IS219 Final
h1 Cities Project
span.Details Access the Cities Records Web Portal
div.NavButtons
if isAuthenticated
a(href="http://localhost:8000")
div.NavButton View Records
a(href="/user")
div.NavButton My Profile
a(href="/delete/")
div.NavButton Delete Record
a(href="/logout")
div.NavButton Logout
else
a(href="/login")
div.NavButton Log in
db structure
CREATE DATABASE citiesData;
use citiesData;
CREATE TABLE IF NOT EXISTS tblCitiesImport (
`id` int AUTO_INCREMENT,
`fldName` VARCHAR(21) CHARACTER SET utf8,
`fldLat` NUMERIC(6, 4),
`fldLong` NUMERIC(7, 4),
`fldCountry` VARCHAR(19) CHARACTER SET utf8,
`fldAbbreviation` VARCHAR(3) CHARACTER SET utf8,
`fldCapitalStatus` VARCHAR(7) CHARACTER SET utf8,
`fldPopulation` INT,
PRIMARY KEY (`id`)
);
app.js
const express = require('express');
const path = require('path');
const expressSession = require('express-session');
const passport = require('passport');
const Auth0Strategy = require('passport-auth0');
require('dotenv').config();
const open = require('open');
const bodyParser = require('body-parser');
const cors = require('cors');
const jwt = require('express-jwt');
const jwtAuthz = require('express-jwt-authz');
const jwksRsa = require('jwks-rsa');
const apiRouter = require('./routes/api');
const dbConn = require('./config/db.config');
const authRouter = require('./auth');
const citiesRoutes = require('./routes/cities.routes');
// App Variables
const app = express();
const port = process.env.PORT || '3000';
// Session Configuration
const session = {
secret: process.env.SESSION_SECRET,
cookie: {},
resave: false,
saveUninitialized: false,
};
if (app.get('env') === 'production') {
// Serve secure cookies, requires HTTPS
session.cookie.secure = true;
}
// Passport Configuration
const strategy = new Auth0Strategy(
{
domain: process.env.AUTH0_DOMAIN,
clientID: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
callbackURL: process.env.AUTH0_CALLBACK_URL,
},
(accessToken, refreshToken, extraParams, profile, done) => {
// Access tokens are used to authorize users to an API
// accessToken is the token to call the Auth0 API or a secured 3rd-party API
// extraParams.id_token has the JSON Web Token (JWT)
// profile has all the information from the user
return done(null, profile);
},
);
// App Configuration
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
app.use(express.static(path.join(__dirname, 'public')));
app.use(expressSession(session));
app.use(bodyParser.urlencoded({ extended: true }));
passport.use(strategy);
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((user, done) => {
done(null, user);
});
// Creating custom middleware with Express
app.use((req, res, next) => {
res.locals.isAuthenticated = req.isAuthenticated();
next();
});
// Authorization middleware. When used, the
// Access Token must exist and be verified against
// the Auth0 JSON Web Key Set
const checkJwt = jwt({
// Dynamically provide a signing key
// based on the kid in the header and
// the signing keys provided by the JWKS endpoint.
secret: jwksRsa.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: 'https://YOURSDOMAIN.us.auth0.com/.well-known/jwks.json'
}),
// Validate the audience and the issuer.
audience: 'http://localhost:3000/api/v1/cities',
issuer: ['https://YOURSDOMAIN.us.auth0.com/'],
algorithms: ['RS256'],
});
// Router Mounting
app.use('/', authRouter);
app.use('/api', apiRouter);
// Routes Definitions
const secured = (req, res, next) => {
if (req.user) {
return next();
}
req.session.returnTo = req.originalUrl;
res.redirect('/login');
};
app.get('/', (req, res) => {
res.render('index', { title: 'Home' });
});
app.get('/user', secured, (req, res, next) => {
const { _raw, _json, ...userProfile } = req.user;
res.render('user', {
title: 'Profile',
userProfile: userProfile,
});
});
// This route is not needed authentication
app.get('/api/public', (req, res) => {
res.json({
message: 'You are in the public endpoint! Authentication is not needed to see this.',
});
});
// This route is needed authentication
app.get('/api/private', checkJwt, (req, res) => {
res.json({
message: 'You are in the private endpoint! Authentication is needed to see this.',
});
});
// using as middleware
app.use('/api/v1/cities', citiesRoutes);
app.set('port', process.env.PORT || 8000);
app.listen(port, () => {
console.log(`Listening to requests on http://localhost:${port}`);
});

Passport not being called

my passport strategy is never called. I recently added passport to my project and am using Boxes API to log a user in. I have done the example problem in another project and gotten it to work (https://github.com/smithdavedesign/OAUTH-Passport-BoxAPILogin-Example/blob/master/login/BoxLogin.js), however when I am trying to integrate it into my current project something has gone haywire. I read sessions and passport session are different and should not cause an issue, that being said I trying to figure out what middle ware is causing the issue. The box API is working correctly and returning me to my dashboard on the callback, however passport seams to be being skipped.
var products = require("../controllers/products");//get functions from product like add update delete ect
var validations = require("../controllers/validations");//get functions from product like add update delete ect
var settings = require("../config/settings");// get all things from settings we need
var Promise = require("bluebird");// adding promise mechanism
var bodyParser = require('body-parser');
var express = require('express');//web framework for node
const expressLayouts = require('express-ejs-layouts');// ejs view engine
const flash = require('connect-flash');//for error and success messages
const session = require('express-session');// holds data of users after login
const uuid = require('uuid')
var MemoryStore = require('memorystore')(session)//https://www.npmjs.com/package/memorystore
const util = require('util');
var os = require("os");
var hostname = os.hostname();//This is the users computer name
const multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads/')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const upload = multer({ storage: storage })
var path = require('path');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var BoxStrategy = require('passport-box').Strategy;
const app = express();//create instance of express
var BOX_CLIENT_ID = "**";
var BOX_CLIENT_SECRET = "**";
// Passport middleware
app.use(passport.initialize());
app.use(passport.session());
passport.serializeUser(function (user, done) {
console.log("serializeUser")//NEVER BEING CALLED
done(null, user);
});
passport.deserializeUser(function (obj, done) {
console.log("deserializeUser")//NEVER BEING CALLED
done(null, obj);
});
passport.use(new BoxStrategy({
clientID: BOX_CLIENT_ID,
clientSecret: BOX_CLIENT_SECRET,
callbackURL: "http://localhost:9000/dashboard"
},
function (accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
return done(null, profile);
});
}
));
//EJS
app.use(expressLayouts);
app.set('view engine', 'ejs');//view engine
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(
session({
genid: (req) => {
console.log('Inside session middleware genid function')
console.log('Request object sessionID from client: ' + req.sessionID);
var new_sid = uuid.v4();
console.log('New session id generated: ' + new_sid);
return new_sid; // use UUIDs for session IDs
},
store: new MemoryStore({
checkPeriod: 86400000 // prune expired entries every 24h
}),
secret: 'secret',
resave: true,
httpOnly: false,
saveUninitialized: false,
cookie: {
maxAge: 24 * 60 * 60 * 1000
}
})
);
// Connect flash
app.use(flash());
// Global variables
app.use(function (req, res, next) {//diferent colors
res.locals.success_msg = req.flash('success_msg');
res.locals.error_msg = req.flash('error_msg');
res.locals.error = req.flash('error');
next();
});
//routes
app.use('/', require('./GraphRoutes'));
app.use('/', require('./dashboardRoutes'));
app.use('/', require('./index'));
app.use('/', require('./extraProccess'));
app.use(passport.initialize());
app.use(passport.session());
app.use(express.static('public'));//public folder where all templates live
app.use(express.static("."));
app.get('/', function (req, res) {
res.render('index', { user: req.user });
});
app.get('/login', function (req, res) {
res.render('login', { user: req.user });
});
app.get('/auth/box', passport.authenticate('box'), function (req, res) {
console.log("box call")
});
app.get('/auth/box/callback',
passport.authenticate('box', { failureRedirect: '/login' }),
function (req, res) {
res.redirect('/dashboard');
});
app.get('/logout', function (req, res) {
req.logout();
res.redirect('/login');
});
I was calling my routes before initializing passport, as well as having cookie parser and other middle ware not in the correct spot.

Node.js passport not authenticating at login

I am trying to implement a simple user login and signup page for my application.
The signup page works and everything is getting stored in mongodb correctly. However, when I try to login it it does not seem to work. It is supposed to redirect to my root page but it will not do that. It always redirect back to /users/login
I've been going through a tutorial online so I do not understand why this isn't working. Here are the relevant files files.
user.js file
const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const passport = require('passport');
let User = require('../models/user');
// Load register form
router.get('/register', function(req, res) {
res.render('register', {
title : 'Register',
errors : req.flash('success')
});
});
// Submit register form
router.post('/register', function(req, res) {
// Get the fields from the form
const firstname = req.body.firstname;
const lastname = req.body.lastname;
const email = req.body.email;
const pass = req.body.pass;
const pass2 = req.body.pass2;
// Verify body is not empty.
req.checkBody('firstname', 'First name is required').notEmpty();
req.checkBody('lastname', 'Last name is required').notEmpty();
req.checkBody('email', 'Email is required').notEmpty();
req.checkBody('email', 'Email is not valid').isEmail();
req.checkBody('pass', 'Password is required').notEmpty();
req.checkBody('pass2', 'Passwords do not match.').equals(req.body.pass);
// Check for errors
let errors = req.validationErrors();
if (errors) {
res.render('register', {
errors:errors
});
} else {
// Create new user object
let newUser = new User({
firstname:firstname,
lastname:lastname,
email:email,
pass:pass
});
// Hash the password for security.
bcrypt.genSalt(10, function(err, salt){
bcrypt.hash(newUser.pass, salt, function(err, hash) {
if (err) {
console.log(err);
}
newUser.pass = hash;
newUser.save(function(err) {
if (err) {
console.log(err);
return;
} else {
console.log("Successful creation.")
req.flash('success', 'Account creation successful!');
res.redirect('/users/login');
}
});
});
})
}
});
// Load login form
router.get('/login', function(req, res){
res.render('login');
});
// Submit login form
router.post('/login', function(req, res, next) {
passport.authenticate('local', {
successRedirect: '..',
failureRedirect: '/users/login',
failureFlash: true
})(req, res, next);
});
module.exports = router;
passport.js file
const LocalStrategy = require('passport-local').Strategy;
const passport = require('passport');
const User = require('../models/user');
const config = require('../config/database');
const bcrypt = require('bcryptjs');
// User Authentication
module.exports = function(passport){
console.log("Made it intro str");
passport.use(new LocalStrategy(function(email, pass, done){
// Match username
let query = {email:email};
User.findOne(query, function(error, user){
if (error){
console.log("error");
return done(error);
}
if (!user) {
console.log("No user found");
return done(null, false, {message: 'No user found.'});
}
bcrypt.compare(pass, user.pass, function(error, isMatch) {
if (error) {
console.log("error2");
return done(error);
}
if (isMatch) {
console.log("Matching password");
return done(null, user);
} else {
console.log("Wrong password");
return done(null, false, {message: 'Invalid password.'});
}
});
});
}));
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
}
App.js
const createError = require('http-errors');
const express = require('express');
const path = require('path');
const logger = require('morgan');
const session = require('express-session');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');
const expressValidator = require('express-validator');
const config = require('./config/database');
const flash = require('connect-flash');
const passport = require('passport');
/* Connect to Database */
mongoose.connect(config.database, { useNewUrlParser: true });
let db = mongoose.connection;
// Check connection.
db.once('open', function(){
console.log('Connected to MongoDB.');
})
// Check DB error.
db.on('error', function(error){
console.log(error);
});
/* Initialize app */
var app = express();
/* Bring in models for database */
let User = require('./models/user');
// Body Parser Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
// Load the view engines
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// Set public folder
app.use(express.static(path.join(__dirname, 'public')));
app.use(expressValidator());
// Keep users session
app.use(session({
secret: 'secret',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 60000 }
}));
app.use(require('connect-flash')());
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res);
next();
});
// Express Validator Middleware
app.use(expressValidator({
errorFormatter: function(param, msg, value) {
var namespace = param.split('.')
, root = namespace.shift()
, formParam = root;
while(namespace.length) {
formParam += '[' + namespace.shift() + ']';
}
return {
param : formParam,
msg : msg,
value : value
};
}
}));
// Passport config
require('./config/passport')(passport);
app.use(passport.initialize());
app.use(passport.session());
// Load homepage
app.get('/', function(req, res) {
res.render('index', {
title: 'Index',
})
})
// Define routes
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/user');
app.use('/', indexRouter);
app.use('/users', usersRouter)
// catch 404 and forward to error handler
app.use(function(req, res, next) {
next(createError(404));
});
// error handler
app.use(function(err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') === 'development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
;
module.exports = app;
I believe the issue is in your passport.js file... By default, LocalStrategy expects to find credentials in parameters named username and password. You need to change that... something like so:
const localOptions = { usernameField: 'email', passwordField: 'pass' };
passport.use(new LocalStrategy(localOptions, function (email, pass, done) {
// Match username
let query = { email: email };
User.findOne(query, function (error, user) {
// etc etc...
});
}));
Link to the docs (at the bottom of the page...): http://www.passportjs.org/docs/username-password/

Resources