update 2025-07-29 09:50:00
This commit is contained in:
parent
d602e7e620
commit
8848075e6e
@ -84,6 +84,8 @@ function index()
|
||||
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
|
||||
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
|
||||
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
|
||||
entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true
|
||||
entry({"admin", "services", appname, "subscribe_manual_all"}, call("subscribe_manual_all")).leaf = true
|
||||
|
||||
--[[rule_list]]
|
||||
entry({"admin", "services", appname, "read_rulelist"}, call("read_rulelist")).leaf = true
|
||||
@ -721,3 +723,51 @@ function subscribe_del_all()
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
|
||||
http.status(200, "OK")
|
||||
end
|
||||
|
||||
function subscribe_manual()
|
||||
local section = http.formvalue("section") or ""
|
||||
local current_url = http.formvalue("url") or ""
|
||||
if section == "" or current_url == "" then
|
||||
http_write_json({ success = false, msg = "Missing section or URL, skip." })
|
||||
return
|
||||
end
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
end
|
||||
if uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. section .. " manual >/dev/null 2>&1 &")
|
||||
http_write_json({ success = true, msg = "Subscribe triggered." })
|
||||
end
|
||||
|
||||
function subscribe_manual_all()
|
||||
local sections = http.formvalue("sections") or ""
|
||||
local urls = http.formvalue("urls") or ""
|
||||
if sections == "" or urls == "" then
|
||||
http_write_json({ success = false, msg = "Missing section or URL, skip." })
|
||||
return
|
||||
end
|
||||
local section_list = util.split(sections, ",")
|
||||
local url_list = util.split(urls, ",")
|
||||
-- 检查是否存在未保存配置
|
||||
for i, section in ipairs(section_list) do
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
if not uci_url or uci_url == "" then
|
||||
http_write_json({ success = false, msg = i18n.translate("Please save and apply before manually subscribing.") })
|
||||
return
|
||||
end
|
||||
end
|
||||
-- 保存有变动的url
|
||||
for i, section in ipairs(section_list) do
|
||||
local current_url = url_list[i] or ""
|
||||
local uci_url = api.sh_uci_get(appname, section, "url")
|
||||
if current_url ~= "" and uci_url ~= current_url then
|
||||
api.sh_uci_set(appname, section, "url", current_url, true)
|
||||
end
|
||||
end
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual >/dev/null 2>&1 &")
|
||||
http_write_json({ success = true, msg = "Subscribe triggered." })
|
||||
end
|
||||
|
@ -136,14 +136,15 @@ function o.cfgvalue(self, section)
|
||||
translate("Delete All Subscribe Node"))
|
||||
end
|
||||
|
||||
o = s:option(Button, "_update", translate("Manual subscription All"))
|
||||
o.inputstyle = "apply"
|
||||
function o.write(t, n)
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start all manual > /dev/null 2>&1 &")
|
||||
luci.http.redirect(api.url("log"))
|
||||
o = s:option(DummyValue, "_update", translate("Manual subscription All"))
|
||||
o.rawhtml = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return string.format([[
|
||||
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribeAll()">%s</button>]],
|
||||
translate("Manual subscription All"))
|
||||
end
|
||||
|
||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "</font>")
|
||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically.") .. "</font>")
|
||||
s.addremove = true
|
||||
s.anonymous = true
|
||||
s.sortable = true
|
||||
@ -204,11 +205,12 @@ function o.cfgvalue(self, section)
|
||||
remark, translate("Delete the subscribed node"))
|
||||
end
|
||||
|
||||
o = s:option(Button, "_update", translate("Manual subscription"))
|
||||
o.inputstyle = "apply"
|
||||
function o.write(t, n)
|
||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " manual > /dev/null 2>&1 &")
|
||||
luci.http.redirect(api.url("log"))
|
||||
o = s:option(DummyValue, "_update", translate("Manual subscription"))
|
||||
o.rawhtml = true
|
||||
o.cfgvalue = function(self, section)
|
||||
return string.format([[
|
||||
<button type="button" class="cbi-button cbi-button-apply" onclick="ManualSubscribe('%s')">%s</button>]],
|
||||
section, translate("Manual subscription"))
|
||||
end
|
||||
|
||||
s:append(Template(appname .. "/node_subscribe/js"))
|
||||
|
@ -132,7 +132,7 @@ if api.compare_versions(xray_version, ">=", "1.8.10") then
|
||||
end
|
||||
|
||||
-- 探测地址
|
||||
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
|
||||
local ucpu = s:option(Flag, _n("useCustomProbeUrl"), translate("Use Custom Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
|
||||
ucpu:depends({ [_n("balancingStrategy")] = "leastPing" })
|
||||
ucpu:depends({ [_n("balancingStrategy")] = "leastLoad" })
|
||||
|
||||
@ -373,6 +373,19 @@ o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translat
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
|
||||
|
||||
o = s:option(Flag, _n("ech"), translate("ECH"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
|
||||
|
||||
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "soft"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
o.validate = function(self, value)
|
||||
return api.trim(value:gsub("[\r\n]", ""))
|
||||
end
|
||||
|
||||
-- [[ REALITY部分 ]] --
|
||||
o = s:option(Value, _n("reality_publicKey"), translate("Public Key"))
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
|
||||
@ -403,6 +416,19 @@ o.default = "chrome"
|
||||
o:depends({ [_n("tls")] = true, [_n("utls")] = true })
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
|
||||
|
||||
o = s:option(Flag, _n("use_mldsa65Verify"), translate("ML-DSA-65"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("reality")] = true })
|
||||
|
||||
o = s:option(TextValue, _n("reality_mldsa65Verify"), "ML-DSA-65 " .. translate("Public key"))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "soft"
|
||||
o:depends({ [_n("use_mldsa65Verify")] = true })
|
||||
o.validate = function(self, value)
|
||||
return api.trim(value:gsub("[\r\n]", ""))
|
||||
end
|
||||
|
||||
o = s:option(ListValue, _n("transport"), translate("Transport"))
|
||||
o:value("raw", "RAW (TCP)")
|
||||
o:value("mkcp", "mKCP")
|
||||
|
@ -465,14 +465,6 @@ o.validate = function(self, value)
|
||||
return value
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
|
||||
o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
|
||||
if singbox_tags:find("with_utls") then
|
||||
o = s:option(Flag, _n("utls"), translate("uTLS"))
|
||||
o.default = "0"
|
||||
|
@ -186,6 +186,19 @@ o:value("h2,http/1.1")
|
||||
o:value("h3,h2,http/1.1")
|
||||
o:depends({ [_n("tls")] = true })
|
||||
|
||||
o = s:option(Flag, _n("use_mldsa65Seed"), translate("ML-DSA-65"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("reality")] = true })
|
||||
|
||||
o = s:option(TextValue, _n("reality_mldsa65Seed"), "ML-DSA-65 " .. translate("Private Key"))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "soft"
|
||||
o:depends({ [_n("use_mldsa65Seed")] = true })
|
||||
o.validate = function(self, value)
|
||||
return api.trim(value:gsub("[\r\n]", ""))
|
||||
end
|
||||
|
||||
-- o = s:option(Value, _n("minversion"), translate("minversion"))
|
||||
-- o.default = "1.3"
|
||||
-- o:value("1.3")
|
||||
@ -223,6 +236,19 @@ o.validate = function(self, value, t)
|
||||
return nil
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("ech"), translate("ECH"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
|
||||
|
||||
o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
|
||||
o.default = ""
|
||||
o.rows = 5
|
||||
o.wrap = "soft"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
o.validate = function(self, value)
|
||||
return api.trim(value:gsub("[\r\n]", ""))
|
||||
end
|
||||
|
||||
o = s:option(ListValue, _n("transport"), translate("Transport"))
|
||||
o:value("raw", "RAW")
|
||||
o:value("mkcp", "mKCP")
|
||||
|
@ -323,14 +323,6 @@ o.validate = function(self, value)
|
||||
return value
|
||||
end
|
||||
|
||||
o = s:option(Flag, _n("pq_signature_schemes_enabled"), translate("PQ signature schemes"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
|
||||
o = s:option(Flag, _n("dynamic_record_sizing_disabled"), translate("Disable adaptive sizing of TLS records"))
|
||||
o.default = "0"
|
||||
o:depends({ [_n("ech")] = true })
|
||||
|
||||
o = s:option(ListValue, _n("transport"), translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
o:value("http", "HTTP")
|
||||
|
@ -60,7 +60,8 @@ function uci_save(cursor, config, commit, apply)
|
||||
end
|
||||
|
||||
function sh_uci_get(config, section, option)
|
||||
exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
|
||||
local _, val = exec_call(string.format("uci -q get %s.%s.%s", config, section, option))
|
||||
return val
|
||||
end
|
||||
|
||||
function sh_uci_set(config, section, option, val, commit)
|
||||
|
@ -1,11 +1,13 @@
|
||||
local _M = {}
|
||||
|
||||
local function gh_release_url(self)
|
||||
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
|
||||
--return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
|
||||
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-release-api.json"
|
||||
end
|
||||
|
||||
local function gh_pre_release_url(self)
|
||||
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
|
||||
--return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
|
||||
return "https://github.com/xiaorouji/openwrt-passwall-packages/releases/download/api-cache/" .. string.lower(self.name) .. "-pre-release-api.json"
|
||||
end
|
||||
|
||||
-- 排序顺序定义
|
||||
|
@ -159,9 +159,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
--max_version = "1.3",
|
||||
ech = {
|
||||
enabled = (node.ech == "1") and true or false,
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
|
||||
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
|
||||
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
|
||||
},
|
||||
utls = {
|
||||
enabled = (node.utls == "1" or node.reality == "1") and true or false,
|
||||
@ -380,9 +378,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
ech = {
|
||||
enabled = (node.ech == "1") and true or false,
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
|
||||
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
|
||||
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -414,9 +410,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
} or nil,
|
||||
ech = {
|
||||
enabled = (node.ech == "1") and true or false,
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
|
||||
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
|
||||
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -448,9 +442,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
insecure = (node.tls_allowInsecure == "1") and true or false,
|
||||
ech = {
|
||||
enabled = (node.ech == "1") and true or false,
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {},
|
||||
pq_signature_schemes_enabled = node.pq_signature_schemes_enabled and true or false,
|
||||
dynamic_record_sizing_disabled = node.dynamic_record_sizing_disabled and true or false
|
||||
config = node.ech_config and split(node.ech_config:gsub("\\n", "\n"), "\n") or {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -507,9 +499,7 @@ function gen_config_server(node)
|
||||
if node.tls == "1" and node.ech == "1" then
|
||||
tls.ech = {
|
||||
enabled = true,
|
||||
key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {},
|
||||
pq_signature_schemes_enabled = (node.pq_signature_schemes_enabled == "1") and true or false,
|
||||
dynamic_record_sizing_disabled = (node.dynamic_record_sizing_disabled == "1") and true or false,
|
||||
key = node.ech_key and split(node.ech_key:gsub("\\n", "\n"), "\n") or {}
|
||||
}
|
||||
end
|
||||
|
||||
|
@ -157,14 +157,16 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
tlsSettings = (node.stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
|
||||
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil
|
||||
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
|
||||
echConfigList = (node.ech == "1") and node.ech_config or nil
|
||||
} or nil,
|
||||
realitySettings = (node.stream_security == "reality") and {
|
||||
serverName = node.tls_serverName,
|
||||
publicKey = node.reality_publicKey,
|
||||
shortId = node.reality_shortId or "",
|
||||
spiderX = node.reality_spiderX or "/",
|
||||
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome"
|
||||
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome",
|
||||
mldsa65Verify = (node.use_mldsa65Verify == "1") and node.reality_mldsa65Verify or nil
|
||||
} or nil,
|
||||
rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and {
|
||||
header = {
|
||||
@ -463,7 +465,8 @@ function gen_config_server(node)
|
||||
certificateFile = node.tls_certificateFile,
|
||||
keyFile = node.tls_keyFile
|
||||
}
|
||||
}
|
||||
},
|
||||
echServerKeys = (node.ech == "1") and node.ech_key or nil
|
||||
} or nil,
|
||||
rawSettings = (node.transport == "raw" or node.transport == "tcp") and {
|
||||
header = {
|
||||
@ -548,7 +551,8 @@ function gen_config_server(node)
|
||||
dest = node.reality_dest,
|
||||
serverNames = node.reality_serverNames or {},
|
||||
privateKey = node.reality_private_key,
|
||||
shortIds = node.reality_shortId or ""
|
||||
shortIds = node.reality_shortId or "",
|
||||
mldsa65Seed = (node.use_mldsa65Seed == "1") and node.reality_mldsa65Seed or nil
|
||||
} or nil
|
||||
end
|
||||
end
|
||||
|
@ -286,6 +286,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += opt.query("pbk", dom_prefix + "reality_publicKey");
|
||||
params += opt.query("sid", dom_prefix + "reality_shortId");
|
||||
params += opt.query("spx", dom_prefix + "reality_spiderX");
|
||||
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
|
||||
}
|
||||
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
|
||||
let v_flow = opt.get(dom_prefix + "flow").value;
|
||||
@ -294,6 +295,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += "&security=" + v_security;
|
||||
params += opt.query("alpn", dom_prefix + "alpn");
|
||||
params += opt.query("sni", dom_prefix + "tls_serverName");
|
||||
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
|
||||
params += opt.query("ech", dom_prefix + "ech_config");
|
||||
}
|
||||
|
||||
if (opt.get(dom_prefix + "shadowtls")?.checked) {
|
||||
@ -461,6 +464,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += opt.query("pbk", dom_prefix + "reality_publicKey");
|
||||
params += opt.query("sid", dom_prefix + "reality_shortId");
|
||||
params += opt.query("spx", dom_prefix + "reality_spiderX");
|
||||
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
|
||||
}
|
||||
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
|
||||
let v_flow = opt.get(dom_prefix + "flow").value;
|
||||
@ -470,6 +474,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += opt.query("alpn", dom_prefix + "alpn");
|
||||
params += opt.query("sni", dom_prefix + "tls_serverName");
|
||||
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
|
||||
params += opt.query("ech", dom_prefix + "ech_config");
|
||||
}
|
||||
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
@ -529,6 +534,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += opt.query("pbk", dom_prefix + "reality_publicKey");
|
||||
params += opt.query("sid", dom_prefix + "reality_shortId");
|
||||
params += opt.query("spx", dom_prefix + "reality_spiderX");
|
||||
params += opt.query("pqv", dom_prefix + "reality_mldsa65Verify");
|
||||
}
|
||||
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
|
||||
let v_flow = opt.get(dom_prefix + "flow").value;
|
||||
@ -538,6 +544,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
params += opt.query("alpn", dom_prefix + "alpn");
|
||||
params += opt.query("sni", dom_prefix + "tls_serverName");
|
||||
params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure");
|
||||
params += opt.query("ech", dom_prefix + "ech_config");
|
||||
}
|
||||
params += "#" + encodeURI(v_alias.value);
|
||||
if (params[0] == "&") {
|
||||
@ -968,6 +975,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
opt.set(dom_prefix + 'utls', true);
|
||||
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
|
||||
}
|
||||
opt.set(dom_prefix + 'ech', !!queryParam.ech);
|
||||
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
|
||||
}
|
||||
|
||||
if (queryParam.security == "reality") {
|
||||
@ -983,6 +992,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
|
||||
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
|
||||
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
|
||||
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
|
||||
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1347,6 +1358,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
opt.set(dom_prefix + 'utls', true);
|
||||
opt.set(dom_prefix + 'fingerprint', queryParam.fp);
|
||||
}
|
||||
opt.set(dom_prefix + 'ech', !!queryParam.ech);
|
||||
opt.set(dom_prefix + 'ech_config', queryParam.ech || '');
|
||||
}
|
||||
|
||||
if (queryParam.security == "reality") {
|
||||
@ -1362,6 +1375,8 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
|
||||
opt.set(dom_prefix + 'reality_publicKey', queryParam.pbk || '');
|
||||
opt.set(dom_prefix + 'reality_shortId', queryParam.sid || '');
|
||||
opt.set(dom_prefix + 'reality_spiderX', queryParam.spx || '');
|
||||
opt.set(dom_prefix + 'use_mldsa65Verify', !!queryParam.pqv);
|
||||
opt.set(dom_prefix + 'reality_mldsa65Verify', queryParam.pqv || '');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ local api = require "luci.passwall.api"
|
||||
-%>
|
||||
<script type="text/javascript">
|
||||
//<![CDATA[
|
||||
var appname = "<%= api.appname %>"
|
||||
|
||||
function confirmDeleteNode(remark) {
|
||||
if (!confirm("<%:Delete the subscribed node%>: " + remark + " ?"))
|
||||
return false;
|
||||
@ -34,5 +36,76 @@ local api = require "luci.passwall.api"
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
function ManualSubscribe(sectionId) {
|
||||
var urlInput = document.querySelector("input[name='cbid." + appname + "." + sectionId + ".url']");
|
||||
var currentUrl = urlInput ? urlInput.value.trim() : "";
|
||||
if (!currentUrl) {
|
||||
alert("<%:Subscribe URL cannot be empty.%>");
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('<%= api.url("subscribe_manual") %>?section='
|
||||
+ encodeURIComponent(sectionId)
|
||||
+ '&url='
|
||||
+ encodeURIComponent(currentUrl))
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) {
|
||||
alert(data.msg || "Operation failed");
|
||||
} else {
|
||||
window.location.href = '<%= api.url("log") %>'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ManualSubscribeAll() {
|
||||
var sectionIds = [];
|
||||
var urls = [];
|
||||
|
||||
var table = document.getElementById("cbi-" + appname + "-subscribe_list");
|
||||
var editBtns = table ? table.getElementsByClassName("cbi-button cbi-button-edit") : [];
|
||||
|
||||
for (var i = 0; i < editBtns.length; i++) {
|
||||
var btn = editBtns[i];
|
||||
var onclickStr = btn.getAttribute("onclick");
|
||||
if (!onclickStr) continue;
|
||||
|
||||
var id = onclickStr.substring(onclickStr.lastIndexOf('/') + 1, onclickStr.length - 1);
|
||||
if (!id) continue;
|
||||
|
||||
var urlInput = document.querySelector("input[name='cbid." + appname + "." + id + ".url']");
|
||||
var currentUrl = urlInput ? urlInput.value.trim() : "";
|
||||
if (!currentUrl) {
|
||||
alert("<%:Subscribe URL cannot be empty.%>");
|
||||
return;
|
||||
}
|
||||
|
||||
sectionIds.push(id);
|
||||
urls.push(currentUrl);
|
||||
}
|
||||
|
||||
if (sectionIds.length === 0) {
|
||||
//alert("No subscriptions found.");
|
||||
return;
|
||||
}
|
||||
|
||||
var params = new URLSearchParams();
|
||||
params.append("sections", sectionIds.join(","));
|
||||
params.append("urls", urls.join(","));
|
||||
|
||||
fetch('<%= api.url("subscribe_manual_all") %>', {
|
||||
method: 'POST',
|
||||
body: params
|
||||
})
|
||||
.then(response => response.json())
|
||||
.then(data => {
|
||||
if (!data.success) {
|
||||
alert(data.msg || "Operation failed");
|
||||
} else {
|
||||
window.location.href = '<%= api.url("log") %>'
|
||||
}
|
||||
});
|
||||
}
|
||||
//]]>
|
||||
</script>
|
||||
|
@ -445,7 +445,7 @@ msgstr "负载均衡策略"
|
||||
msgid "Fallback Node"
|
||||
msgstr "后备节点"
|
||||
|
||||
msgid "Use Custome Probe URL"
|
||||
msgid "Use Custom Probe URL"
|
||||
msgstr "使用自定义探测网址"
|
||||
|
||||
msgid "By default the built-in probe URL will be used, enable this option to use a custom probe URL."
|
||||
@ -1072,8 +1072,14 @@ msgstr "订阅网址"
|
||||
msgid "Subscribe URL Access Method"
|
||||
msgstr "订阅网址访问方式"
|
||||
|
||||
msgid "Please input the subscription url first, save and submit before manual subscription."
|
||||
msgstr "请输入订阅网址保存应用后再手动订阅。"
|
||||
msgid "When adding a new subscription, please save and apply before manually subscribing. If you only change the subscription URL, you can subscribe manually, and the system will save it automatically."
|
||||
msgstr "新增订阅请先保存并应用后再手动订阅;如仅修改订阅地址,可直接手动订阅,系统将自动保存。"
|
||||
|
||||
msgid "Please save and apply before manually subscribing."
|
||||
msgstr "请先保存并应用后再手动订阅。"
|
||||
|
||||
msgid "Subscribe URL cannot be empty."
|
||||
msgstr "订阅网址不能为空。"
|
||||
|
||||
msgid "Subscribe via proxy"
|
||||
msgstr "通过代理订阅"
|
||||
@ -1706,16 +1712,10 @@ msgid "Protocol parameter. Enable length block encryption."
|
||||
msgstr "协议参数。启用长度块加密。"
|
||||
|
||||
msgid "ECH Config"
|
||||
msgstr "ECH 密钥"
|
||||
|
||||
msgid "ECH Key"
|
||||
msgstr "ECH 配置"
|
||||
|
||||
msgid "PQ signature schemes"
|
||||
msgstr "后量子对等证书签名方案"
|
||||
|
||||
msgid "Disable adaptive sizing of TLS records"
|
||||
msgstr "禁用 TLS 记录的自适应大小调整"
|
||||
msgid "ECH Key"
|
||||
msgstr "ECH 密钥"
|
||||
|
||||
msgid "Enable Multipath TCP, need to be enabled in both server and client configuration."
|
||||
msgstr "启用 Multipath TCP,需在服务端和客户端配置中同时启用。"
|
||||
|
@ -8,7 +8,3 @@
|
||||
120.53.53.53
|
||||
180.184.1.1
|
||||
180.184.2.2
|
||||
203.208.39.192/28
|
||||
203.208.40.0/23
|
||||
34.149.0.0/16
|
||||
72.18.83.0/24
|
||||
|
@ -820,11 +820,17 @@ local function processData(szType, content, add_mode, add_from)
|
||||
result.utls = "1"
|
||||
result.fingerprint = params.fp
|
||||
end
|
||||
if params.ech and params.ech ~= "" then
|
||||
result.ech = "1"
|
||||
result.ech_config = params.ech
|
||||
end
|
||||
if params.security == "reality" then
|
||||
result.reality = "1"
|
||||
result.reality_publicKey = params.pbk or nil
|
||||
result.reality_shortId = params.sid or nil
|
||||
result.reality_spiderX = params.spx or nil
|
||||
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
end
|
||||
params.allowinsecure = params.allowinsecure or params.insecure
|
||||
@ -1196,11 +1202,17 @@ local function processData(szType, content, add_mode, add_from)
|
||||
result.utls = "1"
|
||||
result.fingerprint = params.fp
|
||||
end
|
||||
if params.ech and params.ech ~= "" then
|
||||
result.ech = "1"
|
||||
result.ech_config = params.ech
|
||||
end
|
||||
if params.security == "reality" then
|
||||
result.reality = "1"
|
||||
result.reality_publicKey = params.pbk or nil
|
||||
result.reality_shortId = params.sid or nil
|
||||
result.reality_spiderX = params.spx or nil
|
||||
result.use_mldsa65Verify = (params.pqv and params.pqv ~= "") and "1" or nil
|
||||
result.reality_mldsa65Verify = params.pqv or nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -1913,7 +1925,6 @@ local execute = function()
|
||||
local raw_data = api.trim(stdout)
|
||||
local old_md5 = value.md5 or ""
|
||||
local new_md5 = luci.sys.exec("md5sum " .. tmp_file .. " 2>/dev/null | awk '{print $1}'"):gsub("\n", "")
|
||||
os.remove(tmp_file)
|
||||
if not manual_sub and old_md5 == new_md5 then
|
||||
log('订阅:【' .. remark .. '】没有变化,无需更新。')
|
||||
else
|
||||
@ -1924,6 +1935,7 @@ local execute = function()
|
||||
fail_list[#fail_list + 1] = value
|
||||
end
|
||||
end
|
||||
luci.sys.call("rm -f " .. tmp_file)
|
||||
allowInsecure_default = nil
|
||||
filter_keyword_mode_default = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
|
||||
filter_keyword_discard_list_default = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
|
||||
|
Loading…
x
Reference in New Issue
Block a user