sessionstore
Advanced tools
Comparing version 0.4.8 to 1.0.0
12
index.js
@@ -1,13 +0,3 @@ | ||
/*var index; | ||
'use strict'; | ||
if (typeof module.exports !== 'undefined') { | ||
index = module.exports; | ||
} else { | ||
index = root.index = {}; | ||
} | ||
index.VERSION = '0.0.1'; | ||
*/ | ||
module.exports = require('./lib/sessionstore'); |
@@ -1,32 +0,48 @@ | ||
var util = require(process.binding('natives').util ? 'util' : 'sys'), | ||
Session = require('../library').getExpressSession(), | ||
_ = require('lodash'), | ||
'use strict'; | ||
var util = require('util'), | ||
Session = require('../sessionInterface'), | ||
async = require('async'), | ||
cradle = require('cradle'); | ||
cradle = require('cradle'), | ||
_ = require('lodash'); | ||
var CouchDbSessionStore = function (options, callback) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var CouchDbSessionStore = function (options) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var defaults = { | ||
host: 'http://localhost', | ||
port: 5984, | ||
dbName: 'express-sessions', | ||
collectionName: 'sessions' | ||
}; | ||
var defaults = { | ||
host: 'http://localhost', | ||
port: 5984, | ||
dbName: 'express-sessions', | ||
collectionName: 'sessions' | ||
}; | ||
_.defaults(options, defaults); | ||
_.defaults(options, defaults); | ||
var defaultOpt = { | ||
cache: true, | ||
raw: false//, | ||
// secure: true, | ||
// auth: { username: 'login', password: 'pwd' } | ||
}; | ||
var defaultOpt = { | ||
cache: true, | ||
raw: false, | ||
forceSave: true//, | ||
// secure: true, | ||
// auth: { username: 'login', password: 'pwd' } | ||
}; | ||
options.options = options.options || {}; | ||
options.options = options.options || {}; | ||
_.defaults(options.options, defaultOpt); | ||
_.defaults(options.options, defaultOpt); | ||
this.options = options; | ||
this.collectionName = options.collectionName; | ||
}; | ||
util.inherits(CouchDbSessionStore, Session.Store); | ||
_.extend(CouchDbSessionStore.prototype, { | ||
connect: function (callback) { | ||
var self = this; | ||
var options = this.options; | ||
var client = new (cradle.Connection)(options.host, options.port, options.options); | ||
@@ -36,106 +52,130 @@ var db = client.database(options.dbName); | ||
function finish() { | ||
self.client = client; | ||
self.db = db; | ||
self.isConnected = true; | ||
function finish() { | ||
self.client = client; | ||
self.db = db; | ||
db.get('_design/collection', function (err, obj) { | ||
db.get('_design/sessions', function (err, obj) { | ||
var view = { | ||
views: { | ||
findAll: { | ||
map: function (doc) { | ||
emit(doc.collectionName, doc); | ||
} | ||
} | ||
} | ||
}; | ||
if (err && err.error == 'not_found') { | ||
db.save('_design/collection', view, function (err) { | ||
if (callback) { | ||
return callback(null); | ||
} | ||
}); | ||
} else if (err) { | ||
if (callback) { | ||
return callback(err); | ||
} | ||
} else { | ||
db.save('_design/collection', obj._rev, view, function (err) { | ||
if (callback) { | ||
return callback(null); | ||
} | ||
}); | ||
var view = { | ||
views: { | ||
findAll: { | ||
map: function (doc) { | ||
emit(doc.collectionName, doc); | ||
} | ||
} | ||
} | ||
}; | ||
if (err && err.error === 'not_found') { | ||
db.save('_design/sessions', view, function (err) { | ||
if (!err) { | ||
self.emit('connect'); | ||
} | ||
if (callback) callback(err); | ||
}); | ||
} | ||
return; | ||
} | ||
if (!err) { | ||
self.emit('connect'); | ||
} | ||
if (callback) callback(err, self); | ||
}); | ||
} | ||
if (err) { | ||
if (callback) { | ||
return callback(err); | ||
} | ||
} else if (!exists) { | ||
db.create(function (err) { | ||
finish(); | ||
}); | ||
} else { | ||
finish(); | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (!exists) { | ||
db.create(function (err) { | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
finish(); | ||
}); | ||
return; | ||
} | ||
finish(); | ||
}); | ||
}; | ||
}, | ||
util.inherits(CouchDbSessionStore, Session.Store); | ||
disconnect: function(callback) { | ||
if (!this.client) { | ||
if (callback) callback(null); | ||
return; | ||
} | ||
CouchDbSessionStore.prototype.set = function (hash, sess, callback) { | ||
// this.client.close(); | ||
this.emit('disconnect'); | ||
if (callback) callback(null); | ||
}, | ||
set: function (hash, sess, callback) { | ||
sess.collectionName = this.collectionName; | ||
this.db.save(hash, sess, callback); | ||
}; | ||
this.db.save(hash, sess, callback || function() {}); | ||
}, | ||
CouchDbSessionStore.prototype.get = function (hash, callback) { | ||
this.db.get(hash, callback); | ||
}; | ||
get: function (hash, callback) { | ||
// this.db.get(hash, callback || function() {}); | ||
this.db.get(hash, function(err, res) { | ||
if (err && err.error === 'not_found') { | ||
err = null; | ||
} | ||
if (callback) callback(err, res); | ||
}); | ||
}, | ||
CouchDbSessionStore.prototype.destroy = function (hash, callback) { | ||
this.db.remove(hash, callback); | ||
}; | ||
destroy: function (hash, callback) { | ||
var self = this; | ||
this.db.get(hash, function(err, doc) { | ||
if (doc) { | ||
self.db.remove(doc._id, doc._rev, callback || function() {}); | ||
} else { | ||
if (callback) callback(null); | ||
} | ||
}); | ||
}, | ||
CouchDbSessionStore.prototype.all = function (callback) { | ||
this.db.view('collection/findAll', { key: this.collectionName }, function (err, docs) { | ||
var res = []; | ||
all: function (callback) { | ||
this.db.view('sessions/findAll', { key: this.collectionName }, function (err, docs) { | ||
var res = []; | ||
for (var i = 0, len = docs.length; i < len; i++) { | ||
var obj = docs[i].value; | ||
obj.id = obj._id; | ||
var found = _.find(res, function (r) { | ||
return r.id === obj.id; | ||
}); | ||
for (var i = 0, len = docs.length; i < len; i++) { | ||
var obj = docs[i].value; | ||
obj.id = obj._id; | ||
var found = _.find(res, function (r) { | ||
return r.id === obj.id; | ||
}); | ||
if (!found) { | ||
res.push(obj); | ||
} | ||
if (!found) { | ||
res.push(obj); | ||
} | ||
} | ||
callback(err, res); | ||
if (callback) callback(err, res); | ||
}); | ||
}; | ||
}, | ||
CouchDbSessionStore.prototype.length = function (callback) { | ||
length: function (callback) { | ||
this.all(function (err, res) { | ||
callback(res.length); | ||
if (callback) callback(null, res.length); | ||
}); | ||
}; | ||
}, | ||
CouchDbSessionStore.prototype.clear = function (callback) { | ||
clear: function (callback) { | ||
var self = this; | ||
this.all(function (err, results) { | ||
async.forEach(results, function (item, clb) { | ||
self.db.remove(item._id, item._rev, clb); | ||
}, function (err) { | ||
callback(err); | ||
}); | ||
async.each(results, function (item, clb) { | ||
self.db.remove(item._id, item._rev, clb); | ||
}, function (err) { | ||
if (callback) callback(err); | ||
}); | ||
}); | ||
}; | ||
} | ||
}); | ||
module.exports = CouchDbSessionStore; |
@@ -1,32 +0,44 @@ | ||
var util = require(process.binding('natives').util ? 'util' : 'sys'), | ||
Session = require('../library').getExpressSession(), | ||
'use strict'; | ||
var util = require('util'), | ||
Session = require('../sessionInterface'), | ||
_ = require('lodash'), | ||
memjs = require('memjs'); | ||
var MemcachedSessionStore = function (options, callback) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var MemcachedSessionStore = function (options) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var self = this; | ||
var self = this; | ||
var defaults = { | ||
host: 'localhost', | ||
port: 11211, | ||
prefix: 'sess', | ||
expires: 80, | ||
retries: 2, | ||
failover: false, | ||
failoverTime: 60 | ||
}; | ||
var defaults = { | ||
host: 'localhost', | ||
port: 11211, | ||
prefix: 'sess', | ||
expires: 80, | ||
retries: 2, | ||
failover: false, | ||
failoverTime: 60 | ||
}; | ||
_.defaults(options, defaults); | ||
_.defaults(options, defaults); | ||
if (!options.servers) { | ||
if (options.username) { | ||
options.servers = options.username + ':' + options.password + '@' + options.host + ':' + options.port; | ||
} else { | ||
options.servers = options.host + ':' + options.port; | ||
} | ||
if (!options.servers) { | ||
if (options.username) { | ||
options.servers = options.username + ':' + options.password + '@' + options.host + ':' + options.port; | ||
} else { | ||
options.servers = options.host + ':' + options.port; | ||
} | ||
} | ||
this.options = options; | ||
}; | ||
util.inherits(MemcachedSessionStore, Session.Store); | ||
_.extend(MemcachedSessionStore.prototype, { | ||
connect: function (callback) { | ||
var options = this.options; | ||
this.client = memjs.Client.create(options.servers, options); | ||
@@ -36,9 +48,13 @@ | ||
this.emit('connect'); | ||
if (callback) callback(null, this); | ||
}, | ||
}; | ||
disconnect: function (callback) { | ||
this.client.close(); | ||
this.emit('disconnect'); | ||
if (callback) callback(null, this); | ||
}, | ||
util.inherits(MemcachedSessionStore, Session.Store); | ||
MemcachedSessionStore.prototype.set = function (sid, sess, callback) { | ||
set: function (sid, sess, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
@@ -48,57 +64,55 @@ | ||
try { | ||
sessString = JSON.stringify(sess); | ||
sessString = JSON.stringify(sess); | ||
} catch (err) { | ||
if (callback) callback(err); | ||
return; | ||
if (callback) callback(err); | ||
return; | ||
} | ||
this.client.set(prefixedSid, sessString, function (err, res) { | ||
if (callback) callback(err, res); | ||
}); | ||
}; | ||
this.client.set(prefixedSid, sessString, callback || function () {}); | ||
}, | ||
MemcachedSessionStore.prototype.get = function (sid, callback) { | ||
get: function (sid, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
this.client.get(prefixedSid, function (err, value, key) { | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (!value) { | ||
if (callback) callback(null, null); | ||
return; | ||
} | ||
if (!value) { | ||
if (callback) callback(null, null); | ||
return; | ||
} | ||
var result; | ||
var result; | ||
try { | ||
result = JSON.parse(value); | ||
} catch (error) { | ||
if (callback) callback(error); | ||
return; | ||
} | ||
try { | ||
result = JSON.parse(value); | ||
} catch (error) { | ||
if (callback) callback(error); | ||
return; | ||
} | ||
if (callback) callback(null, result); | ||
if (callback) callback(null, result); | ||
}); | ||
}; | ||
}, | ||
MemcachedSessionStore.prototype.destroy = function (sid, callback) { | ||
destroy: function (sid, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
this.client.delete(prefixedSid, function (err, res) { | ||
if (callback) callback(err, res); | ||
}); | ||
}; | ||
this.client.delete(prefixedSid, callback || function() {}); | ||
}, | ||
MemcachedSessionStore.prototype.length = function (callback) { | ||
length: function (callback) { | ||
// memjs doesn't have this function | ||
if (callback) callback(null); | ||
}; | ||
}, | ||
MemcachedSessionStore.prototype.clear = function (callback) { | ||
this.client.flush(callback); | ||
}; | ||
clear: function (callback) { | ||
this.client.flush(callback || function() {}); | ||
} | ||
}); | ||
module.exports = MemcachedSessionStore; |
@@ -1,3 +0,5 @@ | ||
var util = require(process.binding('natives').util ? 'util' : 'sys'), | ||
Session = require('../library').getExpressSession(), | ||
'use strict'; | ||
var util = require('util'), | ||
Session = require('../sessionInterface'), | ||
mongo = require('mongodb'), | ||
@@ -8,43 +10,57 @@ ObjectID = mongo.BSONPure.ObjectID, | ||
function cleanSessionData(json) { | ||
var data = {}; | ||
for (var i in json) { | ||
data[i] = json[i]; | ||
if (data[i] instanceof Object) { | ||
if ('low_' in data[i] || 'high_' in data[i]) { | ||
data[i] = data[i].toNumber(); | ||
} | ||
} | ||
if (!json) { | ||
return json; | ||
} | ||
var data = {}; | ||
for (var i in json) { | ||
data[i] = json[i]; | ||
if (data[i] instanceof Object) { | ||
if ('low_' in data[i] || 'high_' in data[i]) { | ||
data[i] = data[i].toNumber(); | ||
} | ||
} | ||
return data; | ||
} | ||
return data; | ||
} | ||
var MongoSessionStore = function (options, callback) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var MongoSessionStore = function (options) { | ||
options = options || {}; | ||
var self = this; | ||
Session.Store.call(this, options); | ||
var defaults = { | ||
host: 'localhost', | ||
port: 27017, | ||
dbName: 'express-sessions', | ||
collectionName: 'sessions', | ||
reapInterval: 600000, | ||
maxAge: 1000 * 60 * 60 * 2 | ||
}; | ||
var defaults = { | ||
host: 'localhost', | ||
port: 27017, | ||
dbName: 'express-sessions', | ||
collectionName: 'sessions', | ||
reapInterval: 600000, | ||
maxAge: 1000 * 60 * 60 * 2 | ||
}; | ||
_.defaults(options, defaults); | ||
_.defaults(options, defaults); | ||
var defaultOpt = { | ||
auto_reconnect: true, | ||
ssl: false | ||
}; | ||
var defaultOpt = { | ||
auto_reconnect: false, | ||
ssl: false | ||
}; | ||
options.options = options.options || {}; | ||
options.options = options.options || {}; | ||
_.defaults(options.options, defaultOpt); | ||
_.defaults(options.options, defaultOpt); | ||
this.options = options; | ||
}; | ||
util.inherits(MongoSessionStore, Session.Store); | ||
_.extend(MongoSessionStore.prototype, { | ||
connect: function (callback) { | ||
var self = this; | ||
var options = this.options; | ||
setInterval(function () { | ||
self.reap(options.maxAge); | ||
self.reap(options.maxAge); | ||
}, options.reapInterval); | ||
@@ -55,109 +71,133 @@ | ||
if (options.servers && Array.isArray(options.servers)){ | ||
var servers = []; | ||
var servers = []; | ||
options.servers.forEach(function(item){ | ||
if(item.host && item.port) { | ||
servers.push(new mongo.Server(item.host, item.port, item.options)); | ||
} | ||
}); | ||
options.servers.forEach(function(item){ | ||
if(item.host && item.port) { | ||
servers.push(new mongo.Server(item.host, item.port, item.options)); | ||
} | ||
}); | ||
server = new mongo.ReplSetServers(servers); | ||
server = new mongo.ReplSetServers(servers); | ||
} else { | ||
server = new mongo.Server(options.host, options.port, options.options); | ||
server = new mongo.Server(options.host, options.port, options.options); | ||
} | ||
new mongo.Db(options.dbName, server, { safe: true }).open(function (err, client) { | ||
if (err) { | ||
if (callback) callback(err); | ||
this.db = new mongo.Db(options.dbName, server, { safe: true }); | ||
this.db.on('close', function() { | ||
self.emit('disconnect'); | ||
}); | ||
this.db.open(function (err, client) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
var finish = function (err) { | ||
self.client = client; | ||
self.sessions = new mongo.Collection(client, options.collectionName); | ||
self.sessions.ensureIndex({ '_sessionid': 1 }, function() {}); | ||
if (!err) { | ||
self.emit('connect'); | ||
} | ||
if (callback) callback(err, self); | ||
}; | ||
if (options.username) { | ||
client.authenticate(options.username, options.password, finish); | ||
} else { | ||
var finish = function (err) { | ||
self.client = client; | ||
self.sessions = new mongo.Collection(client, options.collectionName); | ||
if (callback) callback(err, self); | ||
}; | ||
if (options.username) { | ||
client.authenticate(options.username, options.password, finish); | ||
} else { | ||
finish(); | ||
} | ||
finish(); | ||
} | ||
} | ||
}); | ||
}; | ||
}, | ||
util.inherits(MongoSessionStore, Session.Store); | ||
disconnect: function (callback) { | ||
if (!this.db) { | ||
if (callback) callback(null); | ||
return; | ||
} | ||
MongoSessionStore.prototype.reap = function (ms, callback) { | ||
this.db.close(callback || function () {}); | ||
}, | ||
reap: function (ms, callback) { | ||
var thresh = Number(new Date(Number(new Date()) - ms)); | ||
this.sessions.remove({ '$or': [ | ||
{ "lastAccess": { "$lt": thresh }}, | ||
{ "lastAccess": { "$exists": false }} | ||
] }, callback || function () { | ||
}); | ||
}; | ||
this.sessions.remove( | ||
{ | ||
'$or': [ | ||
{ "lastAccess": { "$lt": thresh }}, | ||
{ "lastAccess": { "$exists": false }} | ||
] | ||
}, callback || function () {}); | ||
}, | ||
MongoSessionStore.prototype.set = function (sid, sess, callback) { | ||
set: function (sid, sess, callback) { | ||
var self = this; | ||
this.sessions.findOne({ _sessionid: sid }, function (err, session_data) { | ||
if (err) { | ||
function requestClb(err, session_data) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
sess._sessionid = sid; | ||
var method = 'insert'; | ||
if (session_data) { | ||
sess._id = session_data._id; | ||
sess.lastAccess = (new Date()).getTime(); | ||
method = 'save'; | ||
} | ||
self.sessions[method](sess, function (err, document) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
sess._sessionid = sid; | ||
var method = 'insert'; | ||
if (session_data) { | ||
sess.lastAccess = (new Date()).getTime(); | ||
method = 'save'; | ||
} | ||
self.sessions[method](sess, function (err, document) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
if (callback) callback(null, sess); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
return; | ||
} | ||
if (callback) callback(null, sess); | ||
}); | ||
} | ||
} | ||
MongoSessionStore.prototype.get = function (sid, callback) { | ||
if (sess._id) { | ||
this.sessions.get(sess._id, requestClb); | ||
return; | ||
} | ||
this.sessions.findOne({ _sessionid: sid }, requestClb); | ||
}, | ||
get: function (sid, callback) { | ||
this.sessions.findOne({ _sessionid: sid }, function (err, session_data) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
if (session_data) { | ||
session_data = cleanSessionData(session_data); | ||
} | ||
if (callback) callback(null, session_data); | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
session_data = cleanSessionData(session_data); | ||
if (callback) callback(null, session_data); | ||
}); | ||
}; | ||
}, | ||
MongoSessionStore.prototype.destroy = function (sid, callback) { | ||
this.sessions.remove({ _sessionid: sid }, callback || function () { | ||
}); | ||
}; | ||
destroy: function (sid, callback) { | ||
this.sessions.remove({ _sessionid: sid }, callback || function () {}); | ||
}, | ||
MongoSessionStore.prototype.length = function (callback) { | ||
this.sessions.count(callback || function () { | ||
}); | ||
}; | ||
length: function (callback) { | ||
this.sessions.count(callback || function () {}); | ||
}, | ||
MongoSessionStore.prototype.all = function (callback) { | ||
all: function (callback) { | ||
var arr = []; | ||
this.sessions.find(function (err, cursor) { | ||
cursor.each(function (err, d) { | ||
d = cleanSessionData(d); | ||
arr.push(d); | ||
if (!d._id) { | ||
if (callback) callback(arr); | ||
} | ||
}); | ||
cursor.each(function (err, d) { | ||
d = cleanSessionData(d); | ||
arr.push(d); | ||
if (!d._id) { | ||
if (callback) callback(null, arr); | ||
} | ||
}); | ||
}); | ||
}; | ||
}, | ||
MongoSessionStore.prototype.clear = function (callback) { | ||
this.sessions.remove(callback || function () { | ||
}); | ||
}; | ||
clear: function (callback) { | ||
this.sessions.remove(callback || function () {}); | ||
} | ||
}); | ||
module.exports = MongoSessionStore; |
@@ -1,39 +0,53 @@ | ||
var util = require(process.binding('natives').util ? 'util' : 'sys'), | ||
Session = require('../library').getExpressSession(), | ||
'use strict'; | ||
var util = require('util'), | ||
Session = require('../sessionInterface'), | ||
_ = require('lodash'), | ||
async = require('async'), | ||
redis = require('redis'); | ||
var RedisSessionStore = function (options, callback) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var RedisSessionStore = function (options) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var self = this; | ||
var defaults = { | ||
host: 'localhost', | ||
port: 6379, | ||
prefix: 'sess', | ||
ttl: 804600, | ||
max_attempts: 1 | ||
}; | ||
var defaults = { | ||
host: 'localhost', | ||
port: 6379, | ||
prefix: 'sess', | ||
ttl: 804600 | ||
}; | ||
_.defaults(options, defaults); | ||
_.defaults(options, defaults); | ||
if (options.url) { | ||
var url = require('url').parse(options.url); | ||
if (url.protocol === 'redis:') { | ||
if (url.auth) { | ||
var userparts = url.auth.split(":"); | ||
options.user = userparts[0]; | ||
if (userparts.length === 2) { | ||
options.password = userparts[1]; | ||
} | ||
if (options.url) { | ||
var url = require('url').parse(options.url); | ||
if (url.protocol === 'redis:') { | ||
if (url.auth) { | ||
var userparts = url.auth.split(":"); | ||
options.user = userparts[0]; | ||
if (userparts.length === 2) { | ||
options.password = userparts[1]; | ||
} | ||
options.host = url.hostname; | ||
options.port = url.port; | ||
if (url.pathname) { | ||
options.db = url.pathname.replace("/", "", 1); | ||
} | ||
} | ||
options.host = url.hostname; | ||
options.port = url.port; | ||
if (url.pathname) { | ||
options.db = url.pathname.replace("/", "", 1); | ||
} | ||
} | ||
} | ||
this.options = options; | ||
}; | ||
util.inherits(RedisSessionStore, Session.Store); | ||
_.extend(RedisSessionStore.prototype, { | ||
connect: function (callback) { | ||
var self = this; | ||
var options = this.options; | ||
this.client = new redis.createClient(options.port || options.socket, options.host, options); | ||
@@ -50,5 +64,5 @@ | ||
if (err && !calledBack && callback) { | ||
calledBack = true; | ||
if (callback) callback(err, self); | ||
return; | ||
calledBack = true; | ||
if (callback) callback(err, self); | ||
return; | ||
} | ||
@@ -60,106 +74,132 @@ if (err) throw err; | ||
if (options.db) { | ||
this.client.select(options.db); | ||
this.client.select(options.db); | ||
} | ||
this.client.on('error', function () { | ||
self.emit('disconnect'); | ||
this.client.on('end', function () { | ||
self.disconnect(); | ||
}); | ||
if (calledBack) return; | ||
calledBack = true; | ||
if (callback) callback(null, self); | ||
this.client.on('error', function (err) { | ||
console.log(err); | ||
if (calledBack) return; | ||
calledBack = true; | ||
if (callback) callback(null, self); | ||
}); | ||
this.client.on('connect', function () { | ||
if (options.db) { | ||
self.client.send_anyways = true; | ||
self.client.select(options.db); | ||
self.client.send_anyways = false; | ||
} | ||
self.emit('connect'); | ||
if (options.db) { | ||
self.client.send_anyways = true; | ||
self.client.select(options.db); | ||
self.client.send_anyways = false; | ||
} | ||
self.emit('connect'); | ||
if (calledBack) return; | ||
calledBack = true; | ||
if (callback) callback(null, self); | ||
if (calledBack) return; | ||
calledBack = true; | ||
if (callback) callback(null, self); | ||
}); | ||
}; | ||
}, | ||
util.inherits(RedisSessionStore, Session.Store); | ||
disconnect: function (callback) { | ||
this.client.end(); | ||
this.emit('disconnect'); | ||
if (callback) callback(null, this); | ||
}, | ||
RedisSessionStore.prototype.set = function (sid, sess, callback) { | ||
set: function (sid, sess, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
try { | ||
var ttl = this.ttl; | ||
sess = JSON.stringify(sess); | ||
this.client.setex(prefixedSid, ttl, sess, function (err, result) { | ||
if (callback) { | ||
callback(err, result); | ||
} | ||
}); | ||
var ttl = this.ttl; | ||
sess = JSON.stringify(sess); | ||
this.client.setex(prefixedSid, ttl, sess, callback || function () {}); | ||
} catch (err) { | ||
if (callback) { | ||
callback(err); | ||
} | ||
if (callback) callback(err); | ||
} | ||
}; | ||
}, | ||
RedisSessionStore.prototype.get = function (sid, callback) { | ||
get: function (sid, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
this.client.get(prefixedSid, function (err, data) { | ||
if (err) { | ||
if (callback) { | ||
callback(err); | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (!data) { | ||
if (callback) callback(null, null); | ||
return; | ||
} | ||
var result; | ||
try { | ||
result = JSON.parse(data.toString()); | ||
} catch (error) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (callback) callback(null, result); | ||
}); | ||
}, | ||
destroy: function (sid, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
this.client.del(prefixedSid, callback || function () {}); | ||
}, | ||
all: function (callback) { | ||
var self = this; | ||
this.client.keys(this.prefix + ':*', function(err, docs) { | ||
async.map(docs, function(doc, callback) { | ||
self.client.get(doc, function (err, data) { | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (!data) { | ||
if (callback) { | ||
callback(null, null); | ||
} | ||
} | ||
if (!data) { | ||
if (callback) callback(null, null); | ||
return; | ||
} | ||
} | ||
var result; | ||
var result; | ||
try { | ||
try { | ||
result = JSON.parse(data.toString()); | ||
} catch (error) { | ||
if (callback) { | ||
callback(error); | ||
} | ||
} catch (error) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
} | ||
if (callback) { | ||
callback(null, result); | ||
} | ||
if (callback) callback(null, result); | ||
}); | ||
}, callback); | ||
}); | ||
}; | ||
}, | ||
RedisSessionStore.prototype.destroy = function (sid, callback) { | ||
var prefixedSid = this.prefix + ':' + sid; | ||
this.client.del(prefixedSid, callback); | ||
}; | ||
RedisSessionStore.prototype.all = function (callback) { | ||
this.client.keys(this.prefix + ':*', callback); | ||
}; | ||
RedisSessionStore.prototype.length = function (callback) { | ||
length: function (callback) { | ||
this.client.keys(this.prefix + ':*', function (err, docs) { | ||
if (err) { | ||
return callback && callback(err); | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
if (callback) callback(null, docs.length); | ||
if (callback) callback(null, docs.length); | ||
}); | ||
}; | ||
}, | ||
RedisSessionStore.prototype.clear = function (callback) { | ||
this.client.del(this.prefix + ':*', callback); | ||
}; | ||
clear: function (callback) { | ||
var self = this; | ||
this.client.keys(this.prefix + ':*', function(err, docs) { | ||
async.each(docs, function(doc, callback) { | ||
self.client.del(doc, callback); | ||
}, callback || function () {}); | ||
}); | ||
} | ||
module.exports = RedisSessionStore; | ||
}); | ||
module.exports = RedisSessionStore; |
@@ -1,3 +0,5 @@ | ||
var util = require(process.binding('natives').util ? 'util' : 'sys'), | ||
Session = require('../library').getExpressSession(), | ||
'use strict'; | ||
var util = require('util'), | ||
Session = require('../sessionInterface'), | ||
tingodb = require('tingodb')(), | ||
@@ -8,114 +10,149 @@ ObjectID = tingodb.ObjectID, | ||
function cleanSessionData(json) { | ||
var data = {}; | ||
for (var i in json) { | ||
data[i] = json[i]; | ||
if (data[i] instanceof Object) { | ||
if ('low_' in data[i] || 'high_' in data[i]) { | ||
data[i] = data[i].toNumber(); | ||
} | ||
} | ||
if (!json) { | ||
return json; | ||
} | ||
var data = {}; | ||
for (var i in json) { | ||
data[i] = json[i]; | ||
if (data[i] instanceof Object) { | ||
if ('low_' in data[i] || 'high_' in data[i]) { | ||
data[i] = data[i].toNumber(); | ||
} | ||
} | ||
return data; | ||
} | ||
return data; | ||
} | ||
var TingoSessionStore = function (options, callback) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var TingoSessionStore = function (options) { | ||
options = options || {}; | ||
Session.Store.call(this, options); | ||
var defaults = { | ||
dbPath: require('path').join(__dirname, '../../'), | ||
collectionName: 'sessions', | ||
reapInterval: 600000, | ||
maxAge: 1000 * 60 * 60 * 2 | ||
}; | ||
_.defaults(options, defaults); | ||
this.options = options; | ||
}; | ||
util.inherits(TingoSessionStore, Session.Store); | ||
_.extend(TingoSessionStore.prototype, { | ||
connect: function (callback) { | ||
var self = this; | ||
var defaults = { | ||
dbPath: __dirname + '/', | ||
collectionName: 'sessions', | ||
reapInterval: 600000, | ||
maxAge: 1000 * 60 * 60 * 2 | ||
}; | ||
var options = this.options; | ||
_.defaults(options, defaults); | ||
setInterval(function () { | ||
self.reap(options.maxAge); | ||
self.reap(options.maxAge); | ||
}, options.reapInterval); | ||
this.dbPath = options.dbPath; | ||
this.db = new tingodb.Db(this.dbPath, {}); | ||
this.db = new tingodb.Db(options.dbPath, {}); | ||
// this.db.on('close', function() { | ||
// self.emit('disconnect'); | ||
// }); | ||
this.sessions = this.db.collection(options.collectionName + '.tingo'); | ||
this.emit('connect'); | ||
if (callback) callback(null, this); | ||
}; | ||
}, | ||
util.inherits(TingoSessionStore, Session.Store); | ||
disconnect: function (callback) { | ||
if (!this.db) { | ||
if (callback) callback(null); | ||
return; | ||
} | ||
TingoSessionStore.prototype.reap = function (ms, callback) { | ||
this.emit('disconnect'); | ||
this.db.close(callback || function () {}); | ||
}, | ||
reap: function (ms, callback) { | ||
var thresh = Number(new Date(Number(new Date()) - ms)); | ||
this.sessions.remove({ '$or': [ | ||
{ "lastAccess": { "$lt": thresh }}, | ||
{ "lastAccess": { "$exists": false }} | ||
] }, callback || function () { | ||
}); | ||
}; | ||
this.sessions.remove( | ||
{ | ||
'$or': [ | ||
{ "lastAccess": { "$lt": thresh }}, | ||
{ "lastAccess": { "$exists": false }} | ||
] | ||
}, callback || function () {}); | ||
}, | ||
TingoSessionStore.prototype.set = function (sid, sess, callback) { | ||
set: function (sid, sess, callback) { | ||
var self = this; | ||
this.sessions.findOne({ _sessionid: sid }, function (err, session_data) { | ||
if (err) { | ||
function requestClb(err, session_data) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
sess._sessionid = sid; | ||
var method = 'insert'; | ||
if (session_data) { | ||
sess._id = session_data._id; | ||
sess.lastAccess = (new Date()).getTime(); | ||
method = 'save'; | ||
} | ||
self.sessions[method](sess, function (err, document) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
sess._sessionid = sid; | ||
var method = 'insert'; | ||
if (session_data) { | ||
sess.lastAccess = (new Date()).getTime(); | ||
method = 'save'; | ||
} | ||
self.sessions[method](sess, function (err, document) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
if (callback) callback(null, sess); | ||
} | ||
}); | ||
} | ||
}); | ||
}; | ||
return; | ||
} | ||
if (callback) callback(null, sess); | ||
}); | ||
} | ||
} | ||
TingoSessionStore.prototype.get = function (sid, callback) { | ||
if (sess._id) { | ||
this.sessions.get(sess._id, requestClb); | ||
return; | ||
} | ||
this.sessions.findOne({ _sessionid: sid }, requestClb); | ||
}, | ||
get: function (sid, callback) { | ||
this.sessions.findOne({ _sessionid: sid }, function (err, session_data) { | ||
if (err) { | ||
if (callback) callback(err); | ||
} else { | ||
if (session_data) { | ||
session_data = cleanSessionData(session_data); | ||
} | ||
if (callback) callback(null, session_data); | ||
} | ||
if (err) { | ||
if (callback) callback(err); | ||
return; | ||
} | ||
session_data = cleanSessionData(session_data); | ||
if (callback) callback(null, session_data); | ||
}); | ||
}; | ||
}, | ||
TingoSessionStore.prototype.destroy = function (sid, callback) { | ||
this.sessions.remove({ _sessionid: sid }, callback); | ||
}; | ||
destroy: function (sid, callback) { | ||
this.sessions.remove({ _sessionid: sid }, callback || function () {}); | ||
}, | ||
TingoSessionStore.prototype.length = function (callback) { | ||
this.sessions.count(callback); | ||
}; | ||
length: function (callback) { | ||
this.sessions.count(callback || function () {}); | ||
}, | ||
TingoSessionStore.prototype.all = function (callback) { | ||
all: function (callback) { | ||
var arr = []; | ||
this.sessions.find(function (err, cursor) { | ||
cursor.each(function (d) { | ||
d = cleanSessionData(d); | ||
arr.push(d); | ||
}); | ||
if (callback) callback(arr); | ||
cursor.each(function (err, d) { | ||
d = cleanSessionData(d); | ||
arr.push(d); | ||
if (!d._id) { | ||
if (callback) callback(null, arr); | ||
} | ||
}); | ||
}); | ||
}; | ||
}, | ||
TingoSessionStore.prototype.clear = function (callback) { | ||
this.sessions.remove(function (err) { | ||
if (callback) callback(err); | ||
}); | ||
}; | ||
clear: function (callback) { | ||
this.sessions.remove(callback || function () {}); | ||
} | ||
module.exports = TingoSessionStore; | ||
}); | ||
module.exports = TingoSessionStore; |
@@ -1,38 +0,61 @@ | ||
var library = require('../lib/library'); | ||
'use strict'; | ||
var sessionInterface = require('../lib/sessionInterface'), | ||
tolerate = require('tolerance'); | ||
function getSpecificStore(options) { | ||
options = options || { type: 'inMemory' }; | ||
options = options || {}; | ||
if (options.type === 'inMemory') { | ||
return library.getExpressSession().MemoryStore; | ||
} else { | ||
options.type = options.type || 'inmemory'; | ||
options.type = options.type.toLowerCase(); | ||
var dbPath = __dirname + "/databases/" + options.type + ".js"; | ||
options.type = options.type.toLowerCase(); | ||
var dbPath = __dirname + "/databases/" + options.type + ".js"; | ||
var exists = require('fs').existsSync || require('path').existsSync; | ||
if (exists(dbPath)) { | ||
try { | ||
var db = require(dbPath); | ||
return db; | ||
} catch (err) { | ||
if (err.message.indexOf("Cannot find module") >= 0 && err.message.indexOf("'") > 0 && err.message.lastIndexOf("'") !== err.message.indexOf("'")) { | ||
var moduleName = err.message.substring(err.message.indexOf("'") + 1, err.message.lastIndexOf("'")); | ||
console.log('Please install module "' + moduleName + '" to work with db implementation "' + options.type + '"!'); | ||
} | ||
var exists = require('fs').existsSync || require('path').existsSync; | ||
if (!exists(dbPath)) { | ||
var errMsg = 'Implementation for db "' + options.type + '" does not exist!'; | ||
console.log(errMsg); | ||
throw new Error(errMsg); | ||
} | ||
throw err; | ||
} | ||
} else { | ||
return library.getExpressSession().MemoryStore; | ||
} | ||
try { | ||
var db = require(dbPath); | ||
return db; | ||
} catch (err) { | ||
if (err.message.indexOf('Cannot find module') >= 0 && | ||
err.message.indexOf("'") > 0 && | ||
err.message.lastIndexOf("'") !== err.message.indexOf("'")) { | ||
var moduleName = err.message.substring(err.message.indexOf("'") + 1, err.message.lastIndexOf("'")); | ||
console.log('Please install module "' + moduleName + | ||
'" to work with db implementation "' + options.type + '"!'); | ||
} | ||
throw err; | ||
} | ||
} | ||
module.exports = { | ||
createSessionStore: function(options, callback) { | ||
var Store = getSpecificStore(options); | ||
return new Store(options, callback); | ||
createSessionStore: function(options, callback) { | ||
options = options || {}; | ||
var Store; | ||
try { | ||
Store = getSpecificStore(options); | ||
} catch (err) { | ||
if (callback) callback(err); | ||
throw err; | ||
} | ||
var store = new Store(options); | ||
process.nextTick(function() { | ||
tolerate(function(callback) { | ||
store.connect(callback); | ||
}, options.timeout || 0, callback || function () {}); | ||
}); | ||
return store; | ||
} | ||
}; |
{ | ||
"author": "adrai", | ||
"name": "sessionstore", | ||
"version": "0.4.8", | ||
"version": "1.0.0", | ||
"private": false, | ||
"main": "index.js", | ||
"engines": { | ||
"node": ">=0.4.12" | ||
"node": ">=0.8.0" | ||
}, | ||
@@ -14,6 +14,8 @@ "directories": { | ||
"dependencies": { | ||
"async": ">= 0.1.18", | ||
"lodash": ">= 0.5.x" | ||
"async": "0.9.0", | ||
"lodash": "2.4.1", | ||
"tolerance": "1.0.0" | ||
}, | ||
"devDependencies": { | ||
"cradle": ">=0.2.7", | ||
"expect.js": ">= 0.1.2", | ||
@@ -20,0 +22,0 @@ "express": ">= 2.5.0", |
@@ -39,3 +39,4 @@ # Introduction | ||
reapInterval: 600000, // optional | ||
maxAge: 1000 * 60 * 60 * 2 // optional | ||
maxAge: 1000 * 60 * 60 * 2,// optional | ||
timeout: 10000 // optional | ||
}) | ||
@@ -57,3 +58,4 @@ })); | ||
reapInterval: 600000, // optional | ||
maxAge: 1000 * 60 * 60 * 2 // optional | ||
maxAge: 1000 * 60 * 60 * 2,// optional | ||
timeout: 10000 // optional | ||
}) | ||
@@ -75,21 +77,7 @@ })); | ||
dbName: 'express-sessions',// optional | ||
collectionName: 'sessions' // optional | ||
collectionName: 'sessions',// optional | ||
timeout: 10000 // optional | ||
}) | ||
})); | ||
## Connecting to nstore | ||
var sessionstore = require('sessionstore'); | ||
var express = require('express'); | ||
var app = express(); | ||
app.use(express.session({ | ||
store: sessionstore.createSessionStore({ | ||
type: 'nstore', | ||
dbFile: __dirname + '/sessions.db', //optional | ||
maxAge: 3600000 //optional | ||
}) | ||
})); | ||
## Connecting to redis | ||
@@ -108,3 +96,4 @@ | ||
prefix: 'sess', // optional | ||
ttl: 804600 // optional | ||
ttl: 804600, // optional | ||
timeout: 10000 // optional | ||
}) | ||
@@ -129,17 +118,36 @@ })); | ||
failover: false, // optional | ||
failoverTime: 60 // optional | ||
failoverTime: 60, // optional | ||
timeout: 10000 // optional | ||
}) | ||
})); | ||
## Catch connect ad disconnect events | ||
var ss = module.exports.createSessionStore({ type: 'mongodb' }, function(err, ss) { | ||
console.log('hello from callback'); | ||
// use store here... | ||
// app.use(express.session({ | ||
// store: ss | ||
// })); | ||
}); | ||
ss.on('connect', function() { | ||
console.log('hello from event'); | ||
// or here | ||
// app.use(express.session({ | ||
// store: ss | ||
// })); | ||
}); | ||
ss.on('disconnect', function() { | ||
console.log('bye'); | ||
}); | ||
# Database Support | ||
Currently these databases are supported: | ||
1. inMemory | ||
1. inmemory | ||
2. mongodb ([node-mongodb-native] (https://github.com/mongodb/node-mongodb-native)) | ||
3. nstore ([nstore] (https://github.com/creationix/nstore)) | ||
4. couchdb ([cradle] (https://github.com/cloudhead/cradle)) | ||
5. tingodb ([tingodb] (https://github.com/sergeyksv/tingodb)) | ||
6. redis ([redis] (https://github.com/mranney/node_redis)) | ||
7. memcached ([memjs] (https://github.com/alevy/memjs)) | ||
3. couchdb ([cradle] (https://github.com/cloudhead/cradle)) | ||
4. tingodb ([tingodb] (https://github.com/sergeyksv/tingodb)) | ||
5. redis ([redis] (https://github.com/mranney/node_redis)) | ||
6. memcached ([memjs] (https://github.com/alevy/memjs)) | ||
@@ -146,0 +154,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
779
0
171
3
30310
3
9
14
1
+ Addedtolerance@1.0.0
+ Addedasync@0.9.0(transitive)
+ Addedlodash@2.4.1(transitive)
+ Addedretry@0.13.1(transitive)
+ Addedtolerance@1.0.0(transitive)
- Removedasync@3.2.6(transitive)
- Removedlodash@4.17.21(transitive)
Updatedasync@0.9.0
Updatedlodash@2.4.1