From 37de6575dfca82913a658074955ada6fa6bca682 Mon Sep 17 00:00:00 2001 From: chenchen Date: Mon, 11 May 2026 17:14:35 +0800 Subject: [PATCH] fix(server): backport two prod hot-patches that kept getting wiped MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. /api/heicode-auth/* proxy: CriticalRateLimit (20/20min) → GlobalAPIRateLimit (180/180s). The Heicode external-identity proxy is hit on every page render for /me + /refresh plus the login burst — CriticalRateLimit is sized for sensitive ops (password reset, 2FA) and trips at ~5 quick page loads, returning 429 to a normal user. APIM upstream rate-limits itself, so a second tight layer here adds no security and just manufactures 429s. 2. JIT-create user group: seed "default" instead of me.Data.ChannelID. Companion to 578a68f which only patched the every-login overwrite path. New users (yj2824269760@gmail.com et al, JIT-created after 578a68f) still landed in a UUID group → empty /v1/models response → desktop client showed the static 3-Claude fallback list. Both fixes were applied on the production VM directly today (sed + python patch) — committing them so the next docker rebuild on VM keeps them instead of reverting to the buggy file via git checkout. DB hot-fix already applied: 6 affected users moved to group=default. Co-Authored-By: Claude Opus 4.7 (1M context) --- heicode/controller/heicode_agnet_session.go | 11 +++++++---- heicode/router/api-router.go | 7 ++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/heicode/controller/heicode_agnet_session.go b/heicode/controller/heicode_agnet_session.go index 81e02e7..721f3cc 100644 --- a/heicode/controller/heicode_agnet_session.go +++ b/heicode/controller/heicode_agnet_session.go @@ -242,10 +242,13 @@ func syncLocalUserFromAgnet(me agnetMeEnvelope) (*model.User, error) { if display == "" { display = strings.Split(email, "@")[0] } - group := strings.TrimSpace(me.Data.ChannelID) - if group == "" { - group = "default" - } + // Local model-access bucket — never seed with the Agnet channelId + // (no abilities row matches a random UUID, so the new user would land + // with zero models on first /v1/models call). Admins control group + // from the NewAPI dashboard after JIT-create. Fix companion to + // 578a68f which only patched the every-login overwrite path. + group := "default" + _ = me.Data.ChannelID nu := model.User{ Username: jitUsernameFromEmail(email), Password: common.GetRandomString(32), diff --git a/heicode/router/api-router.go b/heicode/router/api-router.go index 5668a2c..044572a 100644 --- a/heicode/router/api-router.go +++ b/heicode/router/api-router.go @@ -58,7 +58,12 @@ func SetApiRouter(router *gin.Engine) { // Frontend calls /api/heicode-auth/; controller forwards to // ${HEICODE_AUTH_BASE_URL}/. Avoids browser CORS preflight failures // when APIM has not added code.xinghanlab.com to its allow-list. - apiRouter.Any("/heicode-auth/*proxyPath", middleware.CriticalRateLimit(), controller.HeicodeAuthProxy) + // Use GlobalAPIRateLimit (180 req / 180s) not CriticalRateLimit (20 req + // / 20 min). The proxy is hit on every page render for /me /refresh + // plus the login burst — CriticalRateLimit is for sensitive ops + // (login, password reset) and trips at ~5 quick page loads, returning + // 429 to a normal user. Upstream APIM rate-limits itself anyway. + apiRouter.Any("/heicode-auth/*proxyPath", middleware.GlobalAPIRateLimit(), controller.HeicodeAuthProxy) userRoute := apiRouter.Group("/user") {