fix(grok): 完善密码与SSO授权能力控制

This commit is contained in:
IanShaw027
2026-08-07 14:13:07 +08:00
parent 2413441b5f
commit d0930c4bdb
12 changed files with 122 additions and 10 deletions
+18 -2
View File
@@ -19,6 +19,17 @@ export interface GrokAuthUrlRequest {
redirect_uri?: string
}
export interface GrokOAuthCapabilities {
password_auth_enabled: boolean
}
const GROK_AUTHORIZATION_TIMEOUT_MS = 120_000
export async function getCapabilities(): Promise<GrokOAuthCapabilities> {
const { data } = await apiClient.get<GrokOAuthCapabilities>('/admin/grok/oauth/capabilities')
return data
}
export interface GrokExchangeCodeRequest {
session_id: string
state: string
@@ -177,7 +188,9 @@ export async function validateSSOToken(
): Promise<GrokTokenInfo> {
const payload: Record<string, unknown> = { sso_token: ssoToken }
if (proxyId) payload.proxy_id = proxyId
const { data } = await apiClient.post<GrokTokenInfo>('/admin/grok/oauth/sso-token', payload)
const { data } = await apiClient.post<GrokTokenInfo>('/admin/grok/oauth/sso-token', payload, {
timeout: GROK_AUTHORIZATION_TIMEOUT_MS
})
return data
}
@@ -196,12 +209,15 @@ export async function authorizePassword(
const password = idx >= 0 ? emailAndPassword.slice(idx + sep.length) : ''
const payload: Record<string, unknown> = { email, password }
if (proxyId) payload.proxy_id = proxyId
const { data } = await apiClient.post<GrokTokenInfo>('/admin/grok/oauth/password', payload)
const { data } = await apiClient.post<GrokTokenInfo>('/admin/grok/oauth/password', payload, {
timeout: GROK_AUTHORIZATION_TIMEOUT_MS
})
return data
}
export default {
generateAuthUrl,
getCapabilities,
exchangeCode,
refreshGrokToken,
queryQuota,
@@ -59,7 +59,7 @@
t(getOAuthKey('ssoCookieAuth'))
}}</span>
</label>
<label v-if="showEmailPasswordOption" class="flex cursor-pointer items-center gap-2">
<label v-if="emailPasswordOptionEnabled" class="flex cursor-pointer items-center gap-2">
<input
v-model="inputMethod"
type="radio"
@@ -900,6 +900,7 @@ import { useClipboard } from '@/composables/useClipboard'
import Icon from '@/components/icons/Icon.vue'
import type { AddMethod, AuthInputMethod } from '@/composables/useAccountOAuth'
import type { AccountPlatform } from '@/types'
import { adminAPI } from '@/api/admin'
interface Props {
addMethod: AddMethod
@@ -975,6 +976,10 @@ const emit = defineEmits<{
}>()
const { t } = useI18n()
const passwordAuthEnabled = ref(false)
const emailPasswordOptionEnabled = computed(
() => props.showEmailPasswordOption && props.platform === 'grok' && passwordAuthEnabled.value
)
const showLocalCallbackNotice = computed(() => props.platform === 'openai' || props.platform === 'grok')
@@ -1021,6 +1026,25 @@ const showHelpDialog = ref(false)
const oauthState = ref('')
const projectId = ref('')
watch(
() => [props.platform, props.showEmailPasswordOption] as const,
async ([platform, requested]) => {
passwordAuthEnabled.value = false
if (platform !== 'grok' || !requested) return
try {
const capabilities = await adminAPI.grok.getCapabilities()
passwordAuthEnabled.value = capabilities.password_auth_enabled
} catch {
// Fail closed; the backend enforces the same capability.
}
},
{ immediate: true }
)
watch(emailPasswordOptionEnabled, (enabled) => {
if (!enabled && inputMethod.value === 'email_password') inputMethod.value = 'manual'
})
// Computed: show method selection only when there is something to choose.
const methodOptionCount = computed(() => [
props.showManualOption,
@@ -1033,7 +1057,7 @@ const methodOptionCount = computed(() => [
props.showAgentIdentityOption,
props.showCodexPatOption,
props.showSsoOption,
props.showEmailPasswordOption
emailPasswordOptionEnabled.value
].filter(Boolean).length)
const showMethodSelection = computed(() => methodOptionCount.value > 1)