update 2026-09-05 22:43:26
marry-jell / merge (push) Canceled after 0s

This commit is contained in:
action committed 2026-09-05 22:43:26 +08:00
1 parent ccd677de3a
commit 825070ba95
2037 files changed
+1694705 -12285

No files matched your search

@@ -47,6 +47,11 @@ function waitForElement(selector, callback) {
observer.observe(document.body, { childList: true, subtree: true });
}
function waitForElementId(id, callback) {
waitForElement("#" + CSS.escape(id), callback);
//waitForElement('[id="' + id + '"]', callback);
}
function get_current_url() {
return window.location.origin + window.location.pathname;
}
@@ -221,6 +221,16 @@ o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ node = "", ['!reverse'] = true })
o = s:option(DummyValue, "_is_singbox", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends("_hide", "1")
o = s:option(DummyValue, "_is_xray", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends("_hide", "1")
o = s:option(Flag, "log", translate("Enable Node Log"))
o:depends("_node", "1")
@@ -249,7 +259,7 @@ o:depends("log", "1")
o = s:option(DummyValue, "_show_dns_option", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends("_hide", "1")
o:depends({ mode = "1", _node = "1" })
o = s:option(ListValue, "direct_dns_query_strategy", translate("Direct Query Strategy"))
o.default = "UseIP"
@@ -262,11 +272,9 @@ o = s:option(ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
o:value("tcp", "TCP")
o:value("doh", "DoH")
o:value("udp", "UDP")
if current_node.type == "sing-box" then
o:value("tls", "TLS(DoT)")
o:value("quic", "QUIC(DoQ)")
o:value("http3", "HTTP3(DoH3)")
end
o:value("tls", "TLS(DoT)", { _is_singbox = "1" })
o:value("quic", "QUIC(DoQ)", { _is_singbox = "1" })
o:value("http3", "HTTP3(DoH3)", { _is_singbox = "1" })
o:depends("_show_dns_option", "1")
---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ)
@@ -307,44 +315,30 @@ o = s:option(Value, "remote_dns_client_ip", translate("Remote DNS EDNS Client Su
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
o.datatype = "ipaddr"
o:depends("remote_dns_protocol", "tcp")
o:depends("remote_dns_protocol", "doh")
o:depends("remote_dns_protocol", "udp")
o:depends("remote_dns_protocol", "http3")
o:depends("remote_dns_protocol", "quic")
o:depends("remote_dns_protocol", "tls")
o:depends("_show_dns_option", "1")
o = s:option(ListValue, "remote_dns_detour", translate("Remote DNS Outbound"))
o.default = "remote"
o:value("remote", translate("Remote"))
o:value("direct", translate("Direct"))
o:depends("remote_dns_protocol", "tcp")
o:depends("remote_dns_protocol", "doh")
o:depends("remote_dns_protocol", "udp")
o:depends("remote_dns_protocol", "http3")
o:depends("remote_dns_protocol", "quic")
o:depends("remote_dns_protocol", "tls")
o:depends("_show_dns_option", "1")
o = s:option(Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy."))
o.default = "0"
o.rmempty = false
o:depends("_hide", "1")
o = s:option(ListValue, "remote_dns_query_strategy", translate("Remote Query Strategy"))
o.default = "UseIPv4"
o:value("UseIP")
o:value("UseIPv4")
o:value("UseIPv6")
o:depends("remote_dns_protocol", "tcp")
o:depends("remote_dns_protocol", "doh")
o:depends("remote_dns_protocol", "udp")
o:depends("remote_dns_protocol", "http3")
o:depends("remote_dns_protocol", "quic")
o:depends("remote_dns_protocol", "tls")
o:depends("_show_dns_option", "1")
o = s:option(Value, "remote_rewrite_ttl", translate("Remote DNS") .. " TTL")
o.datatype = "min(1)"
o.default = "30"
o:depends("_hide", "1")
o:depends({ _show_dns_option = "1", _is_singbox = "1" })
o = s:option(ListValue, "dns_hosts_mode", translate("Domain Override"))
o:value("default", translate("Use global config"))
@@ -368,22 +362,39 @@ end
local o_node = s.fields["node"]
local shunt_list = {}
for k, v in pairs(nodes_table) do
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
if v.type == "Xray" then
--s.fields["_is_xray"]:depends({ node = v.id })
end
if v.type == "sing-box" then
s.fields["remote_rewrite_ttl"]:depends({ node = v.id })
s.fields["_is_singbox"]:depends({ node = v.id })
end
s.fields["_show_dns_option"]:depends({ mode = "1", node = v.id })
if v.node_type == "normal" or v.protocol == "_balancing" or v.protocol == "_urltest" then
--Shunt node has its own separate options.
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tcp" })
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "doh" })
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "udp" })
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "http3" })
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "quic" })
s.fields["remote_fakedns"]:depends({ node = v.id, remote_dns_protocol = "tls" })
s.fields["remote_fakedns"]:depends({ node = v.id, _show_dns_option = "1" })
end
if v.protocol and v.protocol == "_shunt" then
shunt_list[#shunt_list + 1] = v
end
end
--m:appendTemplate("/acl/options", {section = arg[1]})
-- Shunt Start
if current_node.protocol == "_shunt" then
local shunt_lua = loadfile("/usr/lib/lua/luci/model/cbi/passwall2/client/include/shunt_options.lua")
setfenv(shunt_lua, getfenv(1))(m, s, {
s_cfgid = s.section,
node_id = current_node_id,
node = current_node,
verify_option = s.fields["node"]
})
end
m:appendTemplate("/acl/shunt", { shunt_list = api.jsonc.stringify(shunt_list), section = s.section })
return api.return_map(m)
@@ -85,6 +85,16 @@ o.template = m:template_path("/cbi/nodes_listvalue")
o:value("", translate("Close"))
o.group = {""}
o = s:taboption("Main", DummyValue, "_node", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends({ node = "", ['!reverse'] = true })
o = s:taboption("Main", DummyValue, "_is_singbox", "")
o.template = m:template_path("/cbi/hidevalue")
o.value = "1"
o:depends("_hide", "1")
current_node_id = m:get(s.section, "node")
current_node = current_node_id and m:get(current_node_id) or {}
@@ -113,7 +123,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
tips.cfgvalue = function(t, n)
return string.format('<a style="color: red">%s</a>', translate("There are no available nodes, please add or subscribe nodes first."))
end
tips:depends({ node = "", ["!reverse"] = true })
tips:depends("_node", "1")
for k, v in pairs(shunt_list) do
tips:depends("node", v.id)
end
@@ -157,10 +167,11 @@ end
node_socks_port = s:taboption("Main", Value, "node_socks_port", translate("Node") .. " Socks " .. translate("Listen Port"))
node_socks_port.default = 1070
node_socks_port.datatype = "port"
node_socks_port:depends("_node", "1")
node_socks_bind_local = s:taboption("Main", Flag, "node_socks_bind_local", translate("Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
node_socks_bind_local.default = "1"
node_socks_bind_local:depends({ node = "", ["!reverse"] = true })
node_socks_bind_local:depends("_node", "1")
s:tab("DNS", translate("DNS"))
@@ -190,11 +201,9 @@ o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS P
o:value("tcp", "TCP")
o:value("doh", "DoH")
o:value("udp", "UDP")
if current_node.type == "sing-box" then
o:value("tls", "TLS(DoT)")
o:value("quic", "QUIC(DoQ)")
o:value("http3", "HTTP3(DoH3)")
end
o:value("tls", "TLS(DoT)", { _is_singbox = "1" })
o:value("quic", "QUIC(DoQ)", { _is_singbox = "1" })
o:value("http3", "HTTP3(DoH3)", { _is_singbox = "1" })
---- DNS over TCP or UDP or TLS (DoT) or QUIC (DoQ)
o = s:taboption("DNS", Value, "remote_dns", translate("Remote DNS"))
@@ -388,6 +397,9 @@ for k, v in pairs(nodes_table) do
if #normal_list == 0 and #iface_list == 0 then
break
end
if v.type == "sing-box" then
s.fields["_is_singbox"]:depends({ node = v.id })
end
o_node:value(v.id, v["remark"])
o_node.group[#o_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
o_socks:value(v.id, v["remark"])
@@ -4,6 +4,7 @@ if not data.node_id or not data.node then
return
end
local api = m.api
local s_cfgid = data.s_cfgid
local current_node_id = data.node_id
local node_list = data.node_list or api.get_node_list()
@@ -0,0 +1,56 @@
<%
local map = self.map
local api = map.api
local config = map.config
local section = self.section
-%>
<script type="text/javascript">
//<![CDATA[
function setOption(option, val) {
const dom = document.getElementById('cbid.<%=config%>.<%=section%>.' + option);
if (dom) {
dom.value = val;
}
const combobox_dom = document.getElementById('cbi.combobox.cbid.<%=config%>.<%=section%>.' + option);
if (combobox_dom) {
combobox_dom.value = val;
//combobox_dom.selectedIndex = val;
//combobox_dom.dispatchEvent(new Event("change", { bubbles: true }));
}
}
document.addEventListener("DOMContentLoaded", function () {
function dom_event() {
waitForElementId('cbi.combobox.cbid.<%=config%>.<%=section%>.tcp_no_redir_ports', function(el) {
const o_val = el.value;
el.addEventListener("change", () => {
const udp_no_redir_ports = getOption("<%=config%>", "<%=section%>", "udp_no_redir_ports");
if (el.value == "1:65535" && udp_no_redir_ports && udp_no_redir_ports.value == "1:65535") {
setOption("tcp_no_redir_ports", "");
setOption("udp_no_redir_ports", "");
setOption("mode", 0);
cbi_d_update();
}
});
});
waitForElementId('cbi.combobox.cbid.<%=config%>.<%=section%>.udp_no_redir_ports', function(el) {
const o_val = el.value;
el.addEventListener("change", () => {
const tcp_no_redir_ports = getOption("<%=config%>", "<%=section%>", "tcp_no_redir_ports");
if (el.value == "1:65535" && tcp_no_redir_ports && tcp_no_redir_ports.value == "1:65535") {
setOption("tcp_no_redir_ports", "");
setOption("udp_no_redir_ports", "");
setOption("mode", 0);
cbi_d_update();
}
});
});
}
const ori_cbi_d_update = cbi_d_update;
cbi_d_update = function() {
ori_cbi_d_update();
dom_event();
};
dom_event();
});
//]]>
</script>
@@ -0,0 +1,38 @@
<%
local map = self.map
local api = map.api
local appname = map.config
local section = self.section
-%>
<script type="text/javascript">
//<![CDATA[
const shunt_list = JSON.parse('<%=self.shunt_list%>');
document.addEventListener("DOMContentLoaded", () => setTimeout(() => {
const hiddenSelect = document.getElementById("cbid.<%=appname%>.<%=section%>.node");
let o_val = hiddenSelect.value
const o_hasItem = shunt_list.find(element => element.id == o_val);
hiddenSelect.addEventListener("change", function(el){
let new_val = el.target.value
let new_hasItem = shunt_list.find(element => element.id == new_val);
new_hasItem = true;
if (new_hasItem) {
XHR.get('<%=api.url("update_config")%>', {
id: "<%=section%>",
data: JSON.stringify({
node: new_val
})
},
function(x, data) {
if (x && x.status == 200 && data.code == 1) {
window.location.reload();
}
else {
alert("<%:Error%>");
}
});
}
});
}, 100));
//]]>
</script>
@@ -419,10 +419,10 @@ table td, .table .td {
<%- else %>
(function() {
if (typeof(cbi_t_switch) === "function") {
var old_switch = cbi_t_switch;
const ori_cbi_t_switch = cbi_t_switch;
cbi_t_switch = function(section, tab) {
dechecked_all_node();
return old_switch(section, tab);
return ori_cbi_t_switch(section, tab);
};
}
})();
@@ -1521,22 +1521,47 @@ table td, .table .td {
}
});
}
waitForElement('input[type="checkbox"][name*="<%=appname%>"][name*="show_node_info"]', function(el) {
el.addEventListener("change", () => {
el.blur();
show_node_info = el.checked ? "1" : "0";
onChange("show_node_info", show_node_info);
function dom_event() {
waitForElement('input[type="checkbox"][name*="<%=appname%>"][name*="show_node_info"]', function(el) {
el.addEventListener("change", () => {
el.blur();
show_node_info = el.checked ? "1" : "0";
onChange("show_node_info", show_node_info);
});
});
});
waitForElement('select[name*="<%=appname%>"][name*="auto_detection_time"]', function(el) {
el.addEventListener("change", () => {
el.blur();
auto_detection_time = el.value;
onChange("auto_detection_time", auto_detection_time);
waitForElement('select[name*="<%=appname%>"][name*="auto_detection_time"]', function(el) {
el.addEventListener("change", () => {
el.blur();
auto_detection_time = el.value;
onChange("auto_detection_time", auto_detection_time);
});
});
});
waitForElement('select[id*="<%=appname%>"][id*="url_test_url"]', function(el) {
el.addEventListener("change", () => {
if (el.value) {
onChange("url_test_url", el.value);
}
});
});
waitForElement('input[id*="<%=appname%>"][id*="url_test_url"]', function(el) {
el.addEventListener("change", () => {
if (el.value) {
onChange("url_test_url", el.value);
}
});
});
}
const ori_cbi_d_update = cbi_d_update;
cbi_d_update = function() {
ori_cbi_d_update();
dom_event();
};
dom_event();
const links = document.querySelectorAll('a');
links.forEach(link => {
@@ -111,7 +111,7 @@ api.uci_foreach_c("haproxy_config", function(t)
if server_node.type ~= "Socks" then
local relay_port = server_node.port
local new_port = api.get_new_port()
local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port)
local config_file = string.format("%s_%s.json", t[".name"], new_port)
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s",