From e7a3c1202eafca989857dd18f9cfaf0c4de9be67 Mon Sep 17 00:00:00 2001 From: wucm667 Date: Fri, 14 Aug 2026 02:40:18 +0800 Subject: [PATCH 1/2] fix(antigravity): route paid accounts to daily endpoint --- .../service/antigravity_gateway_retry.go | 30 +++++++++--- .../service/antigravity_rate_limit_test.go | 46 ++++++++++++++++--- 2 files changed, 63 insertions(+), 13 deletions(-) diff --git a/backend/internal/service/antigravity_gateway_retry.go b/backend/internal/service/antigravity_gateway_retry.go index f2f5d44f8..5e16ba869 100644 --- a/backend/internal/service/antigravity_gateway_retry.go +++ b/backend/internal/service/antigravity_gateway_retry.go @@ -48,17 +48,14 @@ type antigravityRetryLoopResult struct { // resolveAntigravityForwardBaseURL 解析转发用 base URL。 // -// 默认使用生产端点 cloudcode-pa.googleapis.com(antigravity.BaseURLs 的首个地址, -// 与账号 OAuth 登录/测试连接所用的 antigravity.BaseURL 一致)。 +// 显式环境变量优先。未配置时,LoadCodeAssist 返回 paidTier 的付费账号使用 +// daily 端点,其他账号继续使用生产端点,避免免费账号的 OAuth token 出现 401。 // // 历史上这里改用 ForwardBaseURLs()(把 daily/sandbox 排到首位)并默认取首个地址, // 导致网关把带生产 OAuth token 的请求发到 daily-cloudcode-pa.sandbox.googleapis.com, // 上游拒绝 → 账号被 401「Invalid bearer token」/502 打入临时不可调度且无法恢复 // (见 #3611 / #2962)。后台「测试连接」用的是生产端点,所以「测试成功但网关 401」。 -// -// daily/sandbox 端点仅供内部联调,需显式设置 -// GATEWAY_ANTIGRAVITY_FORWARD_BASE_URL=daily(或 sandbox)才启用。 -func resolveAntigravityForwardBaseURL() string { +func resolveAntigravityForwardBaseURL(account *Account) string { baseURLs := antigravity.BaseURLs if len(baseURLs) == 0 { return "" @@ -67,9 +64,28 @@ func resolveAntigravityForwardBaseURL() string { if (mode == "daily" || mode == "sandbox") && len(baseURLs) > 1 { return baseURLs[1] } + if mode == "" && accountHasAntigravityPaidTier(account) && len(baseURLs) > 1 { + return baseURLs[1] + } return baseURLs[0] } +func accountHasAntigravityPaidTier(account *Account) bool { + if account == nil || account.Credentials == nil { + return false + } + planType, ok := account.Credentials["plan_type"].(string) + if !ok { + return false + } + switch strings.ToLower(strings.TrimSpace(planType)) { + case "pro", "ultra": + return true + default: + return false + } +} + // smartRetryAction 智能重试的处理结果 type smartRetryAction int @@ -488,7 +504,7 @@ func (s *AntigravityGatewayService) antigravityRetryLoop(p antigravityRetryLoopP } } - baseURL := resolveAntigravityForwardBaseURL() + baseURL := resolveAntigravityForwardBaseURL(p.account) if baseURL == "" { return nil, errors.New("no antigravity forward base url configured") } diff --git a/backend/internal/service/antigravity_rate_limit_test.go b/backend/internal/service/antigravity_rate_limit_test.go index 374b29f61..c9b429829 100644 --- a/backend/internal/service/antigravity_rate_limit_test.go +++ b/backend/internal/service/antigravity_rate_limit_test.go @@ -1009,9 +1009,7 @@ func TestIsAntigravityAccountSwitchError(t *testing.T) { } } -func TestResolveAntigravityForwardBaseURL_DefaultDaily(t *testing.T) { - t.Setenv(antigravityForwardBaseURLEnv, "") - +func TestResolveAntigravityForwardBaseURL(t *testing.T) { oldBaseURLs := append([]string(nil), antigravity.BaseURLs...) defer func() { antigravity.BaseURLs = oldBaseURLs @@ -1019,10 +1017,46 @@ func TestResolveAntigravityForwardBaseURL_DefaultDaily(t *testing.T) { prodURL := "https://prod.test" dailyURL := "https://daily.test" - antigravity.BaseURLs = []string{dailyURL, prodURL} + antigravity.BaseURLs = []string{prodURL, dailyURL} - resolved := resolveAntigravityForwardBaseURL() - require.Equal(t, dailyURL, resolved) + tests := []struct { + name string + env string + account *Account + want string + }{ + { + name: "pro defaults to daily", account: &Account{Credentials: map[string]any{"plan_type": " Pro "}}, + want: dailyURL, + }, + { + name: "ultra defaults to daily", account: &Account{Credentials: map[string]any{"plan_type": "ULTRA"}}, + want: dailyURL, + }, + {name: "free defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "free"}}, want: prodURL}, + {name: "abnormal defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "Abnormal"}}, want: prodURL}, + {name: "unknown defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": "enterprise"}}, want: prodURL}, + {name: "malformed defaults to prod", account: &Account{Credentials: map[string]any{"plan_type": map[string]any{"name": "pro"}}}, want: prodURL}, + {name: "missing defaults to prod", account: &Account{Credentials: map[string]any{}}, want: prodURL}, + {name: "nil account defaults to prod", account: nil, want: prodURL}, + { + name: "daily override wins for free tier", env: " daily ", + account: &Account{Credentials: map[string]any{"plan_type": "free"}}, + want: dailyURL, + }, + { + name: "prod override wins for paid tier", env: " PROD ", + account: &Account{Credentials: map[string]any{"plan_type": "pro"}}, + want: prodURL, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Setenv(antigravityForwardBaseURLEnv, tt.env) + require.Equal(t, tt.want, resolveAntigravityForwardBaseURL(tt.account)) + }) + } } func TestAntigravityAccountSwitchError_Error(t *testing.T) { From b410c39133a117a05745a2eb2ba5fecd5f598c69 Mon Sep 17 00:00:00 2001 From: wucm667 Date: Wed, 19 Aug 2026 10:17:52 +0800 Subject: [PATCH 2/2] fix(security): add nanoid audit exception for GHSA-2v37-7h3g-55p8 --- .github/audit-exceptions.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/audit-exceptions.yml b/.github/audit-exceptions.yml index 2a89dd076..6243f0fa7 100644 --- a/.github/audit-exceptions.yml +++ b/.github/audit-exceptions.yml @@ -35,3 +35,10 @@ exceptions: mitigation: "Proxy configuration not user-controlled; upgrade when axios releases fix" expires_on: "2026-07-10" owner: "security@your-domain" + - package: nanoid + advisory: "GHSA-2v37-7h3g-55p8" + severity: high + reason: "Custom generator with size=0 not used; all nanoid calls use default size or positive values" + mitigation: "No zero-size custom generators in codebase; upgrade when nanoid releases fix" + expires_on: "2026-10-13" + owner: "security@your-domain"