fix(server): backport two prod hot-patches that kept getting wiped
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 to578a68fwhich only patched the every-login overwrite path. New users (yj2824269760@gmail.com et al, JIT-created after578a68f) 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) <noreply@anthropic.com>
This commit is contained in:
@@ -242,10 +242,13 @@ func syncLocalUserFromAgnet(me agnetMeEnvelope) (*model.User, error) {
|
|||||||
if display == "" {
|
if display == "" {
|
||||||
display = strings.Split(email, "@")[0]
|
display = strings.Split(email, "@")[0]
|
||||||
}
|
}
|
||||||
group := strings.TrimSpace(me.Data.ChannelID)
|
// Local model-access bucket — never seed with the Agnet channelId
|
||||||
if group == "" {
|
// (no abilities row matches a random UUID, so the new user would land
|
||||||
group = "default"
|
// 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{
|
nu := model.User{
|
||||||
Username: jitUsernameFromEmail(email),
|
Username: jitUsernameFromEmail(email),
|
||||||
Password: common.GetRandomString(32),
|
Password: common.GetRandomString(32),
|
||||||
|
|||||||
@@ -58,7 +58,12 @@ func SetApiRouter(router *gin.Engine) {
|
|||||||
// Frontend calls /api/heicode-auth/<path>; controller forwards to
|
// Frontend calls /api/heicode-auth/<path>; controller forwards to
|
||||||
// ${HEICODE_AUTH_BASE_URL}/<path>. Avoids browser CORS preflight failures
|
// ${HEICODE_AUTH_BASE_URL}/<path>. Avoids browser CORS preflight failures
|
||||||
// when APIM has not added code.xinghanlab.com to its allow-list.
|
// 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")
|
userRoute := apiRouter.Group("/user")
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user