Skip to content
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

feat(clerk-js): Allow token refresh when Client failed to resolve #5345

Merged

Conversation

panteliselef
Copy link
Member

@panteliselef panteliselef commented Mar 13, 2025

Description

Until now we depended on the client to be successfully fetched in order to mark clerk as initialized. This is changing in this PR.

When /client fails for any reason, a 4xx error, a 5xx error, a network error (aka blocked), we are creating a "local" only representation of the client. If the user is already signed in, clerk-js leverages the existing JWT of the __session cookie to create the client based on the existing information (userId, sessionId, orgId etc.).

With this PR, (only for standard browsers) if /client fails, clerk-js always initiates a local-only client to allow for operations like Clerk.session?.getToken() to still operate as expected. That means Clerk.loaded will be true even when we don't have a proper client object in memory.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Copy link

changeset-bot bot commented Mar 13, 2025

🦋 Changeset detected

Latest commit: 14af574

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-js Patch
@clerk/types Patch
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/elements Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/clerk-react Patch
@clerk/remix Patch
@clerk/shared Patch
@clerk/tanstack-start Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link

vercel bot commented Mar 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 18, 2025 8:49am

Comment on lines -186 to -191

if (isNetworkError(e)) {
return;
}

clerkCoreErrorTokenRefreshFailed(e.toString());
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to stop throwing errors on status 5xx here. These errors are not useful to us, and developers cannot catch them and handle them.

In case of an FAPI outage, the poller would continue to throw errors, that would pollute a customer's Sentry logs

@@ -68,7 +71,6 @@ export interface EnvironmentJSON extends ClerkResourceJSON {
export interface ClientJSON extends ClerkResourceJSON {
object: 'client';
id: string;
status: any;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is safe to remove

Comment on lines +2059 to +2075
.then(res => this.updateClient(res))
.catch(async e => {
if (isClerkAPIResponseError(e) && e.errors[0].code === 'requires_captcha') {
throw e;
}

const jwtInCookie = this.#authService?.getSessionCookie();
const localClient = createClientFromJwt(jwtInCookie);

this.updateClient(localClient);

// Always grab a fresh token
await this.session?.getToken({ skipCache: true });

// Allows for Clerk to be marked as loaded with the client and session created from the JWT.
return null;
});
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't focus too much on where this code is located, we might refactor once both this and #5287 are merged.

Comment on lines +243 to +246
external_id: string | null;
primary_email_address_id: string | null;
primary_phone_number_id: string | null;
primary_web3_wallet_id: string | null;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our fapi docs

image_url: string;
has_image: boolean;
username: string;
username: string | null;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our fapi docs

Comment on lines +264 to +265
first_name: string | null;
last_name: string | null;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our fapi docs

@@ -275,7 +277,7 @@ export interface UserJSON extends ClerkResourceJSON {
created_at: number;
}

export interface PublicUserDataJSON extends ClerkResourceJSON {
export interface PublicUserDataJSON {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per our fapi docs

…ent-fails

# Conflicts:
#	packages/clerk-js/bundlewatch.config.json
#	packages/types/src/jwt.ts
@panteliselef panteliselef marked this pull request as ready for review March 17, 2025 11:02
{
object: 'session',
id: sid,
status: 'active',
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be added in a later PR, but we now have a new claim in the JWT: sts - it's only added when a session is in a pending status

We should extract it here and default to active: sts ?? 'active' -> happy to open up another PR later to update the JWT types and apply it here as well!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doing this in another PR sounds proper. TBH i don't think it is that important, because it might force redirect you to the appropriate page, but clerk will be down so you will not be able to proceed.

Copy link
Member

@jacekradko jacekradko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:shipit:

…sh-when-client-fails

# Conflicts:
#	packages/clerk-js/bundlewatch.config.json
@panteliselef panteliselef merged commit 3dddcda into main Mar 18, 2025
30 checks passed
@panteliselef panteliselef deleted the elef/sdki-915-support-token-refresh-when-client-fails branch March 18, 2025 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants