mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-03 01:40:21 +08:00
Fix OAuth token import and table filters
This commit is contained in:
@@ -2,7 +2,9 @@ import { describe, expect, it } from 'vitest'
|
||||
|
||||
import {
|
||||
getAccountStatusDisplay,
|
||||
getOAuthRefreshButtonTitle,
|
||||
getOAuthStatusDisplay,
|
||||
getOAuthStatusDisplayWithFallback,
|
||||
getOAuthStatusTitle,
|
||||
} from '@/utils/providerKeyStatus'
|
||||
|
||||
@@ -155,4 +157,50 @@ describe('providerKeyStatus', () => {
|
||||
oauth_expires_at: future,
|
||||
}, 0)).toContain('Token 剩余有效期:')
|
||||
})
|
||||
|
||||
it('shows missing refresh token state for access-token-only oauth credentials', () => {
|
||||
const input = {
|
||||
auth_type: 'oauth',
|
||||
oauth_managed: true,
|
||||
oauth_temporary: true,
|
||||
}
|
||||
|
||||
expect(getOAuthStatusDisplay(input, 0)).toBeNull()
|
||||
expect(getOAuthStatusDisplayWithFallback(input, 0)).toEqual({
|
||||
text: '未添加',
|
||||
isExpired: false,
|
||||
isExpiringSoon: false,
|
||||
isInvalid: false,
|
||||
})
|
||||
expect(getOAuthStatusTitle(input, 0)).toBe('Refresh Token 未添加,无法自动刷新')
|
||||
expect(getOAuthRefreshButtonTitle(input, 0)).toBe('仅 Access Token 导入,无法自动刷新,到期后需要重新导入')
|
||||
})
|
||||
|
||||
it('does not show invalid oauth state when refresh token is missing', () => {
|
||||
const input = {
|
||||
auth_type: 'oauth',
|
||||
oauth_managed: true,
|
||||
oauth_temporary: true,
|
||||
status_snapshot: {
|
||||
oauth: {
|
||||
code: 'invalid',
|
||||
reason: 'missing_refresh_token',
|
||||
requires_reauth: true,
|
||||
},
|
||||
account: {
|
||||
code: 'ok',
|
||||
blocked: false,
|
||||
},
|
||||
quota: { code: 'ok', exhausted: false },
|
||||
},
|
||||
}
|
||||
|
||||
expect(getOAuthStatusDisplayWithFallback(input, 0)).toEqual({
|
||||
text: '未添加',
|
||||
isExpired: false,
|
||||
isExpiringSoon: false,
|
||||
isInvalid: false,
|
||||
})
|
||||
expect(getOAuthStatusTitle(input, 0)).toBe('Refresh Token 未添加,无法自动刷新')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -3,6 +3,7 @@ export interface ProviderKeyAuthCarrier {
|
||||
credential_kind?: string | null
|
||||
runtime_auth_kind?: string | null
|
||||
oauth_managed?: boolean | null
|
||||
oauth_temporary?: boolean | null
|
||||
can_refresh_oauth?: boolean | null
|
||||
can_export_oauth?: boolean | null
|
||||
can_edit_oauth?: boolean | null
|
||||
@@ -68,12 +69,19 @@ export function isServiceAccountCredential(input: ProviderKeyAuthCarrier): boole
|
||||
}
|
||||
|
||||
export function canRefreshOAuthCredential(input: ProviderKeyAuthCarrier): boolean {
|
||||
if (input.oauth_temporary === true) {
|
||||
return false
|
||||
}
|
||||
if (typeof input.can_refresh_oauth === 'boolean') {
|
||||
return input.can_refresh_oauth
|
||||
}
|
||||
return isOAuthManagedCredential(input)
|
||||
}
|
||||
|
||||
export function shouldShowOAuthRefreshControl(input: ProviderKeyAuthCarrier): boolean {
|
||||
return isOAuthManagedCredential(input)
|
||||
}
|
||||
|
||||
export function canExportOAuthCredential(input: ProviderKeyAuthCarrier): boolean {
|
||||
if (typeof input.can_export_oauth === 'boolean') {
|
||||
return input.can_export_oauth
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
isRefreshFailedReason,
|
||||
} from './accountBlock'
|
||||
import {
|
||||
canRefreshOAuthCredential,
|
||||
isOAuthManagedCredential,
|
||||
type ProviderKeyAuthCarrier,
|
||||
} from './providerKeyAuth'
|
||||
@@ -157,6 +158,19 @@ function mergeOAuthStatusDisplay(
|
||||
return snapshotStatus ?? legacyStatus
|
||||
}
|
||||
|
||||
function isOAuthCredentialWithoutRefreshToken(input: ProviderKeyStatusCarrier): boolean {
|
||||
return isOAuthManagedCredential(input) && !canRefreshOAuthCredential(input)
|
||||
}
|
||||
|
||||
function getMissingRefreshTokenStatus(): OAuthStatusInfo {
|
||||
return {
|
||||
text: '未添加',
|
||||
isExpired: false,
|
||||
isExpiringSoon: false,
|
||||
isInvalid: false,
|
||||
}
|
||||
}
|
||||
|
||||
export function getOAuthStatusDisplay(
|
||||
input: ProviderKeyStatusCarrier,
|
||||
tick: number,
|
||||
@@ -167,12 +181,38 @@ export function getOAuthStatusDisplay(
|
||||
)
|
||||
}
|
||||
|
||||
export function getOAuthStatusDisplayWithFallback(
|
||||
input: ProviderKeyStatusCarrier,
|
||||
tick: number,
|
||||
): OAuthStatusInfo | null {
|
||||
if (isOAuthCredentialWithoutRefreshToken(input)) {
|
||||
return getMissingRefreshTokenStatus()
|
||||
}
|
||||
|
||||
const status = getOAuthStatusDisplay(input, tick)
|
||||
if (status) return status
|
||||
if (!isOAuthManagedCredential(input)) return null
|
||||
|
||||
return {
|
||||
text: '有效期未知',
|
||||
isExpired: false,
|
||||
isExpiringSoon: false,
|
||||
isInvalid: false,
|
||||
}
|
||||
}
|
||||
|
||||
export function getOAuthStatusTitle(
|
||||
input: ProviderKeyStatusCarrier,
|
||||
tick: number,
|
||||
): string {
|
||||
if (isOAuthCredentialWithoutRefreshToken(input)) {
|
||||
return 'Refresh Token 未添加,无法自动刷新'
|
||||
}
|
||||
|
||||
const status = getOAuthStatusDisplay(input, tick)
|
||||
if (!status) return ''
|
||||
if (!status) {
|
||||
return isOAuthManagedCredential(input) ? 'Token 有效期未知' : ''
|
||||
}
|
||||
if (status.isInvalid) {
|
||||
const reason = normalizeText(status.invalidReason)
|
||||
return reason ? `Token 已失效: ${reason}` : 'Token 已失效'
|
||||
@@ -187,6 +227,13 @@ export function getOAuthRefreshButtonTitle(
|
||||
input: ProviderKeyStatusCarrier,
|
||||
tick: number,
|
||||
): string {
|
||||
if (isOAuthManagedCredential(input) && !canRefreshOAuthCredential(input)) {
|
||||
if (input.oauth_temporary === true) {
|
||||
return '仅 Access Token 导入,无法自动刷新,到期后需要重新导入'
|
||||
}
|
||||
return '当前 OAuth 凭据无法自动刷新,到期后需要重新导入'
|
||||
}
|
||||
|
||||
const status = getOAuthStatusDisplay(input, tick)
|
||||
if (status?.isInvalid || status?.isExpired) {
|
||||
return '重新授权'
|
||||
|
||||
Reference in New Issue
Block a user