UNPKG

ohm

Version:

Node.js Session Manager

112 lines (96 loc) 3.6 kB
'use strict'; (function () { 'use strict'; var _ = require('lodash'); var SESSION_DATA_FIELDS = ['cookie', 'sessionID', 'viewerContextID']; var session = require('express-session'); var MemoryStore = session.MemoryStore; var RedisStore = require('connect-redis')(session); var emptyFunction = include('models/emptyFunction.js'); var production = process.env.NODE_ENV === 'production'; var redis = require('redis'); /** * Implementation of session data memory store. * * The npm package connect (and hence express.js) relies on the concept of * a MomeryStore in order to make sessionData a persistent object * stored on the server. However, because this is in RAM, any reboot of the server * causes all this information to be lost. Hence we instead will implement * a DB backed store to fetch and store session data. * * See https://github.com/senchalabs/connect/blob/master/lib/middleware/session/memory.js * for an example implementation of what connect expected from the session API. * * You MUST implement: * - get: function (sessionID, callback) * - set: function (sessionID, sessionData, callback) * - destroy: function (sessionID, callback) * @module SessionDataStore */ function SessionDataStore(config) { this.config = config; if (!production) { this.cache = new MemoryStore({ reapInterval: 60000 * 10 }); } else { this.cache = new RedisStore({ client: redis.createClient(config.REDIS_PORT, config.REDIS_HOST) }); } } _.extend(SessionDataStore.prototype, RedisStore.prototype, { renameIDToSessionID: function renameIDToSessionID(sessionDataJSON) { var copy = _.omit(sessionDataJSON, 'id'); if (sessionDataJSON.id) { copy.sessionID = sessionDataJSON.id; } return copy; }, areEqual: function areEqual(sessionDataJSON1, sessionDataJSON2) { return _.isEqual(_.pick(this.renameIDToSessionID(sessionDataJSON1), SESSION_DATA_FIELDS), _.pick(this.renameIDToSessionID(sessionDataJSON2), SESSION_DATA_FIELDS)); }, _getFromCache: function _getFromCache(sessionID, callback) { this.cache.get(sessionID, callback); }, dirtyCache: function dirtyCache(sessionID, callback) { this.cache.destroy(sessionID, callback); }, _updateCache: function _updateCache(err, sessionID, sessionDataJSON, callback) { if (sessionDataJSON && !err) { this.cache.set(sessionID, sessionDataJSON); callback(null, sessionDataJSON); } else { callback(err); } }, get: function get(sessionID, callback) { var _this = this; process.nextTick(function () { _this._getFromCache(sessionID, callback); }); }, set: function set(sessionID, sessionDataJSON, callback) { var _this2 = this; callback = callback || emptyFunction; process.nextTick(function () { _this2._getFromCache(sessionID, function (err, cacheSessionDataJSON) { cacheSessionDataJSON = cacheSessionDataJSON || {}; if (_this2.areEqual(cacheSessionDataJSON, sessionDataJSON)) { return callback(); } else { _this2._updateCache(err, sessionID, sessionDataJSON, callback); } }); }); }, destroy: function destroy(sessionID, callback) { var _this3 = this; callback = callback || emptyFunction; process.nextTick(function () { _this3.dirtyCache(sessionID, callback); }); } }); module.exports = SessionDataStore; })();