Skip to content

Commit 9d6e1bf

Browse files
committed
chore(backend): Generate suffixed/un-suffixed cookies in handshake
1 parent 216f9ac commit 9d6e1bf

File tree

4 files changed

+72
-25
lines changed

4 files changed

+72
-25
lines changed

integration/tests/handshake.test.ts

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ test.describe('Client handshake @generic', () => {
164164
expect(res.headers.get('location')).toBe(
165165
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
166166
`${app.serverUrl}/`,
167-
)}${devBrowserQuery}`,
167+
)}&suffixed_cookies=true${devBrowserQuery}`,
168168
);
169169
});
170170

@@ -185,7 +185,9 @@ test.describe('Client handshake @generic', () => {
185185
});
186186
expect(res.status).toBe(307);
187187
expect(res.headers.get('location')).toBe(
188-
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
188+
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
189+
`${app.serverUrl}/`,
190+
)}&suffixed_cookies=true`,
189191
);
190192
});
191193

@@ -207,7 +209,9 @@ test.describe('Client handshake @generic', () => {
207209
});
208210
expect(res.status).toBe(307);
209211
expect(res.headers.get('location')).toBe(
210-
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
212+
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
213+
`${app.serverUrl}/`,
214+
)}&suffixed_cookies=true`,
211215
);
212216
});
213217

@@ -230,7 +234,7 @@ test.describe('Client handshake @generic', () => {
230234
expect(res.headers.get('location')).toBe(
231235
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
232236
`${app.serverUrl}/`,
233-
)}${devBrowserQuery}`,
237+
)}&suffixed_cookies=true${devBrowserQuery}`,
234238
);
235239
});
236240

@@ -254,7 +258,7 @@ test.describe('Client handshake @generic', () => {
254258
expect(res.headers.get('location')).toBe(
255259
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
256260
`${app.serverUrl}/`,
257-
)}${devBrowserQuery}`,
261+
)}&suffixed_cookies=true${devBrowserQuery}`,
258262
);
259263
});
260264

@@ -278,7 +282,7 @@ test.describe('Client handshake @generic', () => {
278282
expect(res.headers.get('location')).toBe(
279283
`https://example.com/clerk/v1/client/handshake?redirect_url=${encodeURIComponent(
280284
`${app.serverUrl}/`,
281-
)}${devBrowserQuery}`,
285+
)}&suffixed_cookies=true${devBrowserQuery}`,
282286
);
283287
});
284288

@@ -300,7 +304,9 @@ test.describe('Client handshake @generic', () => {
300304
});
301305
expect(res.status).toBe(307);
302306
expect(res.headers.get('location')).toBe(
303-
`https://example.com/clerk/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
307+
`https://example.com/clerk/v1/client/handshake?redirect_url=${encodeURIComponent(
308+
`${app.serverUrl}/`,
309+
)}&suffixed_cookies=true`,
304310
);
305311
});
306312

@@ -324,7 +330,7 @@ test.describe('Client handshake @generic', () => {
324330
expect(res.headers.get('location')).toBe(
325331
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
326332
`${app.serverUrl}/`,
327-
)}${devBrowserQuery}`,
333+
)}&suffixed_cookies=true${devBrowserQuery}`,
328334
);
329335
});
330336

@@ -346,7 +352,9 @@ test.describe('Client handshake @generic', () => {
346352
});
347353
expect(res.status).toBe(307);
348354
expect(res.headers.get('location')).toBe(
349-
`https://clerk.example.com/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
355+
`https://clerk.example.com/v1/client/handshake?redirect_url=${encodeURIComponent(
356+
`${app.serverUrl}/`,
357+
)}&suffixed_cookies=true`,
350358
);
351359
});
352360

@@ -367,7 +375,7 @@ test.describe('Client handshake @generic', () => {
367375
expect(res.headers.get('location')).toBe(
368376
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
369377
`${app.serverUrl}/`,
370-
)}${devBrowserQuery}`,
378+
)}&suffixed_cookies=true${devBrowserQuery}`,
371379
);
372380
});
373381

@@ -386,7 +394,9 @@ test.describe('Client handshake @generic', () => {
386394
});
387395
expect(res.status).toBe(307);
388396
expect(res.headers.get('location')).toBe(
389-
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
397+
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
398+
`${app.serverUrl}/`,
399+
)}&suffixed_cookies=true`,
390400
);
391401
});
392402

