feat(frontend): 标明 OpenAI 认证模式

This commit is contained in:
cat
2026-07-14 19:25:13 +08:00
parent ec7c1b6f72
commit 6485081122
6 changed files with 50 additions and 13 deletions
@@ -276,7 +276,7 @@
</div>
</div>
<!-- Codex OAuth/session JSON batch import -->
<!-- Codex auth.json / session credential batch import -->
<div v-if="inputMethod === 'codex_session'" class="space-y-4">
<div
class="rounded-lg border border-blue-300 bg-white/80 p-4 dark:border-blue-600 dark:bg-gray-800/80"
@@ -77,6 +77,7 @@ const { t } = useI18n()
interface Props {
platform: AccountPlatform
type: AccountType
authMode?: string
planType?: string
privacyMode?: string
subscriptionExpiresAt?: string
@@ -92,7 +93,15 @@ const platformLabel = computed(() => {
return 'Gemini'
})
const normalizedAuthMode = computed(() =>
(props.authMode || '').trim().toLowerCase().replace(/[\s_-]+/g, '')
)
const typeLabel = computed(() => {
if (props.platform === 'openai' && props.type === 'oauth') {
if (normalizedAuthMode.value === 'agentidentity') return 'Agent Identity'
if (normalizedAuthMode.value === 'personalaccesstoken') return 'PAT'
}
switch (props.type) {
case 'oauth':
return 'OAuth'
@@ -62,3 +62,24 @@ describe('PlatformTypeBadge Grok plans', () => {
expect(wrapper.findAll('path')).toHaveLength(2)
})
})
describe('PlatformTypeBadge OpenAI authentication modes', () => {
it('distinguishes Agent Identity, PAT, and OAuth accounts', async () => {
const wrapper = mount(PlatformTypeBadge, {
props: {
platform: 'openai',
type: 'oauth',
authMode: 'agentIdentity',
},
})
expect(wrapper.text()).toContain('Agent Identity')
await wrapper.setProps({ authMode: 'personalAccessToken' })
expect(wrapper.text()).toContain('PAT')
expect(wrapper.text()).not.toContain('Agent Identity')
await wrapper.setProps({ authMode: undefined })
expect(wrapper.text()).toContain('OAuth')
})
})
@@ -822,13 +822,13 @@ export default {
refreshTokenAuth: 'Manual RT Input',
refreshTokenDesc: 'Enter your existing OpenAI Refresh Token(s). Supports batch input (one per line). The system will automatically validate and create accounts.',
refreshTokenPlaceholder: 'Paste your OpenAI Refresh Token...\nSupports multiple, one per line',
codexSessionAuth: 'Codex JSON / AT Batch Input',
codexSessionDesc: 'Paste Codex JSON or an accessToken. Accounts use the step 1 settings.',
codexSessionInputLabel: 'Codex JSON or accessToken',
codexSessionPlaceholder: 'Multiple lines supported, one token or JSON per line',
codexSessionHint: 'sessionToken will not be saved as refresh_token. Without refresh_token, the account expires with the accessToken expiry; import is rejected if the expiry cannot be parsed and step 1 has no expiration.',
codexSessionAuth: 'Codex auth.json / AT Import',
codexSessionDesc: 'Paste a Codex auth.json (OAuth or Agent Identity) or an accessToken. Accounts use the step 1 settings.',
codexSessionInputLabel: 'Codex auth.json or accessToken',
codexSessionPlaceholder: 'Multiple lines supported, one token or auth.json object per line',
codexSessionHint: 'Agent Identity keeps no OAuth token and signs each upstream request dynamically. Session/access-token imports retain their existing expiration behavior.',
codexSessionImportAndCreate: 'Import & Create Account',
codexSessionEmpty: 'Please enter Codex JSON or accessToken',
codexSessionEmpty: 'Please enter a Codex auth.json or accessToken',
codexSessionImportFailed: 'Failed to import Codex account',
codexSessionImportSuccess: 'Import completed: created {created}, updated {updated}, skipped {skipped}',
codexSessionImportPartial: 'Partial success: created {created}, updated {updated}, skipped {skipped}, failed {failed}',
@@ -909,13 +909,13 @@ export default {
refreshTokenAuth: '手动输入 RT',
refreshTokenDesc: '输入您已有的 OpenAI Refresh Token,支持批量输入(每行一个),系统将自动验证并创建账号。',
refreshTokenPlaceholder: '粘贴您的 OpenAI Refresh Token...\n支持多个,每行一个',
codexSessionAuth: 'Codex JSON / AT 批量输入',
codexSessionDesc: '粘贴 Codex JSON 或 accessToken,按第一步配置创建账号。',
codexSessionInputLabel: 'Codex JSON 或 accessToken',
codexSessionPlaceholder: '支持多行,每行一个 token 或 JSON',
codexSessionHint: 'sessionToken 不会作为 refresh_token 保存;未包含 refresh_token 时会按 accessToken 过期时间设置账号过期,无法解析且第一步未设置过期时间时会拒绝导入。',
codexSessionAuth: 'Codex auth.json / AT 入',
codexSessionDesc: '粘贴 Codex auth.jsonOAuth 或 Agent Identity或 accessToken,按第一步配置创建账号。',
codexSessionInputLabel: 'Codex auth.json 或 accessToken',
codexSessionPlaceholder: '支持多行,每行一个 token 或 auth.json 对象',
codexSessionHint: 'Agent Identity 不保存 OAuth token,并为每次上游请求动态签名;session/accessToken 导入继续沿用原有过期规则。',
codexSessionImportAndCreate: '导入并创建账号',
codexSessionEmpty: '请输入 Codex JSON 或 accessToken',
codexSessionEmpty: '请输入 Codex auth.json 或 accessToken',
codexSessionImportFailed: 'Codex 账号导入失败',
codexSessionImportSuccess: '导入完成:新增 {created},更新 {updated},跳过 {skipped}',
codexSessionImportPartial: '部分成功:新增 {created},更新 {updated},跳过 {skipped},失败 {failed}',
@@ -234,6 +234,7 @@
<div class="flex min-w-0 flex-col gap-1">
<div class="flex flex-wrap items-center gap-1">
<PlatformTypeBadge :platform="row.platform" :type="row.type"
:auth-mode="getOpenAIAuthMode(row)"
:plan-type="getAccountPlanType(row)"
:privacy-mode="row.extra?.privacy_mode || row.parent_privacy_mode"
:subscription-expires-at="row.credentials?.subscription_expires_at || row.parent_subscription_expires_at" />
@@ -1167,6 +1168,12 @@ function getAccountPlanType(row: any): string | undefined {
return row.credentials?.plan_type || row.parent_plan_type || undefined
}
function getOpenAIAuthMode(row: any): string | undefined {
if (!row || row.platform !== 'openai' || row.type !== 'oauth') return undefined
const authMode = row.credentials?.auth_mode
return typeof authMode === 'string' && authMode.trim() ? authMode : undefined
}
// Antigravity 订阅等级辅助函数
function getAntigravityTierFromRow(row: any): string | null {
if (row.platform !== 'antigravity') return null