From 47f0f8b69e43491b6dc9993f01759cc028ed6d25 Mon Sep 17 00:00:00 2001 From: Hui Zhao <10602282+HuiSF@users.noreply.github.com> Date: Wed, 15 May 2024 17:30:44 -0700 Subject: [PATCH] fix(adapter-nextjs): Set-Cookie headers incorrectly set with getServerSideProps context (#13388) --- ...torageAdapterFromNextServerContext.test.ts | 35 ++++++++++++++----- ...okieStorageAdapterFromNextServerContext.ts | 4 +-- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/packages/adapter-nextjs/__tests__/utils/createCookieStorageAdapterFromNextServerContext.test.ts b/packages/adapter-nextjs/__tests__/utils/createCookieStorageAdapterFromNextServerContext.test.ts index 0023fb7aa80..858a8ad4b62 100644 --- a/packages/adapter-nextjs/__tests__/utils/createCookieStorageAdapterFromNextServerContext.test.ts +++ b/packages/adapter-nextjs/__tests__/utils/createCookieStorageAdapterFromNextServerContext.test.ts @@ -293,7 +293,7 @@ describe('createCookieStorageAdapterFromNextServerContext', () => { const request = new IncomingMessage(new Socket()); const response = new ServerResponse(request); - const setHeaderSpy = jest.spyOn(response, 'setHeader'); + const appendHeaderSpy = jest.spyOn(response, 'appendHeader'); Object.defineProperty(request, 'cookies', { get() { @@ -314,21 +314,30 @@ describe('createCookieStorageAdapterFromNextServerContext', () => { ]); result.set('key3', 'value3'); - expect(setHeaderSpy).toHaveBeenCalledWith('Set-Cookie', 'key3=value3;'); + expect(appendHeaderSpy).toHaveBeenCalledWith( + 'Set-Cookie', + 'key3=value3;', + ); result.set('key4', 'value4', { httpOnly: true, }); - expect(setHeaderSpy).toHaveBeenCalledWith( + expect(appendHeaderSpy).toHaveBeenCalledWith( 'Set-Cookie', 'key4=value4;HttpOnly', ); result.delete('key3'); - expect(setHeaderSpy).toHaveBeenCalledWith( + expect(appendHeaderSpy).toHaveBeenCalledWith( 'Set-Cookie', `key3=;Expires=${DATE_IN_THE_PAST.toUTCString()}`, ); + + expect(response.getHeader('Set-Cookie')).toEqual([ + 'key3=value3;', + 'key4=value4;HttpOnly', + 'key3=;Expires=Thu, 01 Jan 1970 00:00:00 GMT', + ]); }); it('operates with the underlying cookie store with encoded cookie names', () => { @@ -346,7 +355,7 @@ describe('createCookieStorageAdapterFromNextServerContext', () => { const request = new IncomingMessage(new Socket()); const response = new ServerResponse(request); - const setHeaderSpy = jest.spyOn(response, 'setHeader'); + const appendHeaderSpy = jest.spyOn(response, 'appendHeader'); Object.defineProperty(request, 'cookies', { get() { @@ -371,7 +380,10 @@ describe('createCookieStorageAdapterFromNextServerContext', () => { ]); result.set('key3', 'value3'); - expect(setHeaderSpy).toHaveBeenCalledWith('Set-Cookie', 'key3=value3;'); + expect(appendHeaderSpy).toHaveBeenCalledWith( + 'Set-Cookie', + 'key3=value3;', + ); result.set('key4', 'value4', { httpOnly: true, @@ -381,16 +393,23 @@ describe('createCookieStorageAdapterFromNextServerContext', () => { 'test@email.com.somethingElse', ); result.set(encodeURIComponent('test@email.com.somethingElse'), 'value5'); - expect(setHeaderSpy).toHaveBeenCalledWith( + expect(appendHeaderSpy).toHaveBeenCalledWith( 'Set-Cookie', `${encodeURIComponent(encodedCookieName)}=value5;`, ); result.delete('key3'); - expect(setHeaderSpy).toHaveBeenCalledWith( + expect(appendHeaderSpy).toHaveBeenCalledWith( 'Set-Cookie', `key3=;Expires=${DATE_IN_THE_PAST.toUTCString()}`, ); + + expect(response.getHeader('Set-Cookie')).toEqual([ + 'key3=value3;', + 'key4=value4;HttpOnly', + 'test%2540email.com.somethingElse=value5;', + 'key3=;Expires=Thu, 01 Jan 1970 00:00:00 GMT', + ]); }); }); diff --git a/packages/adapter-nextjs/src/utils/createCookieStorageAdapterFromNextServerContext.ts b/packages/adapter-nextjs/src/utils/createCookieStorageAdapterFromNextServerContext.ts index 882860436ac..564259510e1 100644 --- a/packages/adapter-nextjs/src/utils/createCookieStorageAdapterFromNextServerContext.ts +++ b/packages/adapter-nextjs/src/utils/createCookieStorageAdapterFromNextServerContext.ts @@ -171,7 +171,7 @@ const createCookieStorageAdapterFromGetServerSidePropsContext = ( return allCookies; }, set(name, value, options) { - response.setHeader( + response.appendHeader( 'Set-Cookie', `${ensureEncodedForJSCookie(name)}=${value};${ options ? serializeSetCookieOptions(options) : '' @@ -179,7 +179,7 @@ const createCookieStorageAdapterFromGetServerSidePropsContext = ( ); }, delete(name) { - response.setHeader( + response.appendHeader( 'Set-Cookie', `${ensureEncodedForJSCookie( name,