mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-01 05:49:54 +00:00
[API Node] Show message tip about API-key-based login (#3851)
Co-authored-by: github-actions <github-actions@github.com> Co-authored-by: Chenlei Hu <hcl@comfy.org>
This commit is contained in:
@@ -67,9 +67,9 @@ import Tabs from 'primevue/tabs'
|
||||
import { computed, watch } from 'vue'
|
||||
|
||||
import SearchBox from '@/components/common/SearchBox.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useSettingSearch } from '@/composables/setting/useSettingSearch'
|
||||
import { useSettingUI } from '@/composables/setting/useSettingUI'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { SettingTreeNode } from '@/stores/settingStore'
|
||||
import { ISettingGroup, SettingParams } from '@/types/settingTypes'
|
||||
import { flattenTree } from '@/utils/treeUtil'
|
||||
@@ -107,7 +107,7 @@ const {
|
||||
getSearchResults
|
||||
} = useSettingSearch()
|
||||
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
|
||||
// Sort groups for a category
|
||||
const sortedGroups = (category: SettingTreeNode): ISettingGroup[] => {
|
||||
@@ -140,7 +140,7 @@ watch(activeCategory, (_, oldValue) => {
|
||||
activeCategory.value = oldValue
|
||||
}
|
||||
if (activeCategory.value?.key === 'credits') {
|
||||
void authService.fetchBalance()
|
||||
void authActions.fetchBalance()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -101,6 +101,15 @@
|
||||
{{ t('auth.apiKey.generateKey') }}
|
||||
</a>
|
||||
</small>
|
||||
<Message
|
||||
v-if="authActions.accessError.value"
|
||||
severity="info"
|
||||
icon="pi pi-info-circle"
|
||||
variant="outlined"
|
||||
closable
|
||||
>
|
||||
{{ t('toastMessages.useApiKeyTip') }}
|
||||
</Message>
|
||||
</div>
|
||||
|
||||
<!-- Terms & Contact -->
|
||||
@@ -134,12 +143,12 @@
|
||||
import Button from 'primevue/button'
|
||||
import Divider from 'primevue/divider'
|
||||
import Message from 'primevue/message'
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { COMFY_PLATFORM_BASE_URL } from '@/config/comfyApi'
|
||||
import { SignInData, SignUpData } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { isInChina } from '@/utils/networkUtil'
|
||||
|
||||
import ApiKeyForm from './signin/ApiKeyForm.vue'
|
||||
@@ -151,7 +160,7 @@ const { onSuccess } = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const isSecureContext = window.isSecureContext
|
||||
const isSignIn = ref(true)
|
||||
const showApiKeyForm = ref(false)
|
||||
@@ -162,25 +171,25 @@ const toggleState = () => {
|
||||
}
|
||||
|
||||
const signInWithGoogle = async () => {
|
||||
if (await authService.signInWithGoogle()) {
|
||||
if (await authActions.signInWithGoogle()) {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
const signInWithGithub = async () => {
|
||||
if (await authService.signInWithGithub()) {
|
||||
if (await authActions.signInWithGithub()) {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
const signInWithEmail = async (values: SignInData) => {
|
||||
if (await authService.signInWithEmail(values.email, values.password)) {
|
||||
if (await authActions.signInWithEmail(values.email, values.password)) {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
const signUpWithEmail = async (values: SignUpData) => {
|
||||
if (await authService.signUpWithEmail(values.email, values.password)) {
|
||||
if (await authActions.signUpWithEmail(values.email, values.password)) {
|
||||
onSuccess()
|
||||
}
|
||||
}
|
||||
@@ -189,4 +198,8 @@ const userIsInChina = ref(false)
|
||||
onMounted(async () => {
|
||||
userIsInChina.value = await isInChina()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
authActions.accessError.value = false
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
import Button from 'primevue/button'
|
||||
|
||||
import UserCredit from '@/components/common/UserCredit.vue'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
|
||||
import CreditTopUpOption from './credit/CreditTopUpOption.vue'
|
||||
|
||||
@@ -65,9 +65,9 @@ const {
|
||||
preselectedAmountOption?: number
|
||||
}>()
|
||||
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
|
||||
const handleSeeDetails = async () => {
|
||||
await authService.accessBillingPortal()
|
||||
await authActions.accessBillingPortal()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -23,10 +23,10 @@ import Button from 'primevue/button'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import PasswordFields from '@/components/dialog/content/signin/PasswordFields.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { updatePasswordSchema } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const loading = ref(false)
|
||||
|
||||
const { onSuccess } = defineProps<{
|
||||
@@ -37,7 +37,7 @@ const onSubmit = async (event: FormSubmitEvent) => {
|
||||
if (event.valid) {
|
||||
loading.value = true
|
||||
try {
|
||||
await authService.updatePassword(event.values.password)
|
||||
await authActions.updatePassword(event.values.password)
|
||||
onSuccess()
|
||||
} finally {
|
||||
loading.value = false
|
||||
|
||||
@@ -41,9 +41,9 @@ import ProgressSpinner from 'primevue/progressspinner'
|
||||
import Tag from 'primevue/tag'
|
||||
import { onBeforeUnmount, ref } from 'vue'
|
||||
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
|
||||
const {
|
||||
amount,
|
||||
@@ -61,7 +61,7 @@ const loading = ref(false)
|
||||
|
||||
const handleBuyNow = async () => {
|
||||
loading.value = true
|
||||
await authService.purchaseCredits(editable ? customAmount.value : amount)
|
||||
await authActions.purchaseCredits(editable ? customAmount.value : amount)
|
||||
loading.value = false
|
||||
didClickBuyNow.value = true
|
||||
}
|
||||
@@ -69,7 +69,7 @@ const handleBuyNow = async () => {
|
||||
onBeforeUnmount(() => {
|
||||
if (didClickBuyNow.value) {
|
||||
// If clicked buy now, then returned back to the dialog and closed, fetch the balance
|
||||
void authService.fetchBalance()
|
||||
void authActions.fetchBalance()
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
text
|
||||
size="small"
|
||||
severity="secondary"
|
||||
@click="() => authService.fetchBalance()"
|
||||
@click="() => authActions.fetchBalance()"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -112,8 +112,8 @@ import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import UserCredit from '@/components/common/UserCredit.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import { formatMetronomeCurrency } from '@/utils/formatUtil'
|
||||
|
||||
@@ -127,7 +127,7 @@ interface CreditHistoryItemData {
|
||||
const { t } = useI18n()
|
||||
const dialogService = useDialogService()
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const loading = computed(() => authStore.loading)
|
||||
const balanceLoading = computed(() => authStore.isFetchingBalance)
|
||||
|
||||
@@ -142,7 +142,7 @@ const handlePurchaseCreditsClick = () => {
|
||||
}
|
||||
|
||||
const handleCreditsHistoryClick = async () => {
|
||||
await authService.accessBillingPortal()
|
||||
await authActions.accessBillingPortal()
|
||||
}
|
||||
|
||||
const handleMessageSupport = () => {
|
||||
|
||||
@@ -80,12 +80,12 @@ import ProgressSpinner from 'primevue/progressspinner'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { type SignInData, signInSchema } from '@/schemas/signInSchema'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const firebaseAuthService = useFirebaseAuthService()
|
||||
const firebaseAuthActions = useFirebaseAuthActions()
|
||||
const loading = computed(() => authStore.loading)
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -102,6 +102,6 @@ const onSubmit = (event: FormSubmitEvent) => {
|
||||
|
||||
const handleForgotPassword = async (email: string) => {
|
||||
if (!email) return
|
||||
await firebaseAuthService.sendPasswordReset(email)
|
||||
await firebaseAuthActions.sendPasswordReset(email)
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -69,11 +69,11 @@ import { onMounted } from 'vue'
|
||||
import UserAvatar from '@/components/common/UserAvatar.vue'
|
||||
import UserCredit from '@/components/common/UserCredit.vue'
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
|
||||
const { userDisplayName, userEmail, userPhotoUrl } = useCurrentUser()
|
||||
const authService = useFirebaseAuthService()
|
||||
const authActions = useFirebaseAuthActions()
|
||||
const dialogService = useDialogService()
|
||||
|
||||
const handleOpenUserSettings = () => {
|
||||
@@ -89,6 +89,6 @@ const handleOpenApiPricing = () => {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
void authService.fetchBalance()
|
||||
void authActions.fetchBalance()
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { FirebaseError } from 'firebase/app'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { t } from '@/i18n'
|
||||
@@ -11,11 +12,13 @@ import { usdToMicros } from '@/utils/formatUtil'
|
||||
* All actions are wrapped with error handling.
|
||||
* @returns {Object} - Object containing all Firebase Auth actions
|
||||
*/
|
||||
export const useFirebaseAuthService = () => {
|
||||
export const useFirebaseAuthActions = () => {
|
||||
const authStore = useFirebaseAuthStore()
|
||||
const toastStore = useToastStore()
|
||||
const { wrapWithErrorHandlingAsync, toastErrorHandler } = useErrorHandling()
|
||||
|
||||
const accessError = ref(false)
|
||||
|
||||
const reportError = (error: unknown) => {
|
||||
// Ref: https://firebase.google.com/docs/auth/admin/errors
|
||||
if (
|
||||
@@ -26,6 +29,7 @@ export const useFirebaseAuthService = () => {
|
||||
'auth/unauthorized-continue-uri'
|
||||
].includes(error.code)
|
||||
) {
|
||||
accessError.value = true
|
||||
toastStore.add({
|
||||
severity: 'error',
|
||||
summary: t('g.error'),
|
||||
@@ -141,6 +145,7 @@ export const useFirebaseAuthService = () => {
|
||||
signInWithGithub,
|
||||
signInWithEmail,
|
||||
signUpWithEmail,
|
||||
updatePassword
|
||||
updatePassword,
|
||||
accessError
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
LiteGraph
|
||||
} from '@comfyorg/litegraph'
|
||||
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import {
|
||||
DEFAULT_DARK_COLOR_PALETTE,
|
||||
DEFAULT_LIGHT_COLOR_PALETTE
|
||||
@@ -13,7 +14,6 @@ import { t } from '@/i18n'
|
||||
import { api } from '@/scripts/api'
|
||||
import { app } from '@/scripts/app'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useFirebaseAuthService } from '@/services/firebaseAuthService'
|
||||
import { useLitegraphService } from '@/services/litegraphService'
|
||||
import { useWorkflowService } from '@/services/workflowService'
|
||||
import type { ComfyCommand } from '@/stores/commandStore'
|
||||
@@ -32,7 +32,7 @@ export function useCoreCommands(): ComfyCommand[] {
|
||||
const workflowStore = useWorkflowStore()
|
||||
const dialogService = useDialogService()
|
||||
const colorPaletteStore = useColorPaletteStore()
|
||||
const firebaseAuthService = useFirebaseAuthService()
|
||||
const firebaseAuthActions = useFirebaseAuthActions()
|
||||
const toastStore = useToastStore()
|
||||
const getTracker = () => workflowStore.activeWorkflow?.changeTracker
|
||||
|
||||
@@ -671,7 +671,7 @@ export function useCoreCommands(): ComfyCommand[] {
|
||||
label: 'Sign Out',
|
||||
versionAdded: '1.18.1',
|
||||
function: async () => {
|
||||
await firebaseAuthService.logout()
|
||||
await firebaseAuthActions.logout()
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1259,7 +1259,8 @@
|
||||
"failedToInitiateCreditPurchase": "Failed to initiate credit purchase: {error}",
|
||||
"failedToAccessBillingPortal": "Failed to access billing portal: {error}",
|
||||
"failedToPurchaseCredits": "Failed to purchase credits: {error}",
|
||||
"unauthorizedDomain": "Your domain {domain} is not authorized to use this service. Please contact {email} to add your domain to the whitelist."
|
||||
"unauthorizedDomain": "Your domain {domain} is not authorized to use this service. Please contact {email} to add your domain to the whitelist.",
|
||||
"useApiKeyTip": "Tip: Can't access normal login? Use the Comfy API Key option."
|
||||
},
|
||||
"auth": {
|
||||
"apiKey": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "No se puede obtener la ruta del archivo del modelo",
|
||||
"unauthorizedDomain": "Tu dominio {domain} no está autorizado para usar este servicio. Por favor, contacta a {email} para agregar tu dominio a la lista blanca.",
|
||||
"updateRequested": "Actualización solicitada",
|
||||
"useApiKeyTip": "Consejo: ¿No puedes acceder al inicio de sesión normal? Usa la opción de clave API de Comfy.",
|
||||
"userNotAuthenticated": "Usuario no autenticado"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "Impossible d'obtenir le chemin du fichier modèle",
|
||||
"unauthorizedDomain": "Votre domaine {domain} n'est pas autorisé à utiliser ce service. Veuillez contacter {email} pour ajouter votre domaine à la liste blanche.",
|
||||
"updateRequested": "Mise à jour demandée",
|
||||
"useApiKeyTip": "Astuce : Vous ne pouvez pas accéder à la connexion normale ? Utilisez l’option Clé API Comfy.",
|
||||
"userNotAuthenticated": "Utilisateur non authentifié"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "モデルファイルのパスを取得できません",
|
||||
"unauthorizedDomain": "あなたのドメイン {domain} はこのサービスを利用する権限がありません。ご利用のドメインをホワイトリストに追加するには、{email} までご連絡ください。",
|
||||
"updateRequested": "更新が要求されました",
|
||||
"useApiKeyTip": "ヒント:通常のログインにアクセスできませんか?Comfy APIキーオプションを使用してください。",
|
||||
"userNotAuthenticated": "ユーザーが認証されていません"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "모델 파일 경로를 가져올 수 없습니다",
|
||||
"unauthorizedDomain": "귀하의 도메인 {domain}은(는) 이 서비스를 사용할 수 있는 권한이 없습니다. 도메인을 허용 목록에 추가하려면 {email}로 문의해 주세요.",
|
||||
"updateRequested": "업데이트 요청됨",
|
||||
"useApiKeyTip": "팁: 일반 로그인을 사용할 수 없나요? Comfy API Key 옵션을 사용하세요.",
|
||||
"userNotAuthenticated": "사용자가 인증되지 않았습니다"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "Не удалось получить путь к файлу модели",
|
||||
"unauthorizedDomain": "Ваш домен {domain} не авторизован для использования этого сервиса. Пожалуйста, свяжитесь с {email}, чтобы добавить ваш домен в белый список.",
|
||||
"updateRequested": "Запрошено обновление",
|
||||
"useApiKeyTip": "Совет: Нет доступа к обычному входу? Используйте опцию Comfy API Key.",
|
||||
"userNotAuthenticated": "Пользователь не аутентифицирован"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
@@ -1362,6 +1362,7 @@
|
||||
"unableToGetModelFilePath": "无法获取模型文件路径",
|
||||
"unauthorizedDomain": "您的域名 {domain} 未被授权使用此服务。请联系 {email} 将您的域名添加到白名单。",
|
||||
"updateRequested": "已请求更新",
|
||||
"useApiKeyTip": "提示:无法正常登录?请使用 Comfy API Key 选项。",
|
||||
"userNotAuthenticated": "用户未认证"
|
||||
},
|
||||
"userSelect": {
|
||||
|
||||
Reference in New Issue
Block a user