Skip to content

Fixes for browserCookiePersistence#10125

Open
jamesdaniels wants to merge 8 commits into
firebase:mainfrom
jamesdaniels:jamesdaniels_fixCookieAuth
Open

Fixes for browserCookiePersistence#10125
jamesdaniels wants to merge 8 commits into
firebase:mainfrom
jamesdaniels:jamesdaniels_fixCookieAuth

Conversation

@jamesdaniels

Copy link
Copy Markdown
Contributor
  1. need to have a refresh token of off the stsTokenManager, otherwise JS SDK doesn't try to refresh and logs out
  2. SameSite needs to be lax, so logout happens on navigation not just hard load
  3. Safari doesn't trust localhost, so we need to set the cookie as insecure. Cookie auth already requires secure context, so we can assume http === dev on localhost
  4. Don't wait for the DELETE method to complete for logout to fulfill, this is entirely optional to wipe out the refreshToken—fire and forget—the logout sentinel value "" is sufficient is the client cannot reach the backend
  5. Fix dynamic setPersistence race conditions by properly swapping storage event listeners and recovering existing cookie sessions.

@jamesdaniels jamesdaniels requested review from a team, NhienLam, pashanka and sam-gc as code owners June 30, 2026 16:29
@changeset-bot

changeset-bot Bot commented Jun 30, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 8d30d27

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request refactors token management and persistence handling, specifically for cookie persistence. It removes hardcoded cookie-specific redaction logic from PersistenceUserManager and centralizes the handling of 'REDACTED' refresh tokens within StsTokenManager. Additionally, it updates setPersistence to properly swap event listeners and recover existing sessions. The review feedback correctly identifies a potential race condition in setPersistence where this.boundEventHandler() is called without being awaited, and suggests awaiting the resulting promise to ensure state consistency.

Comment on lines +118 to 123
} else {
const userInNewPersistence = await this.getCurrentUser();
if (userInNewPersistence) {
this.boundEventHandler();
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

Issue: Floating Promise & Potential Race Condition

this.boundEventHandler binds to auth._onStorageEvent, which is an async function returning a Promise<void>. Calling it without await creates a floating promise, meaning setPersistence can resolve before the authentication state is fully updated on the auth instance. This can lead to race conditions in client applications where subsequent operations are executed before the state transition completes.

Recommendation

Await the promise returned by this.boundEventHandler(). Since boundEventHandler is typed as returning void, you can cast it to unknown and then Promise<void> to satisfy the TypeScript compiler.

Additionally, note that _onStorageEvent internally calls getCurrentUser() again. If you want to optimize performance by avoiding double asynchronous storage reads, you could consider refactoring the test setup to allow calling this.boundEventHandler() directly without the pre-check, as _onStorageEvent already handles the null-user case gracefully.

Suggested change
} else {
const userInNewPersistence = await this.getCurrentUser();
if (userInNewPersistence) {
this.boundEventHandler();
}
}
} else {
const userInNewPersistence = await this.getCurrentUser();
if (userInNewPersistence) {
await (this.boundEventHandler() as unknown as Promise<void>);
}
}

@jamesdaniels jamesdaniels changed the base branch from jamesdaniels_fixCookieAuth to main June 30, 2026 20:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant