mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-01-31 13:29:55 +00:00
## Summary Add workspace authentication composables and types for per-tab workspace isolation. This infrastructure enables users to work in different workspaces in different browser tabs. ## Changes - **useWorkspaceAuth composable** - workspace token management - Exchange Firebase token for workspace-scoped JWT via `POST /api/auth/token` - Auto-refresh tokens 5 minutes before expiry - Per-tab sessionStorage caching - **useWorkspaceSwitch composable** - workspace switching with unsaved changes confirmation - **WorkspaceWithRole/WorkspaceTokenResponse types** - aligned with backend API - **firebaseAuthStore.getAuthHeader()** - prioritizes workspace tokens over Firebase tokens - **useSessionCookie** - uses Firebase token directly (getIdToken()) since getAuthHeader() now returns workspace token ## Backend Dependency - `POST /api/auth/token` - exchange Firebase token for workspace token - `GET /api/workspaces` - list user's workspaces ## Related - https://github.com/Comfy-Org/ComfyUI_frontend/pull/6295 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8073-feat-add-per-tab-workspace-authentication-infrastructure-2e96d73d3650816c8cf9dae9c330aebb) by [Unito](https://www.unito.io) --------- Co-authored-by: anthropic/claude <noreply@anthropic.com> Co-authored-by: Amp <amp@ampcode.com> Co-authored-by: Simula_r <18093452+simula-r@users.noreply.github.com>
50 lines
1.3 KiB
TypeScript
50 lines
1.3 KiB
TypeScript
import { storeToRefs } from 'pinia'
|
|
import { useI18n } from 'vue-i18n'
|
|
|
|
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
|
import { useDialogService } from '@/services/dialogService'
|
|
import { useWorkspaceAuthStore } from '@/stores/workspaceAuthStore'
|
|
|
|
export function useWorkspaceSwitch() {
|
|
const { t } = useI18n()
|
|
const workspaceAuthStore = useWorkspaceAuthStore()
|
|
const { currentWorkspace } = storeToRefs(workspaceAuthStore)
|
|
const workflowStore = useWorkflowStore()
|
|
const dialogService = useDialogService()
|
|
|
|
function hasUnsavedChanges(): boolean {
|
|
return workflowStore.modifiedWorkflows.length > 0
|
|
}
|
|
|
|
async function switchWithConfirmation(workspaceId: string): Promise<boolean> {
|
|
if (currentWorkspace.value?.id === workspaceId) {
|
|
return true
|
|
}
|
|
|
|
if (hasUnsavedChanges()) {
|
|
const confirmed = await dialogService.confirm({
|
|
title: t('workspace.unsavedChanges.title'),
|
|
message: t('workspace.unsavedChanges.message'),
|
|
type: 'dirtyClose'
|
|
})
|
|
|
|
if (!confirmed) {
|
|
return false
|
|
}
|
|
}
|
|
|
|
try {
|
|
await workspaceAuthStore.switchWorkspace(workspaceId)
|
|
window.location.reload()
|
|
return true
|
|
} catch {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return {
|
|
hasUnsavedChanges,
|
|
switchWithConfirmation
|
|
}
|
|
}
|