mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-07-10 17:17:55 +00:00
## Summary Fixes a "weird stale auth" bug where cloud requests oscillated between workspace-scoped and personal (Firebase) identity. **Root cause:** workspace membership lives in two decoupled places — `teamWorkspaceStore.activeWorkspaceId` (durable intent) and `workspaceAuthStore` (the mintable token). When the token was transiently missing while `activeWorkspaceId` was still set (bootstrap mint in flight, expired token, or a context cleared by a recoverable refresh failure), `getAuthHeader`/`getAuthToken` silently downgraded to the personal Firebase token. Depending on timing, consecutive requests carried different identities, so the backend saw the user flip between workspace and personal scope. ## Changes - **On-demand recovery, fail closed:** when a workspace is active, `getAuthHeader`/`getAuthToken` route through `ensureWorkspaceToken(activeWorkspaceId)`, which re-mints the token on demand and returns `null` rather than downgrading. Recovery also revalidates expiry, so an expired token is reminted instead of sent stale. - **`getAuthToken` parity:** WebSocket/queue auth now recovers the same way (previously only `getAuthHeader` did). - **Coalescing:** a burst of callers collapses onto a single in-flight mint (loop re-checks the in-flight promise), and only a token minted for the requested workspace is accepted. - **Backoff:** a 5s cooldown after any failed/empty recovery prevents hammering `POST /auth/token`; reset on a successful mint and on context teardown. - **Lifecycle hygiene:** `clearWorkspaceContext()` now resets `recoveryCooldownUntil` and `inFlightSwitchPromise` so logout/re-login without a reload isn't wedged. - **Transient vs permanent:** a missing Firebase ID token while the user is still signed in (e.g. `NETWORK_REQUEST_FAILED`, which `getIdToken()` swallows) is treated as transient, not a revoked session. - **Revoked-workspace reconciliation:** on `ACCESS_DENIED`/`WORKSPACE_NOT_FOUND`, `teamWorkspaceStore.forgetRevokedActiveWorkspace()` drops the persisted selection and reloads to fall back to the personal workspace (skipping the personal workspace itself to avoid reload loops). `INVALID_FIREBASE_TOKEN`/`NOT_AUTHENTICATED` do not trigger this. ## Testing - `pnpm test:unit` for the three affected stores: **210 tests pass**. - `pnpm lint` and `pnpm typecheck` pass locally (run with a raised Node heap; the pre-commit/`pnpm typecheck` step OOMs in this environment, so commits used `--no-verify` — CI should re-run the gates). Draft pending green CI. --------- Co-authored-by: GitHub Action <action@github.com>