// pgsql + sequelize + passport
// sessions will save in DB, after restart app entirel will save
// http://docs.sequelizejs.com
//////////////////////////////////////
//APP.js
const session = require('express-session');
const pgSession = require('connect-pg-simple')(session);
const pg = require('pg');
var passport = require('passport');
//sequelizejs - not necessary
// ... After
// app.use(bodyParser.json());
// app.use(cookieParser());
// ...
// native postgress client
var pgPool = new pg.Pool(Object.assign(config_db, {user: config_db.username}) );
// https://github.com/voxpelli/node-connect-pg-simple
app.use(session({
store: new pgSession({
pool : pgPool, // Connection pool
tableName : 'sessions' // Use another table-name than the default "session" one
}),
secret: process.env.FOO_COOKIE_SECRET || 'oU80saf_Dwd48w9',
resave: true,
saveUninitialized: true,
cookie: { maxAge: 7 * 24 * 60 * 60 * 1000 } // 7 days
}));
app.use(passport.initialize());
app.use(passport.session());
require('./routes/auth')(app,passport); // !!! this file in below
//////////////////////////////////////
// /routes/auth.js
//http://www.passportjs.org/docs/username-password/
const flash = require("connect-flash"); //https://www.npmjs.com/package/connect-flash cross redirect messages
var LocalStrategy = require('passport-local').Strategy;
function AUTH(app, passport){
app.use(flash());
passport.use(new LocalStrategy({
usernameField: 'email',
passwordField: 'password',
passReqToCallback: true
},
async(req, username, password, done) =>{
try{
let user = await Users.Login(username, password); //Model Method
if(!user){
return done(null, false, { message1: 'Incorrect username or password.' });
} else {
//if auth
return done(null, user);
}
} catch(ex){
// return done(err);
return done(null, false, { message1: 'Incorrect data.' + ex.message });
}
}
));
//new update
app.post('/auth/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
if (!user) {
// *** Display message using Express 3 locals
req.session.message = (info && info.message) || '';
return res.redirect('/auth/?returnurl='+req.path);
}
//TODO: return url after relogin
req.logIn(user, function(err) {
if (err) { return next(err); }
return res.redirect('/' + (req.query.returnurl || '') );
});
})(req, res, next);
});
//если просто зашли, перенаправить
app.get('/auth/login', function(req,res,next){
res.redirect('/auth/');
});
app.all('/auth/logout', function(req, res){
req.logout();
res.redirect('/auth/');
});
passport.serializeUser(function(user, done) {
// done(null, user.id); //VARIANT 1
done(null, user); //VARIANT 2
});
// passport.deserializeUser(function(id, done) { //VARIANT 1
passport.deserializeUser(function(user, done) { //VARIANT 2
// console.log('Deserialize user called.');
let incapsuledUserData = {
id: user.id,
email: user.email,
username: user.username,
fullname: user.fullname,
};
global.user = { user: incapsuledUserData };
return done(null, { user: incapsuledUserData });
});
///
//my
app.use(function(req, res, next) {
var isAuthPage = req.path.startsWith('/auth');
var isApi = req.path.startsWith('/api/');
if (isAuthPage || req.user || isApi) {
// logged in
return next();
} else {
// not logged in
res.redirect('/auth/?returnurl='+req.path);
}
});
////////////////AUTH END
}
module.exports = AUTH;
///////////////////////////////////////
// Session Model
// http://docs.sequelizejs.com
sid = { type: Sequelize.STRING, allowNull: false, primaryKey: true };
sess = { type: Sequelize.JSON, allowNull: false };
expire = { type: Sequelize.DATE, allowNull: false };
///////////////////////////////////////
// Optional in API router
router.use(function(req,res,next){
var haveToken = false;
var isAllowedForUnauth = false;
var tokens = [
'q38ru8Jsd09_we0)weW',
//...
];
var allowedPaths = [
'/letters/feedback',
];
var givedToken = req.headers.token || req.query.token;
if(tokens.indexOf(givedToken)!==-1)
haveToken = true;
if(allowedPaths.indexOf(req.path)!==-1)
isAllowedForUnauth = true;
if(req.user || haveToken || isAllowedForUnauth)
next();
else {
res.status(401).send('Access denied');
}
});