From a6ef21d02371dc11d4c931f46c68bbe270e72818 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sun, 19 Jan 2025 17:29:05 +0800 Subject: [PATCH 1/2] fix: make sure options instance is not mutated --- src/index.ts | 17 ++++++++++------- test/store.test.ts | 40 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/index.ts b/src/index.ts index e116660..ae275fe 100644 --- a/src/index.ts +++ b/src/index.ts @@ -188,19 +188,23 @@ export function createSession(opts: CreateSessionOptions | any, app: any): Middl throw new TypeError('app instance required: `session(opts, app)`'); } + const options: SessionOptions = opts ?? {}; + // back-compat maxage - if (opts && !('maxAge' in opts) && 'maxage' in opts) { - Reflect.set(opts, 'maxAge', Reflect.get(opts, 'maxage')); + if (!('maxAge' in options) && 'maxage' in options) { + Reflect.set(options, 'maxAge', Reflect.get(options, 'maxage')); if (process.env.NODE_ENV !== 'production') { console.warn('DeprecationWarning: `maxage` option has been renamed to `maxAge`'); } } - let options = { + + // keep backwards compatibility: make sure options instance is not mutated + Object.assign(options, { ...DEFAULT_SESSION_OPTIONS, - ...opts, - }; + ...options, + }); SessionOptions.parse(options); - options = formatOptions(options); + formatOptions(options); extendContext(app.context, options); return async function session(ctx: any, next: any) { @@ -264,7 +268,6 @@ function formatOptions(opts: SessionOptions) { opts.genid = () => randomUUID(); } } - return opts; } /** diff --git a/test/store.test.ts b/test/store.test.ts index 39ba1b8..3f300ab 100644 --- a/test/store.test.ts +++ b/test/store.test.ts @@ -11,7 +11,7 @@ const inspect = Symbol.for('nodejs.util.inspect.custom'); function App(options: CreateSessionOptions = {}) { const app = new Koa(); app.keys = [ 'a', 'b' ]; - options.store = store; + options.store = options.store ?? store; app.use(session(options, app)); return app; } @@ -21,14 +21,15 @@ describe('Koa Session External Store', () => { describe('when the session contains a ;', () => { it('should still work', async () => { - const app = App(); + const options: CreateSessionOptions = { store }; + const app = App(options); app.use(async (ctx: Koa.Context) => { if (ctx.method === 'POST') { - ctx.session!.string = ';'; + ctx.session.string = ';'; ctx.status = 204; } else { - ctx.body = ctx.session!.string; + ctx.body = ctx.session.string; } }); @@ -43,6 +44,37 @@ describe('Koa Session External Store', () => { .set('Cookie', cookie.join(';')) .expect(';'); }); + + it('should disable store on options', async () => { + const options: CreateSessionOptions = { store }; + const app = App(options); + + app.use(async (ctx: Koa.Context) => { + if (ctx.method === 'POST') { + ctx.session.string = ';'; + ctx.status = 204; + } else { + ctx.body = ctx.session.string ?? 'new session create'; + } + }); + + const server = app.callback(); + const res = await request(server) + .post('/') + .expect(204); + + const cookie = res.get('Set-Cookie')!; + await request(server) + .get('/') + .set('Cookie', cookie.join(';')) + .expect(';'); + + options.store = undefined; + await request(server) + .get('/') + .set('Cookie', cookie.join(';')) + .expect('new session create'); + }); }); describe('new session', () => { From 9406d377e36877a6ba1a76abcb13807aae0af0b8 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sun, 19 Jan 2025 17:33:07 +0800 Subject: [PATCH 2/2] f --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index ae275fe..74ec11a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -194,7 +194,7 @@ export function createSession(opts: CreateSessionOptions | any, app: any): Middl if (!('maxAge' in options) && 'maxage' in options) { Reflect.set(options, 'maxAge', Reflect.get(options, 'maxage')); if (process.env.NODE_ENV !== 'production') { - console.warn('DeprecationWarning: `maxage` option has been renamed to `maxAge`'); + console.warn('[koa-session] DeprecationWarning: `maxage` option has been renamed to `maxAge`'); } }