From 7aaf1c0427bdfa6d86f8514952573e3f8e050e5f Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 22:26:50 -0600 Subject: [PATCH 01/11] add: promise support for sessionStore save --- index.js | 25 ++++++++++++++++++++----- session/session.js | 27 +++++++++++++++++++++------ test/session.js | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 42639913..81fd47d6 100644 --- a/index.js +++ b/index.js @@ -370,16 +370,31 @@ function session(options) { function reload(callback) { debug('reloading %s', this.id) - _reload.call(this, function () { - wrapmethods(req.session) - callback.apply(this, arguments) - }) + if (callback) { + _reload.call(this, function () { + wrapmethods(req.session) + callback.apply(this, arguments) + }) + return + } + + if (!callback && !global.Promise) { + throw new Error('must use callback without Promise') + } + + return _reload.call(this) + .then(function() { + return wrapmethods(req.session) + }) + .catch(function(err) { + return err + }) } function save() { debug('saving %s', this.id); savedHash = hash(this); - _save.apply(this, arguments); + return _save.apply(this, arguments); } Object.defineProperty(sess, 'reload', { diff --git a/session/session.js b/session/session.js index fee7608c..0369a03f 100644 --- a/session/session.js +++ b/session/session.js @@ -63,15 +63,30 @@ defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() { /** * Save the session data with optional callback `fn(err)`. * - * @param {Function} fn - * @return {Session} for chaining + * @param {Function} [fn] + * @return {Promise} * @api public */ -defineMethod(Session.prototype, 'save', function save(fn) { - this.req.sessionStore.set(this.id, this, fn || function(){}); - return this; -}); +defineMethod(Session.prototype, 'save', function save (fn) { + if (fn) { + this.req.sessionStore.set(this.id, this, fn) + return + } + + if (!fn && !global.Promise) { + this.req.sessionStore.set(this.id, this, function(){}) + return + } + + var sess = this + return new Promise(function (resolve, reject) { + sess.req.sessionStore.set(sess.id, sess, function (err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Re-loads the session data _without_ altering diff --git a/test/session.js b/test/session.js index 6862ccc4..e2bbca8d 100644 --- a/test/session.js +++ b/test/session.js @@ -1671,6 +1671,43 @@ describe('session()', function(){ .expect(200, 'stored', done) }) + it('should return Promise without callback', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.save() + .then(function () { + store.get(req.session.id, function (err, sess) { + if (err) return res.end(err.message) + res.end(sess ? 'stored' : 'empty') + }) + }) + .catch(function (err) { + if (err) return res.end(err.message) + }) + }) + + request(server) + .get('/') + .expect(200, 'stored', done) + }) + + it('should not return Promise with callback', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + var ret = req.session.save(function (err) { + if (err) return res.end(err.message) + res.statusCode = (ret === undefined) ? 200 : 500 + res.end() + }) + }) + + request(server) + .get('/') + .expect(200, done) + }) + it('should prevent end-of-request save', function (done) { var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { From f735620f10b9ec5202cac438571f628835e37fc7 Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:18:57 -0600 Subject: [PATCH 02/11] add: promise support for sessionStore reload --- session/session.js | 37 ++++++++++++++------ test/session.js | 84 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 11 deletions(-) diff --git a/session/session.js b/session/session.js index 0369a03f..7348d810 100644 --- a/session/session.js +++ b/session/session.js @@ -95,23 +95,38 @@ defineMethod(Session.prototype, 'save', function save (fn) { * `req.session` property will be a new `Session` object, * although representing the same session. * - * @param {Function} fn - * @return {Session} for chaining + * @param {Function} [fn] + * @return {Promise} * @api public */ -defineMethod(Session.prototype, 'reload', function reload(fn) { +defineMethod(Session.prototype, 'reload', function reload (fn) { var req = this.req var store = this.req.sessionStore + if (fn) { + store.get(this.id, function (err, sess) { + if (err) return fn(err) + if (!sess) return fn(new Error('failed to load session')) + store.createSession(req, sess) + fn() + }) + return + } - store.get(this.id, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(new Error('failed to load session')); - store.createSession(req, sess); - fn(); - }); - return this; -}); + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var parent = this + return new Promise(function (resolve, reject) { + store.get(parent.id, function (err, sess) { + if (err) reject(err) + if (!sess) reject(new Error('failed to load session')) + store.createSession(req, sess) + resolve() + }) + }) +}) /** * Destroy `this` session. diff --git a/test/session.js b/test/session.js index e2bbca8d..c705bd63 100644 --- a/test/session.js +++ b/test/session.js @@ -1622,6 +1622,90 @@ describe('session()', function(){ }) }) + it('should return Promise without callback', function (done) { + var server = createServer(null, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + req.session.url = req.url + + if (req.url === '/bar') { + res.end('saw ' + req.session.url) + return + } + + request(server) + .get('/bar') + .set('Cookie', val) + .expect(200, 'saw /bar', function (err, resp) { + if (err) return done(err) + req.session.reload() + .then(function () { + res.end('saw ' + req.session.url) + }) + .catch(function (err) { + if (err) return done(err) + }) + }) + }) + var val + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + val = cookie(res) + request(server) + .get('/foo') + .set('Cookie', val) + .expect(200, 'saw /bar', done) + }) + }) + + it('should not return promise with callback', function (done) { + var server = createServer(null, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + req.session.url = req.url + + if (req.url === '/bar') { + res.end('saw ' + req.session.url) + return + } + + request(server) + .get('/bar') + .set('Cookie', val) + .expect(200, 'saw /bar', function (err, resp) { + if (err) return done(err) + var ret = req.session.reload(function (err) { + if (err) return done(err) + res.statusCode = (ret === undefined) ? 200 : 500 + res.end('saw ' + req.session.url) + }) + }) + }) + var val + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + val = cookie(res) + request(server) + .get('/foo') + .set('Cookie', val) + .expect(200, 'saw /bar', done) + }) + }) + it('should error is session missing', function (done) { var store = new session.MemoryStore() var server = createServer({ store: store }, function (req, res) { From 878f4adbbc9d1c4c1faf2a44e72386c7c438c792 Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:24:09 -0600 Subject: [PATCH 03/11] add: promise support for sessionStore destroy --- session/session.js | 22 ++++++++++++++++++---- test/session.js | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/session/session.js b/session/session.js index 7348d810..d3309bf6 100644 --- a/session/session.js +++ b/session/session.js @@ -137,10 +137,24 @@ defineMethod(Session.prototype, 'reload', function reload (fn) { */ defineMethod(Session.prototype, 'destroy', function destroy(fn) { - delete this.req.session; - this.req.sessionStore.destroy(this.id, fn); - return this; -}); + delete this.req.session + if (fn) { + this.req.sessionStore.destroy(this.id, fn) + return + } + + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var parent = this + return new Promise(function (resolve, reject) { + parent.req.sessionStore.destroy(parent.id, function(err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Regenerate this request's session. diff --git a/test/session.js b/test/session.js index c705bd63..c813d26e 100644 --- a/test/session.js +++ b/test/session.js @@ -1540,7 +1540,7 @@ describe('session()', function(){ }) }) - describe('.destroy()', function(){ + describe('.destroy()', function () { it('should destroy the previous session', function(done){ var server = createServer(null, function (req, res) { req.session.destroy(function (err) { @@ -1554,6 +1554,38 @@ describe('session()', function(){ .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, 'undefined', done) }) + + it('should return Promise without callback', function(done){ + var server = createServer(null, function (req, res) { + req.session.destroy() + .then(function() { + res.end(String(req.session)) + }) + .catch(function (err) { + if (err) res.statusCode = 500 + }) + }) + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', done) + }) + + it('should not return Promise with callback', function(done){ + var server = createServer(null, function (req, res) { + var ret = req.session.destroy(function (err) { + if (err) res.statusCode = 500 + res.statusCode = (ret === undefined) ? 200 : 500 + res.end(String(req.session)) + }) + }) + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', done) + }) }) describe('.regenerate()', function(){ From 44cc8d1ff29655b2d3512b9ff20c7c77fb21504f Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:29:08 -0600 Subject: [PATCH 04/11] add: promise support for sessionStore regenerate --- session/session.js | 20 +++++++++++++++--- test/session.js | 52 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 68 insertions(+), 4 deletions(-) diff --git a/session/session.js b/session/session.js index d3309bf6..4763ea9f 100644 --- a/session/session.js +++ b/session/session.js @@ -165,9 +165,23 @@ defineMethod(Session.prototype, 'destroy', function destroy(fn) { */ defineMethod(Session.prototype, 'regenerate', function regenerate(fn) { - this.req.sessionStore.regenerate(this.req, fn); - return this; -}); + if (fn) { + this.req.sessionStore.regenerate(this.req, fn) + return + } + + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var sess = this + return new Promise(function (resolve, reject) { + sess.req.sessionStore.regenerate(sess.req, function(err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Helper function for creating a method on a prototype. diff --git a/test/session.js b/test/session.js index c813d26e..664cc0da 100644 --- a/test/session.js +++ b/test/session.js @@ -1588,7 +1588,7 @@ describe('session()', function(){ }) }) - describe('.regenerate()', function(){ + describe('.regenerate()', function () { it('should destroy/replace the previous session', function(done){ var server = createServer(null, function (req, res) { var id = req.session.id @@ -1611,6 +1611,56 @@ describe('session()', function(){ .expect(200, 'false', done) }); }) + + it('should return Promise without callback', function (done) { + var server = createServer(null, function (req, res) { + var id = req.session.id + req.session.regenerate() + .then(function() { + res.end(String(req.session.id === id)) + }) + .catch(function (err) { + if (err) res.statusCode = 500 + }) + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) + .expect(shouldSetCookieToDifferentSessionId(sid(res))) + .expect(200, 'false', done) + }) + }) + + it('should not return Promise with callback', function(done){ + var server = createServer(null, function (req, res) { + var id = req.session.id + var ret = req.session.regenerate(function (err) { + if (err) res.statusCode = 500 + res.statusCode = (ret === undefined) ? 200 : 500 + res.end(String(req.session.id === id)) + }) + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, function (err, res) { + if (err) return done(err) + request(server) + .get('/') + .set('Cookie', cookie(res)) + .expect(shouldSetCookie('connect.sid')) + .expect(shouldSetCookieToDifferentSessionId(sid(res))) + .expect(200, 'false', done) + }) + }) }) describe('.reload()', function () { From 8081d4d83b022b04a790913fb9a7d1f905912cda Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 22:26:50 -0600 Subject: [PATCH 05/11] add: promise support for sessionStore save --- index.js | 25 ++++++++++++---- package.json | 1 + session/session.js | 27 +++++++++++++---- test/session.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 11 deletions(-) diff --git a/index.js b/index.js index 42639913..81fd47d6 100644 --- a/index.js +++ b/index.js @@ -370,16 +370,31 @@ function session(options) { function reload(callback) { debug('reloading %s', this.id) - _reload.call(this, function () { - wrapmethods(req.session) - callback.apply(this, arguments) - }) + if (callback) { + _reload.call(this, function () { + wrapmethods(req.session) + callback.apply(this, arguments) + }) + return + } + + if (!callback && !global.Promise) { + throw new Error('must use callback without Promise') + } + + return _reload.call(this) + .then(function() { + return wrapmethods(req.session) + }) + .catch(function(err) { + return err + }) } function save() { debug('saving %s', this.id); savedHash = hash(this); - _save.apply(this, arguments); + return _save.apply(this, arguments); } Object.defineProperty(sess, 'reload', { diff --git a/package.json b/package.json index d473f546..15169c97 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ }, "devDependencies": { "after": "0.8.2", + "bluebird": "3.5.3", "cookie-parser": "1.4.3", "eslint": "3.19.0", "eslint-plugin-markdown": "1.0.0", diff --git a/session/session.js b/session/session.js index fee7608c..0369a03f 100644 --- a/session/session.js +++ b/session/session.js @@ -63,15 +63,30 @@ defineMethod(Session.prototype, 'resetMaxAge', function resetMaxAge() { /** * Save the session data with optional callback `fn(err)`. * - * @param {Function} fn - * @return {Session} for chaining + * @param {Function} [fn] + * @return {Promise} * @api public */ -defineMethod(Session.prototype, 'save', function save(fn) { - this.req.sessionStore.set(this.id, this, fn || function(){}); - return this; -}); +defineMethod(Session.prototype, 'save', function save (fn) { + if (fn) { + this.req.sessionStore.set(this.id, this, fn) + return + } + + if (!fn && !global.Promise) { + this.req.sessionStore.set(this.id, this, function(){}) + return + } + + var sess = this + return new Promise(function (resolve, reject) { + sess.req.sessionStore.set(sess.id, sess, function (err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Re-loads the session data _without_ altering diff --git a/test/session.js b/test/session.js index 6862ccc4..76ccf0c1 100644 --- a/test/session.js +++ b/test/session.js @@ -12,6 +12,11 @@ var util = require('util') var Cookie = require('../session/cookie') +var Promise = global.Promise || require('bluebird') + +// Add Promise to mocha's global list +global.Promise = global.Promise + var min = 60 * 1000; describe('session()', function(){ @@ -1718,6 +1723,76 @@ describe('session()', function(){ .expect(200, 'saved', done) }) }) + + describe('with global Promise', function () { + beforeEach(function () { + global.Promise = Promise + }) + + afterEach(function () { + global.Promise = undefined + }) + + it('should return Promise without callback', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.save() + .then(function () { + store.get(req.session.id, function (err, sess) { + if (err) return res.end(err.message) + res.end(sess ? 'stored' : 'empty') + }) + }) + .catch(function (err) { + res.statusCode = 500 + res.end(err.message) + }) + }) + + request(server) + .get('/') + .expect(200, 'stored', done) + }) + + it('should not return Promise with callback', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + var ret = req.session.save(function (err) { + res.statusCode = (!err && ret === undefined) ? 200 : 500 + res.end() + }) + }) + + request(server) + .get('/') + .expect(200, done) + }) + }) + + describe('without global Promise', function () { + beforeEach(function () { + global.Promise = undefined + }) + + afterEach(function () { + global.Promise = Promise + }) + + it('should work without callback', function (done) { + var store = new session.MemoryStore() + var server = createServer({ store: store }, function (req, res) { + req.session.hit = true + req.session.save() + res.end() + }) + + request(server) + .get('/') + .expect(200, done) + }) + }) }) describe('.touch()', function () { From 3d100d9546e3200f61b2f8c9a4d30a8d3d82e033 Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:18:57 -0600 Subject: [PATCH 06/11] add: promise support for sessionStore reload --- session/session.js | 37 ++++++++++++------ test/session.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 11 deletions(-) diff --git a/session/session.js b/session/session.js index 0369a03f..7348d810 100644 --- a/session/session.js +++ b/session/session.js @@ -95,23 +95,38 @@ defineMethod(Session.prototype, 'save', function save (fn) { * `req.session` property will be a new `Session` object, * although representing the same session. * - * @param {Function} fn - * @return {Session} for chaining + * @param {Function} [fn] + * @return {Promise} * @api public */ -defineMethod(Session.prototype, 'reload', function reload(fn) { +defineMethod(Session.prototype, 'reload', function reload (fn) { var req = this.req var store = this.req.sessionStore + if (fn) { + store.get(this.id, function (err, sess) { + if (err) return fn(err) + if (!sess) return fn(new Error('failed to load session')) + store.createSession(req, sess) + fn() + }) + return + } - store.get(this.id, function(err, sess){ - if (err) return fn(err); - if (!sess) return fn(new Error('failed to load session')); - store.createSession(req, sess); - fn(); - }); - return this; -}); + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var parent = this + return new Promise(function (resolve, reject) { + store.get(parent.id, function (err, sess) { + if (err) reject(err) + if (!sess) reject(new Error('failed to load session')) + store.createSession(req, sess) + resolve() + }) + }) +}) /** * Destroy `this` session. diff --git a/test/session.js b/test/session.js index 76ccf0c1..820bba7d 100644 --- a/test/session.js +++ b/test/session.js @@ -1655,6 +1655,100 @@ describe('session()', function(){ .expect(500, 'failed to load session', done) }) }) + + describe('with global Promise', function () { + beforeEach(function () { + global.Promise = Promise + }) + + afterEach(function () { + global.Promise = undefined + }) + + it('should return Promise without callback', function (done) { + var server = createServer(null, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + req.session.url = req.url + + if (req.url === '/bar') { + res.end('saw ' + req.session.url) + return + } + + request(server) + .get('/bar') + .set('Cookie', val) + .expect(200, 'saw /bar', function (err, resp) { + if (err) return done(err) + req.session.reload() + .then(function () { + res.end('saw ' + req.session.url) + }) + .catch(function (err) { + if (err) return done(err) + }) + }) + }) + var val + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + val = cookie(res) + request(server) + .get('/foo') + .set('Cookie', val) + .expect(200, 'saw /bar', done) + }) + }) + + it('should not return promise with callback', function (done) { + var server = createServer(null, function (req, res) { + if (req.url === '/') { + req.session.active = true + res.end('session created') + return + } + + req.session.url = req.url + + if (req.url === '/bar') { + res.end('saw ' + req.session.url) + return + } + + request(server) + .get('/bar') + .set('Cookie', val) + .expect(200, 'saw /bar', function (err, resp) { + if (err) return done(err) + var ret = req.session.reload(function (err) { + if (err) return done(err) + res.statusCode = (ret === undefined) ? 200 : 500 + res.end('saw ' + req.session.url) + }) + }) + }) + var val + + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + val = cookie(res) + request(server) + .get('/foo') + .set('Cookie', val) + .expect(200, 'saw /bar', done) + }) + }) + }) }) describe('.save()', function () { From 55b218b55dea45aab0a39c6fbc3e2f5147c00448 Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:24:09 -0600 Subject: [PATCH 07/11] add: promise support for sessionStore destroy --- session/session.js | 22 ++++++++++++++++++---- test/session.js | 44 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/session/session.js b/session/session.js index 7348d810..d3309bf6 100644 --- a/session/session.js +++ b/session/session.js @@ -137,10 +137,24 @@ defineMethod(Session.prototype, 'reload', function reload (fn) { */ defineMethod(Session.prototype, 'destroy', function destroy(fn) { - delete this.req.session; - this.req.sessionStore.destroy(this.id, fn); - return this; -}); + delete this.req.session + if (fn) { + this.req.sessionStore.destroy(this.id, fn) + return + } + + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var parent = this + return new Promise(function (resolve, reject) { + parent.req.sessionStore.destroy(parent.id, function(err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Regenerate this request's session. diff --git a/test/session.js b/test/session.js index 820bba7d..47d1bf53 100644 --- a/test/session.js +++ b/test/session.js @@ -1545,7 +1545,7 @@ describe('session()', function(){ }) }) - describe('.destroy()', function(){ + describe('.destroy()', function () { it('should destroy the previous session', function(done){ var server = createServer(null, function (req, res) { req.session.destroy(function (err) { @@ -1559,6 +1559,48 @@ describe('session()', function(){ .expect(shouldNotHaveHeader('Set-Cookie')) .expect(200, 'undefined', done) }) + + describe('with global Promise', function () { + beforeEach(function () { + global.Promise = Promise + }) + + afterEach(function () { + global.Promise = undefined + }) + + it('should return Promise without callback', function(done){ + var server = createServer(null, function (req, res) { + req.session.destroy() + .then(function() { + res.end(String(req.session)) + }) + .catch(function (err) { + if (err) res.statusCode = 500 + }) + }) + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', done) + }) + + it('should not return Promise with callback', function(done){ + var server = createServer(null, function (req, res) { + var ret = req.session.destroy(function (err) { + if (err) res.statusCode = 500 + res.statusCode = (ret === undefined) ? 200 : 500 + res.end(String(req.session)) + }) + }) + + request(server) + .get('/') + .expect(shouldNotHaveHeader('Set-Cookie')) + .expect(200, 'undefined', done) + }) + }) }) describe('.regenerate()', function(){ From c687d5a276edcadccb235a1727feff1e4a3ae10f Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Sat, 23 Feb 2019 23:29:08 -0600 Subject: [PATCH 08/11] add: promise support for sessionStore regenerate --- session/session.js | 20 +++++++++-- test/session.js | 86 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/session/session.js b/session/session.js index d3309bf6..4763ea9f 100644 --- a/session/session.js +++ b/session/session.js @@ -165,9 +165,23 @@ defineMethod(Session.prototype, 'destroy', function destroy(fn) { */ defineMethod(Session.prototype, 'regenerate', function regenerate(fn) { - this.req.sessionStore.regenerate(this.req, fn); - return this; -}); + if (fn) { + this.req.sessionStore.regenerate(this.req, fn) + return + } + + if (!fn && !global.Promise) { + throw new Error('must use callback without promises') + } + + var sess = this + return new Promise(function (resolve, reject) { + sess.req.sessionStore.regenerate(sess.req, function(err) { + if (err) reject(err) + resolve() + }) + }) +}) /** * Helper function for creating a method on a prototype. diff --git a/test/session.js b/test/session.js index 47d1bf53..ddd202cc 100644 --- a/test/session.js +++ b/test/session.js @@ -1603,7 +1603,7 @@ describe('session()', function(){ }) }) - describe('.regenerate()', function(){ + describe('.regenerate()', function () { it('should destroy/replace the previous session', function(done){ var server = createServer(null, function (req, res) { var id = req.session.id @@ -1626,6 +1626,83 @@ describe('session()', function(){ .expect(200, 'false', done) }); }) + + describe('with global Promise', function () { + beforeEach(function () { + global.Promise = Promise + }) + + afterEach(function () { + global.Promise = undefined + }) + + it('should return Promise without callback', function (done) { + var server = createServer(null, function (req, res) { + var id = req.session.id + req.session.regenerate() + .then(function() { + res.end(String(req.session.id === id)) + }) + .catch(function () { + res.statusCode = 500 + }) + }) + + request(server) + .get('/') + .expect(200, 'false', done) + }) + + it('should not return Promise with callback', function(done){ + var server = createServer(null, function (req, res) { + var id = req.session.id + var ret = req.session.regenerate(function (err) { + res.statusCode = (!err && ret === undefined) ? 200 : 500 + res.end(String(req.session.id === id)) + }) + }) + + request(server) + .get('/') + .expect(200, 'false', done) + }) + }) + + describe('without global Promise', function () { + beforeEach(function () { + global.Promise = undefined + }) + + afterEach(function () { + global.Promise = Promise + }) + + it('should error without callback', function (done) { + var server = createServer(null, function (req, res) { + req.session.regenerate() + res.end() + }) + + request(server) + .get('/') + .expect(500, 'must use callback without promises', done) + }) + + it('should not return Promise with callback', function(done){ + var server = createServer(null, function (req, res) { + var id = req.session.id + var ret = req.session.regenerate(function (err) { + res.statusCode = (!err && ret === undefined) ? 200 : 500 + res.end(String(req.session.id === id)) + }) + }) + + request(server) + .get('/') + .expect(shouldSetCookie('connect.sid')) + .expect(200, 'false', done) + }) + }) }) describe('.reload()', function () { @@ -2371,7 +2448,12 @@ function createRequestListener(opts, fn) { return } - respond(req, res) + try { + respond(req, res) + } catch (e) { + res.statusCode = 500 + res.end(e.message) + } }) } } From 28897aac9ec85f381030564ab3d9f0d5f71f257b Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Feb 2019 10:41:00 -0500 Subject: [PATCH 09/11] fixup! add: promise support for sessionStore destroy --- test/session.js | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/test/session.js b/test/session.js index ddd202cc..7c34f48c 100644 --- a/test/session.js +++ b/test/session.js @@ -1569,36 +1569,55 @@ describe('session()', function(){ global.Promise = undefined }) - it('should return Promise without callback', function(done){ + it('should return Promise without callback', function (done) { var server = createServer(null, function (req, res) { req.session.destroy() - .then(function() { - res.end(String(req.session)) + .then(function () { + res.end() }) .catch(function (err) { - if (err) res.statusCode = 500 + res.statusCode = 500 + res.end(err.message) }) }) request(server) .get('/') - .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, 'undefined', done) + .expect(200, done) }) - it('should not return Promise with callback', function(done){ + it('should not return Promise with callback', function (done) { var server = createServer(null, function (req, res) { var ret = req.session.destroy(function (err) { - if (err) res.statusCode = 500 - res.statusCode = (ret === undefined) ? 200 : 500 - res.end(String(req.session)) + res.statusCode = (!err && ret === undefined) ? 200 : 500 + res.end() }) }) request(server) .get('/') - .expect(shouldNotHaveHeader('Set-Cookie')) - .expect(200, 'undefined', done) + .expect(200, done) + }) + }) + + describe('without global Promise', function () { + beforeEach(function () { + global.Promise = undefined + }) + + afterEach(function () { + global.Promise = Promise + }) + + it('should require callback', function (done) { + var server = createServer(null, function (req, res) { + req.session.destroy() + res.end() + }) + + request(server) + .get('/') + .expect(500, 'must use callback without promises', done) }) }) }) From cfd6abec2a79687c1db5b0ffc829aba0ff94fdfb Mon Sep 17 00:00:00 2001 From: Douglas Christopher Wilson Date: Tue, 26 Feb 2019 10:55:05 -0500 Subject: [PATCH 10/11] fixup! add: promise support for sessionStore reload --- test/session.js | 102 ++++++++++++++++++++++-------------------------- 1 file changed, 47 insertions(+), 55 deletions(-) diff --git a/test/session.js b/test/session.js index 7c34f48c..ce98dd65 100644 --- a/test/session.js +++ b/test/session.js @@ -1811,39 +1811,25 @@ describe('session()', function(){ return } - req.session.url = req.url - - if (req.url === '/bar') { - res.end('saw ' + req.session.url) - return - } - - request(server) - .get('/bar') - .set('Cookie', val) - .expect(200, 'saw /bar', function (err, resp) { - if (err) return done(err) - req.session.reload() - .then(function () { - res.end('saw ' + req.session.url) - }) - .catch(function (err) { - if (err) return done(err) - }) - }) + req.session.reload() + .then(function () { + res.end() + }) + .catch(function (err) { + res.statusCode = 500 + res.end(err.message) + }) }) - var val request(server) - .get('/') - .expect(200, 'session created', function (err, res) { - if (err) return done(err) - val = cookie(res) - request(server) - .get('/foo') - .set('Cookie', val) - .expect(200, 'saw /bar', done) - }) + .get('/') + .expect(200, 'session created', function (err, res) { + if (err) return done(err) + request(server) + .get('/foo') + .set('Cookie', cookie(res)) + .expect(200, done) + }) }) it('should not return promise with callback', function (done) { @@ -1854,37 +1840,43 @@ describe('session()', function(){ return } - req.session.url = req.url - - if (req.url === '/bar') { - res.end('saw ' + req.session.url) - return - } + req.session.reload(function (err) { + if (!err) return res.end() + res.statusCode = 500 + res.end(err.message) + }) + }) - request(server) - .get('/bar') - .set('Cookie', val) - .expect(200, 'saw /bar', function (err, resp) { + request(server) + .get('/') + .expect(200, 'session created', function (err, res) { if (err) return done(err) - var ret = req.session.reload(function (err) { - if (err) return done(err) - res.statusCode = (ret === undefined) ? 200 : 500 - res.end('saw ' + req.session.url) - }) + request(server) + .get('/foo') + .set('Cookie', cookie(res)) + .expect(200, done) }) + }) + }) + + describe('without global Promise', function () { + beforeEach(function () { + global.Promise = undefined + }) + + afterEach(function () { + global.Promise = Promise + }) + + it('should require callback', function (done) { + var server = createServer(null, function (req, res) { + req.session.reload() + res.end() }) - var val request(server) - .get('/') - .expect(200, 'session created', function (err, res) { - if (err) return done(err) - val = cookie(res) - request(server) - .get('/foo') - .set('Cookie', val) - .expect(200, 'saw /bar', done) - }) + .get('/') + .expect(500, 'must use callback without Promise', done) }) }) }) From 23b0882eff1d869c601365cb434c7de4632ebe20 Mon Sep 17 00:00:00 2001 From: Brandon Manke Date: Thu, 28 Feb 2019 20:41:03 -0600 Subject: [PATCH 11/11] fix: redundant error checking in wrapmethods --- index.js | 4 ---- test/session.js | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/index.js b/index.js index 81fd47d6..84b766dd 100644 --- a/index.js +++ b/index.js @@ -378,10 +378,6 @@ function session(options) { return } - if (!callback && !global.Promise) { - throw new Error('must use callback without Promise') - } - return _reload.call(this) .then(function() { return wrapmethods(req.session) diff --git a/test/session.js b/test/session.js index d040bbee..58e41f48 100644 --- a/test/session.js +++ b/test/session.js @@ -1960,7 +1960,7 @@ describe('session()', function(){ request(server) .get('/') - .expect(500, 'must use callback without Promise', done) + .expect(500, 'must use callback without promises', done) }) }) })