Fixes a race causing “No auth header available for session creation”
during sign‑in, by skipping the initial token refresh event, and
wrapping extension auth hooks with async error handling.
Sentry:
https://comfy-org.sentry.io/issues/6990347926/?alert_rule_id=1614600&project=4509681221369857
Context
- Error surfaced as an unhandled rejection when session creation was
triggered without a valid auth header.
- Triggers: both onAuthUserResolved and onAuthTokenRefreshed fired
during initial login.
- Pre‑fix, onIdTokenChanged treated the very first token emission as a
“refresh” as well, so two concurrent createSession() calls ran
back‑to‑back.
- One of those calls could land before a Firebase ID token existed, so
getAuthHeader() returned null → createSession threw “No auth header
available for session creation”.
Exact pre‑fix failure path
- src/extensions/core/cloudSessionCookie.ts
- onAuthUserResolved → useSessionCookie().createSession()
- onAuthTokenRefreshed → useSessionCookie().createSession()
- src/stores/firebaseAuthStore.ts
- onIdTokenChanged increments tokenRefreshTrigger even for the initial
token (treated as a refresh)
- getAuthHeader() → getIdToken() may be undefined briefly during
initialization
- src/platform/auth/session/useSessionCookie.ts
- createSession(): calls authStore.getAuthHeader(); if falsy, throws
Error('No auth header available for session creation')
What this PR changes
1) Skip initial token “refresh”
- Track lastTokenUserId and ignore the first onIdTokenChanged for a
user; only subsequent token changes count as refresh events.
- File: src/stores/firebaseAuthStore.ts
2) Wrap extension auth hooks with async error handling
- Use wrapWithErrorHandlingAsync for
onAuthUserResolved/onAuthTokenRefreshed/onAuthUserLogout callbacks to
avoid unhandled rejections.
- File: src/services/extensionService.ts
Result
- Eliminates the timing window where createSession() runs before
getIdToken() returns a token.
- Ensures any remaining errors are caught and reported instead of
surfacing as unhandled promise rejections.
Notes
- Lint and typecheck run clean (pnpm lint:fix && pnpm typecheck).
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-6563-Fix-session-cookie-creation-race-dedupe-calls-skip-initial-token-refresh-wrap-extensio-2a16d73d365081ef8c22c5ac8cb948aa)
by [Unito](https://www.unito.io)
## Summary
This reverts PR #5614 which moved VueFire persistence configuration to
initialization.
## Reason for Revert
It breaks Google SSO login with error:
```
useErrorHandling.ts:12 FirebaseError: Firebase: Error (auth/argument-error).
at createErrorInternal (index-c92d61ad.js:506:41)
at _assert (index-c92d61ad.js:512:15)
at _withDefaultResolver (index-c92d61ad.js:9237:5)
at signInWithPopup (index-c92d61ad.js:9457:30)
at executeAuthAction.createCustomer (firebaseAuthStore.ts:263:25)
at executeAuthAction (firebaseAuthStore.ts:223:28)
at Proxy.loginWithGoogle (firebaseAuthStore.ts:262:5)
at Proxy.wrappedAction (pinia.mjs:1405:26)
at useFirebaseAuthActions.ts:104:28
at Object.signInWithGoogle (useErrorHandling.ts:39:22)
```
## Changes
- Reverts commit ea4e57b60 "Move VueFire persistence configuration to
initialization (#5614)"
- Restores previous Firebase auth persistence behavior
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5729-Revert-Move-VueFire-persistence-configuration-to-initialization-5614-2776d73d3650814c9b80d9c67c852874)
by [Unito](https://www.unito.io)
## Summary
Some users were authenticating successfully but their email addresses
weren't being extracted from the Firebase token. This happened because
we weren't explicitly requesting the email scope during OAuth
authentication.
While Firebase's default configuration includes basic profile info, it
doesn't guarantee email access for all account types - particularly
Google Workspace accounts with restrictive policies or users with
privacy-conscious settings.
[Github
Scopes](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/scopes-for-oauth-apps)
## Changes
Adding email scope for Google + Github social OAuth.
## Review Focus
N/A
## Screenshots (if applicable)
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-5638-Explicitly-add-email-scope-for-social-auth-login-2726d73d3650817ab356fc9c04f8641b)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Alexander Brown <drjkl@comfy.org>
* [fix] gracefully handle Firebase auth failure
* [test] Add failing tests to reproduce Firebase Auth network issue #4468
Add test cases that demonstrate the current problematic behavior where
Firebase Auth makes network requests when offline without graceful error
handling, causing toast error messages and degraded offline experience.
Tests reproduce:
- getIdToken() throwing auth/network-request-failed instead of returning null
- getAuthHeader() failing to fallback gracefully when Firebase token refresh fails
These tests currently pass by expecting the error to be thrown. After
implementing the fix, the tests should be updated to verify graceful
handling (returning null instead of throwing).
Related to issue #4468: Firebase Auth makes network requests when offline
without evicting token
🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
* [test] update firebaseAuthStore tests
They match the behavior of the implemented solution now
* [test] add firebaseAuthStore.getTokenId test for non-network errors
* [chore] code review feedback
* [test] use FirebaseError
Co-authored-by: Alexander Brown <drjkl@comfy.org>
* [fix] remove indentation and fix test
---------
Co-authored-by: snomiao <snomiao@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Alexander Brown <drjkl@comfy.org>