feat(sub): auto-detect subscription format by User-Agent (Updated) (#5826)

* feat(settings): add subscription format controls

* feat(sub): auto-detect subscription formats

* fix(xray): validate balancer regexes before save

* Revert "fix(xray): validate balancer regexes before save"

This reverts commit 8a208ce71b.

* doc(endpoints): align indent spaces

* doc(settings): improve error message formatting in validateSubUserAgentRegex

- Use NewErrorf with proper formatting instead of NewError with string concatenation
- Add comment explaining the rationale for returning original pattern value
- This preserves the intentional design where empty input is stored as empty
  in the DB and inherited as the runtime default at read time

---------

Co-authored-by: Tomilla <5007859+Tomilla@users.noreply.github.com>
Co-authored-by: Sanaei <ho3ein.sanaei@gmail.com>
This commit is contained in:
Tomi lla
2026-07-14 19:01:40 +08:00
committed by GitHub
parent f2b17397f4
commit 129f50d92a
40 changed files with 1588 additions and 89 deletions
+87
View File
@@ -176,6 +176,9 @@
"subCertFile": {
"type": "string"
},
"subClashAutoDetect": {
"type": "boolean"
},
"subClashEnable": {
"type": "boolean"
},
@@ -191,6 +194,9 @@
"subClashURI": {
"type": "string"
},
"subClashUserAgentRegex": {
"type": "string"
},
"subDomain": {
"type": "string"
},
@@ -212,6 +218,12 @@
"subIncyRoutingRules": {
"type": "string"
},
"subJsonAlwaysArray": {
"type": "boolean"
},
"subJsonAutoDetect": {
"type": "boolean"
},
"subJsonEnable": {
"type": "boolean"
},
@@ -230,6 +242,9 @@
"subJsonURI": {
"type": "string"
},
"subJsonUserAgentRegex": {
"type": "string"
},
"subKeyFile": {
"type": "string"
},
@@ -391,11 +406,13 @@
"smtpUsername",
"subAnnounce",
"subCertFile",
"subClashAutoDetect",
"subClashEnable",
"subClashEnableRouting",
"subClashPath",
"subClashRules",
"subClashURI",
"subClashUserAgentRegex",
"subDomain",
"subEnable",
"subEnableRouting",
@@ -403,12 +420,15 @@
"subHideSettings",
"subIncyEnableRouting",
"subIncyRoutingRules",
"subJsonAlwaysArray",
"subJsonAutoDetect",
"subJsonEnable",
"subJsonFinalMask",
"subJsonMux",
"subJsonPath",
"subJsonRules",
"subJsonURI",
"subJsonUserAgentRegex",
"subKeyFile",
"subListen",
"subPath",
@@ -617,6 +637,9 @@
"subCertFile": {
"type": "string"
},
"subClashAutoDetect": {
"type": "boolean"
},
"subClashEnable": {
"type": "boolean"
},
@@ -632,6 +655,9 @@
"subClashURI": {
"type": "string"
},
"subClashUserAgentRegex": {
"type": "string"
},
"subDomain": {
"type": "string"
},
@@ -653,6 +679,12 @@
"subIncyRoutingRules": {
"type": "string"
},
"subJsonAlwaysArray": {
"type": "boolean"
},
"subJsonAutoDetect": {
"type": "boolean"
},
"subJsonEnable": {
"type": "boolean"
},
@@ -671,6 +703,9 @@
"subJsonURI": {
"type": "string"
},
"subJsonUserAgentRegex": {
"type": "string"
},
"subKeyFile": {
"type": "string"
},
@@ -839,11 +874,13 @@
"smtpUsername",
"subAnnounce",
"subCertFile",
"subClashAutoDetect",
"subClashEnable",
"subClashEnableRouting",
"subClashPath",
"subClashRules",
"subClashURI",
"subClashUserAgentRegex",
"subDomain",
"subEnable",
"subEnableRouting",
@@ -851,12 +888,15 @@
"subHideSettings",
"subIncyEnableRouting",
"subIncyRoutingRules",
"subJsonAlwaysArray",
"subJsonAutoDetect",
"subJsonEnable",
"subJsonFinalMask",
"subJsonMux",
"subJsonPath",
"subJsonRules",
"subJsonURI",
"subJsonUserAgentRegex",
"subKeyFile",
"subListen",
"subPath",
@@ -9263,6 +9303,53 @@
}
}
},
"/panel/api/setting/validateRegex": {
"post": {
"tags": [
"Settings"
],
"summary": "Validate any regular expression with the backend Go RE2 compiler without saving it.",
"operationId": "post_panel_api_setting_validateRegex",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object"
},
"example": {
"regex": "(?m)^general-purpose$"
}
}
}
},
"responses": {
"200": {
"description": "Successful response",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"success": {
"type": "boolean"
},
"msg": {
"type": "string"
},
"obj": {}
}
},
"example": {
"success": true,
"msg": ""
}
}
}
}
}
}
},
"/panel/api/setting/updateUser": {
"post": {
"tags": [