From 6b4fa793bbc4df26c4054bb6656abb4f8aead2d0 Mon Sep 17 00:00:00 2001 From: palmtale Date: Fri, 5 May 2017 15:06:47 +0800 Subject: [PATCH 1/3] Add feature of regeneration for #34 Signed-off-by: Cartoon Zhang --- index.js | 7 +++++++ lib/context.js | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/index.js b/index.js index 47992fc..836c581 100644 --- a/index.js +++ b/index.js @@ -105,6 +105,13 @@ function extendContext(context, opts) { return this[_CONTEXT_SESSION]; }, }, + regenerateSession: { + get() { + return async() => { + await this[_CONTEXT_SESSION].regenerate() + } + } + }, session: { get() { return this[CONTEXT_SESSION].get(); diff --git a/lib/context.js b/lib/context.js index 88cea73..f4d1214 100644 --- a/lib/context.js +++ b/lib/context.js @@ -181,6 +181,12 @@ class ContextSession { this.session = new Session(this.ctx, val); } + async regenerate() { + await this.remove(); + this.create(); + this.session.save(); + } + /** * Commit the session changes or removal. * From dcede0c23b2b434ce03d30b3a7d307f0977fe384 Mon Sep 17 00:00:00 2001 From: palmtale Date: Fri, 5 May 2017 15:15:39 +0800 Subject: [PATCH 2/3] Correct code as the eslint rules Signed-off-by: Cartoon Zhang --- index.js | 6 +++--- lib/context.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/index.js b/index.js index 836c581..3d36a14 100644 --- a/index.js +++ b/index.js @@ -108,9 +108,9 @@ function extendContext(context, opts) { regenerateSession: { get() { return async() => { - await this[_CONTEXT_SESSION].regenerate() - } - } + await this[_CONTEXT_SESSION].regenerate(); + }; + }, }, session: { get() { diff --git a/lib/context.js b/lib/context.js index f4d1214..913a368 100644 --- a/lib/context.js +++ b/lib/context.js @@ -186,7 +186,7 @@ class ContextSession { this.create(); this.session.save(); } - + /** * Commit the session changes or removal. * From 919968a19436ccbefc36dfd05599b6939eab3fb8 Mon Sep 17 00:00:00 2001 From: palmtale Date: Sun, 18 Jun 2017 22:20:25 +0800 Subject: [PATCH 3/3] Refactor regenerate as session signal _requireRegenerate. --- index.js | 7 ------- lib/context.js | 11 +++++------ lib/session.js | 4 ++++ test/cookie.test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ test/store.test.js | 42 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 3d36a14..47992fc 100644 --- a/index.js +++ b/index.js @@ -105,13 +105,6 @@ function extendContext(context, opts) { return this[_CONTEXT_SESSION]; }, }, - regenerateSession: { - get() { - return async() => { - await this[_CONTEXT_SESSION].regenerate(); - }; - }, - }, session: { get() { return this[CONTEXT_SESSION].get(); diff --git a/lib/context.js b/lib/context.js index 913a368..dec015b 100644 --- a/lib/context.js +++ b/lib/context.js @@ -181,12 +181,6 @@ class ContextSession { this.session = new Session(this.ctx, val); } - async regenerate() { - await this.remove(); - this.create(); - this.session.save(); - } - /** * Commit the session changes or removal. * @@ -207,6 +201,11 @@ class ContextSession { await this.remove(); return; } + if (session._requireRegenerate) { + await this.remove(); + if (this.opts.store) this.externalKey = uid.sync(24); + session.save(); + } // force save session when `session._requireSave` set if (!session._requireSave) { diff --git a/lib/session.js b/lib/session.js index b585f2a..c509f78 100644 --- a/lib/session.js +++ b/lib/session.js @@ -110,6 +110,10 @@ class Session { save() { this._requireSave = true; } + + regenerate() { + this._requireRegenerate = true; + } } module.exports = Session; diff --git a/test/cookie.test.js b/test/cookie.test.js index b1fa1e5..a662086 100644 --- a/test/cookie.test.js +++ b/test/cookie.test.js @@ -623,6 +623,48 @@ describe('Koa Session Cookie', () => { }); }); + describe('ctx.session.regenerate', () => { + it('should change the session key, but not content', done => { + const app = new App(); + const message = 'hi'; + app.use(async function(ctx, next) { + ctx.session = { message: 'hi' }; + await next(); + }); + + app.use(async function(ctx, next) { + const sessionKey = ctx.cookies.get('koa:sess'); + if (sessionKey) { + await ctx.session.regenerate(); + } + await next(); + }); + + app.use(async function(ctx) { + ctx.session.message.should.equal(message); + ctx.body = ''; + }); + let koaSession = null; + request(app.callback()) + .get('/') + .expect(200, (err, res) => { + should.not.exist(err); + koaSession = res.headers['set-cookie'][0]; + koaSession.should.containEql('koa:sess='); + request(app.callback()) + .get('/') + .set('Cookie', koaSession) + .expect(200, (err, res) => { + should.not.exist(err); + const cookies = res.headers['set-cookie'][0]; + cookies.should.containEql('koa:sess='); + cookies.should.not.equal(koaSession); + done(); + }); + }); + }); + }); + describe('when get session before enter session middleware', () => { it('should work', done => { const app = new Koa(); diff --git a/test/store.test.js b/test/store.test.js index 008a35f..4de0500 100644 --- a/test/store.test.js +++ b/test/store.test.js @@ -479,6 +479,48 @@ describe('Koa Session External Store', () => { }); }); + describe('ctx.session.regenerate', () => { + it('should change the session key, but not content', done => { + const app = new App(); + const message = 'hi'; + app.use(async function(ctx, next) { + ctx.session = { message: 'hi' }; + await next(); + }); + + app.use(async function(ctx, next) { + const sessionKey = ctx.cookies.get('koa:sess'); + if (sessionKey) { + await ctx.session.regenerate(); + } + await next(); + }); + + app.use(async function(ctx) { + ctx.session.message.should.equal(message); + ctx.body = ''; + }); + let koaSession = null; + request(app.callback()) + .get('/') + .expect(200, (err, res) => { + should.not.exist(err); + koaSession = res.headers['set-cookie'][0]; + koaSession.should.containEql('koa:sess='); + request(app.callback()) + .get('/') + .set('Cookie', koaSession) + .expect(200, (err, res) => { + should.not.exist(err); + const cookies = res.headers['set-cookie'][0]; + cookies.should.containEql('koa:sess='); + cookies.should.not.equal(koaSession); + done(); + }); + }); + }); + }); + describe('when store return empty', () => { it('should create new Session', done => { const app = App({ signed: false });