From e624bcd7064edace68e2422d7f4e92d6e5b27b5a Mon Sep 17 00:00:00 2001 From: adamjmcgrath Date: Thu, 18 Feb 2021 12:36:11 +0000 Subject: [PATCH] We should cleanup unused cookies when switching between chunked and unchunked --- src/auth0-session/cookie-store.ts | 17 ++++++++++++- tests/auth0-session/cookie-store.test.ts | 31 ++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/auth0-session/cookie-store.ts b/src/auth0-session/cookie-store.ts index 780f1461a..ad6aca379 100644 --- a/src/auth0-session/cookie-store.ts +++ b/src/auth0-session/cookie-store.ts @@ -160,10 +160,11 @@ export default class CookieStore { cookie: { transient, ...cookieConfig }, name: sessionName } = this.config.session; + const cookies = getCookies(req); if (!session) { debug('clearing all matching session cookies'); - for (const cookieName of Object.keys(getCookies(req))) { + for (const cookieName of Object.keys(cookies)) { if (cookieName.match(`^${sessionName}(?:\\.\\d)?$`)) { clearCookie(res, cookieName, { domain: cookieConfig.domain, @@ -196,8 +197,22 @@ export default class CookieStore { const chunkCookieName = `${sessionName}.${i}`; setCookie(res, chunkCookieName, chunkValue, cookieOptions); } + if (sessionName in cookies) { + clearCookie(res, sessionName, { + domain: cookieConfig.domain, + path: cookieConfig.path + }); + } } else { setCookie(res, sessionName, value, cookieOptions); + for (const cookieName of Object.keys(cookies)) { + if (cookieName.match(`^${sessionName}\\.\\d$`)) { + clearCookie(res, cookieName, { + domain: cookieConfig.domain, + path: cookieConfig.path + }); + } + } } } } diff --git a/tests/auth0-session/cookie-store.test.ts b/tests/auth0-session/cookie-store.test.ts index 7948c8fe9..cba683d60 100644 --- a/tests/auth0-session/cookie-store.test.ts +++ b/tests/auth0-session/cookie-store.test.ts @@ -148,6 +148,37 @@ describe('CookieStore', () => { await expect(get(baseURL, '/session', { cookieJar })).rejects.toThrowError('Unauthorized'); }); + it('should clean up single cookie when switching to chunked', async () => { + const baseURL = await setup(defaultConfig); + const appSession = encrypted({ + big_claim: randomBytes(2000).toString('base64') + }); + expect(appSession.length).toBeGreaterThan(4000); + const cookieJar = toCookieJar({ appSession }, baseURL); + const session = await get(baseURL, '/session', { cookieJar }); + expect(session.claims).toHaveProperty('big_claim'); + const cookies = fromCookieJar(cookieJar, baseURL); + expect(cookies).toHaveProperty(['appSession.0']); + expect(cookies).not.toHaveProperty('appSession'); + }); + + it('should clean up chunked cookies when switching to a single cookie', async () => { + const baseURL = await setup(defaultConfig); + const appSession = encrypted({ sub: 'foo' }); + const cookieJar = toCookieJar( + { + 'appSession.0': appSession.slice(0, 100), + 'appSession.1': appSession.slice(100) + }, + baseURL + ); + const session = await get(baseURL, '/session', { cookieJar }); + expect(session.claims).toHaveProperty('sub'); + const cookies = fromCookieJar(cookieJar, baseURL); + expect(cookies).toHaveProperty('appSession'); + expect(cookies).not.toHaveProperty(['appSession.0']); + }); + it('should set the default cookie options on http', async () => { const baseURL = await setup(defaultConfig); const appSession = encrypted();