UNPKG

agg-session-manager

Version:
256 lines (204 loc) 6.45 kB
var moment = require('moment'); var crypto = require('crypto'); var error = {'status': 'error', 'message': 'There was an error' }; var sessionMgr = function(cfg) { var session = {}, collection = 'sessions', sessionTimeout = 86400, // 1 day sessionExtend = false, sessionModel, sessionCron; session.initialize = function (cfg) { cfg = cfg || {}; collection = cfg.collection || collection; sessionTimeout = cfg.sessionTimeout || sessionTimeout; sessionExtend = cfg.sessionExtend || sessionExtend; sessionModel = require('./sessionModel')(collection); sessionCron = require('./sessionCron')(session); sessionCron.start(); }; session.initialize(cfg); // create session session.createSession = function (username, data, callback) { console.log('Creating session for user %s', username); // handle older implementation that might not send in data parameter if (data) { if (typeof data === 'function') { callback = data; data = null; } } var token = createToken(username); // data can contain extra session information (e.g. E1 companies for Mixer Cabin app) var session = { createdTimestamp: +new Date(), username: username, token: token, data: data }; sessionModel.create(session, function(err, res) { if (err) { error.message = err; return callback(error); } callback(null, token); }); }; // check if logged in session.isLoggedInMiddleware = function (req, res, next) { console.log('Middleware is checking for a session...') var token = req.body.token ? req.body.token : req.query.token; session.validateSession(token, function(err, msg) { if (err) { return res.json(error); } if (msg.data && msg.data.message === 'Session has expired') { error.message = msg.data.message; return res.json(error); } if (!msg.data || !msg.data.sessionValid) { error.message = 'Not authorised'; return res.json(error); } // append the username to the request so that it can be used elsewhere req.username = msg.data.username; req.sessionData = msg.data.sessionData; next() }); }; // validate session session.validateSession = function (token, callback) { var response = {'status': 'fail', 'data': {'sessionValid' : false} }; console.log('Attempting to validate session with token: %s', token) sessionModel.readByToken(token, function(err, res) { if (err) { error.message = err; return callback(error); } if (!res.list) { error.message = 'No results list returned'; return callback(error); } if (res.list.length === 0) { return callback(null, response); } var record = res.list[0]; if (!record.fields.token) { return callback(null, response); } var createdOn = moment(record.fields.createdTimestamp); var now = moment(); // check if the session is still active if (sessionTimeout && now.diff(createdOn, 'seconds') > sessionTimeout) { console.log('Session has expired'); response.data.message = 'Session has expired'; return callback(null, response); } // extend session if (sessionExtend) { record.fields.createdTimestamp = +new Date(); sessionModel.update(record.guid, record.fields, function(err, res) { if (err) { return console.log(err); } console.log('Session extended until %s for token: %s', moment().add(sessionTimeout, 'seconds'), token); }); } console.log('Found valid session'); response.status = 'success'; response.data.sessionValid = true; response.data.username = record.fields.username response.data.sessionData = record.fields.data callback(null, response); }); }; // delete session session.deleteSession = function (token, callback) { // sessionModel.deleteByUsername() console.log('Removing session token: %s', token); sessionModel.readByToken(token, function(err, res) { if (err) { error.message = err; return callback(error); } if (!res.list) { error.message = 'No results list returned'; return callback(error); } // there should only be one item in the list array var ids = [] for (var i = 0; i < res.list.length; i++) { var record = res.list[i]; if (record.guid) { // add the database id of the session to the ids array ids.push(record.guid); } }; sessionModel.deleteTokensByIds(ids, function(err, res) { if (err) { error.message = err; return callback(error); } if (!res || res.length === 0) { return callback(null, {'status': 'fail', 'data': { 'message': 'No sessions removed' } }); } callback(null, { 'status': 'success', 'data': { 'message': 'Session removed' } }); }); }); }; session.checkSessions = function (body, callback) { // simple logger function if no callback passed in callback = callback || logger; // called by cron job to check for expired sessions console.log('Checking for expired sessions in %s', collection); // expired sessions will have been created at a time before now - SESSION_TIMEOUT var timeNow = +new Date(), createdTime = timeNow - (sessionTimeout * 1000); sessionModel.findExpiredSessions(createdTime, function(err, res) { if (err) { error.message = err; return callback(error); } if (!res.list) { error.message = 'No results list returned'; return callback(error); } // create an array of session IDs that will be deleted var ids = [] for (var i = 0; i < res.list.length; i++) { if (res.list[i].guid) { // add the database id of the session to the ids array ids.push(res.list[i].guid); } }; sessionModel.deleteTokensByIds(ids, function(err, res) { if (err) { error.message = err; return callback(error); } if (!res || res.length === 0) { return callback(null, 'No sessions removed'); } callback(null, 'Removed ' + res.length + ' sessions from ' + collection); }); }); }; return session; } // create token var createToken = function(username) { var current_date = (new Date()).valueOf().toString(); var random = Math.random().toString(); var token = crypto.createHash('sha1').update(username + current_date + random).digest('hex'); return token; } var logger = function (err, msg) { if (err) { return console.log(err); } console.log(msg); }; module.exports = sessionMgr;