Skip to content

Commit

Permalink
feat(clerk-js,backend): Throw error if signInUrl is on same origin as…
Browse files Browse the repository at this point in the history
… satellite app (#1845)
  • Loading branch information
desiprisg authored Oct 10, 2023
1 parent 25cfa7a commit c9b17f5
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .changeset/polite-rats-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@clerk/clerk-js': patch
'@clerk/backend': patch
---

Throw an error if the `signInUrl` is on the same origin of a satellite application or if it is of invalid format
4 changes: 4 additions & 0 deletions packages/backend/src/tokens/request.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -319,12 +319,14 @@ export default (QUnit: QUnit) => {
apiKey: 'deadbeef',
clientUat: '0',
isSatellite: true,
signInUrl: 'https://primary.dev/sign-in',
domain: 'satellite.dev',
});

assertInterstitial(assert, requestState, {
reason: AuthErrorReason.SatelliteCookieNeedsSyncing,
isSatellite: true,
signInUrl: 'https://primary.dev/sign-in',
domain: 'satellite.dev',
});
assert.equal(requestState.message, '');
Expand All @@ -337,13 +339,15 @@ export default (QUnit: QUnit) => {
apiKey: 'deadbeef',
clientUat: '0',
isSatellite: true,
signInUrl: 'https://primary.dev/sign-in',
domain: 'satellite.dev',
userAgent: '[some-agent]',
});

assertSignedOut(assert, requestState, {
reason: AuthErrorReason.SatelliteCookieNeedsSyncing,
isSatellite: true,
signInUrl: 'https://primary.dev/sign-in',
domain: 'satellite.dev',
});
assertSignedOutToAuth(assert, requestState);
Expand Down
16 changes: 16 additions & 0 deletions packages/backend/src/tokens/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,19 @@ function assertProxyUrlOrDomain(proxyUrlOrDomain: string | undefined) {
}
}

function assertSignInUrlFormatAndOrigin(_signInUrl: string, origin: string) {
let signInUrl: URL;
try {
signInUrl = new URL(_signInUrl);
} catch {
throw new Error(`The signInUrl needs to have a absolute url format.`);
}

if (signInUrl.origin === origin) {
throw new Error(`The signInUrl needs to be on a different origin than your satellite application.`);
}
}

export async function authenticateRequest(options: AuthenticateRequestOptions): Promise<RequestState> {
const { cookies, headers, searchParams } = buildRequest(options?.request);

Expand All @@ -128,6 +141,9 @@ export async function authenticateRequest(options: AuthenticateRequestOptions):

if (options.isSatellite) {
assertSignInUrlExists(options.signInUrl, (options.secretKey || options.apiKey) as string);
if (options.signInUrl && options.origin /* could this actually be undefined? */) {
assertSignInUrlFormatAndOrigin(options.signInUrl, options.origin);
}
assertProxyUrlOrDomain(options.proxyUrl || options.domain);
}

Expand Down
20 changes: 20 additions & 0 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ import type { DevBrowserHandler } from './devBrowserHandler';
import createDevBrowserHandler from './devBrowserHandler';
import {
clerkErrorInitFailed,
clerkInvalidSignInUrlFormat,
clerkInvalidSignInUrlOrigin,
clerkMissingDevBrowserJwt,
clerkMissingProxyUrlAndDomain,
clerkMissingSignInUrlAsSatellite,
Expand Down Expand Up @@ -1278,17 +1280,35 @@ export default class Clerk implements ClerkInterface {
}
};

#assertSignInFormatAndOrigin = (_signInUrl: string, origin: string) => {
let signInUrl: URL;
try {
signInUrl = new URL(_signInUrl);
} catch {
clerkInvalidSignInUrlFormat();
}

if (signInUrl.origin === origin) {
clerkInvalidSignInUrlOrigin();
}
};

#validateMultiDomainOptions = () => {
if (!this.isSatellite) {
return;
}

if (this.#instanceType === 'development' && !this.#options.signInUrl) {
clerkMissingSignInUrlAsSatellite();
}

if (!this.proxyUrl && !this.domain) {
clerkMissingProxyUrlAndDomain();
}

if (this.#options.signInUrl) {
this.#assertSignInFormatAndOrigin(this.#options.signInUrl, window.location.origin);
}
};

#loadInStandardBrowser = async (): Promise<boolean> => {
Expand Down
8 changes: 8 additions & 0 deletions packages/clerk-js/src/core/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,14 @@ export function clerkMissingProxyUrlAndDomain(): never {
);
}

export function clerkInvalidSignInUrlOrigin(): never {
throw new Error(`${errorPrefix} The signInUrl needs to be on a different origin than your satellite application.`);
}

export function clerkInvalidSignInUrlFormat(): never {
throw new Error(`${errorPrefix} The signInUrl needs to have a absolute url format.`);
}

export function clerkMissingSignInUrlAsSatellite(): never {
throw new Error(
`${errorPrefix} Missing signInUrl. A satellite application needs to specify the signInUrl for development instances.`,
Expand Down

0 comments on commit c9b17f5

Please sign in to comment.