mirror of
https://github.com/Sagit-chu/flvx.git
synced 2026-10-05 01:26:37 +08:00
fix(backend): improve captcha validation and forward service sync
- Add cloudflare site/secret key validation for captcha enabled check - Fix forward create to use UpdateService with tolerateExists for idempotent sync - Introduce isAlreadyExistsMessage helper excluding address-in-use errors - Add contract tests for forward toggle, address-in-use rollback, captcha compatibility
This commit is contained in:
@@ -311,7 +311,7 @@ func (h *Handler) sendNodeCommand(nodeID int64, commandType string, data interfa
|
||||
}
|
||||
msg := strings.ToLower(strings.TrimSpace(err.Error()))
|
||||
if tolerateExists {
|
||||
if strings.Contains(msg, "exists") || strings.Contains(msg, "already") || strings.Contains(msg, "已存在") {
|
||||
if isAlreadyExistsMessage(msg) {
|
||||
return result, nil
|
||||
}
|
||||
}
|
||||
@@ -907,6 +907,17 @@ func isNotFoundError(err error) bool {
|
||||
return strings.Contains(msg, "not found") || strings.Contains(msg, "不存在")
|
||||
}
|
||||
|
||||
func isAlreadyExistsMessage(message string) bool {
|
||||
msg := strings.ToLower(strings.TrimSpace(message))
|
||||
if msg == "" {
|
||||
return false
|
||||
}
|
||||
if strings.Contains(msg, "address already in use") {
|
||||
return false
|
||||
}
|
||||
return strings.Contains(msg, "already exists") || strings.Contains(msg, "已存在")
|
||||
}
|
||||
|
||||
func buildForwardServiceConfigs(baseName string, forward *forwardRecord, tunnel *tunnelRecord, node *nodeRecord, port int, limiterID *int64, tunnelTLSProtocol bool) []map[string]interface{} {
|
||||
protocols := []string{"tcp", "udp"}
|
||||
services := make([]map[string]interface{}, 0, 2)
|
||||
|
||||
@@ -53,3 +53,15 @@ func TestShouldTryLegacySingleService(t *testing.T) {
|
||||
t.Fatalf("DeleteService should not require legacy fallback")
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsAlreadyExistsMessage(t *testing.T) {
|
||||
if !isAlreadyExistsMessage("service demo already exists") {
|
||||
t.Fatalf("expected already exists message to be tolerated")
|
||||
}
|
||||
if !isAlreadyExistsMessage("服务已存在") {
|
||||
t.Fatalf("expected Chinese already exists message to be tolerated")
|
||||
}
|
||||
if isAlreadyExistsMessage("listen tcp [::]:10001: bind: address already in use") {
|
||||
t.Fatalf("address already in use must not be treated as already exists")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -989,10 +989,27 @@ func (h *Handler) captchaEnabled() (bool, error) {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if cfg == nil {
|
||||
if cfg == nil || !strings.EqualFold(strings.TrimSpace(cfg.Value), "true") {
|
||||
return false, nil
|
||||
}
|
||||
return strings.EqualFold(cfg.Value, "true"), nil
|
||||
|
||||
siteCfg, err := h.repo.GetConfigByName("cloudflare_site_key")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if siteCfg == nil || strings.TrimSpace(siteCfg.Value) == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
secretCfg, err := h.repo.GetConfigByName("cloudflare_secret_key")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if secretCfg == nil || strings.TrimSpace(secretCfg.Value) == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (h *Handler) apiClientCaptchaBypassEnabled(r *http.Request) bool {
|
||||
|
||||
@@ -1183,7 +1183,7 @@ func (h *Handler) forwardCreate(w http.ResponseWriter, r *http.Request) {
|
||||
response.WriteJSON(w, response.Err(-2, err.Error()))
|
||||
return
|
||||
}
|
||||
if err := h.syncForwardServices(createdForward, "AddService", false); err != nil {
|
||||
if err := h.syncForwardServices(createdForward, "UpdateService", true); err != nil {
|
||||
_ = h.deleteForwardByID(forwardID)
|
||||
response.WriteJSON(w, response.ErrDefault(err.Error()))
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user