-
Notifications
You must be signed in to change notification settings - Fork 381
fix(backend): Consider proxyUrl in determining frontendApi URL #6120
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
7701f84
7cc8325
bc66f6d
d144b7b
4b8f3d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
'@clerk/backend': patch | ||
--- | ||
|
||
Add logic to ensure that we consider the proxy_url when creating the frontendApi url. |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -10,31 +10,33 @@ import type { AuthenticateRequestOptions } from './types'; | |||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
interface AuthenticateContext extends AuthenticateRequestOptions { | ||||||||||||||||||||||||||||
// header-based values | ||||||||||||||||||||||||||||
tokenInHeader: string | undefined; | ||||||||||||||||||||||||||||
origin: string | undefined; | ||||||||||||||||||||||||||||
host: string | undefined; | ||||||||||||||||||||||||||||
accept: string | undefined; | ||||||||||||||||||||||||||||
forwardedHost: string | undefined; | ||||||||||||||||||||||||||||
forwardedProto: string | undefined; | ||||||||||||||||||||||||||||
host: string | undefined; | ||||||||||||||||||||||||||||
origin: string | undefined; | ||||||||||||||||||||||||||||
referrer: string | undefined; | ||||||||||||||||||||||||||||
userAgent: string | undefined; | ||||||||||||||||||||||||||||
secFetchDest: string | undefined; | ||||||||||||||||||||||||||||
accept: string | undefined; | ||||||||||||||||||||||||||||
tokenInHeader: string | undefined; | ||||||||||||||||||||||||||||
userAgent: string | undefined; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// cookie-based values | ||||||||||||||||||||||||||||
sessionTokenInCookie: string | undefined; | ||||||||||||||||||||||||||||
refreshTokenInCookie: string | undefined; | ||||||||||||||||||||||||||||
clientUat: number; | ||||||||||||||||||||||||||||
refreshTokenInCookie: string | undefined; | ||||||||||||||||||||||||||||
sessionTokenInCookie: string | undefined; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// handshake-related values | ||||||||||||||||||||||||||||
devBrowserToken: string | undefined; | ||||||||||||||||||||||||||||
handshakeNonce: string | undefined; | ||||||||||||||||||||||||||||
handshakeToken: string | undefined; | ||||||||||||||||||||||||||||
handshakeRedirectLoopCounter: number; | ||||||||||||||||||||||||||||
handshakeToken: string | undefined; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
// url derived from headers | ||||||||||||||||||||||||||||
clerkUrl: URL; | ||||||||||||||||||||||||||||
// enforce existence of the following props | ||||||||||||||||||||||||||||
publishableKey: string; | ||||||||||||||||||||||||||||
instanceType: string; | ||||||||||||||||||||||||||||
frontendApi: string; | ||||||||||||||||||||||||||||
instanceType: string; | ||||||||||||||||||||||||||||
publishableKey: string; | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||
|
@@ -44,6 +46,12 @@ interface AuthenticateContext extends AuthenticateRequestOptions { | |||||||||||||||||||||||||||
* to perform a handshake. | ||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||
class AuthenticateContext implements AuthenticateContext { | ||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||
* The original Clerk frontend API URL, extracted from publishable key before proxy URL override. | ||||||||||||||||||||||||||||
* Used for backend operations like token validation and issuer checking. | ||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||
private originalFrontendApi: string = ''; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||
* Retrieves the session token from either the cookie or the header. | ||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||
|
@@ -163,6 +171,13 @@ class AuthenticateContext implements AuthenticateContext { | |||||||||||||||||||||||||||
assertValidPublishableKey(options.publishableKey); | ||||||||||||||||||||||||||||
this.publishableKey = options.publishableKey; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
const originalPk = parsePublishableKey(this.publishableKey, { | ||||||||||||||||||||||||||||
fatal: true, | ||||||||||||||||||||||||||||
domain: options.domain, | ||||||||||||||||||||||||||||
isSatellite: options.isSatellite, | ||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||
this.originalFrontendApi = originalPk.frontendApi; | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
const pk = parsePublishableKey(this.publishableKey, { | ||||||||||||||||||||||||||||
fatal: true, | ||||||||||||||||||||||||||||
proxyUrl: options.proxyUrl, | ||||||||||||||||||||||||||||
|
@@ -266,7 +281,8 @@ class AuthenticateContext implements AuthenticateContext { | |||||||||||||||||||||||||||
return false; | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
const tokenIssuer = data.payload.iss.replace(/https?:\/\//gi, ''); | ||||||||||||||||||||||||||||
return this.frontendApi === tokenIssuer; | ||||||||||||||||||||||||||||
// Use original frontend API for token validation since tokens are issued by the actual Clerk API, not proxy | ||||||||||||||||||||||||||||
return this.originalFrontendApi === tokenIssuer; | ||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||
Comment on lines
283
to
286
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Issuer check ignores trailing slashes / “/v1” – could produce false negatives
- const tokenIssuer = data.payload.iss.replace(/https?:\/\//gi, '');
- return this.originalFrontendApi === tokenIssuer;
+ const tokenIssuer = data.payload.iss
+ .replace(/https?:\/\//gi, '')
+ .replace(/\/+v1\/?$/, '') // strip “/v1” if present
+ .replace(/\/+$/, ''); // strip trailing slash(es)
+
+ return this.originalFrontendApi.replace(/\/+$/, '') === tokenIssuer; This keeps proxy handling intact while tolerating the canonical Clerk issuer suffix. 📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents
|
||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
private sessionExpired(jwt: Jwt | undefined): boolean { | ||||||||||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.