Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 82 additions & 51 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ var oneDay = 86400 * 1000;

var inherits = require('util').inherits,
events = require('events'),
MongoClient = require('mongodb').MongoClient;
MongoClient = require('mongodb').MongoClient,
Db = require('mongodb').Db;

var createIndexes = function(collection, callback) {
var times = 2;
Expand All @@ -31,7 +32,7 @@ var createIndexes = function(collection, callback) {
};

var makeConnectionString = function(options) {
return 'mongodb://' + (options.host || '127.0.0.1') + ':' +
return 'mongodb://' + (options.host || '127.0.0.1') + ':' +
(options.port || '27017') + '/' +
(options.db || 'test') +
'?ssl=' + (options.ssl || false);
Expand All @@ -47,17 +48,17 @@ var makeConnectionString = function(options) {
module.exports = function(connect) {

/**
* Connect's Store.
*/
* Connect's Store.
*/

var Store = connect.Store || connect.session.Store;

/**
* Initialize MongoStore with the given `options`.
*
* @param {Object} options
* @api public
*/
* Initialize MongoStore with the given `options`.
*
* @param {Object} options
* @api public
*/

function MongoStore(options) {
var self = this;
Expand All @@ -76,10 +77,37 @@ module.exports = function(connect) {
createIndexes(this.col, emitConnect);
} else {
var dbUrl = options.url || makeConnectionString(options);
MongoClient.connect(dbUrl, function(err, db) {
var opts = {};
if (options.user && options.password) {
opts.auth = {
user: options.user,
password: options.password
};
}
MongoClient.connect(dbUrl, opts, function(err, client) {
if (err) throw err;
var db;
if (client instanceof MongoClient) {
var dbName = 'test';
if (typeof options.db === 'string') {
dbName === options.db;
} else if (
client.s && client.s.options &&
typeof client.s.options.dbName === 'string'
) {
dbName = client.s.options.dbName;
}
db = client.db(dbName);
} else if (client instanceof Db) {
db = client;
} else {
throw new Error('mongodb connect failed');
}
self.col = db.collection(options.collection || 'sessions');
if (options.user && options.password) {
if (
options.user && options.password &&
typeof db.authenticate === 'function'
) {
db.authenticate(options.user, options.password, function(err, res) {
if (err) throw err;
if (!res) throw new Error('mongodb authentication failed');
Expand All @@ -93,62 +121,65 @@ module.exports = function(connect) {
};

/**
* Inherit from `Store`.
*/
* Inherit from `Store`.
*/

inherits(MongoStore, Store);

/**
* Attempt to fetch session by the given `sid`.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/

MongoStore.prototype.get = function(sid, fn){
this.col.findOne({sid: sid}, {_id: 0, ttl: 0, sid: 0}, function(err, data) {
if (err) return fn(err);
if (!data) return fn();
return fn(null, data);
});
* Attempt to fetch session by the given `sid`.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/

MongoStore.prototype.get = function(sid, fn) {
this.col.findOne({sid: sid}, {projection: {_id: 0, ttl: 0, sid: 0}})
.then(function(data) {
if (!data) return fn();
return fn(null, data);
})
.catch(fn);
};

/**
* Commit the given `sess` object associated with the given `sid`.
*
* @param {String} sid
* @param {Session} sess
* @param {Function} fn
* @api public
*/
* Commit the given `sess` object associated with the given `sid`.
*
* @param {String} sid
* @param {Session} sess
* @param {Function} fn
* @api public
*/

MongoStore.prototype.set = function(sid, sess, fn) {
try {
var maxAge = sess.cookie.maxAge;
var maxAge = sess.cookie.maxAge;

sess.sid = sid;
sess.ttl = new Date((this.ttl || ('number' === typeof maxAge
? maxAge : oneDay)) + Date.now());
sess.sid = sid;
sess.ttl = new Date((this.ttl || ('number' === typeof maxAge
? maxAge : oneDay)) + Date.now());

this.col.replaceOne({sid: sid}, sess, {upsert: true}, function() {
fn && fn.apply(this, arguments);
});
} catch (err) {
fn && fn(err);
}
this.col.replaceOne({sid: sid}, sess, {upsert: true})
.then(function() {
fn(null, true);
})
.catch(fn);
};

/**
* Destroy the session associated with the given `sid`.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/
* Destroy the session associated with the given `sid`.
*
* @param {String} sid
* @param {Function} fn
* @api public
*/

MongoStore.prototype.destroy = function(sid, fn) {
this.col.deleteOne({sid: sid}, fn);
this.col.deleteOne({sid: sid})
.then(function() {
fn();
})
.catch(fn);
};

return MongoStore;
Expand Down
22 changes: 12 additions & 10 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ var assert = require('assert'),

var testsCount = 3;

var done = (function () {
var done = (function() {
var count = 0;
return function () {
return function() {
++count;
if (count == testsCount) {
console.log('done');
Expand All @@ -28,19 +28,21 @@ store.on('connect', function() {
});

// test with initialized db object
MongoClient.connect('mongodb://127.0.0.1:27017/testdb', function(err, db) {
var store = new MongoStore({db: db});
MongoClient.connect('mongodb://127.0.0.1:27017/testdb', function(err, client) {
var db = client instanceof MongoClient ? client.db('testdb') : client;
var store = new MongoStore({ db: db });
store.on('connect', function() {
baseTest.apply(this);
});
});

// test mongodb auth
MongoClient.connect('mongodb://127.0.0.1:27017/testauth', function(err, db) {
MongoClient.connect('mongodb://127.0.0.1:27017/testauth', function(err, client) {
var db = client instanceof MongoClient ? client.db('testauth') : client;
db.removeUser('user', function() {
db.addUser('user', 'pass', {roles: ['readWrite']}, function(err, res) {
db.addUser('user', 'pass', { roles: ['readWrite'] }, function(err, res) {
assert.ok(!err, '#addUser error');
var store = new MongoStore({user: 'user', password: 'pass', db: 'testauth'});
var store = new MongoStore({ user: 'user', password: 'pass', db: 'testauth' });
store.on('connect', function() {
baseTest.apply(this);
});
Expand All @@ -52,20 +54,20 @@ MongoClient.connect('mongodb://127.0.0.1:27017/testauth', function(err, db) {
function baseTest() {
var self = this;
// #set()
self.set('123', {cookie: {maxAge: 2000}, name: 'name'}, function(err, ok) {
self.set('123', { cookie: { maxAge: 2000 }, name: 'name' }, function(err, ok) {
assert.ok(!err, '#set() got an error');
assert.ok(ok, '#set() is not ok');

// #get()
self.get('123', function(err, data) {
assert.ok(!err, '#get() got an error');
assert.deepEqual({
cookie: {maxAge: 2000},
cookie: { maxAge: 2000 },
name: 'name'
}, data);

// #set null
self.set('123', {cookie: {maxAge: 2000}, name: 'name'}, function() {
self.set('123', { cookie: { maxAge: 2000 }, name: 'name' }, function() {
self.destroy('123', function() {
done();
});
Expand Down