diff --git a/src/actions/cloud.ts b/src/actions/cloud.ts index 5379bee..f02095a 100644 --- a/src/actions/cloud.ts +++ b/src/actions/cloud.ts @@ -2,7 +2,7 @@ import { ipc } from '@/ipc/manager'; import type { DeviceProfile } from '@/types/account'; import { isValidProxyUrl } from '@/utils/url'; -export function addGoogleAccount(input: { authCode: string }) { +export function addGoogleAccount(input: { authCode: string; oauthClientKey?: string }) { return ipc.client.cloud.addGoogleAccount(input); } @@ -39,8 +39,29 @@ export function syncLocalAccount() { return ipc.client.cloud.syncLocalAccount(); } -export function startAuthFlow() { - return ipc.client.cloud.startAuthFlow(); +export interface OAuthClientDescriptor { + key: string; + label: string; + client_id: string; + is_active: boolean; + is_builtin: boolean; +} + +export function startAuthFlow(input?: { oauthClientKey?: string }) { + return ipc.client.cloud.startAuthFlow(input); +} + +export function listOAuthClients() { + return ipc.client.cloud.listOAuthClients() as Promise; +} + +export async function getActiveOAuthClient() { + const response = await ipc.client.cloud.getActiveOAuthClient(); + return response.client_key; +} + +export function setActiveOAuthClient(input: { clientKey: string }) { + return ipc.client.cloud.setActiveOAuthClient(input); } export function getSwitchStatus() { diff --git a/src/components/accountValidationStatus.ts b/src/components/accountValidationStatus.ts new file mode 100644 index 0000000..4846009 --- /dev/null +++ b/src/components/accountValidationStatus.ts @@ -0,0 +1,26 @@ +import type { TFunction } from 'i18next'; +import { isOAuthReauthReason, isRateLimitReason } from '@/utils/account-status'; + +export function getValidationBlockedStatusLabel( + status: 'active' | 'rate_limited' | 'expired' | undefined, + reason: string | undefined, + t: TFunction, +): string | null { + const normalizedReason = (reason || '').toLowerCase(); + const hasReason = normalizedReason !== ''; + const isBlockedByStatus = status === 'rate_limited' || status === 'expired'; + + if (!isBlockedByStatus && !hasReason) { + return null; + } + + if (status === 'rate_limited' || isRateLimitReason(normalizedReason)) { + return t('cloud.card.validationRiskControlled'); + } + + if (status === 'expired' || isOAuthReauthReason(normalizedReason)) { + return t('cloud.card.validationOAuthReauthRequired'); + } + + return t('cloud.card.validationRequired'); +}