Conversation
📝 WalkthroughWalkthroughAdds a WorkspaceAuthGate component at app root to coordinate Firebase auth startup, auth-aware remote config refresh, feature-flag checks, and conditional workspace store initialization; the gate shows a spinner until initialization completes and gracefully degrades on timeouts/errors. Changes
Sequence DiagramsequenceDiagram
participant App
participant WorkspaceAuthGate
participant FirebaseAuth
participant RemoteConfig
participant FeatureFlags
participant WorkspaceStore
App->>WorkspaceAuthGate: mount
WorkspaceAuthGate->>FirebaseAuth: wait for auth init (<=16s)
FirebaseAuth-->>WorkspaceAuthGate: auth ready / unauthenticated
alt unauthenticated
WorkspaceAuthGate->>App: mark ready -> render slot
else authenticated
WorkspaceAuthGate->>RemoteConfig: refresh with auth (race 10s)
RemoteConfig-->>WorkspaceAuthGate: loaded / timeout / error
WorkspaceAuthGate->>FeatureFlags: read teamWorkspacesEnabled
FeatureFlags-->>WorkspaceAuthGate: flag value
alt teamWorkspacesEnabled = false
WorkspaceAuthGate->>App: mark ready -> render slot (Firebase auth)
else teamWorkspacesEnabled = true
WorkspaceAuthGate->>WorkspaceStore: initialize workspace mode
WorkspaceStore-->>WorkspaceAuthGate: init success / error
WorkspaceAuthGate->>App: mark ready -> render slot (workspace mode or fallback)
end
end
Possibly related PRs
Suggested reviewers
✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🎨 Storybook Build Status✅ Build completed successfully! ⏰ Completed at: 01/28/2026, 03:52:35 AM UTC 🔗 Links🎉 Your Storybook is ready for review! |
🎭 Playwright Tests: ✅ PassedResults: 507 passed, 0 failed, 0 flaky, 8 skipped (Total: 515) 📊 Browser Reports
|
Bundle Size ReportSummary
Category Glance Per-category breakdownApp Entry Points — 25.9 kB (baseline 22.9 kB) • 🔴 +2.96 kBMain entry bundles and manifests
Status: 1 added / 1 removed Graph Workspace — 960 kB (baseline 961 kB) • 🟢 -1.04 kBGraph editor runtime, canvas, workflow orchestration
Status: 1 added / 1 removed Views & Navigation — 80.7 kB (baseline 80.7 kB) • ⚪ 0 BTop-level views, pages, and routed surfaces
Status: 11 added / 11 removed Panels & Settings — 471 kB (baseline 470 kB) • 🔴 +385 BConfiguration panels, inspectors, and settings screens
Status: 24 added / 24 removed User & Accounts — 3.94 kB (baseline 3.94 kB) • ⚪ 0 BAuthentication, profile, and account management bundles
Status: 3 added / 3 removed Editors & Dialogs — 2.86 kB (baseline 2.86 kB) • ⚪ 0 BModals, dialogs, drawers, and in-app editors
Status: 2 added / 2 removed UI Components — 33.7 kB (baseline 33.7 kB) • ⚪ 0 BReusable component library chunks
Status: 9 added / 9 removed Data & Services — 2.7 MB (baseline 2.7 MB) • 🔴 +289 BStores, services, APIs, and repositories
Status: 9 added / 10 removed Utilities & Hooks — 25.3 kB (baseline 25.2 kB) • 🔴 +91 BHelpers, composables, and utility bundles
Status: 10 added / 10 removed Vendor & Third-Party — 10.7 MB (baseline 10.7 MB) • ⚪ 0 BExternal libraries and shared vendor chunks
Status: 5 added / 5 removed Other — 7.04 MB (baseline 7.04 MB) • 🟢 -195 BBundles that do not match a named category
Status: 90 added / 90 removed |
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
src/platform/remoteConfig/refreshRemoteConfig.ts (1)
32-45: SetremoteConfigStatetoerrorfor any non‑OK response.
Line 40 logs failures, but only 401/403 update the state (Line 41-45). Other HTTP failures (e.g., 500) leave the state unchanged, which can keep auth gating or feature flags stuck on a stale state.As per coding guidelines: Implement proper error handling.🔧 Suggested fix
console.warn('Failed to load remote config:', response.statusText) if (response.status === 401 || response.status === 403) { window.__CONFIG__ = {} remoteConfig.value = {} - remoteConfigState.value = 'error' } + remoteConfigState.value = 'error'
🤖 Fix all issues with AI agents
In `@src/components/auth/WorkspaceAuthGate.vue`:
- Around line 1-9: Replace the PrimeVue ProgressSpinner usage in
WorkspaceAuthGate.vue with the project-standard loading component (e.g., import
and use the shared FullscreenLoader or LoadingSpinner from src/components/) and
remove any PrimeVue-specific imports; render that component in place of
<ProgressSpinner /> inside the v-else block. Also replace the hardcoded z-[1100]
with the theme design token (use the CSS variable or class token used across the
project, e.g., use style/class that references --z-overlay or the project's
overlay z-index token) so the wrapper uses the centralized z-index token instead
of an arbitrary number.
In `@src/stores/firebaseAuthStore.ts`:
- Around line 252-275: The workspace token retrieval and expiry-check logic is
duplicated between getAuthToken and getAuthHeader; extract that shared logic
into a single helper (e.g., getValidWorkspaceToken or retrieveWorkspaceToken)
and have both getAuthToken and getAuthHeader call it; the helper should read
WORKSPACE_STORAGE_KEYS.TOKEN and WORKSPACE_STORAGE_KEYS.EXPIRES_AT from
sessionStorage, parse and validate the expiry (apply any buffer logic there),
and return the token or undefined so both functions use the same validation
behavior.
| <template> | ||
| <slot v-if="isReady" /> | ||
| <div | ||
| v-else | ||
| class="fixed inset-0 z-[1100] flex items-center justify-center bg-[var(--p-mask-background)]" | ||
| > | ||
| <ProgressSpinner /> | ||
| </div> | ||
| </template> |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check for existing loading/spinner components and z-index usage patterns
echo "=== Existing spinner/loading components in Vue files ==="
fd -e vue | xargs rg -l -i 'spinner|loading' 2>/dev/null | head -20
echo ""
echo "=== Search for ProgressSpinner usage ==="
rg 'ProgressSpinner' --type vue --type ts | head -20
echo ""
echo "=== Check for alternative loading indicators ==="
fd -e vue -path "*/components/*" | xargs rg -l -i 'loading|spinner' 2>/dev/null | head -20
echo ""
echo "=== z-index values in the codebase ==="
rg 'z-\[' --type vue --type ts | grep -E 'z-\[[0-9]{3,}' | head -20Repository: Comfy-Org/ComfyUI_frontend
Length of output: 2556
🏁 Script executed:
#!/bin/bash
# Read the actual file to see what's being used
echo "=== Full WorkspaceAuthGate.vue file ==="
cat -n src/components/auth/WorkspaceAuthGate.vue
echo ""
echo "=== Search for imports of ProgressSpinner in the codebase ==="
rg 'import.*ProgressSpinner|from.*ProgressSpinner'
echo ""
echo "=== Search for z-index definitions and arbitrary values ==="
rg 'z-\[' src/ --no-heading | head -20
echo ""
echo "=== Look for common loading/spinner alternatives ==="
fd -type f -name '*.vue' -path '*/components/*' | xargs grep -l 'loading\|spinner' 2>/dev/null | head -10Repository: Comfy-Org/ComfyUI_frontend
Length of output: 8139
🏁 Script executed:
#!/bin/bash
# Check for z-index design tokens or theme values
echo "=== Search for z-index in CSS/theme files ==="
find src -name '*.css' -o -name 'style.*' | xargs grep -n 'z-index' 2>/dev/null | head -20
echo ""
echo "=== Check for tailwind z-index configuration ==="
cat tailwind.config.ts 2>/dev/null | grep -A 20 'zIndex' || echo "Config check completed"
echo ""
echo "=== Look for custom loading/spinner components in src/components ==="
fd -type f -name '*.vue' src/components/ | xargs grep -l 'spinner\|loading' -i 2>/dev/null | head -10
echo ""
echo "=== Check style.css for semantic z-index values ==="
grep -n 'z-index\|--.*z' src/style.css 2>/dev/null | head -15Repository: Comfy-Org/ComfyUI_frontend
Length of output: 781
🏁 Script executed:
#!/bin/bash
# Check if Suspense is used in similar auth/init gate patterns
echo "=== Search for Suspense usage in Vue components ==="
rg 'Suspense|<Suspense' src/ --no-heading | head -15
echo ""
echo "=== Check if there are similar auth gate components ==="
fd -type f -name '*[Aa]uth*[Gg]ate*.vue' src/
echo ""
echo "=== Check the main App.vue to see how it handles initial loading ==="
head -50 src/App.vueRepository: Comfy-Org/ComfyUI_frontend
Length of output: 2601
Replace PrimeVue ProgressSpinner with a custom loading component.
Per coding guidelines, "Avoid new usage of PrimeVue components." Consider using a project-standard loading indicator from src/components/ or implementing a simple spinner alternative.
Also, the z-[1100] hardcoded value should use a design token instead of an arbitrary number to maintain consistency with the theme system and avoid conflicts with other overlays.
🧰 Tools
🪛 ESLint
[error] 1-1: Resolve error: EACCES: permission denied, open '/iVKfOXJLLN'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_44eddb5b99ae4bce470e6fb9a90221ee/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_44eddb5b99ae4bce470e6fb9a90221ee/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/rules/no-unresolved.js:31:34)
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1180:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1321:10)
(import-x/no-unresolved)
[error] 1-1: Resolve error: EACCES: permission denied, open '/HOcZIXwqKG'
at Object.writeFileSync (node:fs:2409:20)
at l (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:13670)
at createFilesMatcher (file:///home/jailuser/git/node_modules/.pnpm/get-tsconfig@4.10.1/node_modules/get-tsconfig/dist/index.mjs:7:14422)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_44eddb5b99ae4bce470e6fb9a90221ee/node_modules/eslint-import-resolver-typescript/lib/index.js:70:65)
at Object.resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-import-resolver-typescript@4.4.4_eslint-plugin-import-x@4.16.1_@typescript-eslin_44eddb5b99ae4bce470e6fb9a90221ee/node_modules/eslint-import-resolver-typescript/lib/index.js:147:20)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:69
at setRuleContext (/home/jailuser/git/node_modules/.pnpm/eslint-import-context@0.1.9_unrs-resolver@1.11.1/node_modules/eslint-import-context/lib/index.js:23:20)
at fullResolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:170:30)
at relative (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:215:12)
at resolve (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/resolve.js:220:16)
at importType (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/import-type.js:126:63)
at checkImportForRelativePackage (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:15:38)
at file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/rules/no-relative-packages.js:59:40
at checkSourceValue (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:14:9)
at checkSource (file:///home/jailuser/git/node_modules/.pnpm/eslint-plugin-import-x@4.16.1_@typescript-eslint+utils@8.50.0_eslint@9.39.1_jiti@2.6.1__eacac87f98d760f1781d40e8519857dc/node_modules/eslint-plugin-import-x/lib/utils/module-visitor.js:17:9)
at ruleErrorHandler (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1173:33)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:46
at Array.forEach ()
at SourceCodeVisitor.callSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-visitor.js:76:30)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-traverser.js:291:18
at Array.forEach ()
at SourceCodeTraverser.traverseSync (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/source-code-traverser.js:290:10)
at runRules (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1214:12)
at #flatVerifyWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2101:4)
at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2189:43)
at /home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1773:17
at Array.map ()
at Linter._verifyWithFlatConfigArrayAndProcessor (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1768:30)
at Linter._verifyWithFlatConfigArray (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2275:16)
at Linter.verify (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:1677:10)
at Linter.verifyAndFix (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/linter/linter.js:2557:20)
at verifyText (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1180:45)
at readAndVerifyFile (/home/jailuser/git/node_modules/.pnpm/eslint@9.39.1_jiti@2.6.1/node_modules/eslint/lib/eslint/eslint-helpers.js:1321:10)
(import-x/no-relative-packages)
🤖 Prompt for AI Agents
In `@src/components/auth/WorkspaceAuthGate.vue` around lines 1 - 9, Replace the
PrimeVue ProgressSpinner usage in WorkspaceAuthGate.vue with the
project-standard loading component (e.g., import and use the shared
FullscreenLoader or LoadingSpinner from src/components/) and remove any
PrimeVue-specific imports; render that component in place of <ProgressSpinner />
inside the v-else block. Also replace the hardcoded z-[1100] with the theme
design token (use the CSS variable or class token used across the project, e.g.,
use style/class that references --z-overlay or the project's overlay z-index
token) so the wrapper uses the centralized z-index token instead of an arbitrary
number.
| /** | ||
| * Returns the raw auth token (not wrapped in a header object). | ||
| * Priority: workspace token > Firebase token. | ||
| * Use this for WebSocket connections and backend node auth. | ||
| */ | ||
| const getAuthToken = async (): Promise<string | undefined> => { | ||
| if (flags.teamWorkspacesEnabled) { | ||
| const workspaceToken = sessionStorage.getItem( | ||
| WORKSPACE_STORAGE_KEYS.TOKEN | ||
| ) | ||
| const expiresAt = sessionStorage.getItem( | ||
| WORKSPACE_STORAGE_KEYS.EXPIRES_AT | ||
| ) | ||
|
|
||
| if (workspaceToken && expiresAt) { | ||
| const expiryTime = parseInt(expiresAt, 10) | ||
| if (Date.now() < expiryTime) { | ||
| return workspaceToken | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return await getIdToken() | ||
| } |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
Code duplication with getAuthHeader() - consider extracting shared logic.
The workspace token retrieval logic (lines 258-271) duplicates lines 215-230 in getAuthHeader(). If the token validation logic changes (e.g., adding a buffer before expiry), both locations need updating.
Consider extracting the shared logic:
♻️ Proposed refactor to eliminate duplication
+ /**
+ * Returns a valid workspace token if available and not expired.
+ * Returns undefined if workspace feature is disabled or token is expired/missing.
+ */
+ function getValidWorkspaceToken(): string | undefined {
+ if (!flags.teamWorkspacesEnabled) return undefined
+
+ const workspaceToken = sessionStorage.getItem(WORKSPACE_STORAGE_KEYS.TOKEN)
+ const expiresAt = sessionStorage.getItem(WORKSPACE_STORAGE_KEYS.EXPIRES_AT)
+
+ if (workspaceToken && expiresAt) {
+ const expiryTime = parseInt(expiresAt, 10)
+ if (Date.now() < expiryTime) {
+ return workspaceToken
+ }
+ }
+ return undefined
+ }
+
const getAuthHeader = async (): Promise<AuthHeader | null> => {
- if (flags.teamWorkspacesEnabled) {
- const workspaceToken = sessionStorage.getItem(
- WORKSPACE_STORAGE_KEYS.TOKEN
- )
- const expiresAt = sessionStorage.getItem(
- WORKSPACE_STORAGE_KEYS.EXPIRES_AT
- )
-
- if (workspaceToken && expiresAt) {
- const expiryTime = parseInt(expiresAt, 10)
- if (Date.now() < expiryTime) {
- return {
- Authorization: `Bearer ${workspaceToken}`
- }
- }
- }
+ const workspaceToken = getValidWorkspaceToken()
+ if (workspaceToken) {
+ return { Authorization: `Bearer ${workspaceToken}` }
}
// ... rest unchanged
}
const getAuthToken = async (): Promise<string | undefined> => {
- if (flags.teamWorkspacesEnabled) {
- const workspaceToken = sessionStorage.getItem(
- WORKSPACE_STORAGE_KEYS.TOKEN
- )
- const expiresAt = sessionStorage.getItem(
- WORKSPACE_STORAGE_KEYS.EXPIRES_AT
- )
-
- if (workspaceToken && expiresAt) {
- const expiryTime = parseInt(expiresAt, 10)
- if (Date.now() < expiryTime) {
- return workspaceToken
- }
- }
- }
-
+ const workspaceToken = getValidWorkspaceToken()
+ if (workspaceToken) return workspaceToken
return await getIdToken()
}🤖 Prompt for AI Agents
In `@src/stores/firebaseAuthStore.ts` around lines 252 - 275, The workspace token
retrieval and expiry-check logic is duplicated between getAuthToken and
getAuthHeader; extract that shared logic into a single helper (e.g.,
getValidWorkspaceToken or retrieveWorkspaceToken) and have both getAuthToken and
getAuthHeader call it; the helper should read WORKSPACE_STORAGE_KEYS.TOKEN and
WORKSPACE_STORAGE_KEYS.EXPIRES_AT from sessionStorage, parse and validate the
expiry (apply any buffer logic there), and return the token or undefined so both
functions use the same validation behavior.
7fda05d to
3f246d8
Compare
|
## Summary - Fix auth related race conditions with a new WorkspaceAuthGate in App.vue - De dup initialization calls - Add state machine to track state of refreshRemoteConfig - Fix websocket not using new workspace jwt - Misc improvments (cherry picked from commit 34fc28a)
## Summary Backport of #8350 to cloud/1.37 - Fix auth related race conditions with a new WorkspaceAuthGate in App.vue - De dup initialization calls - Add state machine to track state of refreshRemoteConfig - Fix websocket not using new workspace jwt - Misc improvements ## Changes Cherry-picked from commit 34fc28a Resolved conflict in `src/views/GraphView.vue`: - Kept workspace store initialization from cloud/1.37 branch - Applied PR's refactored event listener pattern using `useEventListener` from VueUse - Applied PR's `useIntervalFn` for tab count tracking ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8357-backport-cloud-1-37-Feat-workspaces-5-auth-gate-check-2f66d73d365081bd8fe4f0cea481de11) by [Unito](https://www.unito.io) --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Summary
Changes
┆Issue is synchronized with this Notion page by Unito