mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
fix(provider): 隐藏 Windsurf refresh token 刷新入口
This commit is contained in:
@@ -50,6 +50,7 @@ pub(crate) struct ProviderKeyAuthSemantics {
|
|||||||
credential_kind: ProviderKeyCredentialKind,
|
credential_kind: ProviderKeyCredentialKind,
|
||||||
runtime_auth_kind: ProviderKeyRuntimeAuthKind,
|
runtime_auth_kind: ProviderKeyRuntimeAuthKind,
|
||||||
oauth_managed: bool,
|
oauth_managed: bool,
|
||||||
|
can_refresh_oauth: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProviderKeyAuthSemantics {
|
impl ProviderKeyAuthSemantics {
|
||||||
@@ -66,7 +67,7 @@ impl ProviderKeyAuthSemantics {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const fn can_refresh_oauth(self) -> bool {
|
pub(crate) const fn can_refresh_oauth(self) -> bool {
|
||||||
self.oauth_managed
|
self.can_refresh_oauth
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) const fn can_export_oauth(self) -> bool {
|
pub(crate) const fn can_export_oauth(self) -> bool {
|
||||||
@@ -179,10 +180,12 @@ pub(crate) fn provider_key_auth_semantics(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let provider_type_normalized = provider_type.trim().to_ascii_lowercase();
|
||||||
ProviderKeyAuthSemantics {
|
ProviderKeyAuthSemantics {
|
||||||
credential_kind,
|
credential_kind,
|
||||||
runtime_auth_kind,
|
runtime_auth_kind,
|
||||||
oauth_managed,
|
oauth_managed,
|
||||||
|
can_refresh_oauth: oauth_managed && provider_type_normalized != "windsurf",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,6 +344,7 @@ mod tests {
|
|||||||
let semantics = provider_key_auth_semantics(&sample_key("oauth"), "windsurf");
|
let semantics = provider_key_auth_semantics(&sample_key("oauth"), "windsurf");
|
||||||
|
|
||||||
assert!(semantics.oauth_managed());
|
assert!(semantics.oauth_managed());
|
||||||
|
assert!(!semantics.can_refresh_oauth());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
semantics.credential_kind(),
|
semantics.credential_kind(),
|
||||||
ProviderKeyCredentialKind::OAuthSession
|
ProviderKeyCredentialKind::OAuthSession
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { describe, expect, it } from 'vitest'
|
import { describe, expect, it } from 'vitest'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
canRefreshOAuthCredential,
|
||||||
getProviderMaskedSecretLabel,
|
getProviderMaskedSecretLabel,
|
||||||
shouldShowOAuthRefreshControl,
|
shouldShowOAuthRefreshControl,
|
||||||
} from '@/utils/providerKeyAuth'
|
} from '@/utils/providerKeyAuth'
|
||||||
@@ -17,14 +18,25 @@ describe('providerKeyAuth', () => {
|
|||||||
expect(shouldShowOAuthRefreshControl(key, 'grok')).toBe(false)
|
expect(shouldShowOAuthRefreshControl(key, 'grok')).toBe(false)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('keeps standard OAuth providers on OAuth token semantics', () => {
|
it('hides oauth refresh control when backend marks a provider as non-refreshable', () => {
|
||||||
const key = {
|
const input = {
|
||||||
auth_type: 'oauth',
|
auth_type: 'oauth',
|
||||||
oauth_managed: true,
|
oauth_managed: true,
|
||||||
can_refresh_oauth: false,
|
can_refresh_oauth: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
expect(getProviderMaskedSecretLabel(key, 'codex')).toBe('[OAuth Token]')
|
expect(canRefreshOAuthCredential(input)).toBe(false)
|
||||||
expect(shouldShowOAuthRefreshControl(key, 'codex')).toBe(true)
|
expect(shouldShowOAuthRefreshControl(input)).toBe(false)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('keeps legacy oauth refresh control visible when backend capability is absent', () => {
|
||||||
|
const input = {
|
||||||
|
auth_type: 'oauth',
|
||||||
|
oauth_managed: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(canRefreshOAuthCredential(input)).toBe(true)
|
||||||
|
expect(shouldShowOAuthRefreshControl(input)).toBe(true)
|
||||||
|
expect(getProviderMaskedSecretLabel(input, 'codex')).toBe('[OAuth Token]')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -251,4 +251,20 @@ describe('providerKeyStatus', () => {
|
|||||||
})
|
})
|
||||||
expect(getOAuthStatusTitle(input, 0)).toBe('Refresh Token 未添加,无法自动刷新')
|
expect(getOAuthStatusTitle(input, 0)).toBe('Refresh Token 未添加,无法自动刷新')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('does not treat non-refreshable provider sessions as missing refresh token', () => {
|
||||||
|
const input = {
|
||||||
|
auth_type: 'oauth',
|
||||||
|
oauth_managed: true,
|
||||||
|
can_refresh_oauth: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(getOAuthStatusDisplayWithFallback(input, 0)).toEqual({
|
||||||
|
text: '有效期未知',
|
||||||
|
isExpired: false,
|
||||||
|
isExpiringSoon: false,
|
||||||
|
isInvalid: false,
|
||||||
|
})
|
||||||
|
expect(getOAuthStatusTitle(input, 0)).toBe('Token 有效期未知')
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ export function shouldShowOAuthRefreshControl(
|
|||||||
providerType?: string | null,
|
providerType?: string | null,
|
||||||
): boolean {
|
): boolean {
|
||||||
if (isGrokSessionCredential(input, providerType)) return false
|
if (isGrokSessionCredential(input, providerType)) return false
|
||||||
return isOAuthManagedCredential(input)
|
return canRefreshOAuthCredential(input)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canExportOAuthCredential(input: ProviderKeyAuthCarrier): boolean {
|
export function canExportOAuthCredential(input: ProviderKeyAuthCarrier): boolean {
|
||||||
|
|||||||
@@ -202,7 +202,7 @@ function mergeOAuthStatusDisplay(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function isOAuthCredentialWithoutRefreshToken(input: ProviderKeyStatusCarrier): boolean {
|
function isOAuthCredentialWithoutRefreshToken(input: ProviderKeyStatusCarrier): boolean {
|
||||||
return isOAuthManagedCredential(input) && !canRefreshOAuthCredential(input)
|
return isOAuthManagedCredential(input) && input.oauth_temporary === true
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMissingRefreshTokenStatus(): OAuthStatusInfo {
|
function getMissingRefreshTokenStatus(): OAuthStatusInfo {
|
||||||
|
|||||||
Reference in New Issue
Block a user