Skip to content

Commit 7318e58

Browse files
committed
feat(clerk-js,nextjs): Introduce multipleAppsSameDomain Clerk option to support cookie suffixing
1 parent cf6ef7a commit 7318e58

File tree

6 files changed

+16
-21
lines changed

6 files changed

+16
-21
lines changed

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

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { setDevBrowserJWTInURL } from '@clerk/shared/devBrowser';
22
import { is4xxError, isClerkAPIResponseError, isNetworkError } from '@clerk/shared/error';
3-
import type { Clerk, EnvironmentResource, TokenResource } from '@clerk/types';
3+
import type { Clerk, EnvironmentResource } from '@clerk/types';
44

5-
import { inBrowser } from '../../utils';
65
import { clerkCoreErrorTokenRefreshFailed, clerkMissingDevBrowserJwt } from '../errors';
76
import { eventBus, events } from '../events';
87
import type { FapiClient } from '../fapiClient';
@@ -14,6 +13,8 @@ import type { DevBrowser } from './devBrowser';
1413
import { createDevBrowser } from './devBrowser';
1514
import { SessionCookiePoller } from './SessionCookiePoller';
1615

16+
// TODO: make SessionCookieService singleton since it handles updating cookies using a poller
17+
// and we need to avoid updating them concurrently.
1718
export class SessionCookieService {
1819
private environment: EnvironmentResource | undefined;
1920
private poller: SessionCookiePoller | null = null;
@@ -24,7 +25,7 @@ export class SessionCookieService {
2425
constructor(private clerk: Clerk, fapiClient: FapiClient, multipleAppsSameDomainEnabled = false) {
2526
// set cookie on token update
2627
eventBus.on(events.TokenUpdate, ({ token }) => {
27-
this.updateSessionCookie(token?.getRawString());
28+
this.updateSessionCookie(token && token.getRawString());
2829
this.setClientUatCookieForDevelopmentInstances();
2930
});
3031

@@ -90,10 +91,6 @@ export class SessionCookieService {
9091
}
9192

9293
private refreshTokenOnVisibilityChange() {
93-
if (!inBrowser()) {
94-
return;
95-
}
96-
9794
document.addEventListener('visibilitychange', () => {
9895
if (document.visibilityState === 'visible') {
9996
void this.refreshSessionToken();
@@ -102,28 +99,19 @@ export class SessionCookieService {
10299
}
103100

104101
private async refreshSessionToken(): Promise<void> {
105-
if (!inBrowser()) {
106-
return;
107-
}
108-
109102
if (!this.clerk.session) {
110103
return;
111104
}
112105

113106
try {
114-
this.updateSessionCookie(await this.clerk.session?.getToken());
107+
await this.clerk.session.getToken();
115108
} catch (e) {
116109
return this.handleGetTokenError(e);
117110
}
118111
}
119112

120-
private updateSessionCookie(token: TokenResource | string | undefined | null) {
121-
const rawToken = typeof token === 'string' ? token : token?.getRawString();
122-
123-
if (rawToken) {
124-
return this.sessionCookie.set(rawToken);
125-
}
126-
return this.sessionCookie.remove();
113+
private updateSessionCookie(token: string | null) {
114+
return token ? this.sessionCookie.set(token) : this.sessionCookie.remove();
127115
}
128116

129117
private setClientUatCookieForDevelopmentInstances() {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export function createDevBrowser(
6060
if (devBrowserJWT && request?.url) {
6161
request.url = setDevBrowserJWTInURL(request.url, devBrowserJWT);
6262
}
63+
request.url?.searchParams.append('_multiple_apps_same_domain', withSuffix.toString());
6364
});
6465

6566
fapiClient.onAfterResponse((_, response) => {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,7 @@ export class Clerk implements ClerkInterface {
13941394
};
13951395

13961396
#loadInStandardBrowser = async (): Promise<boolean> => {
1397-
this.#authService = new SessionCookieService(this, this.#fapiClient);
1397+
this.#authService = new SessionCookieService(this, this.#fapiClient, this.#options.multipleAppsSameDomain);
13981398

13991399
/**
14001400
* 1. Create the devBrowser.

packages/nextjs/src/pages/ClerkProvider.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ export function ClerkProvider({ children, ...props }: NextClerkProviderProps): J
3333

3434
const navigate = (to: string) => push(to);
3535
const replaceNavigate = (to: string) => replace(to);
36-
const mergedProps = mergeNextClerkPropsWithEnv({ ...props, routerPush: navigate, routerReplace: replaceNavigate });
36+
const mergedProps = mergeNextClerkPropsWithEnv({
37+
...props,
38+
routerPush: navigate,
39+
routerReplace: replaceNavigate,
40+
});
3741
// ClerkProvider automatically injects __clerk_ssr_state
3842
// getAuth returns a user-facing authServerSideProps that hides __clerk_ssr_state
3943
// @ts-expect-error initialState is hidden from the types as it's a private prop

packages/nextjs/src/utils/mergeNextClerkPropsWithEnv.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@ export const mergeNextClerkPropsWithEnv = (props: Omit<NextClerkProviderProps, '
2222
debug: isTruthy(process.env.NEXT_PUBLIC_CLERK_TELEMETRY_DEBUG),
2323
},
2424
sdkMetadata: SDK_METADATA,
25+
multipleAppsSameDomain: true,
2526
};
2627
};

packages/types/src/clerk.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,7 @@ export type ClerkOptions = ClerkOptionsNavigation &
551551
};
552552

553553
sdkMetadata?: SDKMetadata;
554+
multipleAppsSameDomain?: boolean;
554555
};
555556

556557
export interface NavigateOptions {

0 commit comments

Comments
 (0)