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:
DaydreamCoding
2026-05-26 19:46:08 +08:00
committed by QTom
co-authored by Claude Opus 4.7
parent 9ef144874a
commit 11fe7de926
6 changed files with 144 additions and 20 deletions
+25
View File
@@ -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,