diff --git a/ddns-go/Makefile b/ddns-go/Makefile index 1a52bfa9a..7d4dcbdc6 100644 --- a/ddns-go/Makefile +++ b/ddns-go/Makefile @@ -5,8 +5,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-go -PKG_VERSION:=6.17.1 -PKG_RELEASE:=18 +PKG_VERSION:=6.17.2 +PKG_RELEASE:=19 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)? diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile index 1e94a163f..f43ac0860 100644 --- a/luci-app-passwall/Makefile +++ b/luci-app-passwall/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall -PKG_VERSION:=26.7.15 -PKG_RELEASE:=180 +PKG_VERSION:=26.7.16 +PKG_RELEASE:=181 PKG_PO_VERSION:=$(PKG_VERSION) PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js new file mode 100644 index 000000000..3f9d64706 --- /dev/null +++ b/luci-app-passwall/htdocs/luci-static/resources/view/passwall/cbi.js @@ -0,0 +1,38 @@ +function is_json(str) { + try { + const result = JSON.parse(str); + return typeof result === 'object' && result !== null; + } catch (e) { + return false; + } +} + +function is_timehhmm(str) { + const match = String(str).match(/^(\d?\d):(\d\d)$/); + if (match) { + const hour = parseInt(match[1], 10); + const minute = parseInt(match[2], 10); + if (hour >= 0 && hour <= 23 && minute >= 0 && minute <= 59) { + return true; + } + } + return false; +} + +if (typeof cbi_validators !== 'undefined' && cbi_validators !== null) { + cbi_validators['json'] = function() { + return is_json(this); + } + cbi_validators['timehhmm'] = function() { + return is_timehhmm(this); + } +} else { + L.require('validation').then(function(validation) { + validation.types['json'] = function() { + return this.assert(is_json(this.value), _('Must be JSON text!')); + } + validation.types['timehhmm'] = function() { + return this.assert(is_timehhmm(this.value), _('valid time (hh:mm)')); + } + }); +} diff --git a/luci-app-passwall/luasrc/controller/passwall.lua b/luci-app-passwall/luasrc/controller/passwall.lua index 012052c10..602656b68 100644 --- a/luci-app-passwall/luasrc/controller/passwall.lua +++ b/luci-app-passwall/luasrc/controller/passwall.lua @@ -1152,10 +1152,20 @@ function fetch_certsha256() local port = (id ~= "") and uci:get(appname, id, "port") or 0 local sni = (id ~= "") and uci:get(appname, id, "tls_serverName") or "" sni = (sni ~= "") and sni or address + local protocol = uci:get(appname, id, "protocol") + local h3, timeout = false, 10 + if protocol == "hysteria2" then + h3 = true + timeout = 60 + if port == 0 then + local hop = uci:get(appname, id, "hysteria2_hop") or "0" + port = tonumber(hop:match("^%s*(%d+)")) + end + end if address == "" or port == 0 then http_write_json_error() return end - local data = api.fetch_cert_sha256(address, port, sni, 5) + local data = api.fetch_cert_sha256(address, port, sni, timeout, h3) http_write_json(data ~= "" and { code = 1, data = data } or { code = 0 }) end diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua index 9d5edc7e4..e3f3d9a17 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local appname = "passwall" local sys = api.sys +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -13,7 +15,8 @@ o.rmempty = false o.default = false -- [[ ACLs Settings ]]-- -s = m:section(TypedSection, "acl_rule") +local cfgname = "acl_rule" +s = m:section(TypedSection, cfgname) s.template = "cbi/tblsection" s.sortable = true s.anonymous = true @@ -101,4 +104,9 @@ o:value("1:65535", translate("All")) o:value("53", "53") ]]-- -return m +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua index d908e37d0..4dec15808 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua @@ -1,6 +1,8 @@ local api = require "luci.passwall.api" local appname = "passwall" +api.set_default_cbi() + m = Map(appname) m.redirect = api.url("acl") api.set_apply_on_parse(m) @@ -601,4 +603,4 @@ for k, v in pairs(nodes_table) do end end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua index 5f573a9ed..3f2a77604 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/app_update.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local com = require "luci.passwall.com" local appname = "passwall" +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -34,4 +36,4 @@ o.cfgvalue = function(t, n) return string.format('%s', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually.")) end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua index 9d19ae149..9e40564d3 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -8,6 +8,8 @@ local has_gfwlist = fs.access("/usr/share/passwall/rules/gfwlist") local has_chnlist = fs.access("/usr/share/passwall/rules/chnlist") local has_chnroute = fs.access("/usr/share/passwall/rules/chnroute") +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -879,4 +881,4 @@ footer.shunt_list = api.jsonc.stringify(shunt_list) m:append(footer) m:append(Template(appname .. "/global/status_bottom")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua index 972a96a7f..c4784a875 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/haproxy.lua @@ -15,6 +15,8 @@ for k, e in ipairs(api.get_valid_nodes()) do end end +api.set_default_cbi() + m = Map(appname, "HAPROXY " .. translate("Load Balancing")) api.set_apply_on_parse(m) @@ -101,7 +103,8 @@ end o:depends("health_check_type", "passwall_logic") -- [[ Balancing Settings ]]-- -s = m:section(TypedSection, "haproxy_config", translate("Node List")) +local cfgname = "haproxy_config" +s = m:section(TypedSection, cfgname, translate("Node List")) s.description = "" .. translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") .. "
" .. translate("Note that the node configuration parameters for load balancing must be consistent when use TCP health check type, otherwise it cannot be used normally!") .. "
" @@ -177,6 +180,11 @@ o:value(0, translate("Primary")) o:value(1, translate("Standby")) o.rmempty = false +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + m:append(Template(appname .. "/haproxy/js")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index 9cbb3a9ee..1f8ba7af4 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -1,6 +1,8 @@ api = require "luci.passwall.api" appname = "passwall" +api.set_default_cbi() + m = Map(appname, translate("Node Config")) m.redirect = api.url("node_list") api.set_apply_on_parse(m) @@ -120,7 +122,6 @@ local footer = Template(appname .. "/node_config/footer") footer.api = api footer.config = m.config footer.section = arg[1] - m:append(footer) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index 3bdf8fcca..8c16f598f 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -3,6 +3,8 @@ local appname = "passwall" local sys = api.sys local datatypes = api.datatypes +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -33,4 +35,4 @@ s:append(Template(appname .. "/node_list/link_add_node")) m:append(Template(appname .. "/node_list/node_list")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua index 481477aa9..276f28131 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua @@ -38,6 +38,8 @@ if has_hysteria2 then table.insert(hysteria2_type, s) end +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -127,7 +129,8 @@ o.cfgvalue = function(self, section) translate("Manual subscription All")) end -s = m:section(TypedSection, "subscribe_list", "", "" .. 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.") .. "") +local cfgname = "subscribe_list" +s = m:section(TypedSection, cfgname, "", "" .. 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.") .. "") s.addremove = true s.anonymous = true s.sortable = true @@ -148,7 +151,7 @@ o.validate = function(self, value, section) return nil, translate("Remark cannot be empty.") end local duplicate = false - m.uci:foreach(appname, "subscribe_list", function(e) + m.uci:foreach(appname, cfgname, function(e) if e[".name"] ~= section and e["remark"] and e["remark"]:lower() == value:lower() then duplicate = true return false @@ -223,6 +226,11 @@ o.cfgvalue = function(self, section) section, translate("Manual subscription")) end +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + m:append(Template(appname .. "/node_subscribe/js")) -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua index e3d2c44c5..98e52f7e1 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local uci = api.uci local appname = "passwall" +api.set_default_cbi() + m = Map(appname) m.redirect = api.url("node_subscribe") api.set_apply_on_parse(m) @@ -244,13 +246,7 @@ o:value(0, translate("Every Sunday")) o = s:option(Value, "update_time_mode", translate("Update Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" -o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil -end +o.datatype = "timehhmm" o:depends("update_week_mode", "0") o:depends("update_week_mode", "1") o:depends("update_week_mode", "2") @@ -321,4 +317,4 @@ for k, v in pairs(nodes_table) do end end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua index 2f53c6aed..efe0cccc7 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -8,6 +8,8 @@ local port_validate = function(self, value, t) return value:gsub("-", ":") end +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -43,13 +45,7 @@ for index, value in ipairs({"stop", "start", "restart"}) do o = s:option(Value, value .. "_time_mode", translate(value .. " Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" - o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil - end + o.datatype = "timehhmm" o:depends(value .. "_week_mode", "0") o:depends(value .. "_week_mode", "1") o:depends(value .. "_week_mode", "2") @@ -271,4 +267,4 @@ if has_singbox then o.default = 0 end -return m +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua index c6e12ed8d..979d4fe40 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua @@ -3,6 +3,8 @@ local appname = "passwall" local has_xray = api.finded_com("xray") local has_singbox = api.finded_com("sing-box") +api.set_default_cbi() + m = Map(appname) api.set_apply_on_parse(m) @@ -112,13 +114,7 @@ o:value(0, translate("Every Sunday")) o = s:option(Value, "update_time_mode", translate("Update Time")) for t = 0, 23 do o:value(t .. ":00") end o.default = "0:00" -o.validate = function(self, value) - local b = api.is_timehhmm(value) - if b then - return value - end - return nil -end +o.datatype = "timehhmm" o:depends("update_week_mode", "0") o:depends("update_week_mode", "1") o:depends("update_week_mode", "2") @@ -146,8 +142,10 @@ end s:append(Template(appname .. "/rule/rule_version")) +local cfgname = "shunt_rules" + if has_xray or has_singbox then - s = m:section(TypedSection, "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") + s = m:section(TypedSection, cfgname, "Sing-Box/Xray " .. translate("Shunt Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") s.template = "cbi/tblsection" s.anonymous = false s.addremove = true @@ -169,4 +167,9 @@ if has_xray or has_singbox then o = s:option(DummyValue, "remarks", translate("Remarks")) end -return m +local sortable = Template(appname .. "/cbi/sortable") +sortable.api = api +sortable.target_cfgname = cfgname +m:append(sortable) + +return api.return_map(m) diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua index ac2fcdbaa..8bbda0abf 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/rule_list.lua @@ -1,5 +1,5 @@ local api = require "luci.passwall.api" -local appname = "passwall" +local appname = api.appname local fs = api.fs local sys = api.sys local uci = api.uci diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua index 85596c9b4..4b45eba49 100644 --- a/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua +++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua @@ -2,6 +2,8 @@ local api = require "luci.passwall.api" local appname = "passwall" local datatypes = api.datatypes +api.set_default_cbi() + m = Map(appname, "Sing-Box/Xray " .. translate("Shunt Rule")) m.redirect = api.url("rule") api.set_apply_on_parse(m) @@ -245,4 +247,4 @@ ip_list.description = "