mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-10-28 08:08:32 +00:00
fix(account): 重新授权不再清空 Extra 配置
Claude / OpenAI 账号重新授权走通用 PUT /accounts/:id 时,后端 UpdateAccount 会全量覆盖 account.Extra(仅保留 5 个 quota 用量键), 导致 base_rpm / window_cost_limit / window_cost_sticky_reserve / max_sessions / quota_* / privacy_mode 等持久化配置全部丢失。 新增专用接口 POST /accounts/:id/apply-oauth-credentials,沿用 现有 /refresh 路径模式:Credentials-only update + Extra JSONB key 级合并(UpdateAccountExtra) + ClearError + InvalidateToken。 作用域:Claude OAuth / Claude Cookie auth / OpenAI OAuth 三个 调用点。Gemini / Antigravity 现有路径本就不传 extra,保持不变。 顺带修复:旧重新授权路径未调用 InvalidateToken,导致重新授权后 首请求可能仍用缓存中的旧 token 而立即 401。 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
QTom
co-authored by
Claude Opus 4.7
parent
9ef144874a
commit
11fe7de926
@@ -204,6 +204,30 @@ export async function refreshCredentials(id: number): Promise<Account> {
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply OAuth credentials after re-authorization.
|
||||
*
|
||||
* Unlike `update()`, this endpoint:
|
||||
* - never overwrites the whole `extra` JSONB (merges incrementally instead),
|
||||
* so persistent settings like `base_rpm`, `window_cost_limit`, `max_sessions`,
|
||||
* `quota_*` and `privacy_mode` are preserved
|
||||
* - clears the account error and invalidates the token cache server-side
|
||||
*/
|
||||
export async function applyOAuthCredentials(
|
||||
id: number,
|
||||
payload: {
|
||||
type: 'oauth' | 'setup-token'
|
||||
credentials: Record<string, unknown>
|
||||
extra?: Record<string, unknown>
|
||||
}
|
||||
): Promise<Account> {
|
||||
const { data } = await apiClient.post<Account>(
|
||||
`/admin/accounts/${id}/apply-oauth-credentials`,
|
||||
payload
|
||||
)
|
||||
return data
|
||||
}
|
||||
|
||||
/**
|
||||
* Get account usage statistics
|
||||
* @param id - Account ID
|
||||
@@ -665,6 +689,7 @@ export const accountsAPI = {
|
||||
toggleStatus,
|
||||
testAccount,
|
||||
refreshCredentials,
|
||||
applyOAuthCredentials,
|
||||
getStats,
|
||||
clearError,
|
||||
getUsage,
|
||||
|
||||
@@ -371,16 +371,12 @@ const handleExchangeCode = async () => {
|
||||
const extra = oauthClient.buildExtraInfo(tokenInfo)
|
||||
|
||||
try {
|
||||
// Update account with new credentials
|
||||
await adminAPI.accounts.update(props.account.id, {
|
||||
type: 'oauth', // OpenAI OAuth is always 'oauth' type
|
||||
const updatedAccount = await adminAPI.accounts.applyOAuthCredentials(props.account.id, {
|
||||
type: 'oauth',
|
||||
credentials,
|
||||
extra
|
||||
})
|
||||
|
||||
// Clear error status after successful re-authorization
|
||||
const updatedAccount = await adminAPI.accounts.clearError(props.account.id)
|
||||
|
||||
appStore.showSuccess(t('admin.accounts.reAuthorizedSuccess'))
|
||||
emit('reauthorized', updatedAccount)
|
||||
handleClose()
|
||||
@@ -476,16 +472,12 @@ const handleExchangeCode = async () => {
|
||||
|
||||
const extra = claudeOAuth.buildExtraInfo(tokenInfo)
|
||||
|
||||
// Update account with new credentials and type
|
||||
await adminAPI.accounts.update(props.account.id, {
|
||||
type: addMethod.value, // Update type based on selected method
|
||||
credentials: tokenInfo,
|
||||
const updatedAccount = await adminAPI.accounts.applyOAuthCredentials(props.account.id, {
|
||||
type: addMethod.value as 'oauth' | 'setup-token',
|
||||
credentials: tokenInfo as unknown as Record<string, unknown>,
|
||||
extra
|
||||
})
|
||||
|
||||
// Clear error status after successful re-authorization
|
||||
const updatedAccount = await adminAPI.accounts.clearError(props.account.id)
|
||||
|
||||
appStore.showSuccess(t('admin.accounts.reAuthorizedSuccess'))
|
||||
emit('reauthorized', updatedAccount)
|
||||
handleClose()
|
||||
@@ -519,16 +511,12 @@ const handleCookieAuth = async (sessionKey: string) => {
|
||||
|
||||
const extra = claudeOAuth.buildExtraInfo(tokenInfo)
|
||||
|
||||
// Update account with new credentials and type
|
||||
await adminAPI.accounts.update(props.account.id, {
|
||||
type: addMethod.value, // Update type based on selected method
|
||||
credentials: tokenInfo,
|
||||
const updatedAccount = await adminAPI.accounts.applyOAuthCredentials(props.account.id, {
|
||||
type: addMethod.value as 'oauth' | 'setup-token',
|
||||
credentials: tokenInfo as unknown as Record<string, unknown>,
|
||||
extra
|
||||
})
|
||||
|
||||
// Clear error status after successful re-authorization
|
||||
const updatedAccount = await adminAPI.accounts.clearError(props.account.id)
|
||||
|
||||
appStore.showSuccess(t('admin.accounts.reAuthorizedSuccess'))
|
||||
emit('reauthorized', updatedAccount)
|
||||
handleClose()
|
||||
|
||||
Reference in New Issue
Block a user