@@ -485,7 +495,9 @@ test.describe('Client handshake @generic', () => {
485495
});
486496
expect(res.status).toBe(307);
487497
expect(res.headers.get('location')).toBe(
488-
`https://clerk.example.com/v1/client/handshake?redirect_url=${encodeURIComponent(app.serverUrl + '/')}`,
498+
`https://clerk.example.com/v1/client/handshake?redirect_url=${encodeURIComponent(
499+
app.serverUrl + '/',
500+
)}&suffixed_cookies=true`,
489501
);
490502
});
491503

@@ -520,7 +532,9 @@ test.describe('Client handshake @generic', () => {
520532
});
521533
expect(res.status).toBe(307);
522534
expect(res.headers.get('location')).toBe(
523-
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(`${app.serverUrl}/`)}`,
535+
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
536+
`${app.serverUrl}/`,
537+
)}&suffixed_cookies=true`,
524538
);
525539
});
526540

@@ -543,7 +557,7 @@ test.describe('Client handshake @generic', () => {
543557
expect(res.headers.get('location')).toBe(
544558
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
545559
`${app.serverUrl}/`,
546-
)}hello%3Ffoo%3Dbar${devBrowserQuery}`,
560+
)}hello%3Ffoo%3Dbar&suffixed_cookies=true${devBrowserQuery}`,
547561
);
548562
});
549563

@@ -566,7 +580,7 @@ test.describe('Client handshake @generic', () => {
566580
expect(res.headers.get('location')).toBe(
567581
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
568582
`${app.serverUrl}/`,
569-
)}hello%3Ffoo%3Dbar`,
583+
)}hello%3Ffoo%3Dbar&suffixed_cookies=true`,
570584
);
571585
});
572586

@@ -589,7 +603,7 @@ test.describe('Client handshake @generic', () => {
589603
});
590604
expect(res.status).toBe(307);
591605
expect(res.headers.get('location')).toBe(
592-
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%2Fhello%3Ffoo%3Dbar${devBrowserQuery}`,
606+
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%2Fhello%3Ffoo%3Dbar&suffixed_cookies=true${devBrowserQuery}`,
593607
);
594608
});
595609

@@ -612,7 +626,7 @@ test.describe('Client handshake @generic', () => {
612626
});
613627
expect(res.status).toBe(307);
614628
expect(res.headers.get('location')).toBe(
615-
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%2Fhello%3Ffoo%3Dbar`,
629+
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%2Fhello%3Ffoo%3Dbar&suffixed_cookies=true`,
616630
);
617631
});
618632

@@ -635,7 +649,7 @@ test.describe('Client handshake @generic', () => {
635649
});
636650
expect(res.status).toBe(307);
637651
expect(res.headers.get('location')).toBe(
638-
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%3A3213%2Fhello%3Ffoo%3Dbar${devBrowserQuery}`,
652+
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%3A3213%2Fhello%3Ffoo%3Dbar&suffixed_cookies=true${devBrowserQuery}`,
639653
);
640654
});
641655

@@ -658,7 +672,7 @@ test.describe('Client handshake @generic', () => {
658672
});
659673
expect(res.status).toBe(307);
660674
expect(res.headers.get('location')).toBe(
661-
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%3A3213%2Fhello%3Ffoo%3Dbar`,
675+
`https://${config.pkHost}/v1/client/handshake?redirect_url=https%3A%2F%2Fexample.com%3A3213%2Fhello%3Ffoo%3Dbar&suffixed_cookies=true`,
662676
);
663677
});
664678

