🎈 Sync 2026-09-30 10:37:56

This commit is contained in:
github-actions[bot] committed 2026-09-30 10:37:57 +08:00
1 parent 7bb984c650
commit 214a01499a
17 files changed
+386 -69

No files matched your search

@@ -18,6 +18,10 @@
-- 归一为白名单取值后用 json_encode 输出,保证是合法的 JS 字符串字面量
if local_mode ~= "form" then local_mode = "text" end
local js_mode = util.json_encode(local_mode) or '"text"'
-- 协议与字段清单:与 core.merge_form_node 共用 substore/node.lua 的同一份数据
local node_mod = require("substore.node")
local js_protos = (util.json_encode(node_mod.PROTOS) or "[]"):gsub("</", "<\\/")
local js_proto_fields = (util.json_encode(node_mod.PROTO_FIELDS) or "{}"):gsub("</", "<\\/")
%>
<h2><%=is_edit and luci.i18n.translate("Edit local subscription") or luci.i18n.translate("Add local subscription")%></h2>
@@ -118,6 +122,7 @@ var FIELD_LABELS = {
"obfs": "Obfs",
"obfs-param": "Obfs Param",
"obfs-password": "Obfs Password",
"protocol": "Protocol",
"protocol-param": "Protocol Param",
"udp": "UDP",
"skip-cert-verify": "Skip Cert Verify",
@@ -140,8 +145,13 @@ var NODEFORM_I18N = {
"node": "<%:Node%>",
"defaultOpt": "<%:Default%>"
};
// 协议与字段清单由服务端注入(唯一来源:substore/node.lua 的 M.PROTOS /
// M.PROTO_FIELDS)。core.merge_form_node 用同一份清单决定哪些字段可以被表单
// 覆盖,两边必须严格一致,因此不在前端另抄一份。
var SUBSTORE_PROTOS = <%=js_protos%>;
var SUBSTORE_PROTO_FIELDS = <%=js_proto_fields%>;
</script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.2.0"></script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.6.1"></script>
<script>
// 切换导入模式:仅切换显示/禁用,不提交表单
function substore_local_switch(mode) {
@@ -10,6 +10,10 @@
local n = nodes[idx]
-- 注入 JS 的节点对象:转义 "</" 防止提前闭合 script
local js_node = n and ((util.json_encode(n) or "null"):gsub("</", "<\\/")) or "null"
-- 协议与字段清单:与 core.merge_form_node 共用 substore/node.lua 的同一份数据
local node_mod = require("substore.node")
local js_protos = (util.json_encode(node_mod.PROTOS) or "[]"):gsub("</", "<\\/")
local js_proto_fields = (util.json_encode(node_mod.PROTO_FIELDS) or "{}"):gsub("</", "<\\/")
local back_url = luci.dispatcher.build_url('admin/services/substore/nodes') .. "?id=" .. luci.util.urlencode(id)
%>
<h2><%:Edit node%> — <%=luci.util.pcdata(meta and meta.name or "")%></h2>
@@ -61,6 +65,7 @@ var FIELD_LABELS = {
"obfs": "Obfs",
"obfs-param": "Obfs Param",
"obfs-password": "Obfs Password",
"protocol": "Protocol",
"protocol-param": "Protocol Param",
"udp": "UDP",
"skip-cert-verify": "Skip Cert Verify",
@@ -83,9 +88,14 @@ var NODEFORM_I18N = {
"node": "<%:Node%>",
"defaultOpt": "<%:Default%>"
};
// 协议与字段清单由服务端注入(唯一来源:substore/node.lua 的 M.PROTOS /
// M.PROTO_FIELDS)。core.merge_form_node 用同一份清单决定哪些字段可以被表单
// 覆盖,两边必须严格一致,因此不在前端另抄一份。
var SUBSTORE_PROTOS = <%=js_protos%>;
var SUBSTORE_PROTO_FIELDS = <%=js_proto_fields%>;
var NODE_EDIT_DATA = <%=js_node%>;
</script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.2.0"></script>
<script src="/luci-static/resources/substore/nodeform.js?v=2.6.1"></script>
<script>
function node_edit_prepare() {
var arr = collectNodes();
@@ -14,8 +14,12 @@
local group = http.formvalue("group") or q.group or ""
local sort_by = http.formvalue("sort") or q.sort or "name"
local sort_desc = http.formvalue("desc") == "1" or q.desc == "1"
-- id 会进入 <script> 里的 JS 字符串字面量,用 JSON 编码而不是 HTML 转义
local js_id = util.json_encode(id) or '""'
-- id 会进入 <script> 里的 JS 字符串字面量,用 JSON 编码而不是 HTML 转义。
-- 但只有 JSON 编码还不够:json_encode 不转义 "<",id 直接来自查询串,
-- 形如 "</script><script>alert(1)</script>" 的值会在 HTML 词法阶段就闭合
-- script 元素(与 JS 字符串上下文无关),剩下的部分被当作 HTML 执行。
-- 转义 "</" 即可:在 JS 字符串里 "\/" 就是 "/",而 HTML 不再看到 "</script"。
local js_id = (util.json_encode(id) or '""'):gsub("</", "<\\/")
-- 标注原始数组下标(filter 保留表引用、sort 原地排序,下标可穿透筛选排序)
for i, nn in ipairs(nodes) do nn.__idx = i end