mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-03 06:47:33 +00:00
## Summary Backports Firebase authentication with cloud environments. Changes only work when developing for cloud environment locally. ## Changes - Router guards to force unauthenticated users to sign in. - Configure auth headers for REST and Websocket connections. - Code implemented in a way that enables build tree-shaking based on distribution - Updates to build process to build cloud distribution and simplify development workflow ## Review Focus 1. Idomatic Vue/codebase patterns. 2. Build logic (please double check that I integrated correctly with: https://github.com/Comfy-Org/ComfyUI_frontend/blob/rh-test/vite.config.mts) ## Screenshots (if applicable) https://github.com/user-attachments/assets/ee4ea3f7-afa6-4da0-ba43-d62ed8ba4e18 ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6195-Feat-cloud-auth-backport-2946d73d365081f395f5f2a89fb7d800) by [Unito](https://www.unito.io) --------- Co-authored-by: Alexander Brown <drjkl@comfy.org> Co-authored-by: GitHub Action <action@github.com>
96 lines
2.7 KiB
TypeScript
96 lines
2.7 KiB
TypeScript
import { until } from '@vueuse/core'
|
|
import { storeToRefs } from 'pinia'
|
|
import {
|
|
createRouter,
|
|
createWebHashHistory,
|
|
createWebHistory
|
|
} from 'vue-router'
|
|
|
|
import { isCloud } from '@/platform/distribution/types'
|
|
import { useDialogService } from '@/services/dialogService'
|
|
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
|
import { useUserStore } from '@/stores/userStore'
|
|
import { isElectron } from '@/utils/envUtil'
|
|
import LayoutDefault from '@/views/layouts/LayoutDefault.vue'
|
|
|
|
const isFileProtocol = window.location.protocol === 'file:'
|
|
const basePath = isElectron() ? '/' : window.location.pathname
|
|
|
|
const router = createRouter({
|
|
history: isFileProtocol
|
|
? createWebHashHistory()
|
|
: // Base path must be specified to ensure correct relative paths
|
|
// Example: For URL 'http://localhost:7801/ComfyBackendDirect',
|
|
// we need this base path or assets will incorrectly resolve from 'http://localhost:7801/'
|
|
createWebHistory(basePath),
|
|
routes: [
|
|
{
|
|
path: '/',
|
|
component: LayoutDefault,
|
|
children: [
|
|
{
|
|
path: '',
|
|
name: 'GraphView',
|
|
component: () => import('@/views/GraphView.vue'),
|
|
beforeEnter: async (_to, _from, next) => {
|
|
const userStore = useUserStore()
|
|
await userStore.initialize()
|
|
if (userStore.needsLogin) {
|
|
next('/user-select')
|
|
} else {
|
|
next()
|
|
}
|
|
}
|
|
},
|
|
{
|
|
path: 'user-select',
|
|
name: 'UserSelectView',
|
|
component: () => import('@/views/UserSelectView.vue')
|
|
}
|
|
]
|
|
}
|
|
],
|
|
|
|
scrollBehavior(_to, _from, savedPosition) {
|
|
if (savedPosition) {
|
|
return savedPosition
|
|
} else {
|
|
return { top: 0 }
|
|
}
|
|
}
|
|
})
|
|
|
|
if (isCloud) {
|
|
// Global authentication guard
|
|
router.beforeEach(async (_to, _from, next) => {
|
|
const authStore = useFirebaseAuthStore()
|
|
|
|
// Wait for Firebase auth to initialize
|
|
// Timeout after 16 seconds
|
|
if (!authStore.isInitialized) {
|
|
try {
|
|
const { isInitialized } = storeToRefs(authStore)
|
|
await until(isInitialized).toBe(true, { timeout: 16_000 })
|
|
} catch (error) {
|
|
console.error('Auth initialization failed:', error)
|
|
return next({ name: 'cloud-auth-timeout' })
|
|
}
|
|
}
|
|
|
|
// Pass authenticated users
|
|
const authHeader = await authStore.getAuthHeader()
|
|
if (authHeader) {
|
|
return next()
|
|
}
|
|
|
|
// Show sign-in for unauthenticated users
|
|
const dialogService = useDialogService()
|
|
const loginSuccess = await dialogService.showSignInDialog()
|
|
|
|
if (loginSuccess) return next()
|
|
return next(false)
|
|
})
|
|
}
|
|
|
|
export default router
|