Repository navigation
fix(clerk-js): rewrite __clerk_db_jwt without a missing-cookie window #10412
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
base: main
Are you sure you want to change the base?
Changes from all commits
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,6 @@ | ||
| --- | ||
| '@clerk/clerk-js': patch | ||
| '@clerk/backend': patch | ||
| --- | ||
|
|
||
| Development instances no longer drop the suffixed `__clerk_db_jwt` cookie while rewriting it, which was causing intermittent `dev-browser-missing` 401s on concurrent requests. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,26 +46,42 @@ export const createDevBrowserCookie = ( | |
|
|
||
| const get = () => suffixedDevBrowserCookie.get() || devBrowserCookie.get(); | ||
|
|
||
| const cookies = [suffixedDevBrowserCookie, devBrowserCookie]; | ||
|
|
||
| const removeAll = () => { | ||
| const attributes = getCookieAttributes(options); | ||
|
|
||
| for (const cookie of [suffixedDevBrowserCookie, devBrowserCookie]) { | ||
| for (const cookie of cookies) { | ||
| cookie.remove(attributes); | ||
| cookie.remove(); | ||
| cookie.remove(partitionedCookieAttributes); | ||
| } | ||
| }; | ||
|
|
||
| const removeStaleAttributeVariants = (wrotePartitioned: boolean) => { | ||
| // Only strip the variants we did not just write. Removing Partitioned | ||
| // after an unpartitioned write can expire the live cookie on Safari | ||
| // builds that ignore the Partitioned attribute. | ||
| if (!wrotePartitioned) { | ||
| return; | ||
|
Comment on lines
+65
to
+66
Contributor
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. 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift 🔎 Supported by static analysis
Handle the partitioned-to-unpartitioned transition. When Add transition-safe cleanup for the Partitioned variants. Do not remove them blindly, because the existing Safari comment documents that this can expire the new unpartitioned cookie. 🤖 Prompt for AI Agents
|
||
| } | ||
|
|
||
| for (const cookie of cookies) { | ||
| cookie.remove({ sameSite: 'Lax', secure: getSecureAttribute('Lax'), partitioned: false }); | ||
| cookie.remove({ sameSite: 'None', secure: getSecureAttribute('None'), partitioned: false }); | ||
| } | ||
| }; | ||
|
|
||
| const set = (devBrowser: string) => { | ||
| const expires = addYears(Date.now(), 1); | ||
| const { sameSite, secure, partitioned } = getCookieAttributes(options); | ||
|
|
||
| // Remove stale variants before writing. The environment may not be loaded | ||
| // yet, so the current partitioned-cookies setting cannot be trusted. | ||
| removeAll(); | ||
|
|
||
| // Write both cookies first so a concurrent request never sees a hole | ||
| // between remove() and set(). Then drop only the attribute variants | ||
| // that are not the ones we just wrote. | ||
| suffixedDevBrowserCookie.set(devBrowser, { expires, sameSite, secure, partitioned }); | ||
| devBrowserCookie.set(devBrowser, { expires, sameSite, secure, partitioned }); | ||
| removeStaleAttributeVariants(partitioned); | ||
| }; | ||
|
|
||
| const remove = () => removeAll(); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win
🔎 Supported by static analysis
🏁 Script executed:
Repository: clerk/javascript
Length of output: 6955
Track partitioned and unpartitioned cookie variants in the mock.
remove()ignores its attributes and deletescookieStoreby name. The four unpartitioned cleanup calls therefore delete both entries written by the partitionedset(), while the test checks only operation order. No other test in this file checks that partitioned values survive.Use separate stores, or include the partitioned state in the store key, and assert both partitioned cookie values remain.
Suggested test fix
🤖 Prompt for AI Agents