Skip to content

Commit 04410da

Browse files
[feat] Gate top-up functionality on active subscription
Prevent users without active subscriptions from accessing credit top-up features by checking isActiveSubscription across all entry points. Changes: - Hide Purchase Credits button in CreditsPanel when no active subscription - Block purchaseCredits function execution if subscription inactive - Gate showTopUpCreditsDialog service method - Prevent auto-trigger of top-up dialog on insufficient credits error - Fix CurrentUserPopover test mock for isActiveSubscription ref
1 parent 875e235 commit 04410da

File tree

5 files changed

+19
-5
lines changed

5 files changed

+19
-5
lines changed

src/components/dialog/content/setting/CreditsPanel.vue

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
<UserCredit text-class="text-3xl font-bold" />
1616
<Skeleton v-if="loading" width="2rem" height="2rem" />
1717
<Button
18-
v-else
18+
v-else-if="isActiveSubscription"
1919
:label="$t('credits.purchaseCredits')"
2020
:loading="loading"
2121
@click="handlePurchaseCreditsClick"
@@ -116,6 +116,7 @@ import { computed, ref, watch } from 'vue'
116116
import UserCredit from '@/components/common/UserCredit.vue'
117117
import UsageLogsTable from '@/components/dialog/content/setting/UsageLogsTable.vue'
118118
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
119+
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
119120
import { useDialogService } from '@/services/dialogService'
120121
import { useCommandStore } from '@/stores/commandStore'
121122
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
@@ -132,6 +133,7 @@ const dialogService = useDialogService()
132133
const authStore = useFirebaseAuthStore()
133134
const authActions = useFirebaseAuthActions()
134135
const commandStore = useCommandStore()
136+
const { isActiveSubscription } = useSubscription()
135137
const loading = computed(() => authStore.loading)
136138
const balanceLoading = computed(() => authStore.isFetchingBalance)
137139

src/components/topbar/CurrentUserPopover.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ vi.mock('@/stores/firebaseAuthStore', () => ({
8181
// Mock the useSubscription composable
8282
vi.mock('@/platform/cloud/subscription/composables/useSubscription', () => ({
8383
useSubscription: vi.fn(() => ({
84-
isActiveSubscription: vi.fn().mockReturnValue(true)
84+
isActiveSubscription: { value: true }
8585
}))
8686
}))
8787

src/composables/auth/useFirebaseAuthActions.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { useErrorHandling } from '@/composables/useErrorHandling'
77
import type { ErrorRecoveryStrategy } from '@/composables/useErrorHandling'
88
import { t } from '@/i18n'
99
import { isCloud } from '@/platform/distribution/types'
10+
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
1011
import { useToastStore } from '@/platform/updates/common/toastStore'
1112
import { useDialogService } from '@/services/dialogService'
1213
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
@@ -21,6 +22,7 @@ export const useFirebaseAuthActions = () => {
2122
const authStore = useFirebaseAuthStore()
2223
const toastStore = useToastStore()
2324
const { wrapWithErrorHandlingAsync, toastErrorHandler } = useErrorHandling()
25+
const { isActiveSubscription } = useSubscription()
2426

2527
const accessError = ref(false)
2628

@@ -82,6 +84,8 @@ export const useFirebaseAuthActions = () => {
8284
)
8385

8486
const purchaseCredits = wrapWithErrorHandlingAsync(async (amount: number) => {
87+
if (!isActiveSubscription.value) return
88+
8589
const response = await authStore.initiateCreditPurchase({
8690
amount_micros: usdToMicros(amount),
8791
currency: 'usd'

src/scripts/app.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ import { getMp3Metadata } from '@/scripts/metadata/mp3'
4747
import { getOggMetadata } from '@/scripts/metadata/ogg'
4848
import { getSvgMetadata } from '@/scripts/metadata/svg'
4949
import { useDialogService } from '@/services/dialogService'
50+
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
5051
import { useExtensionService } from '@/services/extensionService'
5152
import { useLitegraphService } from '@/services/litegraphService'
5253
import { useSubgraphService } from '@/services/subgraphService'
@@ -698,9 +699,12 @@ export class ComfyApp {
698699
'Payment Required: Please add credits to your account to use this node.'
699700
)
700701
) {
701-
useDialogService().showTopUpCreditsDialog({
702-
isInsufficientCredits: true
703-
})
702+
const { isActiveSubscription } = useSubscription()
703+
if (isActiveSubscription.value) {
704+
useDialogService().showTopUpCreditsDialog({
705+
isInsufficientCredits: true
706+
})
707+
}
704708
} else {
705709
useDialogService().showExecutionErrorDialog(detail)
706710
}

src/services/dialogService.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import ComfyOrgHeader from '@/components/dialog/header/ComfyOrgHeader.vue'
1414
import SettingDialogHeader from '@/components/dialog/header/SettingDialogHeader.vue'
1515
import { t } from '@/i18n'
1616
import { isCloud } from '@/platform/distribution/types'
17+
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
1718
import SettingDialogContent from '@/platform/settings/components/SettingDialogContent.vue'
1819
import type { ExecutionErrorWsMessage } from '@/schemas/apiSchema'
1920
import { useDialogStore } from '@/stores/dialogStore'
@@ -340,6 +341,9 @@ export const useDialogService = () => {
340341
function showTopUpCreditsDialog(options?: {
341342
isInsufficientCredits?: boolean
342343
}) {
344+
const { isActiveSubscription } = useSubscription()
345+
if (!isActiveSubscription.value) return
346+
343347
return dialogStore.showDialog({
344348
key: 'top-up-credits',
345349
component: TopUpCreditsDialogContent,

0 commit comments

Comments
 (0)