memory.js
1 /*! 2 * express-session 3 * Copyright(c) 2010 Sencha Inc. 4 * Copyright(c) 2011 TJ Holowaychuk 5 * Copyright(c) 2015 Douglas Christopher Wilson 6 * MIT Licensed 7 */ 8 9 'use strict'; 10 11 /** 12 * Module dependencies. 13 * @private 14 */ 15 16 var Store = require('./store') 17 var util = require('util') 18 19 /** 20 * Shim setImmediate for node.js < 0.10 21 * @private 22 */ 23 24 /* istanbul ignore next */ 25 var defer = typeof setImmediate === 'function' 26 ? setImmediate 27 : function(fn){ process.nextTick(fn.bind.apply(fn, arguments)) } 28 29 /** 30 * Module exports. 31 */ 32 33 module.exports = MemoryStore 34 35 /** 36 * A session store in memory. 37 * @public 38 */ 39 40 function MemoryStore() { 41 Store.call(this) 42 this.sessions = Object.create(null) 43 } 44 45 /** 46 * Inherit from Store. 47 */ 48 49 util.inherits(MemoryStore, Store) 50 51 /** 52 * Get all active sessions. 53 * 54 * @param {function} callback 55 * @public 56 */ 57 58 MemoryStore.prototype.all = function all(callback) { 59 var sessionIds = Object.keys(this.sessions) 60 var sessions = Object.create(null) 61 62 for (var i = 0; i < sessionIds.length; i++) { 63 var sessionId = sessionIds[i] 64 var session = getSession.call(this, sessionId) 65 66 if (session) { 67 sessions[sessionId] = session; 68 } 69 } 70 71 callback && defer(callback, null, sessions) 72 } 73 74 /** 75 * Clear all sessions. 76 * 77 * @param {function} callback 78 * @public 79 */ 80 81 MemoryStore.prototype.clear = function clear(callback) { 82 this.sessions = Object.create(null) 83 callback && defer(callback) 84 } 85 86 /** 87 * Destroy the session associated with the given session ID. 88 * 89 * @param {string} sessionId 90 * @public 91 */ 92 93 MemoryStore.prototype.destroy = function destroy(sessionId, callback) { 94 delete this.sessions[sessionId] 95 callback && defer(callback) 96 } 97 98 /** 99 * Fetch session by the given session ID. 100 * 101 * @param {string} sessionId 102 * @param {function} callback 103 * @public 104 */ 105 106 MemoryStore.prototype.get = function get(sessionId, callback) { 107 defer(callback, null, getSession.call(this, sessionId)) 108 } 109 110 /** 111 * Commit the given session associated with the given sessionId to the store. 112 * 113 * @param {string} sessionId 114 * @param {object} session 115 * @param {function} callback 116 * @public 117 */ 118 119 MemoryStore.prototype.set = function set(sessionId, session, callback) { 120 this.sessions[sessionId] = JSON.stringify(session) 121 callback && defer(callback) 122 } 123 124 /** 125 * Get number of active sessions. 126 * 127 * @param {function} callback 128 * @public 129 */ 130 131 MemoryStore.prototype.length = function length(callback) { 132 this.all(function (err, sessions) { 133 if (err) return callback(err) 134 callback(null, Object.keys(sessions).length) 135 }) 136 } 137 138 /** 139 * Touch the given session object associated with the given session ID. 140 * 141 * @param {string} sessionId 142 * @param {object} session 143 * @param {function} callback 144 * @public 145 */ 146 147 MemoryStore.prototype.touch = function touch(sessionId, session, callback) { 148 var currentSession = getSession.call(this, sessionId) 149 150 if (currentSession) { 151 // update expiration 152 currentSession.cookie = session.cookie 153 this.sessions[sessionId] = JSON.stringify(currentSession) 154 } 155 156 callback && defer(callback) 157 } 158 159 /** 160 * Get session from the store. 161 * @private 162 */ 163 164 function getSession(sessionId) { 165 var sess = this.sessions[sessionId] 166 167 if (!sess) { 168 return 169 } 170 171 // parse 172 sess = JSON.parse(sess) 173 174 if (sess.cookie) { 175 var expires = typeof sess.cookie.expires === 'string' 176 ? new Date(sess.cookie.expires) 177 : sess.cookie.expires 178 179 // destroy expired session 180 if (expires && expires <= Date.now()) { 181 delete this.sessions[sessionId] 182 return 183 } 184 } 185 186 return sess 187 }