package api import ( "context" "fmt" "net/http" "strings" "github.com/gin-gonic/gin" "golang.org/x/crypto/bcrypt" appsettings "github.com/prism/proxy/internal/settings" "github.com/prism/proxy/internal/store" ) func (s *Server) getSettings(c *gin.Context) { settings, err := s.app.Store.GetSettings(c.Request.Context()) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } safe := make(map[string]string) for k, v := range settings { if k == appsettings.KeyAdminPassword || k == appsettings.KeyProxyAuthPass { safe[k] = "" continue } safe[k] = v } c.JSON(http.StatusOK, appsettings.Display(safe)) } func (s *Server) putSettings(c *gin.Context) { var req map[string]string if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } if pw, ok := req[appsettings.KeyAdminPassword]; ok && pw != "" { hash, err := bcrypt.GenerateFromPassword([]byte(pw), bcrypt.DefaultCost) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } req[appsettings.KeyAdminPassword] = string(hash) } else { delete(req, appsettings.KeyAdminPassword) } if err := normalizeProxyAuthSettings(c.Request.Context(), s.app.Store, req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } appsettings.NormalizeSubmit(req) if err := s.app.Store.SetSettings(c.Request.Context(), req); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } allSettings, _ := s.app.Store.GetSettings(c.Request.Context()) applyGeoSettings(s.app.DataDir, allSettings) base, secret, _ := s.app.MihomoAPIBase(c.Request.Context()) s.health.UpdateAPIBase(base, secret) s.metrics.UpdateAPIBase(base, secret) s.syncMihomoClient(c.Request.Context()) _ = s.app.ReloadEngine(c.Request.Context()) c.JSON(http.StatusOK, gin.H{"ok": true}) } func normalizeProxyAuthSettings(ctx context.Context, st *store.Store, req map[string]string) error { user, hasUser := req["proxy_auth_user"] pass, hasPass := req["proxy_auth_pass"] if !hasUser && !hasPass { return nil } user = strings.TrimSpace(user) if user == "" { req["proxy_auth_user"] = "" req["proxy_auth_pass"] = "" return nil } if strings.Contains(user, ":") { return fmt.Errorf("代理用户名不能包含冒号") } req["proxy_auth_user"] = user if !hasPass || pass == "" { current, err := st.GetSettings(ctx) if err != nil { return err } if existing := current["proxy_auth_pass"]; existing != "" { delete(req, "proxy_auth_pass") return nil } return fmt.Errorf("请填写代理密码") } req["proxy_auth_pass"] = pass return nil }