@@ -787,7 +801,7 @@ test.describe('Client handshake @generic', () => {
787801
expect(res.headers.get('location')).toBe(
788802
`https://${config.pkHost}/v1/client/handshake?redirect_url=${encodeURIComponent(
789803
`${app.serverUrl}/`,
790-
)}&__clerk_db_jwt=asdf`,
804+
)}&suffixed_cookies=true&__clerk_db_jwt=asdf`,
791805
);
792806
});
793807

packages/backend/src/tokens/cookie.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const getCookieName = (cookieDirective: string): string => {
2+
return cookieDirective.split(';')[0]?.split('=')[0];
3+
};
4+
5+
const getSuffixedName = (name: string, suffix: string): string => {
6+
if (name.endsWith(suffix)) {
7+
return name;
8+
}
9+
return `${name}_${suffix}`;
10+
};
11+
12+
export const suffixCookie = (suffix: string, cookieDirective: string): string => {
13+
const name = getCookieName(cookieDirective);
14+
const suffixedName = getSuffixedName(name, suffix);
15+
16+
return cookieDirective.replace(name + '=', suffixedName + '=');
17+
};
18+
19+
export const unSuffixCookie = (suffix: string, cookieDirective: string): string => {
20+
const name = getCookieName(cookieDirective).replace('_' + suffix, '');
21+
const suffixedName = getSuffixedName(suffix, cookieDirective);
22+
return cookieDirective.replace(suffixedName + '=', name + '=');
23+
};

packages/backend/src/tokens/request.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import type { TokenCarrier } from '../errors';
33
import { TokenVerificationError, TokenVerificationErrorReason } from '../errors';
44
import { decodeJwt } from '../jwt/verifyJwt';
55
import { assertValidSecretKey } from '../util/optionsAssertions';
6-
import { isDevelopmentFromSecretKey } from '../util/shared';
6+
import { getCookieSuffix, isDevelopmentFromSecretKey } from '../util/shared';
77
import type { AuthenticateContext } from './authenticateContext';
88
import { createAuthenticateContext } from './authenticateContext';
99
import type { RequestState } from './authStatus';
1010
import { AuthErrorReason, handshake, signedIn, signedOut } from './authStatus';
1111
import { createClerkRequest } from './clerkRequest';
12+
import { suffixCookie, unSuffixCookie } from './cookie';
1213
import { verifyHandshakeToken } from './handshake';
1314
import type { AuthenticateRequestOptions } from './types';
1415
import { verifyToken } from './verify';
@@ -105,12 +106,16 @@ export async function authenticateRequest(
105106

106107
const handshakePayload = await verifyHandshakeToken(authenticateContext.handshakeToken!, authenticateContext);
107108
const cookiesToSet = handshakePayload.handshake;
109+
const cookieSuffix = getCookieSuffix(authenticateContext.publishableKey);
108110

109111
let sessionToken = '';
110112
cookiesToSet.forEach((x: string) => {
111-
headers.append('Set-Cookie', x);
112-
if (x.startsWith(`${constants.Cookies.Session}=`)) {
113-
sessionToken = x.split(';')[0].substring(10);
113+
const suffixedCookie = suffixCookie(cookieSuffix, x);
114+
headers.append('Set-Cookie', suffixedCookie);
115+
const unSuffixedCookie = unSuffixCookie(cookieSuffix, x);
116+
headers.append('Set-Cookie', unSuffixedCookie);
117+
if (unSuffixedCookie.startsWith(`${constants.Cookies.Session}=`)) {
118+
sessionToken = unSuffixedCookie.split(';')[0].substring(10);
114119
}
115120
});
116121

packages/backend/src/util/shared.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
export { addClerkPrefix, getScriptUrl, getClerkJsMajorVersionOrTag } from '@clerk/shared/url';
22
export { callWithRetry } from '@clerk/shared/callWithRetry';
3-
export { isDevelopmentFromSecretKey, isProductionFromSecretKey, parsePublishableKey } from '@clerk/shared/keys';
3+
export {
4+
isDevelopmentFromSecretKey,
5+
isProductionFromSecretKey,
6+
parsePublishableKey,
7+
getCookieSuffix,
8+
} from '@clerk/shared/keys';
49
export { deprecated, deprecatedProperty } from '@clerk/shared/deprecated';
510

611
import { buildErrorThrower } from '@clerk/shared/error';

0 commit comments

Comments
 (0)