Skip to content

Commit 60a559f

Browse files
authored
fix(aws-amplify): createKeyValueStorageFromCookieStorageAdapter misses default path and secure values (#13508)
* fix(aws-amplify): createKeyValueStorageFromCookieStorageAdapter misses default path and secure values * Ensure Path is being serialized * Delete cookie without path attr before setting it
1 parent aa7ae18 commit 60a559f

File tree

5 files changed

+36
-4
lines changed

5 files changed

+36
-4
lines changed

packages/adapter-nextjs/__tests__/utils/createCookieStorageAdapterFromNextServerContext.test.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ describe('createCookieStorageAdapterFromNextServerContext', () => {
147147
sameSite: 'strict' as any,
148148
httpOnly: true,
149149
secure: true,
150+
path: '/a-path',
150151
};
151152

152153
const result = createCookieStorageAdapterFromNextServerContext(mockContext);
@@ -176,7 +177,7 @@ describe('createCookieStorageAdapterFromNextServerContext', () => {
176177
mockSerializeOptions.domain
177178
};Expires=${mockSerializeOptions.expires.toUTCString()};HttpOnly;SameSite=${
178179
mockSerializeOptions.sameSite
179-
};Secure`,
180+
};Secure;Path=${mockSerializeOptions.path}`,
180181
);
181182
});
182183

@@ -188,7 +189,7 @@ describe('createCookieStorageAdapterFromNextServerContext', () => {
188189
mockSerializeOptions.domain
189190
};Expires=${mockSerializeOptions.expires.toUTCString()};HttpOnly;SameSite=${
190191
mockSerializeOptions.sameSite
191-
};Secure`,
192+
};Secure;Path=${mockSerializeOptions.path}`,
192193
);
193194
});
194195

packages/adapter-nextjs/src/utils/createCookieStorageAdapterFromNextServerContext.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ const createMutableCookieStoreFromHeaders = (
218218
const serializeSetCookieOptions = (
219219
options: CookieStorage.SetCookieOptions,
220220
): string => {
221-
const { expires, domain, httpOnly, sameSite, secure } = options;
221+
const { expires, domain, httpOnly, sameSite, secure, path } = options;
222222
const serializedOptions: string[] = [];
223223
if (domain) {
224224
serializedOptions.push(`Domain=${domain}`);
@@ -235,6 +235,9 @@ const serializeSetCookieOptions = (
235235
if (secure) {
236236
serializedOptions.push(`Secure`);
237237
}
238+
if (path) {
239+
serializedOptions.push(`Path=${path}`);
240+
}
238241

239242
return serializedOptions.join(';');
240243
};

packages/aws-amplify/__tests__/adapterCore/storageFactories/createKeyValueStorageFromCookieStorageAdapter.test.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,21 @@ describe('keyValueStorage', () => {
4040
);
4141
});
4242

43+
it('should remove item before setting item', async () => {
44+
const testKey = 'testKey';
45+
const testValue = 'testValue';
46+
keyValueStorage.setItem(testKey, testValue);
47+
expect(mockCookiesStorageAdapter.delete).toHaveBeenCalledWith(testKey);
48+
expect(mockCookiesStorageAdapter.set).toHaveBeenCalledWith(
49+
testKey,
50+
testValue,
51+
{
52+
...defaultSetCookieOptions,
53+
expires: expect.any(Date),
54+
},
55+
);
56+
});
57+
4358
it('should set item with options', async () => {
4459
const testKey = 'testKey';
4560
const testValue = 'testValue';

packages/aws-amplify/src/adapter-core/storageFactories/createKeyValueStorageFromCookieStorageAdapter.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import {
1010
export const defaultSetCookieOptions: CookieStorage.SetCookieOptions = {
1111
// TODO: allow configure with a public interface
1212
sameSite: 'lax',
13+
secure: true,
14+
path: '/',
1315
};
1416
const ONE_YEAR_IN_MS = 365 * 24 * 60 * 60 * 1000;
1517

@@ -25,6 +27,11 @@ export const createKeyValueStorageFromCookieStorageAdapter = (
2527
): KeyValueStorageInterface => {
2628
return {
2729
setItem(key, value) {
30+
// Delete the cookie item first then set it. This results:
31+
// SetCookie: key=;expires=1970-01-01;(path='current-path') <- remove path'ed cookies
32+
// SetCookie: key=value;expires=Date.now() + 365 days;path=/;secure=true
33+
cookieStorageAdapter.delete(key);
34+
2835
// TODO(HuiSF): follow up the default CookieSerializeOptions values
2936
cookieStorageAdapter.set(key, value, {
3037
...defaultSetCookieOptions,

packages/core/src/adapterCore/serverContext/types/cookieStorage.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ export declare namespace CookieStorage {
77
export type SetCookieOptions = Partial<
88
Pick<
99
CookieSerializeOptions,
10-
'domain' | 'expires' | 'httpOnly' | 'maxAge' | 'sameSite' | 'secure'
10+
| 'domain'
11+
| 'expires'
12+
| 'httpOnly'
13+
| 'maxAge'
14+
| 'sameSite'
15+
| 'secure'
16+
| 'path'
1117
>
1218
>;
1319

0 commit comments

Comments
 (0)