From efcc6b5337f0f44d0a6a643d2f886aa7dd332264 Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 11 Mar 2026 11:09:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=9B=B4=E6=96=B0=20ProxyRoute=20?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=20TLS=20=E8=AF=81=E4=B9=A6=E5=AD=97=E6=AE=B5=E9=9A=90=E7=A7=81?= =?UTF-8?q?=EF=BC=8C=E5=A2=9E=E5=BC=BA=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= =?UTF-8?q?=E4=BB=A5=E9=AA=8C=E8=AF=81=20HTTPS=20=E8=B7=AF=E7=94=B1?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- atsf_server/model/proxy_route.go | 11 ++++- atsf_server/model/tls_certificate.go | 4 +- atsf_server/router/api_phase1_test.go | 48 +++++++++++++++++++ atsf_server/web/src/pages/ProxyRoute/index.js | 4 +- 4 files changed, 63 insertions(+), 4 deletions(-) diff --git a/atsf_server/model/proxy_route.go b/atsf_server/model/proxy_route.go index cc29682b..2fab4b6f 100644 --- a/atsf_server/model/proxy_route.go +++ b/atsf_server/model/proxy_route.go @@ -37,7 +37,16 @@ func (route *ProxyRoute) Insert() error { } func (route *ProxyRoute) Update() error { - return DB.Model(route).Select("domain", "origin_url", "enabled", "enable_https", "cert_id", "redirect_http", "custom_headers", "remark").Updates(route).Error + return DB.Model(&ProxyRoute{}).Where("id = ?", route.ID).Updates(map[string]any{ + "domain": route.Domain, + "origin_url": route.OriginURL, + "enabled": route.Enabled, + "enable_https": route.EnableHTTPS, + "cert_id": route.CertID, + "redirect_http": route.RedirectHTTP, + "custom_headers": route.CustomHeaders, + "remark": route.Remark, + }).Error } func (route *ProxyRoute) Delete() error { diff --git a/atsf_server/model/tls_certificate.go b/atsf_server/model/tls_certificate.go index 2c129244..a808cc0e 100644 --- a/atsf_server/model/tls_certificate.go +++ b/atsf_server/model/tls_certificate.go @@ -5,8 +5,8 @@ import "time" type TLSCertificate struct { ID uint `json:"id" gorm:"primaryKey"` Name string `json:"name" gorm:"uniqueIndex;size:255;not null"` - CertPEM string `json:"cert_pem" gorm:"type:text;not null"` - KeyPEM string `json:"key_pem" gorm:"type:text;not null"` + CertPEM string `json:"-" gorm:"type:text;not null"` + KeyPEM string `json:"-" gorm:"type:text;not null"` NotBefore time.Time `json:"not_before"` NotAfter time.Time `json:"not_after"` Remark string `json:"remark" gorm:"size:255"` diff --git a/atsf_server/router/api_phase1_test.go b/atsf_server/router/api_phase1_test.go index ea08fae5..72432171 100644 --- a/atsf_server/router/api_phase1_test.go +++ b/atsf_server/router/api_phase1_test.go @@ -188,6 +188,54 @@ func TestPhase1HTTPSAndCertificateImportLifecycle(t *testing.T) { t.Fatal("expected route to persist https certificate binding") } + updateResp := performJSONRequest(t, engine, token, http.MethodPut, "/api/proxy-routes/"+toString(route.ID), map[string]any{ + "domain": "secure.example.com", + "origin_url": "http://origin-secure.internal", + "enabled": true, + "enable_https": false, + "cert_id": nil, + "redirect_http": false, + "remark": "downgraded route", + }) + decodeResponseData(t, updateResp, &route) + if route.EnableHTTPS || route.CertID != nil || route.RedirectHTTP { + t.Fatalf("expected route to disable https flags, got %+v", route) + } + + updateResp = performJSONRequest(t, engine, token, http.MethodPut, "/api/proxy-routes/"+toString(route.ID), map[string]any{ + "domain": "secure.example.com", + "origin_url": "https://origin-secure.internal", + "enabled": true, + "enable_https": true, + "cert_id": manualCertificate.ID, + "redirect_http": true, + "remark": "re-enabled https route", + }) + decodeResponseData(t, updateResp, &route) + if !route.EnableHTTPS || route.CertID == nil || *route.CertID != manualCertificate.ID || !route.RedirectHTTP { + t.Fatalf("expected route update to persist https fields, got %+v", route) + } + + listResp := performJSONRequest(t, engine, token, http.MethodGet, "/api/proxy-routes/", nil) + var routes []model.ProxyRoute + decodeResponseData(t, listResp, &routes) + if len(routes) != 1 || !routes[0].EnableHTTPS || routes[0].CertID == nil || *routes[0].CertID != manualCertificate.ID || !routes[0].RedirectHTTP { + t.Fatalf("expected route list to reflect https update, got %+v", routes) + } + + certificateListResp := performJSONRequest(t, engine, token, http.MethodGet, "/api/tls-certificates/", nil) + var certificateList []map[string]any + decodeResponseData(t, certificateListResp, &certificateList) + if len(certificateList) == 0 { + t.Fatal("expected certificate list to return records") + } + if _, exists := certificateList[0]["cert_pem"]; exists { + t.Fatal("expected certificate list to omit cert_pem") + } + if _, exists := certificateList[0]["key_pem"]; exists { + t.Fatal("expected certificate list to omit key_pem") + } + resp = performJSONRequest(t, engine, token, http.MethodPost, "/api/config-versions/publish", nil) var version model.ConfigVersion decodeResponseData(t, resp, &version) diff --git a/atsf_server/web/src/pages/ProxyRoute/index.js b/atsf_server/web/src/pages/ProxyRoute/index.js index cce9a42f..315eae46 100644 --- a/atsf_server/web/src/pages/ProxyRoute/index.js +++ b/atsf_server/web/src/pages/ProxyRoute/index.js @@ -119,7 +119,9 @@ const ProxyRoute = () => { setMatchResult(null); }; - const submitRoute = async () => { + const submitRoute = async (event) => { + event?.preventDefault?.(); + const payload = { ...form, domain: form.domain.trim(),