mirror of
https://github.com/CJackHwang/ds2api.git
synced 2026-05-12 12:17:47 +08:00
fix proxy fallback binding and redact proxy password responses
This commit is contained in:
@@ -27,6 +27,19 @@ func validateProxyMutation(cfg *config.Config) error {
|
||||
return config.ValidateAccountProxyReferences(cfg.Accounts, cfg.Proxies)
|
||||
}
|
||||
|
||||
func proxyResponse(proxy config.Proxy) map[string]any {
|
||||
proxy = config.NormalizeProxy(proxy)
|
||||
return map[string]any{
|
||||
"id": proxy.ID,
|
||||
"name": proxy.Name,
|
||||
"type": proxy.Type,
|
||||
"host": proxy.Host,
|
||||
"port": proxy.Port,
|
||||
"username": proxy.Username,
|
||||
"has_password": strings.TrimSpace(proxy.Password) != "",
|
||||
}
|
||||
}
|
||||
|
||||
func (h *Handler) listProxies(w http.ResponseWriter, _ *http.Request) {
|
||||
proxies := h.Store.Snapshot().Proxies
|
||||
items := make([]map[string]any, 0, len(proxies))
|
||||
@@ -57,7 +70,7 @@ func (h *Handler) addProxy(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]any{"detail": err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"success": true, "proxy": proxy})
|
||||
writeJSON(w, http.StatusOK, map[string]any{"success": true, "proxy": proxyResponse(proxy)})
|
||||
}
|
||||
|
||||
func (h *Handler) updateProxy(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -92,7 +105,7 @@ func (h *Handler) updateProxy(w http.ResponseWriter, r *http.Request) {
|
||||
writeJSON(w, http.StatusBadRequest, map[string]any{"detail": err.Error()})
|
||||
return
|
||||
}
|
||||
writeJSON(w, http.StatusOK, map[string]any{"success": true, "proxy": proxy})
|
||||
writeJSON(w, http.StatusOK, map[string]any{"success": true, "proxy": proxyResponse(proxy)})
|
||||
}
|
||||
|
||||
func (h *Handler) deleteProxy(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -126,6 +126,40 @@ func TestDeleteProxyClearsAssignedAccountProxyID(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateProxyResponseDoesNotExposeStoredPassword(t *testing.T) {
|
||||
h := newAdminProxyTestHandler(t, `{
|
||||
"proxies":[{"id":"proxy-1","name":"Node 1","type":"socks5h","host":"127.0.0.1","port":1080,"username":"u","password":"secret"}]
|
||||
}`)
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Put("/admin/proxies/{proxyID}", h.updateProxy)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPut, "/admin/proxies/proxy-1", bytes.NewBufferString(`{
|
||||
"name":"Node 1",
|
||||
"type":"socks5h",
|
||||
"host":"127.0.0.2",
|
||||
"port":1081,
|
||||
"username":"u2"
|
||||
}`))
|
||||
rec := httptest.NewRecorder()
|
||||
r.ServeHTTP(rec, req)
|
||||
|
||||
if rec.Code != http.StatusOK {
|
||||
t.Fatalf("unexpected status: %d body=%s", rec.Code, rec.Body.String())
|
||||
}
|
||||
var payload map[string]any
|
||||
if err := json.Unmarshal(rec.Body.Bytes(), &payload); err != nil {
|
||||
t.Fatalf("decode response: %v", err)
|
||||
}
|
||||
proxy, _ := payload["proxy"].(map[string]any)
|
||||
if _, exists := proxy["password"]; exists {
|
||||
t.Fatalf("response should not expose password, got %#v", proxy)
|
||||
}
|
||||
if hasPassword, _ := proxy["has_password"].(bool); !hasPassword {
|
||||
t.Fatalf("expected has_password=true, got %#v", proxy)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateAccountProxyAssignsProxyID(t *testing.T) {
|
||||
h := newAdminProxyTestHandler(t, `{
|
||||
"proxies":[{"id":"proxy-1","name":"Node 1","type":"socks5h","host":"127.0.0.1","port":1080}],
|
||||
|
||||
Reference in New Issue
Block a user