Files
Prism/internal/api/handlers_settings.go
T
rose_cat707 024c15a836
CI / test (push) Has been cancelled
CI / docker (push) Has been cancelled
feat: Prism HTTP/SOCKS5 代理网关及管理台
Go 控制面(SQLite + REST API)嵌入 Mihomo 数据面,Vue 3 多语言 Web 管理台。
含订阅/节点/规则/出站/监控/日志、OpenAPI、API Key、Gitea Actions CI 与开源文档。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-23 12:18:58 +08:00

98 lines
2.7 KiB
Go

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
}