Skip to content

Commit 806a377

Browse files
authored
Merge branch 'main' into jacek/fix-upgrade-nuxt-getauth-matcher
2 parents 73125aa + c5ca7f7 commit 806a377

16 files changed

Lines changed: 122 additions & 35 deletions

File tree

.changeset/fair-banks-attack.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/clerk-js': minor
3+
'@clerk/shared': minor
4+
'@clerk/react': minor
5+
---
6+
7+
Renames `mountTaskSetupMfa` and `unmountTaskSetupMfa` to `mountTaskSetupMFA` and `unmountTaskSetupMFA` respectively
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@clerk/shared': patch
3+
'@clerk/clerk-js': patch
4+
'@clerk/ui': patch
5+
---
6+
7+
Set `SameSite=None` on cookies for `.replit.dev` origins and consolidate third-party domain list

packages/clerk-js/sandbox/app.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -422,7 +422,7 @@ void (async () => {
422422
);
423423
},
424424
'/task-setup-mfa': () => {
425-
Clerk.mountTaskSetupMfa(
425+
Clerk.mountTaskSetupMFA(
426426
app,
427427
componentControls.taskSetupMFA.getProps() ?? {
428428
redirectUrlComplete: '/user-profile',

packages/clerk-js/src/core/auth/cookies/__tests__/clientUat.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
66
import { getCookieDomain } from '../../getCookieDomain';
77
import { getSecureAttribute } from '../../getSecureAttribute';
88
import { createClientUatCookie } from '../clientUat';
9+
import { requiresSameSiteNone } from '../requireSameSiteNone';
910

1011
vi.mock('@clerk/shared/cookie');
1112
vi.mock('@clerk/shared/date');
1213
vi.mock('@clerk/shared/internal/clerk-js/runtime');
1314
vi.mock('../../getCookieDomain');
1415
vi.mock('../../getSecureAttribute');
16+
vi.mock('../requireSameSiteNone');
1517

1618
describe('createClientUatCookie', () => {
1719
const mockCookieSuffix = 'test-suffix';
@@ -26,6 +28,7 @@ describe('createClientUatCookie', () => {
2628
mockGet.mockReset();
2729
(addYears as ReturnType<typeof vi.fn>).mockReturnValue(mockExpires);
2830
(inCrossOriginIframe as ReturnType<typeof vi.fn>).mockReturnValue(false);
31+
(requiresSameSiteNone as ReturnType<typeof vi.fn>).mockReturnValue(false);
2932
(getCookieDomain as ReturnType<typeof vi.fn>).mockReturnValue(mockDomain);
3033
(getSecureAttribute as ReturnType<typeof vi.fn>).mockReturnValue(true);
3134
(createCookieHandler as ReturnType<typeof vi.fn>).mockImplementation(() => ({
@@ -125,4 +128,22 @@ describe('createClientUatCookie', () => {
125128

126129
expect(result).toBe(0);
127130
});
131+
132+
it('should set cookies with SameSite=None when the host requires it', () => {
133+
(requiresSameSiteNone as ReturnType<typeof vi.fn>).mockReturnValue(true);
134+
const cookieHandler = createClientUatCookie(mockCookieSuffix);
135+
cookieHandler.set({
136+
id: 'test-client',
137+
updatedAt: new Date('2024-01-01'),
138+
signedInSessions: ['session1'],
139+
});
140+
141+
expect(mockSet).toHaveBeenCalledWith('1704067200', {
142+
domain: mockDomain,
143+
expires: mockExpires,
144+
sameSite: 'None',
145+
secure: true,
146+
partitioned: false,
147+
});
148+
});
128149
});

packages/clerk-js/src/core/auth/cookies/__tests__/session.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,14 @@ import { inCrossOriginIframe } from '@clerk/shared/internal/clerk-js/runtime';
44
import { beforeEach, describe, expect, it, vi } from 'vitest';
55

66
import { getSecureAttribute } from '../../getSecureAttribute';
7+
import { requiresSameSiteNone } from '../requireSameSiteNone';
78
import { createSessionCookie } from '../session';
89

910
vi.mock('@clerk/shared/cookie');
1011
vi.mock('@clerk/shared/date');
1112
vi.mock('@clerk/shared/internal/clerk-js/runtime');
1213
vi.mock('../../getSecureAttribute');
14+
vi.mock('../requireSameSiteNone');
1315

1416
describe('createSessionCookie', () => {
1517
const mockCookieSuffix = 'test-suffix';
@@ -24,6 +26,7 @@ describe('createSessionCookie', () => {
2426
mockGet.mockReset();
2527
(addYears as ReturnType<typeof vi.fn>).mockReturnValue(mockExpires);
2628
(inCrossOriginIframe as ReturnType<typeof vi.fn>).mockReturnValue(false);
29+
(requiresSameSiteNone as ReturnType<typeof vi.fn>).mockReturnValue(false);
2730
(getSecureAttribute as ReturnType<typeof vi.fn>).mockReturnValue(true);
2831
(createCookieHandler as ReturnType<typeof vi.fn>).mockImplementation(() => ({
2932
set: mockSet,
@@ -113,4 +116,17 @@ describe('createSessionCookie', () => {
113116

114117
expect(result).toBe('non-suffixed-value');
115118
});
119+
120+
it('should set cookies with None sameSite on .replit.dev origins', () => {
121+
(requiresSameSiteNone as ReturnType<typeof vi.fn>).mockReturnValue(true);
122+
const cookieHandler = createSessionCookie(mockCookieSuffix);
123+
cookieHandler.set(mockToken);
124+
125+
expect(mockSet).toHaveBeenCalledWith(mockToken, {
126+
expires: mockExpires,
127+
sameSite: 'None',
128+
secure: true,
129+
partitioned: false,
130+
});
131+
});
116132
});

packages/clerk-js/src/core/auth/cookies/clientUat.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type { ClientResource } from '@clerk/shared/types';
66

77
import { getCookieDomain } from '../getCookieDomain';
88
import { getSecureAttribute } from '../getSecureAttribute';
9+
import { requiresSameSiteNone } from './requireSameSiteNone';
910

1011
const CLIENT_UAT_COOKIE_NAME = '__client_uat';
1112

@@ -37,7 +38,11 @@ export const createClientUatCookie = (cookieSuffix: string): ClientUatCookieHand
3738
* Generally, this is handled by redirectWithAuth() being called and relying on the dev browser ID in the URL,
3839
* but if that isn't used we rely on this. In production, nothing is cross-domain and Lax is used when client_uat is set from FAPI.
3940
*/
40-
const sameSite = __BUILD_VARIANT_CHIPS__ ? 'None' : inCrossOriginIframe() ? 'None' : 'Strict';
41+
const sameSite = __BUILD_VARIANT_CHIPS__
42+
? 'None'
43+
: inCrossOriginIframe() || requiresSameSiteNone()
44+
? 'None'
45+
: 'Strict';
4146
const secure = getSecureAttribute(sameSite);
4247
const partitioned = __BUILD_VARIANT_CHIPS__ && secure;
4348
const domain = getCookieDomain();

packages/clerk-js/src/core/auth/cookies/devBrowser.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { inCrossOriginIframe } from '@clerk/shared/internal/clerk-js/runtime';
55
import { getSuffixedCookieName } from '@clerk/shared/keys';
66

77
import { getSecureAttribute } from '../getSecureAttribute';
8+
import { requiresSameSiteNone } from './requireSameSiteNone';
89

910
export type DevBrowserCookieHandler = {
1011
set: (jwt: string) => void;
@@ -13,7 +14,7 @@ export type DevBrowserCookieHandler = {
1314
};
1415

1516
const getCookieAttributes = () => {
16-
const sameSite = inCrossOriginIframe() ? 'None' : 'Lax';
17+
const sameSite = inCrossOriginIframe() || requiresSameSiteNone() ? 'None' : 'Lax';
1718
const secure = getSecureAttribute(sameSite);
1819
return { sameSite, secure } as const;
1920
};
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { isThirdPartyCookieDomain as requiresSameSiteNone } from '@clerk/shared/internal/clerk-js/thirdPartyDomains';

packages/clerk-js/src/core/auth/cookies/session.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { inCrossOriginIframe } from '@clerk/shared/internal/clerk-js/runtime';
44
import { getSuffixedCookieName } from '@clerk/shared/keys';
55

66
import { getSecureAttribute } from '../getSecureAttribute';
7+
import { requiresSameSiteNone } from './requireSameSiteNone';
78

89
const SESSION_COOKIE_NAME = '__session';
910

@@ -14,7 +15,7 @@ export type SessionCookieHandler = {
1415
};
1516

1617
const getCookieAttributes = () => {
17-
const sameSite = __BUILD_VARIANT_CHIPS__ ? 'None' : inCrossOriginIframe() ? 'None' : 'Lax';
18+
const sameSite = __BUILD_VARIANT_CHIPS__ ? 'None' : inCrossOriginIframe() || requiresSameSiteNone() ? 'None' : 'Lax';
1819
const secure = getSecureAttribute(sameSite);
1920
const partitioned = __BUILD_VARIANT_CHIPS__ && secure;
2021
return { sameSite, secure, partitioned } as const;

packages/clerk-js/src/core/clerk.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,7 +1444,7 @@ export class Clerk implements ClerkInterface {
14441444
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
14451445
};
14461446

1447-
public mountTaskSetupMfa = (node: HTMLDivElement, props?: TaskSetupMFAProps) => {
1447+
public mountTaskSetupMFA = (node: HTMLDivElement, props?: TaskSetupMFAProps) => {
14481448
this.assertComponentsReady(this.#clerkUI);
14491449

14501450
const component = 'TaskSetupMFA';
@@ -1459,10 +1459,10 @@ export class Clerk implements ClerkInterface {
14591459
}),
14601460
);
14611461

1462-
this.telemetry?.record(eventPrebuiltComponentMounted('TaskSetupMfa', props));
1462+
this.telemetry?.record(eventPrebuiltComponentMounted('TaskSetupMFA', props));
14631463
};
14641464

1465-
public unmountTaskSetupMfa = (node: HTMLDivElement) => {
1465+
public unmountTaskSetupMFA = (node: HTMLDivElement) => {
14661466
void this.#clerkUI?.then(ui => ui.ensureMounted()).then(controls => controls.unmountComponent({ node }));
14671467
};
14681468

0 commit comments

Comments
 (0)