From 63c079d8738f55c8475e26c1417e84e6c8e9fd46 Mon Sep 17 00:00:00 2001 From: a408665321 <408665321@qq.com> Date: Sun, 20 Sep 2026 14:39:36 +0800 Subject: [PATCH] fix(account): preserve settings on OAuth reauth --- .../internal/handler/admin/account_handler.go | 4 ++ ...count_handler_long_context_billing_test.go | 38 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/backend/internal/handler/admin/account_handler.go b/backend/internal/handler/admin/account_handler.go index f97dc4886a..52500c4222 100644 --- a/backend/internal/handler/admin/account_handler.go +++ b/backend/internal/handler/admin/account_handler.go @@ -1609,6 +1609,10 @@ func (h *AccountHandler) ApplyOAuthCredentials(c *gin.Context) { return } + // Re-auth only returns authentication fields. Preserve account configuration + // stored alongside them (for example model_mapping), while allowing the new + // OAuth values to replace their existing counterparts. + req.Credentials = service.MergeCredentials(existing.Credentials, req.Credentials) // Drop SSO/password residue; re-auth must leave only OAuth tokens on disk. req.Credentials = service.SanitizeStoredCredentials(existing.Platform, req.Credentials) diff --git a/backend/internal/handler/admin/account_handler_long_context_billing_test.go b/backend/internal/handler/admin/account_handler_long_context_billing_test.go index 4d40e93bf7..db4e706611 100644 --- a/backend/internal/handler/admin/account_handler_long_context_billing_test.go +++ b/backend/internal/handler/admin/account_handler_long_context_billing_test.go @@ -142,6 +142,44 @@ func TestApplyOAuthCredentialsRejectsMalformedOpenAILongContextBillingBeforeMuta require.Zero(t, stub.updateAccountExtraCalls) } +func TestApplyOAuthCredentialsPreservesExistingNonAuthCredentials(t *testing.T) { + gin.SetMode(gin.TestMode) + stub := newStubAdminService() + stub.getAccountResult = &service.Account{ + ID: 1, + Platform: service.PlatformOpenAI, + Type: service.AccountTypeOAuth, + Credentials: map[string]any{ + "access_token": "old-token", + "refresh_token": "old-refresh-token", + "model_mapping": map[string]any{"gpt-5": "gpt-5"}, + "account_id": "existing-account-id", + "password": "must-not-survive", + "sso_token": "must-not-survive", + "cookie": "must-not-survive", + }, + } + handler := NewAccountHandler(stub, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil) + router := gin.New() + router.POST("/accounts/:id/apply-oauth-credentials", handler.ApplyOAuthCredentials) + recorder := httptest.NewRecorder() + request := httptest.NewRequest(http.MethodPost, "/accounts/1/apply-oauth-credentials", bytes.NewBufferString( + `{"type":"oauth","credentials":{"access_token":"new-token","refresh_token":"new-refresh-token"}}`, + )) + request.Header.Set("Content-Type", "application/json") + + router.ServeHTTP(recorder, request) + + require.Equal(t, http.StatusOK, recorder.Code) + require.Equal(t, 1, stub.updateAccountCalls) + require.Equal(t, map[string]any{ + "access_token": "new-token", + "refresh_token": "new-refresh-token", + "model_mapping": map[string]any{"gpt-5": "gpt-5"}, + "account_id": "existing-account-id", + }, stub.lastUpdateAccountInput.Credentials) +} + func TestOpenAIOAuthCodexPATBoundaryRejectsMalformedOpenAILongContextBillingValueBeforeTokenValidation(t *testing.T) { gin.SetMode(gin.TestMode) handler := NewOpenAIOAuthHandler(nil, newStubAdminService(), nil, nil)