mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-30 08:22:34 +00:00
feat(grok): 对齐 free-usage/empty 失败分类与 sticky/ReAuth 体验
从 grokcli 吸收 body-first 失败分类(free-usage/empty/billing), 接到现有 temp_unsched 与 failover,保留 content-policy 与 pool_mode。 Grok 粘连/缓存在无显式 session 时可用 previous_response_id; ReAuth 预填 email---- 并默认密码 tab(密码不落库)。
This commit is contained in:
@@ -924,6 +924,11 @@ interface Props {
|
||||
showEmailPasswordOption?: boolean
|
||||
showManualOption?: boolean
|
||||
initialInputMethod?: AuthInputMethod
|
||||
/**
|
||||
* Prefill for Grok email----password reauth. Password is never stored;
|
||||
* pass only the email (or "email----") so the operator types the password.
|
||||
*/
|
||||
initialEmailPassword?: string
|
||||
platform?: AccountPlatform // Platform type for different UI/text
|
||||
showProjectId?: boolean // New prop to control project ID visibility
|
||||
}
|
||||
@@ -949,6 +954,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
showEmailPasswordOption: false,
|
||||
showManualOption: true,
|
||||
initialInputMethod: 'manual',
|
||||
initialEmailPassword: '',
|
||||
platform: 'anthropic',
|
||||
showProjectId: true
|
||||
})
|
||||
@@ -1010,7 +1016,7 @@ const sessionTokenInput = ref('')
|
||||
const codexSessionInput = ref('')
|
||||
const codexPATInput = ref('')
|
||||
const ssoCookieInput = ref('')
|
||||
const emailPasswordInput = ref('')
|
||||
const emailPasswordInput = ref(props.initialEmailPassword || '')
|
||||
const showHelpDialog = ref(false)
|
||||
const oauthState = ref('')
|
||||
const projectId = ref('')
|
||||
@@ -1085,6 +1091,16 @@ watch(() => props.initialInputMethod, (newVal) => {
|
||||
inputMethod.value = newVal
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.initialEmailPassword,
|
||||
(newVal) => {
|
||||
// Only prefill when the field is empty so we never overwrite operator input.
|
||||
if (newVal && !emailPasswordInput.value.trim()) {
|
||||
emailPasswordInput.value = newVal
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
watch(inputMethod, (newVal) => {
|
||||
emit('update:inputMethod', newVal)
|
||||
})
|
||||
|
||||
@@ -137,6 +137,8 @@
|
||||
:method-label="t('admin.accounts.inputMethod')"
|
||||
:platform="isOpenAI ? 'openai' : isGemini ? 'gemini' : isAntigravity ? 'antigravity' : isGrok ? 'grok' : 'anthropic'"
|
||||
:show-project-id="isGemini && geminiOAuthType === 'code_assist'"
|
||||
:initial-input-method="grokInitialInputMethod"
|
||||
:initial-email-password="grokPrefillEmailPassword"
|
||||
@generate-url="handleGenerateUrl"
|
||||
@cookie-auth="handleCookieAuth"
|
||||
@validate-refresh-token="handleGrokValidateRefreshToken"
|
||||
@@ -255,6 +257,40 @@ const isAnthropic = computed(() => props.account?.platform === 'anthropic')
|
||||
const isAntigravity = computed(() => props.account?.platform === 'antigravity')
|
||||
const isGrok = computed(() => props.account?.platform === 'grok')
|
||||
|
||||
/** Stored Grok email for reauth prefill (password is never stored). */
|
||||
const grokAccountEmail = computed(() => {
|
||||
if (!isGrok.value || !props.account) return ''
|
||||
const creds = (props.account.credentials || {}) as Record<string, unknown>
|
||||
const email = typeof creds.email === 'string' ? creds.email.trim() : ''
|
||||
return email
|
||||
})
|
||||
|
||||
/**
|
||||
* Prefill "email----" so the operator only types the password.
|
||||
* Empty when no email is known (full email----password required).
|
||||
*/
|
||||
const grokPrefillEmailPassword = computed(() => {
|
||||
const email = grokAccountEmail.value
|
||||
return email ? `${email}----` : ''
|
||||
})
|
||||
|
||||
/**
|
||||
* Grok reauth default tab:
|
||||
* - password first when we know the email (common reauth path)
|
||||
* - refresh_token when email unknown but RT may still work
|
||||
* - email_password otherwise
|
||||
*/
|
||||
const grokInitialInputMethod = computed<AuthInputMethod>(() => {
|
||||
if (!isGrok.value) return 'manual'
|
||||
if (grokAccountEmail.value) return 'email_password'
|
||||
const creds = (props.account?.credentials || {}) as Record<string, unknown>
|
||||
const hasRT =
|
||||
(typeof creds.refresh_token === 'string' && creds.refresh_token.trim() !== '') ||
|
||||
(typeof creds.has_refresh_token === 'boolean' && creds.has_refresh_token)
|
||||
if (hasRT) return 'refresh_token'
|
||||
return 'email_password'
|
||||
})
|
||||
|
||||
// Computed - current OAuth state based on platform
|
||||
const currentAuthUrl = computed(() => {
|
||||
if (isOpenAILike.value) return openaiOAuth.authUrl.value
|
||||
|
||||
@@ -32,4 +32,13 @@ describe('ReAuthAccountModal Grok re-auth paths', () => {
|
||||
expect(source).toContain("method === 'email_password'")
|
||||
expect(source).toContain("method === 'refresh_token'")
|
||||
})
|
||||
|
||||
it('prefills email---- and defaults to password method when email is known', () => {
|
||||
expect(source).toContain('grokPrefillEmailPassword')
|
||||
expect(source).toContain('grokInitialInputMethod')
|
||||
expect(source).toContain(':initial-email-password="grokPrefillEmailPassword"')
|
||||
expect(source).toContain(':initial-input-method="grokInitialInputMethod"')
|
||||
expect(source).toContain('email----')
|
||||
expect(source).toContain("return 'email_password'")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user