mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-25 06:47:35 +00:00
Compare commits
3 Commits
website/02
...
refactor/a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2daa21f81b | ||
|
|
bbdf20d68b | ||
|
|
ed7ceab571 |
@@ -71,8 +71,8 @@ vi.mock('@/workbench/extensions/manager/composables/useManagerState', () => ({
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
currentUser: null,
|
||||
loading: false
|
||||
}))
|
||||
|
||||
@@ -32,8 +32,8 @@ const mockBalance = vi.hoisted(() => ({
|
||||
|
||||
const mockIsFetchingBalance = vi.hoisted(() => ({ value: false }))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
balance: mockBalance.value,
|
||||
isFetchingBalance: mockIsFetchingBalance.value
|
||||
}))
|
||||
|
||||
@@ -30,14 +30,14 @@ import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { formatCreditsFromCents } from '@/base/credits/comfyCredits'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const { textClass, showCreditsOnly } = defineProps<{
|
||||
textClass?: string
|
||||
showCreditsOnly?: boolean
|
||||
}>()
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const balanceLoading = computed(() => authStore.isFetchingBalance)
|
||||
const { t, locale } = useI18n()
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
||||
import {
|
||||
configValueOrDefault,
|
||||
@@ -167,7 +167,7 @@ const { onSuccess } = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const isSecureContext = window.isSecureContext
|
||||
const isSignIn = ref(true)
|
||||
const showApiKeyForm = ref(false)
|
||||
|
||||
@@ -156,7 +156,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { creditsToUsd, usdToCredits } from '@/base/credits/comfyCredits'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import FormattedNumberStepper from '@/components/ui/stepper/FormattedNumberStepper.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
@@ -171,7 +171,7 @@ const { isInsufficientCredits = false } = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const dialogStore = useDialogStore()
|
||||
const settingsDialog = useSettingsDialog()
|
||||
const telemetry = useTelemetry()
|
||||
|
||||
@@ -21,10 +21,10 @@ import { ref } from 'vue'
|
||||
|
||||
import PasswordFields from '@/components/dialog/content/signin/PasswordFields.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { updatePasswordSchema } from '@/schemas/signInSchema'
|
||||
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const loading = ref(false)
|
||||
|
||||
const { onSuccess } = defineProps<{
|
||||
|
||||
@@ -116,12 +116,12 @@ import UserCredit from '@/components/common/UserCredit.vue'
|
||||
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { formatMetronomeCurrency } from '@/utils/formatUtil'
|
||||
|
||||
interface CreditHistoryItemData {
|
||||
@@ -133,8 +133,8 @@ interface CreditHistoryItemData {
|
||||
|
||||
const { buildDocsUrl, docsPaths } = useExternalLink()
|
||||
const dialogService = useDialogService()
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authStore = useAuthStore()
|
||||
const authActions = useAuthActions()
|
||||
const commandStore = useCommandStore()
|
||||
const telemetry = useTelemetry()
|
||||
const { isActiveSubscription } = useBillingContext()
|
||||
|
||||
@@ -18,8 +18,8 @@ import ApiKeyForm from './ApiKeyForm.vue'
|
||||
const mockStoreApiKey = vi.fn()
|
||||
const mockLoading = vi.fn(() => false)
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
loading: mockLoading()
|
||||
}))
|
||||
}))
|
||||
|
||||
@@ -100,9 +100,9 @@ import {
|
||||
} from '@/platform/remoteConfig/remoteConfig'
|
||||
import { apiKeySchema } from '@/schemas/signInSchema'
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const apiKeyStore = useApiKeyAuthStore()
|
||||
const loading = computed(() => authStore.loading)
|
||||
const comfyPlatformBaseUrl = computed(() =>
|
||||
|
||||
@@ -35,15 +35,15 @@ vi.mock('firebase/auth', () => ({
|
||||
|
||||
// Mock the auth composables and stores
|
||||
const mockSendPasswordReset = vi.fn()
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: vi.fn(() => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: vi.fn(() => ({
|
||||
sendPasswordReset: mockSendPasswordReset
|
||||
}))
|
||||
}))
|
||||
|
||||
let mockLoading = false
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
get loading() {
|
||||
return mockLoading
|
||||
}
|
||||
|
||||
@@ -88,14 +88,14 @@ import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { signInSchema } from '@/schemas/signInSchema'
|
||||
import type { SignInData } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const firebaseAuthActions = useFirebaseAuthActions()
|
||||
const authStore = useAuthStore()
|
||||
const firebaseAuthActions = useAuthActions()
|
||||
const loading = computed(() => authStore.loading)
|
||||
const toast = useToast()
|
||||
|
||||
|
||||
@@ -54,12 +54,12 @@ import { useI18n } from 'vue-i18n'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { signUpSchema } from '@/schemas/signInSchema'
|
||||
import type { SignUpData } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
import PasswordFields from './PasswordFields.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const loading = computed(() => authStore.loading)
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
||||
@@ -61,10 +61,10 @@ vi.mock('@/composables/auth/useCurrentUser', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
// Mock the useFirebaseAuthActions composable
|
||||
// Mock the useAuthActions composable
|
||||
const mockLogout = vi.fn()
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: vi.fn(() => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: vi.fn(() => ({
|
||||
fetchBalance: vi.fn().mockResolvedValue(undefined),
|
||||
logout: mockLogout
|
||||
}))
|
||||
@@ -77,7 +77,7 @@ vi.mock('@/services/dialogService', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
// Mock the firebaseAuthStore with hoisted state for per-test manipulation
|
||||
// Mock the authStore with hoisted state for per-test manipulation
|
||||
const mockAuthStoreState = vi.hoisted(() => ({
|
||||
balance: {
|
||||
amount_micros: 100_000,
|
||||
@@ -91,8 +91,8 @@ const mockAuthStoreState = vi.hoisted(() => ({
|
||||
isFetchingBalance: false
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
getAuthHeader: vi
|
||||
.fn()
|
||||
.mockResolvedValue({ Authorization: 'Bearer mock-token' }),
|
||||
|
||||
@@ -159,7 +159,7 @@ import { formatCreditsFromCents } from '@/base/credits/comfyCredits'
|
||||
import UserAvatar from '@/components/common/UserAvatar.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import SubscribeButton from '@/platform/cloud/subscription/components/SubscribeButton.vue'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
@@ -168,7 +168,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useSettingsDialog } from '@/platform/settings/composables/useSettingsDialog'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const emit = defineEmits<{
|
||||
close: []
|
||||
@@ -178,8 +178,8 @@ const { buildDocsUrl, docsPaths } = useExternalLink()
|
||||
|
||||
const { userDisplayName, userEmail, userPhotoUrl, handleSignOut } =
|
||||
useCurrentUser()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authActions = useAuthActions()
|
||||
const authStore = useAuthStore()
|
||||
const settingsDialog = useSettingsDialog()
|
||||
const dialogService = useDialogService()
|
||||
const {
|
||||
|
||||
@@ -11,8 +11,8 @@ import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import type { BillingPortalTargetTier } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { BillingPortalTargetTier } from '@/stores/authStore'
|
||||
import { usdToMicros } from '@/utils/formatUtil'
|
||||
|
||||
/**
|
||||
@@ -20,8 +20,8 @@ import { usdToMicros } from '@/utils/formatUtil'
|
||||
* All actions are wrapped with error handling.
|
||||
* @returns {Object} - Object containing all Firebase Auth actions
|
||||
*/
|
||||
export const useFirebaseAuthActions = () => {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
export const useAuthActions = () => {
|
||||
const authStore = useAuthStore()
|
||||
const toastStore = useToastStore()
|
||||
const { wrapWithErrorHandlingAsync, toastErrorHandler } = useErrorHandling()
|
||||
|
||||
@@ -3,11 +3,11 @@ import { computed, watch } from 'vue'
|
||||
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { AuthUserInfo } from '@/types/authTypes'
|
||||
|
||||
export const useCurrentUser = () => {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const commandStore = useCommandStore()
|
||||
const apiKeyStore = useApiKeyAuthStore()
|
||||
|
||||
|
||||
@@ -70,8 +70,8 @@ vi.mock(
|
||||
})
|
||||
)
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: () => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: () => ({
|
||||
balance: { amount_micros: 5000000 },
|
||||
fetchBalance: vi.fn().mockResolvedValue({ amount_micros: 5000000 })
|
||||
})
|
||||
|
||||
@@ -5,7 +5,7 @@ import type {
|
||||
PreviewSubscribeResponse,
|
||||
SubscribeResponse
|
||||
} from '@/platform/workspace/api/workspaceApi'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
import type {
|
||||
BalanceInfo,
|
||||
@@ -33,7 +33,7 @@ export function useLegacyBilling(): BillingState & BillingActions {
|
||||
showSubscriptionDialog: legacyShowSubscriptionDialog
|
||||
} = useSubscription()
|
||||
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
|
||||
const isInitialized = ref(false)
|
||||
const isLoading = ref(false)
|
||||
|
||||
@@ -56,8 +56,8 @@ vi.mock('@/scripts/api', () => ({
|
||||
|
||||
vi.mock('@/platform/settings/settingStore')
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({}))
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({}))
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuth', () => ({
|
||||
@@ -123,8 +123,8 @@ vi.mock('@/stores/workspace/colorPaletteStore', () => ({
|
||||
useColorPaletteStore: vi.fn(() => ({}))
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: vi.fn(() => ({}))
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: vi.fn(() => ({}))
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems'
|
||||
import { useSubgraphOperations } from '@/composables/graph/useSubgraphOperations'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
@@ -78,7 +78,7 @@ export function useCoreCommands(): ComfyCommand[] {
|
||||
const settingsDialog = useSettingsDialog()
|
||||
const dialogService = useDialogService()
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
const firebaseAuthActions = useFirebaseAuthActions()
|
||||
const firebaseAuthActions = useAuthActions()
|
||||
const toastStore = useToastStore()
|
||||
const canvasStore = useCanvasStore()
|
||||
const executionStore = useExecutionStore()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
/**
|
||||
* Session cookie management for cloud authentication.
|
||||
@@ -21,7 +21,7 @@ export const useSessionCookie = () => {
|
||||
|
||||
const { flags } = useFeatureFlags()
|
||||
try {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
let authHeader: Record<string, string>
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
|
||||
interface Props {
|
||||
errorMessage?: string
|
||||
@@ -83,7 +83,7 @@ interface Props {
|
||||
defineProps<Props>()
|
||||
|
||||
const router = useRouter()
|
||||
const { logout } = useFirebaseAuthActions()
|
||||
const { logout } = useAuthActions()
|
||||
const showTechnicalDetails = ref(false)
|
||||
|
||||
const handleRestart = async () => {
|
||||
|
||||
@@ -76,11 +76,11 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
|
||||
const email = ref('')
|
||||
const loading = ref(false)
|
||||
|
||||
@@ -110,7 +110,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import CloudSignInForm from '@/platform/cloud/onboarding/components/CloudSignInForm.vue'
|
||||
import { useFreeTierOnboarding } from '@/platform/cloud/onboarding/composables/useFreeTierOnboarding'
|
||||
import { getSafePreviousFullPath } from '@/platform/cloud/onboarding/utils/previousFullPath'
|
||||
@@ -120,7 +120,7 @@ import type { SignInData } from '@/schemas/signInSchema'
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const isSecureContext = globalThis.isSecureContext
|
||||
const authError = ref('')
|
||||
const toastStore = useToastStore()
|
||||
|
||||
@@ -133,7 +133,7 @@ import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import SignUpForm from '@/components/dialog/content/signin/SignUpForm.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useFreeTierOnboarding } from '@/platform/cloud/onboarding/composables/useFreeTierOnboarding'
|
||||
import { getSafePreviousFullPath } from '@/platform/cloud/onboarding/utils/previousFullPath'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
@@ -145,7 +145,7 @@ import { isInChina } from '@/utils/networkUtil'
|
||||
const { t } = useI18n()
|
||||
const router = useRouter()
|
||||
const route = useRoute()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const isSecureContext = globalThis.isSecureContext
|
||||
const authError = ref('')
|
||||
const userIsInChina = ref(false)
|
||||
|
||||
@@ -25,8 +25,8 @@ const authActionMocks = vi.hoisted(() => ({
|
||||
accessBillingPortal: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: () => authActionMocks
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: () => authActionMocks
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/useErrorHandling', () => ({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useI18n } from 'vue-i18n'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
|
||||
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import type { TierKey } from '@/platform/cloud/subscription/constants/tierPricing'
|
||||
import { performSubscriptionCheckout } from '@/platform/cloud/subscription/utils/subscriptionCheckoutUtil'
|
||||
@@ -16,7 +16,7 @@ import type { BillingCycle } from '../subscription/utils/subscriptionTierRank'
|
||||
const { t } = useI18n()
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
const { reportError, accessBillingPortal } = useFirebaseAuthActions()
|
||||
const { reportError, accessBillingPortal } = useAuthActions()
|
||||
const { wrapWithErrorHandlingAsync } = useErrorHandling()
|
||||
|
||||
const { isActiveSubscription, isInitialized, initialize } = useBillingContext()
|
||||
|
||||
@@ -89,9 +89,9 @@ import { useI18n } from 'vue-i18n'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { signInSchema } from '@/schemas/signInSchema'
|
||||
import type { SignInData } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const loading = computed(() => authStore.loading)
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
@@ -31,8 +31,8 @@ vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: () => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: () => ({
|
||||
accessBillingPortal: mockAccessBillingPortal,
|
||||
reportError: mockReportError
|
||||
})
|
||||
@@ -56,13 +56,13 @@ vi.mock('@/composables/useErrorHandling', () => ({
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: () =>
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: () =>
|
||||
reactive({
|
||||
getAuthHeader: mockGetAuthHeader,
|
||||
userId: computed(() => mockUserId.value)
|
||||
}),
|
||||
FirebaseAuthStoreError: class extends Error {}
|
||||
AuthStoreError: class extends Error {}
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/telemetry', () => ({
|
||||
|
||||
@@ -262,7 +262,7 @@ import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
import {
|
||||
@@ -279,7 +279,7 @@ import type { BillingCycle } from '@/platform/cloud/subscription/utils/subscript
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import type { CheckoutAttributionMetadata } from '@/platform/telemetry/types'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { components } from '@/types/comfyRegistryTypes'
|
||||
|
||||
type SubscriptionTier = components['schemas']['SubscriptionTier']
|
||||
@@ -365,8 +365,8 @@ const {
|
||||
isYearlySubscription
|
||||
} = useSubscription()
|
||||
const telemetry = useTelemetry()
|
||||
const { userId } = storeToRefs(useFirebaseAuthStore())
|
||||
const { accessBillingPortal, reportError } = useFirebaseAuthActions()
|
||||
const { userId } = storeToRefs(useAuthStore())
|
||||
const { accessBillingPortal, reportError } = useAuthActions()
|
||||
const { wrapWithErrorHandlingAsync } = useErrorHandling()
|
||||
|
||||
const isLoading = ref(false)
|
||||
|
||||
@@ -82,8 +82,8 @@ vi.mock(
|
||||
})
|
||||
)
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: vi.fn(() => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: vi.fn(() => ({
|
||||
authActions: vi.fn(() => ({
|
||||
accessBillingPortal: vi.fn()
|
||||
}))
|
||||
|
||||
@@ -211,7 +211,7 @@ import { computed, onBeforeUnmount, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import SubscribeButton from '@/platform/cloud/subscription/components/SubscribeButton.vue'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
import { useSubscriptionActions } from '@/platform/cloud/subscription/composables/useSubscriptionActions'
|
||||
@@ -227,7 +227,7 @@ import type { TierBenefit } from '@/platform/cloud/subscription/utils/tierBenefi
|
||||
import { getCommonTierBenefits } from '@/platform/cloud/subscription/utils/tierBenefits'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const { t, n } = useI18n()
|
||||
|
||||
const {
|
||||
|
||||
@@ -65,8 +65,8 @@ vi.mock('@/platform/telemetry', () => ({
|
||||
useTelemetry: vi.fn(() => mockTelemetry)
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: vi.fn(() => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: vi.fn(() => ({
|
||||
reportError: mockReportError,
|
||||
accessBillingPortal: mockAccessBillingPortal
|
||||
}))
|
||||
@@ -106,14 +106,14 @@ vi.mock('@/services/dialogService', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
getAuthHeader: mockGetAuthHeader,
|
||||
get userId() {
|
||||
return mockUserId.value
|
||||
}
|
||||
})),
|
||||
FirebaseAuthStoreError: class extends Error {}
|
||||
AuthStoreError: class extends Error {}
|
||||
}))
|
||||
|
||||
// Mock fetch
|
||||
|
||||
@@ -2,7 +2,7 @@ import { computed, ref, watch } from 'vue'
|
||||
import { createSharedComposable } from '@vueuse/core'
|
||||
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { getComfyApiBaseUrl, getComfyPlatformBaseUrl } from '@/config/comfyApi'
|
||||
import { t } from '@/i18n'
|
||||
@@ -10,10 +10,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import type { SubscriptionDialogReason } from '@/platform/cloud/subscription/composables/useSubscriptionDialog'
|
||||
import type { CheckoutAttributionMetadata } from '@/platform/telemetry/types'
|
||||
import {
|
||||
FirebaseAuthStoreError,
|
||||
useFirebaseAuthStore
|
||||
} from '@/stores/firebaseAuthStore'
|
||||
import { AuthStoreError, useAuthStore } from '@/stores/authStore'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { TIER_TO_KEY } from '@/platform/cloud/subscription/constants/tierPricing'
|
||||
import type { operations } from '@/types/comfyRegistryTypes'
|
||||
@@ -37,10 +34,10 @@ function useSubscriptionInternal() {
|
||||
|
||||
return subscriptionStatus.value?.is_active ?? false
|
||||
})
|
||||
const { reportError, accessBillingPortal } = useFirebaseAuthActions()
|
||||
const { reportError, accessBillingPortal } = useAuthActions()
|
||||
const { showSubscriptionRequiredDialog } = useDialogService()
|
||||
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
const { getAuthHeader } = firebaseAuthStore
|
||||
const { wrapWithErrorHandlingAsync } = useErrorHandling()
|
||||
|
||||
@@ -194,7 +191,7 @@ function useSubscriptionInternal() {
|
||||
async function fetchSubscriptionStatus(): Promise<CloudSubscriptionStatusResponse | null> {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
@@ -209,7 +206,7 @@ function useSubscriptionInternal() {
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToFetchSubscription', {
|
||||
error: errorData.message
|
||||
})
|
||||
@@ -248,9 +245,7 @@ function useSubscriptionInternal() {
|
||||
async (): Promise<CloudSubscriptionCheckoutResponse> => {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(
|
||||
t('toastMessages.userNotAuthenticated')
|
||||
)
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
const checkoutAttribution = await getCheckoutAttributionForCloud()
|
||||
|
||||
@@ -268,7 +263,7 @@ function useSubscriptionInternal() {
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToInitiateSubscription', {
|
||||
error: errorData.message
|
||||
})
|
||||
|
||||
@@ -8,8 +8,8 @@ const mockFetchStatus = vi.fn()
|
||||
const mockShowTopUpCreditsDialog = vi.fn()
|
||||
const mockExecute = vi.fn()
|
||||
|
||||
vi.mock('@/composables/auth/useFirebaseAuthActions', () => ({
|
||||
useFirebaseAuthActions: () => ({
|
||||
vi.mock('@/composables/auth/useAuthActions', () => ({
|
||||
useAuthActions: () => ({
|
||||
fetchBalance: mockFetchBalance
|
||||
})
|
||||
}))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
@@ -12,7 +12,7 @@ import { useCommandStore } from '@/stores/commandStore'
|
||||
*/
|
||||
export function useSubscriptionActions() {
|
||||
const dialogService = useDialogService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
const commandStore = useCommandStore()
|
||||
const telemetry = useTelemetry()
|
||||
const { fetchStatus } = useBillingContext()
|
||||
|
||||
@@ -36,14 +36,14 @@ vi.mock('@/platform/telemetry', () => ({
|
||||
useTelemetry: vi.fn(() => mockTelemetry)
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() =>
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() =>
|
||||
reactive({
|
||||
getAuthHeader: mockGetAuthHeader,
|
||||
userId: computed(() => mockUserId.value)
|
||||
})
|
||||
),
|
||||
FirebaseAuthStoreError: class extends Error {}
|
||||
AuthStoreError: class extends Error {}
|
||||
}))
|
||||
|
||||
vi.mock('@/platform/distribution/types', () => ({
|
||||
|
||||
@@ -4,10 +4,7 @@ import { getComfyApiBaseUrl } from '@/config/comfyApi'
|
||||
import { t } from '@/i18n'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import {
|
||||
FirebaseAuthStoreError,
|
||||
useFirebaseAuthStore
|
||||
} from '@/stores/firebaseAuthStore'
|
||||
import { AuthStoreError, useAuthStore } from '@/stores/authStore'
|
||||
import type { CheckoutAttributionMetadata } from '@/platform/telemetry/types'
|
||||
import type { TierKey } from '@/platform/cloud/subscription/constants/tierPricing'
|
||||
import type { BillingCycle } from './subscriptionTierRank'
|
||||
@@ -51,13 +48,13 @@ export async function performSubscriptionCheckout(
|
||||
): Promise<void> {
|
||||
if (!isCloud) return
|
||||
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
const { userId } = storeToRefs(firebaseAuthStore)
|
||||
const telemetry = useTelemetry()
|
||||
const authHeader = await firebaseAuthStore.getAuthHeader()
|
||||
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
const checkoutTier = getCheckoutTier(tierKey, currentBillingCycle)
|
||||
@@ -97,7 +94,7 @@ export async function performSubscriptionCheckout(
|
||||
}
|
||||
}
|
||||
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToInitiateSubscription', {
|
||||
error: errorMessage
|
||||
})
|
||||
|
||||
@@ -90,7 +90,7 @@ import CurrentUserMessage from '@/components/dialog/content/setting/CurrentUserM
|
||||
import BaseModalLayout from '@/components/widget/layout/BaseModalLayout.vue'
|
||||
import NavItem from '@/components/widget/nav/NavItem.vue'
|
||||
import NavTitle from '@/components/widget/nav/NavTitle.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useAuthActions } from '@/composables/auth/useAuthActions'
|
||||
import ColorPaletteMessage from '@/platform/settings/components/ColorPaletteMessage.vue'
|
||||
import SettingsPanel from '@/platform/settings/components/SettingsPanel.vue'
|
||||
import { useSettingSearch } from '@/platform/settings/composables/useSettingSearch'
|
||||
@@ -129,7 +129,7 @@ const {
|
||||
getSearchResults
|
||||
} = useSettingSearch()
|
||||
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const authActions = useAuthActions()
|
||||
|
||||
const navRef = ref<HTMLElement | null>(null)
|
||||
const activeCategoryKey = ref<string | null>(defaultCategory.value?.key ?? null)
|
||||
|
||||
@@ -6,7 +6,7 @@ type MockApiKeyUser = {
|
||||
email?: string
|
||||
} | null
|
||||
|
||||
type MockFirebaseUser = {
|
||||
type MockAuthUser = {
|
||||
uid: string
|
||||
email?: string | null
|
||||
} | null
|
||||
@@ -14,19 +14,19 @@ type MockFirebaseUser = {
|
||||
const {
|
||||
mockCaptureCheckoutAttributionFromSearch,
|
||||
mockUseApiKeyAuthStore,
|
||||
mockUseFirebaseAuthStore,
|
||||
mockUseAuthStore,
|
||||
mockApiKeyAuthStore,
|
||||
mockFirebaseAuthStore
|
||||
mockAuthStore
|
||||
} = vi.hoisted(() => ({
|
||||
mockCaptureCheckoutAttributionFromSearch: vi.fn(),
|
||||
mockUseApiKeyAuthStore: vi.fn(),
|
||||
mockUseFirebaseAuthStore: vi.fn(),
|
||||
mockUseAuthStore: vi.fn(),
|
||||
mockApiKeyAuthStore: {
|
||||
isAuthenticated: false,
|
||||
currentUser: null as MockApiKeyUser
|
||||
},
|
||||
mockFirebaseAuthStore: {
|
||||
currentUser: null as MockFirebaseUser
|
||||
mockAuthStore: {
|
||||
currentUser: null as MockAuthUser
|
||||
}
|
||||
}))
|
||||
|
||||
@@ -38,8 +38,8 @@ vi.mock('@/stores/apiKeyAuthStore', () => ({
|
||||
useApiKeyAuthStore: mockUseApiKeyAuthStore
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: mockUseFirebaseAuthStore
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: mockUseAuthStore
|
||||
}))
|
||||
|
||||
import { ImpactTelemetryProvider } from './ImpactTelemetryProvider'
|
||||
@@ -64,14 +64,14 @@ describe('ImpactTelemetryProvider', () => {
|
||||
beforeEach(() => {
|
||||
mockCaptureCheckoutAttributionFromSearch.mockReset()
|
||||
mockUseApiKeyAuthStore.mockReset()
|
||||
mockUseFirebaseAuthStore.mockReset()
|
||||
mockUseAuthStore.mockReset()
|
||||
mockApiKeyAuthStore.isAuthenticated = false
|
||||
mockApiKeyAuthStore.currentUser = null
|
||||
mockFirebaseAuthStore.currentUser = null
|
||||
mockAuthStore.currentUser = null
|
||||
vi.restoreAllMocks()
|
||||
vi.unstubAllGlobals()
|
||||
mockUseApiKeyAuthStore.mockReturnValue(mockApiKeyAuthStore)
|
||||
mockUseFirebaseAuthStore.mockReturnValue(mockFirebaseAuthStore)
|
||||
mockUseAuthStore.mockReturnValue(mockAuthStore)
|
||||
|
||||
const queueFn: NonNullable<Window['ire']> = (...args: unknown[]) => {
|
||||
;(queueFn.a ??= []).push(args)
|
||||
@@ -93,7 +93,7 @@ describe('ImpactTelemetryProvider', () => {
|
||||
})
|
||||
|
||||
it('captures attribution and invokes identify with hashed email', async () => {
|
||||
mockFirebaseAuthStore.currentUser = {
|
||||
mockAuthStore.currentUser = {
|
||||
uid: 'user-123',
|
||||
email: ' User@Example.com '
|
||||
}
|
||||
@@ -153,7 +153,7 @@ describe('ImpactTelemetryProvider', () => {
|
||||
})
|
||||
|
||||
it('invokes identify on each page view even with identical identity payloads', async () => {
|
||||
mockFirebaseAuthStore.currentUser = {
|
||||
mockAuthStore.currentUser = {
|
||||
uid: 'user-123',
|
||||
email: 'user@example.com'
|
||||
}
|
||||
@@ -189,7 +189,7 @@ describe('ImpactTelemetryProvider', () => {
|
||||
id: 'api-key-user-123',
|
||||
email: 'apikey@example.com'
|
||||
}
|
||||
mockFirebaseAuthStore.currentUser = {
|
||||
mockAuthStore.currentUser = {
|
||||
uid: 'firebase-user-123',
|
||||
email: 'firebase@example.com'
|
||||
}
|
||||
@@ -228,7 +228,7 @@ describe('ImpactTelemetryProvider', () => {
|
||||
id: 'api-key-user-123',
|
||||
email: 'apikey@example.com'
|
||||
}
|
||||
mockFirebaseAuthStore.currentUser = null
|
||||
mockAuthStore.currentUser = null
|
||||
vi.stubGlobal('crypto', {
|
||||
subtle: {
|
||||
digest: vi.fn(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { captureCheckoutAttributionFromSearch } from '@/platform/telemetry/utils/checkoutAttribution'
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
import type { PageViewMetadata, TelemetryProvider } from '../../types'
|
||||
|
||||
@@ -17,7 +17,7 @@ export class ImpactTelemetryProvider implements TelemetryProvider {
|
||||
private initialized = false
|
||||
private stores: {
|
||||
apiKeyAuthStore: ReturnType<typeof useApiKeyAuthStore>
|
||||
firebaseAuthStore: ReturnType<typeof useFirebaseAuthStore>
|
||||
firebaseAuthStore: ReturnType<typeof useAuthStore>
|
||||
} | null = null
|
||||
|
||||
constructor() {
|
||||
@@ -135,7 +135,7 @@ export class ImpactTelemetryProvider implements TelemetryProvider {
|
||||
|
||||
private resolveAuthStores(): {
|
||||
apiKeyAuthStore: ReturnType<typeof useApiKeyAuthStore>
|
||||
firebaseAuthStore: ReturnType<typeof useFirebaseAuthStore>
|
||||
firebaseAuthStore: ReturnType<typeof useAuthStore>
|
||||
} | null {
|
||||
if (this.stores) {
|
||||
return this.stores
|
||||
@@ -144,7 +144,7 @@ export class ImpactTelemetryProvider implements TelemetryProvider {
|
||||
try {
|
||||
const stores = {
|
||||
apiKeyAuthStore: useApiKeyAuthStore(),
|
||||
firebaseAuthStore: useFirebaseAuthStore()
|
||||
firebaseAuthStore: useAuthStore()
|
||||
}
|
||||
this.stores = stores
|
||||
return stores
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { t } from '@/i18n'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
export type WorkspaceType = 'personal' | 'team'
|
||||
export type WorkspaceRole = 'owner' | 'member'
|
||||
@@ -288,27 +287,11 @@ const workspaceApiClient = axios.create({
|
||||
})
|
||||
|
||||
async function getAuthHeaderOrThrow() {
|
||||
const authHeader = await useFirebaseAuthStore().getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new WorkspaceApiError(
|
||||
t('toastMessages.userNotAuthenticated'),
|
||||
401,
|
||||
'NOT_AUTHENTICATED'
|
||||
)
|
||||
}
|
||||
return authHeader
|
||||
return useAuthStore().getAuthHeaderOrThrow()
|
||||
}
|
||||
|
||||
async function getFirebaseHeaderOrThrow() {
|
||||
const authHeader = await useFirebaseAuthStore().getFirebaseAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new WorkspaceApiError(
|
||||
t('toastMessages.userNotAuthenticated'),
|
||||
401,
|
||||
'NOT_AUTHENTICATED'
|
||||
)
|
||||
}
|
||||
return authHeader
|
||||
return useAuthStore().getFirebaseAuthHeaderOrThrow()
|
||||
}
|
||||
|
||||
function handleAxiosError(err: unknown): never {
|
||||
|
||||
@@ -8,8 +8,8 @@ import WorkspaceAuthGate from './WorkspaceAuthGate.vue'
|
||||
const mockIsInitialized = ref(false)
|
||||
const mockCurrentUser = ref<object | null>(null)
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: () => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: () => ({
|
||||
isInitialized: mockIsInitialized,
|
||||
currentUser: mockCurrentUser
|
||||
})
|
||||
|
||||
@@ -27,7 +27,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSubscriptionDialog } from '@/platform/cloud/subscription/composables/useSubscriptionDialog'
|
||||
import { refreshRemoteConfig } from '@/platform/remoteConfig/refreshRemoteConfig'
|
||||
import { useTeamWorkspaceStore } from '@/platform/workspace/stores/teamWorkspaceStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const FIREBASE_INIT_TIMEOUT_MS = 16_000
|
||||
const CONFIG_REFRESH_TIMEOUT_MS = 10_000
|
||||
@@ -38,7 +38,7 @@ const subscriptionDialog = useSubscriptionDialog()
|
||||
async function initialize(): Promise<void> {
|
||||
if (!isCloud) return
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const { isInitialized, currentUser } = storeToRefs(authStore)
|
||||
|
||||
try {
|
||||
|
||||
@@ -10,8 +10,8 @@ import { WORKSPACE_STORAGE_KEYS } from '@/platform/workspace/workspaceConstants'
|
||||
|
||||
const mockGetIdToken = vi.fn()
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: () => ({
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: () => ({
|
||||
getIdToken: mockGetIdToken
|
||||
})
|
||||
}))
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
WORKSPACE_STORAGE_KEYS
|
||||
} from '@/platform/workspace/workspaceConstants'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { AuthHeader } from '@/types/authTypes'
|
||||
import type { WorkspaceWithRole } from '@/platform/workspace/workspaceTypes'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
@@ -181,7 +181,7 @@ export const useWorkspaceAuthStore = defineStore('workspaceAuth', () => {
|
||||
error.value = null
|
||||
|
||||
try {
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
const firebaseToken = await firebaseAuthStore.getIdToken()
|
||||
if (!firebaseToken) {
|
||||
throw new WorkspaceAuthError(
|
||||
@@ -343,6 +343,10 @@ export const useWorkspaceAuthStore = defineStore('workspaceAuth', () => {
|
||||
}
|
||||
}
|
||||
|
||||
function getWorkspaceToken(): string | undefined {
|
||||
return workspaceToken.value ?? undefined
|
||||
}
|
||||
|
||||
function clearWorkspaceContext(): void {
|
||||
// Increment request ID to invalidate any in-flight stale refresh operations
|
||||
refreshRequestId++
|
||||
@@ -370,6 +374,7 @@ export const useWorkspaceAuthStore = defineStore('workspaceAuth', () => {
|
||||
switchWorkspace,
|
||||
refreshToken,
|
||||
getWorkspaceAuthHeader,
|
||||
getWorkspaceToken,
|
||||
clearWorkspaceContext
|
||||
}
|
||||
})
|
||||
|
||||
@@ -38,9 +38,9 @@ vi.mock('@/platform/distribution/types', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', async () => {
|
||||
vi.mock('@/stores/authStore', async () => {
|
||||
return {
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
getAuthHeader: vi.fn(() => Promise.resolve(mockCloudAuth.authHeader))
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { IWidget, LGraphNode } from '@/lib/litegraph/src/litegraph'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import type { RemoteWidgetConfig } from '@/schemas/nodeDefSchema'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
|
||||
const MAX_RETRIES = 5
|
||||
const TIMEOUT = 4096
|
||||
@@ -23,7 +23,7 @@ interface CacheEntry<T> {
|
||||
|
||||
async function getAuthHeaders() {
|
||||
if (isCloud) {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const authHeader = await authStore.getAuthHeader()
|
||||
return {
|
||||
...(authHeader && { headers: authHeader })
|
||||
|
||||
@@ -11,7 +11,7 @@ import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { isCloud, isDesktop } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { useUserStore } from '@/stores/userStore'
|
||||
import LayoutDefault from '@/views/layouts/LayoutDefault.vue'
|
||||
|
||||
@@ -140,7 +140,7 @@ if (isCloud) {
|
||||
}
|
||||
// Global authentication guard
|
||||
router.beforeEach(async (to, _from, next) => {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
|
||||
// Wait for Firebase auth to initialize
|
||||
// Timeout after 16 seconds
|
||||
|
||||
@@ -60,7 +60,7 @@ import type {
|
||||
JobListItem
|
||||
} from '@/platform/remote/comfyui/jobs/jobTypes'
|
||||
import type { ComfyNodeDef } from '@/schemas/nodeDefSchema'
|
||||
import type { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import type { useAuthStore } from '@/stores/authStore'
|
||||
import type { AuthHeader } from '@/types/authTypes'
|
||||
import type { NodeExecutionId } from '@/types/nodeIdentification'
|
||||
import {
|
||||
@@ -332,7 +332,7 @@ export class ComfyApi extends EventTarget {
|
||||
/**
|
||||
* Cache Firebase auth store composable function.
|
||||
*/
|
||||
private authStoreComposable?: typeof useFirebaseAuthStore
|
||||
private authStoreComposable?: typeof useAuthStore
|
||||
|
||||
reportedUnknownMessageTypes = new Set<string>()
|
||||
|
||||
@@ -399,8 +399,8 @@ export class ComfyApi extends EventTarget {
|
||||
private async getAuthStore() {
|
||||
if (isCloud) {
|
||||
if (!this.authStoreComposable) {
|
||||
const module = await import('@/stores/firebaseAuthStore')
|
||||
this.authStoreComposable = module.useFirebaseAuthStore
|
||||
const module = await import('@/stores/authStore')
|
||||
this.authStoreComposable = module.useAuthStore
|
||||
}
|
||||
|
||||
return this.authStoreComposable()
|
||||
|
||||
@@ -67,7 +67,7 @@ import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useExecutionErrorStore } from '@/stores/executionErrorStore'
|
||||
import { useMissingNodesErrorStore } from '@/platform/nodeReplacement/missingNodesErrorStore'
|
||||
import { useExtensionStore } from '@/stores/extensionStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { useNodeOutputStore } from '@/stores/nodeOutputStore'
|
||||
import { useJobPreviewStore } from '@/stores/jobPreviewStore'
|
||||
import { KeyComboImpl } from '@/platform/keybindings/keyCombo'
|
||||
@@ -1591,7 +1591,7 @@ export class ComfyApp {
|
||||
executionErrorStore.clearAllErrors()
|
||||
|
||||
// Get auth token for backend nodes - uses workspace token if enabled, otherwise Firebase token
|
||||
const comfyOrgAuthToken = await useFirebaseAuthStore().getAuthToken()
|
||||
const comfyOrgAuthToken = await useAuthStore().getAuthToken()
|
||||
const comfyOrgApiKey = useApiKeyAuthStore().getApiKey()
|
||||
|
||||
try {
|
||||
|
||||
@@ -11,7 +11,7 @@ const mockAxiosInstance = vi.hoisted(() => ({
|
||||
get: vi.fn()
|
||||
}))
|
||||
|
||||
const mockFirebaseAuthStore = vi.hoisted(() => ({
|
||||
const mockAuthStore = vi.hoisted(() => ({
|
||||
getAuthHeader: vi.fn()
|
||||
}))
|
||||
|
||||
@@ -27,8 +27,8 @@ vi.mock('axios', () => ({
|
||||
}
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => mockFirebaseAuthStore)
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => mockAuthStore)
|
||||
}))
|
||||
|
||||
vi.mock('@/i18n', () => ({
|
||||
@@ -81,7 +81,7 @@ describe('useCustomerEventsService', () => {
|
||||
vi.clearAllMocks()
|
||||
|
||||
// Setup default mocks
|
||||
mockFirebaseAuthStore.getAuthHeader.mockResolvedValue(mockAuthHeaders)
|
||||
mockAuthStore.getAuthHeader.mockResolvedValue(mockAuthHeaders)
|
||||
mockI18n.d.mockImplementation((date, options) => {
|
||||
// Mock i18n date formatting
|
||||
if (options?.month === 'short') {
|
||||
@@ -118,7 +118,7 @@ describe('useCustomerEventsService', () => {
|
||||
limit: 10
|
||||
})
|
||||
|
||||
expect(mockFirebaseAuthStore.getAuthHeader).toHaveBeenCalled()
|
||||
expect(mockAuthStore.getAuthHeader).toHaveBeenCalled()
|
||||
expect(mockAxiosInstance.get).toHaveBeenCalledWith('/customers/events', {
|
||||
params: { page: 1, limit: 10 },
|
||||
headers: mockAuthHeaders
|
||||
@@ -141,7 +141,7 @@ describe('useCustomerEventsService', () => {
|
||||
})
|
||||
|
||||
it('should return null when auth headers are missing', async () => {
|
||||
mockFirebaseAuthStore.getAuthHeader.mockResolvedValue(null)
|
||||
mockAuthStore.getAuthHeader.mockResolvedValue(null)
|
||||
|
||||
const result = await service.getMyEvents()
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import { ref, watch } from 'vue'
|
||||
|
||||
import { getComfyApiBaseUrl } from '@/config/comfyApi'
|
||||
import { d } from '@/i18n'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { components, operations } from '@/types/comfyRegistryTypes'
|
||||
import { isAbortError } from '@/utils/typeGuardUtil'
|
||||
|
||||
@@ -179,7 +179,7 @@ export const useCustomerEventsService = () => {
|
||||
}
|
||||
|
||||
// Get auth headers
|
||||
const authHeaders = await useFirebaseAuthStore().getAuthHeader()
|
||||
const authHeaders = await useAuthStore().getAuthHeader()
|
||||
if (!authHeaders) {
|
||||
error.value = 'Authentication header is missing'
|
||||
return null
|
||||
|
||||
42
src/stores/__tests__/authStoreMock.test.ts
Normal file
42
src/stores/__tests__/authStoreMock.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, expect, it } from 'vitest'
|
||||
|
||||
import { createAuthStoreMock, mockAuthStoreModule } from './authStoreMock'
|
||||
|
||||
describe('authStoreMock', () => {
|
||||
it('creates a mock with reactive computed properties', () => {
|
||||
const { mock, controls } = createAuthStoreMock()
|
||||
|
||||
expect(mock.isAuthenticated).toBe(false)
|
||||
expect(mock.userEmail).toBeNull()
|
||||
expect(mock.userId).toBeNull()
|
||||
|
||||
controls.currentUser.value = { uid: 'u1', email: 'a@b.com' }
|
||||
|
||||
expect(mock.isAuthenticated).toBe(true)
|
||||
expect(mock.userEmail).toBe('a@b.com')
|
||||
expect(mock.userId).toBe('u1')
|
||||
})
|
||||
|
||||
it('starts with clean defaults', () => {
|
||||
const { controls } = createAuthStoreMock()
|
||||
expect(controls.currentUser.value).toBeNull()
|
||||
expect(controls.isInitialized.value).toBe(false)
|
||||
expect(controls.loading.value).toBe(false)
|
||||
expect(controls.balance.value).toBeNull()
|
||||
expect(controls.isFetchingBalance.value).toBe(false)
|
||||
})
|
||||
|
||||
it('creates independent instances per call', () => {
|
||||
const a = createAuthStoreMock()
|
||||
const b = createAuthStoreMock()
|
||||
a.controls.currentUser.value = { uid: 'a' }
|
||||
expect(b.mock.isAuthenticated).toBe(false)
|
||||
})
|
||||
|
||||
it('mockAuthStoreModule wraps mock correctly', () => {
|
||||
const { mock } = createAuthStoreMock()
|
||||
const module = mockAuthStoreModule(mock)
|
||||
expect(module.useAuthStore()).toBe(mock)
|
||||
expect(new module.AuthStoreError('test').name).toBe('AuthStoreError')
|
||||
})
|
||||
})
|
||||
110
src/stores/__tests__/authStoreMock.ts
Normal file
110
src/stores/__tests__/authStoreMock.ts
Normal file
@@ -0,0 +1,110 @@
|
||||
import type { Mock } from 'vitest'
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
/**
|
||||
* Shared mock factory for useAuthStore.
|
||||
*
|
||||
* Usage in test files:
|
||||
* import { createAuthStoreMock, mockAuthStoreModule } from '@/stores/__tests__/authStoreMock'
|
||||
*
|
||||
* const { mock, controls } = createAuthStoreMock()
|
||||
* vi.mock('@/stores/authStore', () => mockAuthStoreModule(mock))
|
||||
*
|
||||
* // Per-test customization:
|
||||
* controls.currentUser.value = { uid: 'test-123', email: 'a@b.com' }
|
||||
* controls.getAuthHeader.mockResolvedValue({ Authorization: 'Bearer tok' })
|
||||
*/
|
||||
|
||||
export interface AuthStoreMockControls {
|
||||
currentUser: ReturnType<typeof ref<Record<string, unknown> | null>>
|
||||
isInitialized: ReturnType<typeof ref<boolean>>
|
||||
loading: ReturnType<typeof ref<boolean>>
|
||||
balance: ReturnType<typeof ref<Record<string, unknown> | null>>
|
||||
isFetchingBalance: ReturnType<typeof ref<boolean>>
|
||||
tokenRefreshTrigger: ReturnType<typeof ref<number>>
|
||||
|
||||
login: Mock
|
||||
register: Mock
|
||||
logout: Mock
|
||||
getIdToken: Mock
|
||||
getAuthHeader: Mock
|
||||
getAuthHeaderOrThrow: Mock
|
||||
getFirebaseAuthHeader: Mock
|
||||
getFirebaseAuthHeaderOrThrow: Mock
|
||||
getAuthToken: Mock
|
||||
createCustomer: Mock
|
||||
fetchBalance: Mock
|
||||
accessBillingPortal: Mock
|
||||
loginWithGoogle: Mock
|
||||
loginWithGithub: Mock
|
||||
sendPasswordReset: Mock
|
||||
updatePassword: Mock
|
||||
initiateCreditPurchase: Mock
|
||||
}
|
||||
|
||||
export function createAuthStoreMock(): {
|
||||
mock: Record<string, unknown>
|
||||
controls: AuthStoreMockControls
|
||||
} {
|
||||
const currentUser = ref<Record<string, unknown> | null>(null)
|
||||
const isInitialized = ref(false)
|
||||
const loading = ref(false)
|
||||
const balance = ref<Record<string, unknown> | null>(null)
|
||||
const isFetchingBalance = ref(false)
|
||||
const tokenRefreshTrigger = ref(0)
|
||||
|
||||
const controls: AuthStoreMockControls = {
|
||||
currentUser,
|
||||
isInitialized,
|
||||
loading,
|
||||
balance,
|
||||
isFetchingBalance,
|
||||
tokenRefreshTrigger,
|
||||
login: vi.fn(),
|
||||
register: vi.fn(),
|
||||
logout: vi.fn(),
|
||||
getIdToken: vi.fn().mockResolvedValue('mock-id-token'),
|
||||
getAuthHeader: vi.fn().mockResolvedValue(null),
|
||||
getAuthHeaderOrThrow: vi.fn().mockResolvedValue({
|
||||
Authorization: 'Bearer mock-id-token'
|
||||
}),
|
||||
getFirebaseAuthHeader: vi.fn().mockResolvedValue(null),
|
||||
getFirebaseAuthHeaderOrThrow: vi.fn().mockResolvedValue({
|
||||
Authorization: 'Bearer mock-id-token'
|
||||
}),
|
||||
getAuthToken: vi.fn().mockResolvedValue(undefined),
|
||||
createCustomer: vi.fn(),
|
||||
fetchBalance: vi.fn(),
|
||||
accessBillingPortal: vi.fn(),
|
||||
loginWithGoogle: vi.fn(),
|
||||
loginWithGithub: vi.fn(),
|
||||
sendPasswordReset: vi.fn(),
|
||||
updatePassword: vi.fn(),
|
||||
initiateCreditPurchase: vi.fn()
|
||||
}
|
||||
|
||||
const mock = reactive({
|
||||
...controls,
|
||||
isAuthenticated: computed(() => !!currentUser.value),
|
||||
userEmail: computed(
|
||||
() => (currentUser.value as Record<string, unknown> | null)?.email ?? null
|
||||
),
|
||||
userId: computed(
|
||||
() => (currentUser.value as Record<string, unknown> | null)?.uid ?? null
|
||||
)
|
||||
})
|
||||
|
||||
return { mock, controls }
|
||||
}
|
||||
|
||||
export function mockAuthStoreModule(mock: Record<string, unknown>) {
|
||||
return {
|
||||
useAuthStore: () => mock,
|
||||
AuthStoreError: class extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
this.name = 'AuthStoreError'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
211
src/stores/__tests__/authTokenPriority.test.ts
Normal file
211
src/stores/__tests__/authTokenPriority.test.ts
Normal file
@@ -0,0 +1,211 @@
|
||||
import type { User } from 'firebase/auth'
|
||||
import * as firebaseAuth from 'firebase/auth'
|
||||
import { setActivePinia } from 'pinia'
|
||||
import type { Mock } from 'vitest'
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import * as vuefire from 'vuefire'
|
||||
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
|
||||
const { mockFeatureFlags } = vi.hoisted(() => ({
|
||||
mockFeatureFlags: {
|
||||
teamWorkspacesEnabled: false
|
||||
}
|
||||
}))
|
||||
|
||||
const { mockDistributionTypes } = vi.hoisted(() => ({
|
||||
mockDistributionTypes: {
|
||||
isCloud: true,
|
||||
isDesktop: true
|
||||
}
|
||||
}))
|
||||
|
||||
const mockWorkspaceAuthHeader = vi.fn().mockReturnValue(null)
|
||||
const mockGetWorkspaceToken = vi.fn().mockReturnValue(undefined)
|
||||
const mockClearWorkspaceContext = vi.fn()
|
||||
|
||||
vi.mock('@/platform/workspace/stores/workspaceAuthStore', () => ({
|
||||
useWorkspaceAuthStore: () => ({
|
||||
getWorkspaceAuthHeader: mockWorkspaceAuthHeader,
|
||||
getWorkspaceToken: mockGetWorkspaceToken,
|
||||
clearWorkspaceContext: mockClearWorkspaceContext
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('@/composables/useFeatureFlags', () => ({
|
||||
useFeatureFlags: () => ({
|
||||
flags: mockFeatureFlags
|
||||
})
|
||||
}))
|
||||
|
||||
vi.mock('vuefire', () => ({
|
||||
useFirebaseAuth: vi.fn()
|
||||
}))
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: () => ({ t: (key: string) => key }),
|
||||
createI18n: () => ({ global: { t: (key: string) => key } })
|
||||
}))
|
||||
|
||||
vi.mock('firebase/auth', async (importOriginal) => {
|
||||
const actual = await importOriginal<typeof firebaseAuth>()
|
||||
return {
|
||||
...actual,
|
||||
signInWithEmailAndPassword: vi.fn(),
|
||||
createUserWithEmailAndPassword: vi.fn(),
|
||||
signOut: vi.fn(),
|
||||
onAuthStateChanged: vi.fn(),
|
||||
onIdTokenChanged: vi.fn(),
|
||||
signInWithPopup: vi.fn(),
|
||||
GoogleAuthProvider: class {
|
||||
addScope = vi.fn()
|
||||
setCustomParameters = vi.fn()
|
||||
},
|
||||
GithubAuthProvider: class {
|
||||
addScope = vi.fn()
|
||||
setCustomParameters = vi.fn()
|
||||
},
|
||||
getAdditionalUserInfo: vi.fn(),
|
||||
setPersistence: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
})
|
||||
|
||||
vi.mock('@/platform/telemetry', () => ({
|
||||
useTelemetry: () => ({ trackAuth: vi.fn() })
|
||||
}))
|
||||
|
||||
vi.mock('@/stores/toastStore', () => ({
|
||||
useToastStore: () => ({ add: vi.fn() })
|
||||
}))
|
||||
|
||||
vi.mock('@/services/dialogService')
|
||||
vi.mock('@/platform/distribution/types', () => mockDistributionTypes)
|
||||
|
||||
const mockApiKeyGetAuthHeader = vi.fn().mockReturnValue(null)
|
||||
vi.mock('@/stores/apiKeyAuthStore', () => ({
|
||||
useApiKeyAuthStore: () => ({
|
||||
getAuthHeader: mockApiKeyGetAuthHeader,
|
||||
getApiKey: vi.fn(),
|
||||
currentUser: null,
|
||||
isAuthenticated: false,
|
||||
storeApiKey: vi.fn(),
|
||||
clearStoredApiKey: vi.fn()
|
||||
})
|
||||
}))
|
||||
|
||||
type MockUser = Omit<User, 'getIdToken'> & { getIdToken: Mock }
|
||||
|
||||
describe('auth token priority chain', () => {
|
||||
let store: ReturnType<typeof useAuthStore>
|
||||
let authStateCallback: (user: User | null) => void
|
||||
|
||||
const mockAuth: Record<string, unknown> = {}
|
||||
|
||||
const mockUser: MockUser = {
|
||||
uid: 'test-user-id',
|
||||
email: 'test@example.com',
|
||||
getIdToken: vi.fn().mockResolvedValue('firebase-token')
|
||||
} as Partial<User> as MockUser
|
||||
|
||||
beforeEach(() => {
|
||||
vi.resetAllMocks()
|
||||
|
||||
mockFeatureFlags.teamWorkspacesEnabled = false
|
||||
mockWorkspaceAuthHeader.mockReturnValue(null)
|
||||
mockGetWorkspaceToken.mockReturnValue(undefined)
|
||||
mockApiKeyGetAuthHeader.mockReturnValue(null)
|
||||
mockUser.getIdToken.mockResolvedValue('firebase-token')
|
||||
|
||||
vi.mocked(vuefire.useFirebaseAuth).mockReturnValue(
|
||||
mockAuth as unknown as ReturnType<typeof vuefire.useFirebaseAuth>
|
||||
)
|
||||
|
||||
vi.mocked(firebaseAuth.onAuthStateChanged).mockImplementation(
|
||||
(_, callback) => {
|
||||
authStateCallback = callback as (user: User | null) => void
|
||||
;(callback as (user: User | null) => void)(mockUser)
|
||||
return vi.fn()
|
||||
}
|
||||
)
|
||||
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
store = useAuthStore()
|
||||
})
|
||||
|
||||
describe('getAuthHeader priority', () => {
|
||||
it('returns workspace auth header when workspace is active and feature enabled', async () => {
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockWorkspaceAuthHeader.mockReturnValue({
|
||||
Authorization: 'Bearer workspace-token'
|
||||
})
|
||||
|
||||
const header = await store.getAuthHeader()
|
||||
|
||||
expect(header).toEqual({
|
||||
Authorization: 'Bearer workspace-token'
|
||||
})
|
||||
})
|
||||
|
||||
it('returns Firebase token when workspace is not active but user is authenticated', async () => {
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockWorkspaceAuthHeader.mockReturnValue(null)
|
||||
|
||||
const header = await store.getAuthHeader()
|
||||
|
||||
expect(header).toEqual({
|
||||
Authorization: 'Bearer firebase-token'
|
||||
})
|
||||
})
|
||||
|
||||
it('returns API key when neither workspace nor Firebase are available', async () => {
|
||||
authStateCallback(null)
|
||||
mockApiKeyGetAuthHeader.mockReturnValue({ 'X-API-KEY': 'test-key' })
|
||||
|
||||
const header = await store.getAuthHeader()
|
||||
|
||||
expect(header).toEqual({ 'X-API-KEY': 'test-key' })
|
||||
})
|
||||
|
||||
it('returns null when no auth method is available', async () => {
|
||||
authStateCallback(null)
|
||||
|
||||
const header = await store.getAuthHeader()
|
||||
|
||||
expect(header).toBeNull()
|
||||
})
|
||||
|
||||
it('skips workspace header when team_workspaces feature is disabled', async () => {
|
||||
mockFeatureFlags.teamWorkspacesEnabled = false
|
||||
mockWorkspaceAuthHeader.mockReturnValue({
|
||||
Authorization: 'Bearer workspace-token'
|
||||
})
|
||||
|
||||
const header = await store.getAuthHeader()
|
||||
|
||||
expect(header).toEqual({
|
||||
Authorization: 'Bearer firebase-token'
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAuthToken priority', () => {
|
||||
it('returns workspace token when workspace is active and feature enabled', async () => {
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockGetWorkspaceToken.mockReturnValue('workspace-raw-token')
|
||||
|
||||
const token = await store.getAuthToken()
|
||||
|
||||
expect(token).toBe('workspace-raw-token')
|
||||
})
|
||||
|
||||
it('returns Firebase token when workspace token is not available', async () => {
|
||||
mockFeatureFlags.teamWorkspacesEnabled = true
|
||||
mockGetWorkspaceToken.mockReturnValue(undefined)
|
||||
|
||||
const token = await store.getAuthToken()
|
||||
|
||||
expect(token).toBe('firebase-token')
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -5,7 +5,7 @@ import { computed, ref, watch } from 'vue'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { t } from '@/i18n'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import type { ApiKeyAuthHeader } from '@/types/authTypes'
|
||||
import type { operations } from '@/types/comfyRegistryTypes'
|
||||
|
||||
@@ -15,7 +15,7 @@ type ComfyApiUser =
|
||||
const STORAGE_KEY = 'comfy_api_key'
|
||||
|
||||
export const useApiKeyAuthStore = defineStore('apiKeyAuth', () => {
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
const apiKey = useLocalStorage<string | null>(STORAGE_KEY, null)
|
||||
const toastStore = useToastStore()
|
||||
const { wrapWithErrorHandlingAsync, toastErrorHandler } = useErrorHandling()
|
||||
|
||||
@@ -7,7 +7,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||
import * as vuefire from 'vuefire'
|
||||
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { createTestingPinia } from '@pinia/testing'
|
||||
|
||||
// Hoisted mocks for dynamic imports
|
||||
@@ -122,8 +122,8 @@ vi.mock('@/stores/apiKeyAuthStore', () => ({
|
||||
})
|
||||
}))
|
||||
|
||||
describe('useFirebaseAuthStore', () => {
|
||||
let store: ReturnType<typeof useFirebaseAuthStore>
|
||||
describe('useAuthStore', () => {
|
||||
let store: ReturnType<typeof useAuthStore>
|
||||
let authStateCallback: (user: User | null) => void
|
||||
let idTokenCallback: (user: User | null) => void
|
||||
|
||||
@@ -182,7 +182,7 @@ describe('useFirebaseAuthStore', () => {
|
||||
|
||||
// Initialize Pinia
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
store = useFirebaseAuthStore()
|
||||
store = useAuthStore()
|
||||
|
||||
// Reset and set up getIdToken mock
|
||||
mockUser.getIdToken.mockReset()
|
||||
@@ -210,8 +210,8 @@ describe('useFirebaseAuthStore', () => {
|
||||
)
|
||||
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
const storeModule = await import('@/stores/firebaseAuthStore')
|
||||
store = storeModule.useFirebaseAuthStore()
|
||||
const storeModule = await import('@/stores/authStore')
|
||||
store = storeModule.useAuthStore()
|
||||
})
|
||||
|
||||
it("should not increment tokenRefreshTrigger on the user's first ID token event", () => {
|
||||
@@ -730,6 +730,37 @@ describe('useFirebaseAuthStore', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('getAuthHeaderOrThrow', () => {
|
||||
it('returns auth header when authenticated', async () => {
|
||||
const header = await store.getAuthHeaderOrThrow()
|
||||
expect(header).toEqual({ Authorization: 'Bearer mock-id-token' })
|
||||
})
|
||||
|
||||
it('throws AuthStoreError when not authenticated', async () => {
|
||||
authStateCallback(null)
|
||||
mockApiKeyGetAuthHeader.mockReturnValue(null)
|
||||
|
||||
await expect(store.getAuthHeaderOrThrow()).rejects.toThrow(
|
||||
'toastMessages.userNotAuthenticated'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getFirebaseAuthHeaderOrThrow', () => {
|
||||
it('returns Firebase auth header when authenticated', async () => {
|
||||
const header = await store.getFirebaseAuthHeaderOrThrow()
|
||||
expect(header).toEqual({ Authorization: 'Bearer mock-id-token' })
|
||||
})
|
||||
|
||||
it('throws AuthStoreError when not authenticated', async () => {
|
||||
authStateCallback(null)
|
||||
|
||||
await expect(store.getFirebaseAuthHeaderOrThrow()).rejects.toThrow(
|
||||
'toastMessages.userNotAuthenticated'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('createCustomer', () => {
|
||||
it('should succeed with API key auth when no Firebase user is present', async () => {
|
||||
authStateCallback(null)
|
||||
@@ -22,10 +22,10 @@ import { useFirebaseAuth } from 'vuefire'
|
||||
|
||||
import { getComfyApiBaseUrl } from '@/config/comfyApi'
|
||||
import { t } from '@/i18n'
|
||||
import { WORKSPACE_STORAGE_KEYS } from '@/platform/workspace/workspaceConstants'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useWorkspaceAuthStore } from '@/platform/workspace/stores/workspaceAuthStore'
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import type { AuthHeader } from '@/types/authTypes'
|
||||
import type { operations } from '@/types/comfyRegistryTypes'
|
||||
@@ -49,14 +49,14 @@ export type BillingPortalTargetTier = NonNullable<
|
||||
>['application/json']
|
||||
>['target_tier']
|
||||
|
||||
export class FirebaseAuthStoreError extends Error {
|
||||
export class AuthStoreError extends Error {
|
||||
constructor(message: string) {
|
||||
super(message)
|
||||
this.name = 'FirebaseAuthStoreError'
|
||||
this.name = 'AuthStoreError'
|
||||
}
|
||||
}
|
||||
|
||||
export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
export const useAuthStore = defineStore('auth', () => {
|
||||
const { flags } = useFeatureFlags()
|
||||
|
||||
// State
|
||||
@@ -110,15 +110,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
isInitialized.value = true
|
||||
if (user === null) {
|
||||
lastTokenUserId.value = null
|
||||
|
||||
// Clear workspace sessionStorage on logout to prevent stale tokens
|
||||
try {
|
||||
sessionStorage.removeItem(WORKSPACE_STORAGE_KEYS.CURRENT_WORKSPACE)
|
||||
sessionStorage.removeItem(WORKSPACE_STORAGE_KEYS.TOKEN)
|
||||
sessionStorage.removeItem(WORKSPACE_STORAGE_KEYS.EXPIRES_AT)
|
||||
} catch {
|
||||
// Ignore sessionStorage errors (e.g., in private browsing mode)
|
||||
}
|
||||
useWorkspaceAuthStore().clearWorkspaceContext()
|
||||
}
|
||||
|
||||
// Reset balance when auth state changes
|
||||
@@ -175,21 +167,8 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
*/
|
||||
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 wsHeader = useWorkspaceAuthStore().getWorkspaceAuthHeader()
|
||||
if (wsHeader) return wsHeader
|
||||
}
|
||||
|
||||
const token = await getIdToken()
|
||||
@@ -218,32 +197,35 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
*/
|
||||
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 wsToken = useWorkspaceAuthStore().getWorkspaceToken()
|
||||
if (wsToken) return wsToken
|
||||
}
|
||||
|
||||
return await getIdToken()
|
||||
}
|
||||
|
||||
const getAuthHeaderOrThrow = async (): Promise<AuthHeader> => {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
return authHeader
|
||||
}
|
||||
|
||||
const getFirebaseAuthHeaderOrThrow = async (): Promise<AuthHeader> => {
|
||||
const authHeader = await getFirebaseAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
return authHeader
|
||||
}
|
||||
|
||||
const fetchBalance = async (): Promise<GetCustomerBalanceResponse | null> => {
|
||||
isFetchingBalance.value = true
|
||||
try {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(
|
||||
t('toastMessages.userNotAuthenticated')
|
||||
)
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
const response = await fetch(buildApiUrl('/customers/balance'), {
|
||||
@@ -259,7 +241,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
return null
|
||||
}
|
||||
const errorData = await response.json()
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToFetchBalance', {
|
||||
error: errorData.message
|
||||
})
|
||||
@@ -279,7 +261,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
const createCustomer = async (): Promise<CreateCustomerResponse> => {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
const createCustomerRes = await fetch(buildApiUrl('/customers'), {
|
||||
@@ -290,7 +272,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
}
|
||||
})
|
||||
if (!createCustomerRes.ok) {
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToCreateCustomer', {
|
||||
error: createCustomerRes.statusText
|
||||
})
|
||||
@@ -300,7 +282,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
const createCustomerResJson: CreateCustomerResponse =
|
||||
await createCustomerRes.json()
|
||||
if (!createCustomerResJson?.id) {
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToCreateCustomer', {
|
||||
error: 'No customer ID returned'
|
||||
})
|
||||
@@ -431,7 +413,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
/** Update password for current user */
|
||||
const _updatePassword = async (newPassword: string): Promise<void> => {
|
||||
if (!currentUser.value) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
await updatePassword(currentUser.value, newPassword)
|
||||
}
|
||||
@@ -441,7 +423,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
): Promise<CreditPurchaseResponse> => {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
// Ensure customer was created during login/registration
|
||||
@@ -461,7 +443,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToInitiateCreditPurchase', {
|
||||
error: errorData.message
|
||||
})
|
||||
@@ -481,7 +463,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
): Promise<AccessBillingPortalResponse> => {
|
||||
const authHeader = await getAuthHeader()
|
||||
if (!authHeader) {
|
||||
throw new FirebaseAuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
throw new AuthStoreError(t('toastMessages.userNotAuthenticated'))
|
||||
}
|
||||
|
||||
const response = await fetch(buildApiUrl('/customers/billing'), {
|
||||
@@ -497,7 +479,7 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new FirebaseAuthStoreError(
|
||||
throw new AuthStoreError(
|
||||
t('toastMessages.failedToAccessBillingPortal', {
|
||||
error: errorData.message
|
||||
})
|
||||
@@ -536,7 +518,9 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
sendPasswordReset,
|
||||
updatePassword: _updatePassword,
|
||||
getAuthHeader,
|
||||
getAuthHeaderOrThrow,
|
||||
getFirebaseAuthHeader,
|
||||
getFirebaseAuthHeaderOrThrow,
|
||||
getAuthToken
|
||||
}
|
||||
})
|
||||
@@ -50,12 +50,12 @@ vi.mock('@/stores/userStore', () => ({
|
||||
}))
|
||||
}))
|
||||
|
||||
const mockIsFirebaseInitialized = ref(false)
|
||||
const mockIsFirebaseAuthenticated = ref(false)
|
||||
vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => ({
|
||||
isInitialized: mockIsFirebaseInitialized,
|
||||
isAuthenticated: mockIsFirebaseAuthenticated
|
||||
const mockIsAuthInitialized = ref(false)
|
||||
const mockIsAuthAuthenticated = ref(false)
|
||||
vi.mock('@/stores/authStore', () => ({
|
||||
useAuthStore: vi.fn(() => ({
|
||||
isInitialized: mockIsAuthInitialized,
|
||||
isAuthenticated: mockIsAuthAuthenticated
|
||||
}))
|
||||
}))
|
||||
|
||||
@@ -67,8 +67,8 @@ vi.mock('@/platform/distribution/types', () => mockDistributionTypes)
|
||||
describe('bootstrapStore', () => {
|
||||
beforeEach(() => {
|
||||
mockIsSettingsReady.value = false
|
||||
mockIsFirebaseInitialized.value = false
|
||||
mockIsFirebaseAuthenticated.value = false
|
||||
mockIsAuthInitialized.value = false
|
||||
mockIsAuthAuthenticated.value = false
|
||||
mockNeedsLogin.value = false
|
||||
mockDistributionTypes.isCloud = false
|
||||
setActivePinia(createTestingPinia({ stubActions: false }))
|
||||
@@ -107,14 +107,14 @@ describe('bootstrapStore', () => {
|
||||
expect(settingStore.isReady).toBe(false)
|
||||
|
||||
// Firebase initialized but user not yet authenticated
|
||||
mockIsFirebaseInitialized.value = true
|
||||
mockIsAuthInitialized.value = true
|
||||
await nextTick()
|
||||
|
||||
expect(store.isI18nReady).toBe(false)
|
||||
expect(settingStore.isReady).toBe(false)
|
||||
|
||||
// User authenticates (e.g. signs in on login page)
|
||||
mockIsFirebaseAuthenticated.value = true
|
||||
mockIsAuthAuthenticated.value = true
|
||||
await bootstrapPromise
|
||||
|
||||
await vi.waitFor(() => {
|
||||
|
||||
@@ -5,7 +5,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useWorkflowStore } from '@/platform/workflow/management/stores/workflowStore'
|
||||
import { api } from '@/scripts/api'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { useUserStore } from '@/stores/userStore'
|
||||
|
||||
export const useBootstrapStore = defineStore('bootstrap', () => {
|
||||
@@ -37,9 +37,7 @@ export const useBootstrapStore = defineStore('bootstrap', () => {
|
||||
|
||||
async function startStoreBootstrap() {
|
||||
if (isCloud) {
|
||||
const { isInitialized, isAuthenticated } = storeToRefs(
|
||||
useFirebaseAuthStore()
|
||||
)
|
||||
const { isInitialized, isAuthenticated } = storeToRefs(useAuthStore())
|
||||
await until(isInitialized).toBe(true)
|
||||
await until(isAuthenticated).toBe(true)
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ import type { SidebarTabExtension, ToastManager } from '@/types/extensionTypes'
|
||||
import { useApiKeyAuthStore } from './apiKeyAuthStore'
|
||||
import { useCommandStore } from './commandStore'
|
||||
import { useExecutionErrorStore } from './executionErrorStore'
|
||||
import { useFirebaseAuthStore } from './firebaseAuthStore'
|
||||
import { useAuthStore } from './authStore'
|
||||
import { useQueueSettingsStore } from './queueStore'
|
||||
import { useBottomPanelStore } from './workspace/bottomPanelStore'
|
||||
import { useSidebarTabStore } from './workspace/sidebarTabStore'
|
||||
@@ -48,7 +48,7 @@ function workspaceStoreSetup() {
|
||||
const dialog = useDialogService()
|
||||
const bottomPanel = useBottomPanelStore()
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authStore = useAuthStore()
|
||||
const apiKeyStore = useApiKeyAuthStore()
|
||||
|
||||
const firebaseUser = computed(() => authStore.currentUser)
|
||||
|
||||
@@ -78,7 +78,7 @@ import { useAppMode } from '@/composables/useAppMode'
|
||||
import { useAssetsStore } from '@/stores/assetsStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
import { useExecutionStore } from '@/stores/executionStore'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { useAuthStore } from '@/stores/authStore'
|
||||
import { useMenuItemStore } from '@/stores/menuItemStore'
|
||||
import { useModelStore } from '@/stores/modelStore'
|
||||
import { useNodeDefStore, useNodeFrequencyStore } from '@/stores/nodeDefStore'
|
||||
@@ -120,7 +120,7 @@ watch(linearMode, (isLinear) => {
|
||||
})
|
||||
|
||||
const telemetry = useTelemetry()
|
||||
const firebaseAuthStore = useFirebaseAuthStore()
|
||||
const firebaseAuthStore = useAuthStore()
|
||||
let hasTrackedLogin = false
|
||||
|
||||
watch(
|
||||
|
||||
Reference in New Issue
Block a user