mirror of
https://github.com/zyycn/codex-proxy-rs.git
synced 2026-11-06 08:06:19 +00:00
fix(accounts): show OAuth results in notifications
Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
@@ -304,7 +304,6 @@
|
||||
"fileReadingFailedTryAgain": "File reading failed, please try again",
|
||||
"uploadFiles": "Upload files",
|
||||
"authorizationExpired": "Authorization expired, start again or check whether authorization completed",
|
||||
"pollingPaused": "Polling paused, check the authorization result to continue",
|
||||
"regenerateAuthorizationLink": "Regenerate authorization link",
|
||||
"generateAuthorizationLink": "Generate authorization link",
|
||||
"authorizationLink": "Authorization link",
|
||||
|
||||
@@ -304,7 +304,6 @@
|
||||
"fileReadingFailedTryAgain": "文件读取失败,请重新选择",
|
||||
"uploadFiles": "上传文件",
|
||||
"authorizationExpired": "授权已过期,可重新开始或检查已完成的授权结果",
|
||||
"pollingPaused": "查询已暂停,可检查授权结果后继续",
|
||||
"regenerateAuthorizationLink": "重新生成授权链接",
|
||||
"generateAuthorizationLink": "生成授权链接",
|
||||
"authorizationLink": "授权链接",
|
||||
|
||||
@@ -304,7 +304,6 @@
|
||||
"fileReadingFailedTryAgain": "文件讀取失敗,請重新選擇",
|
||||
"uploadFiles": "上傳文件",
|
||||
"authorizationExpired": "授權已過期,可重新開始或檢查已完成的授權結果",
|
||||
"pollingPaused": "查詢已暫停,可檢查授權結果後繼續",
|
||||
"regenerateAuthorizationLink": "重新生成授權鏈接",
|
||||
"generateAuthorizationLink": "生成授權鏈接",
|
||||
"authorizationLink": "授權鏈接",
|
||||
|
||||
@@ -3,11 +3,10 @@ import type { AccountAuthorizationView } from '../../composables/useAccountAutho
|
||||
|
||||
import { ZButton, ZForm, ZFormItem, ZIconButton, ZScrollbar, ZTextarea } from '@codex-proxy/ui'
|
||||
import { Copy, KeyRound } from '@lucide/vue'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import { useCopyText } from '@/composables/useCopyText'
|
||||
|
||||
const props = defineProps<{
|
||||
defineProps<{
|
||||
authUrl: string
|
||||
panelTitle: string
|
||||
panelDescription: string
|
||||
@@ -25,13 +24,6 @@ const { t } = useI18n({ useScope: 'global' })
|
||||
|
||||
const callback = defineModel<string>({ required: true })
|
||||
const copyWithToast = useCopyText()
|
||||
const statusText = computed(() => {
|
||||
if (props.authorization.status === 'expired')
|
||||
return t('accounts.onboarding.authorizationExpired')
|
||||
if (props.authorization.status === 'paused')
|
||||
return t('accounts.onboarding.pollingPaused')
|
||||
return ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -89,13 +81,6 @@ const statusText = computed(() => {
|
||||
</ZFormItem>
|
||||
</ZForm>
|
||||
|
||||
<p v-if="statusText" class="m-0 text-z-sm text-z-text-secondary" role="status">
|
||||
{{ statusText }}
|
||||
</p>
|
||||
<p v-if="authorization.error" class="m-0 text-z-sm text-z-error" role="alert">
|
||||
{{ authorization.error }}
|
||||
</p>
|
||||
|
||||
<ZForm v-if="authorization.flow">
|
||||
<ZFormItem :label="callbackLabel" required>
|
||||
<ZTextarea
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
import type { AccountImportSettings, AccountOAuthStartResponse } from '@/api'
|
||||
import { computed, onScopeDispose, shallowRef } from 'vue'
|
||||
import { completeAccountOAuth, startAccountOAuth } from '@/api'
|
||||
import { ApiError } from '@/api/request'
|
||||
import { t } from '@/i18n'
|
||||
import { notification as ZNotification } from '@/utils/notification'
|
||||
import { errorMessage } from '@/utils/operation'
|
||||
|
||||
type Status = 'idle' | 'starting' | 'waiting' | 'paused' | 'expired' | 'completing'
|
||||
type Status = 'idle' | 'starting' | 'waiting' | 'expired' | 'completing'
|
||||
|
||||
export interface AccountAuthorizationView {
|
||||
flow: AccountOAuthStartResponse | null
|
||||
status: Status
|
||||
error: string
|
||||
}
|
||||
|
||||
interface AuthorizationRequest {
|
||||
@@ -20,13 +21,11 @@ interface AuthorizationRequest {
|
||||
export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
const flow = shallowRef<AccountOAuthStartResponse | null>(null)
|
||||
const status = shallowRef<Status>('idle')
|
||||
const error = shallowRef('')
|
||||
const callback = shallowRef('')
|
||||
const busy = computed(() => status.value === 'starting' || status.value === 'completing')
|
||||
const view = computed<AccountAuthorizationView>(() => ({
|
||||
flow: flow.value,
|
||||
status: status.value,
|
||||
error: error.value,
|
||||
}))
|
||||
let context: { provider: string, settings?: AccountImportSettings } | undefined
|
||||
let controller: AbortController | undefined
|
||||
@@ -48,7 +47,6 @@ export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
cancel()
|
||||
flow.value = null
|
||||
status.value = 'idle'
|
||||
error.value = ''
|
||||
callback.value = ''
|
||||
}
|
||||
|
||||
@@ -62,7 +60,7 @@ export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
controller = current
|
||||
status.value = 'starting'
|
||||
try {
|
||||
const result = await startAccountOAuth(request.start, { signal: current.signal, silent: true })
|
||||
const result = await startAccountOAuth(request.start, { signal: current.signal })
|
||||
if (current.signal.aborted)
|
||||
return
|
||||
const expiresAt = Date.parse(result.expiresAt)
|
||||
@@ -75,14 +73,22 @@ export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
: 'waiting'
|
||||
expiryTimer = setTimeout(() => {
|
||||
// 不取消正在确认的提交,过期后仍接收服务端已经提交的结果。
|
||||
if (status.value !== 'completing')
|
||||
if (status.value !== 'completing') {
|
||||
status.value = 'expired'
|
||||
ZNotification.warning({
|
||||
message: t('accounts.onboarding.authorizationExpired'),
|
||||
})
|
||||
}
|
||||
}, Math.max(0, Math.min(expiresAt - Date.now(), 2_147_483_647)))
|
||||
}
|
||||
catch (cause) {
|
||||
if (!current.signal.aborted) {
|
||||
error.value = errorMessage(cause, t('accounts.onboarding.linkFailed'))
|
||||
status.value = 'idle'
|
||||
if (!(cause instanceof ApiError)) {
|
||||
ZNotification.error({
|
||||
message: errorMessage(cause, t('accounts.onboarding.linkFailed')),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -93,17 +99,18 @@ export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
if (!current || !currentFlow || !context || busy.value)
|
||||
return
|
||||
if (!callback.value.trim()) {
|
||||
error.value = t('accounts.onboarding.callbackRequired')
|
||||
ZNotification.warning({
|
||||
message: t('accounts.onboarding.callbackRequired'),
|
||||
})
|
||||
return
|
||||
}
|
||||
status.value = 'completing'
|
||||
error.value = ''
|
||||
try {
|
||||
await completeAccountOAuth({
|
||||
...context,
|
||||
flowId: currentFlow.flowId,
|
||||
callbackUrl: callback.value.trim(),
|
||||
}, { signal: current.signal, silent: true })
|
||||
}, { signal: current.signal })
|
||||
if (!current.signal.aborted) {
|
||||
clearTimers()
|
||||
await onComplete()
|
||||
@@ -113,8 +120,12 @@ export function useAccountAuthorization(onComplete: () => Promise<void>) {
|
||||
if (!current.signal.aborted) {
|
||||
status.value = expired()
|
||||
? 'expired'
|
||||
: 'paused'
|
||||
error.value = errorMessage(cause, t('accounts.onboarding.authorizationFailed'))
|
||||
: 'waiting'
|
||||
if (!(cause instanceof ApiError)) {
|
||||
ZNotification.error({
|
||||
message: errorMessage(cause, t('accounts.onboarding.authorizationFailed')),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user