fix: resolve parental & profile blocklists saving and enforcement, add dashboard support for missing protocols
This commit is contained in:
@@ -2447,9 +2447,17 @@ function renderDefaultState({
|
||||
isCollapsed,
|
||||
onToggleCollapse
|
||||
}) {
|
||||
const isConnectionNode = ["vpn", "awg", "warp"].includes(
|
||||
section.action || ""
|
||||
);
|
||||
const isConnectionNode = [
|
||||
"vpn",
|
||||
"awg",
|
||||
"warp",
|
||||
"anytls",
|
||||
"snell",
|
||||
"mieru",
|
||||
"sudoku",
|
||||
"masque",
|
||||
"openvpn"
|
||||
].includes(section.action || "");
|
||||
const isServiceNode = ["zapret", "zapret2", "byedpi"].includes(section.action || "") || Boolean(section.serviceStatus);
|
||||
if (isServiceNode) {
|
||||
const ss = section.serviceStatus;
|
||||
@@ -2845,9 +2853,17 @@ function renderDefaultState({
|
||||
(o) => o.selected
|
||||
);
|
||||
if (!selectedOutbound) return "";
|
||||
const isConnectionNode2 = ["vpn", "awg", "warp"].includes(
|
||||
section.action || ""
|
||||
);
|
||||
const isConnectionNode2 = [
|
||||
"vpn",
|
||||
"awg",
|
||||
"warp",
|
||||
"anytls",
|
||||
"snell",
|
||||
"mieru",
|
||||
"sudoku",
|
||||
"masque",
|
||||
"openvpn"
|
||||
].includes(section.action || "");
|
||||
function getLatencyColor() {
|
||||
if (isConnectionNode2) {
|
||||
if (latencyFetching)
|
||||
@@ -4950,11 +4966,30 @@ function getJsonOutbounds(section) {
|
||||
const values = getListValues(section.outbound_jsons);
|
||||
return values.length ? values : getListValues(section.outbound_json);
|
||||
}
|
||||
var SINGLE_ENDPOINT_ACTIONS = /* @__PURE__ */ new Set([
|
||||
"vpn",
|
||||
"awg",
|
||||
"warp",
|
||||
"anytls",
|
||||
"snell",
|
||||
"mieru",
|
||||
"sudoku",
|
||||
"masque",
|
||||
"openvpn"
|
||||
]);
|
||||
var ACTION_DISPLAY_NAMES = {
|
||||
awg: "AmneziaWG",
|
||||
warp: "WARP",
|
||||
anytls: "AnyTLS",
|
||||
snell: "Snell",
|
||||
mieru: "Mieru",
|
||||
sudoku: "Sudoku",
|
||||
masque: "MASQUE",
|
||||
openvpn: "OpenVPN"
|
||||
};
|
||||
function isConnectionAction(action) {
|
||||
return Boolean(
|
||||
action && ["connection", "proxy", "outbound", "vpn", "awg", "warp"].includes(
|
||||
action
|
||||
)
|
||||
action && (SINGLE_ENDPOINT_ACTIONS.has(action) || ["connection", "proxy", "outbound"].includes(action))
|
||||
);
|
||||
}
|
||||
function isServiceAction(action) {
|
||||
@@ -5791,9 +5826,11 @@ async function getDashboardSections(options = {}) {
|
||||
outbounds
|
||||
};
|
||||
}
|
||||
if (sectionAction === "vpn" || sectionAction === "awg" || sectionAction === "warp") {
|
||||
if (SINGLE_ENDPOINT_ACTIONS.has(sectionAction || "")) {
|
||||
const outboundTag = getOutboundTagBySection(sectionName);
|
||||
const outbound = proxies.find((proxy) => proxy.code === outboundTag);
|
||||
const defaultLabel = ACTION_DISPLAY_NAMES[sectionAction || ""] || (sectionAction || "").toUpperCase();
|
||||
const customName = outbound?.value?.name && outbound.value.name !== outboundTag ? outbound.value.name : "";
|
||||
return {
|
||||
withTagSelect: false,
|
||||
code: outbound?.code || sectionName,
|
||||
@@ -5803,9 +5840,9 @@ async function getDashboardSections(options = {}) {
|
||||
outbounds: [
|
||||
{
|
||||
code: outbound?.code || sectionName,
|
||||
displayName: section.interface || outbound?.value?.name || (sectionAction === "awg" ? "AmneziaWG" : sectionAction.toUpperCase()),
|
||||
displayName: section.label || section.interface || customName || defaultLabel,
|
||||
latency: outbound?.value?.history?.length ? outbound.value.history[0].delay > 0 ? outbound.value.history[0].delay : -1 : 0,
|
||||
type: sectionAction === "awg" ? "AmneziaWG" : sectionAction === "warp" ? "WARP" : outbound?.value?.type || "",
|
||||
type: ACTION_DISPLAY_NAMES[sectionAction || ""] || outbound?.value?.type || (sectionAction || "").toUpperCase(),
|
||||
selected: true,
|
||||
canCopyLink: false,
|
||||
runtimeAvailable: Boolean(outbound)
|
||||
@@ -8769,9 +8806,17 @@ function updateLatencyProgressInline(sectionsWidget) {
|
||||
if (!label) {
|
||||
return false;
|
||||
}
|
||||
const isConnectionNode = ["vpn", "awg", "warp"].includes(
|
||||
section.action || ""
|
||||
);
|
||||
const isConnectionNode = [
|
||||
"vpn",
|
||||
"awg",
|
||||
"warp",
|
||||
"anytls",
|
||||
"snell",
|
||||
"mieru",
|
||||
"sudoku",
|
||||
"masque",
|
||||
"openvpn"
|
||||
].includes(section.action || "");
|
||||
const text = isConnectionNode ? _("Checking Connection...") : getLatencyTestLabel(
|
||||
sectionsWidget.latencyProgressSections[section.sectionName]
|
||||
);
|
||||
|
||||
@@ -586,7 +586,7 @@ function createProfileContent(section) {
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
for (const line of lines) {
|
||||
const clean = line.replace(/^(full:|keyword:|regex:)/, "");
|
||||
const clean = line.replace(/^(full:|keyword:|regex:)/, "").replace(/^\*?\./, "");
|
||||
if (/^(full:|keyword:|regex:)/.test(line) && !clean) {
|
||||
return _("Invalid domain: empty prefix value");
|
||||
}
|
||||
@@ -599,30 +599,30 @@ function createProfileContent(section) {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
o.write = function (sectionId, value) {
|
||||
const lines = `${value || ""}`
|
||||
.split(/\r?\n/)
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
const existingList = normalizeListValues(
|
||||
uci.get(UCI_PACKAGE, sectionId, "blocked_domains"),
|
||||
);
|
||||
for (const d of lines) {
|
||||
if (!existingList.includes(d)) {
|
||||
uci.add_list(UCI_PACKAGE, sectionId, "blocked_domains", d);
|
||||
}
|
||||
}
|
||||
for (const d of existingList) {
|
||||
if (!lines.includes(d)) {
|
||||
uci.remove_list(UCI_PACKAGE, sectionId, "blocked_domains", d);
|
||||
}
|
||||
}
|
||||
};
|
||||
o.load = function (sectionId) {
|
||||
o.cfgvalue = function (sectionId) {
|
||||
return normalizeListValues(
|
||||
uci.get(UCI_PACKAGE, sectionId, "blocked_domains"),
|
||||
).join("\n");
|
||||
};
|
||||
o.load = o.cfgvalue;
|
||||
o.formvalue = function (sectionId) {
|
||||
const node = document.getElementById(this.cbid(sectionId));
|
||||
return node ? node.value : null;
|
||||
};
|
||||
o.write = function (sectionId, value) {
|
||||
const lines = [];
|
||||
for (const raw of `${value || ""}`.split(/\r?\n/)) {
|
||||
const l = raw.trim();
|
||||
if (l && !lines.includes(l)) {
|
||||
lines.push(l);
|
||||
}
|
||||
}
|
||||
if (lines.length === 0) {
|
||||
uci.unset(UCI_PACKAGE, sectionId, "blocked_domains");
|
||||
} else {
|
||||
uci.set(UCI_PACKAGE, sectionId, "blocked_domains", lines);
|
||||
}
|
||||
};
|
||||
o.remove = function (sectionId) {
|
||||
uci.unset(UCI_PACKAGE, sectionId, "blocked_domains");
|
||||
};
|
||||
@@ -654,18 +654,23 @@ function createProfileContent(section) {
|
||||
if (!merged.includes(d)) merged.push(d);
|
||||
}
|
||||
textarea.value = merged.join("\n");
|
||||
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
textarea.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
});
|
||||
presetRow.appendChild(btn);
|
||||
});
|
||||
container.appendChild(presetRow);
|
||||
|
||||
const cbid = this.cbid(sectionId);
|
||||
const textarea = E("textarea", {
|
||||
id: `cbid.tachyon.${sectionId}.blocked_domains`,
|
||||
id: cbid,
|
||||
name: cbid,
|
||||
class: "cbi-input-textarea",
|
||||
style: "width:100%;min-height:100px;box-sizing:border-box;",
|
||||
placeholder: "tiktok.com\nroblox.com",
|
||||
});
|
||||
if (cfgvalue) textarea.value = cfgvalue;
|
||||
const strVal = Array.isArray(cfgvalue) ? cfgvalue.join("\n") : (cfgvalue || "");
|
||||
if (strVal) textarea.value = strVal;
|
||||
container.appendChild(textarea);
|
||||
return container;
|
||||
};
|
||||
@@ -1170,7 +1175,7 @@ function createParentalContent(section) {
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
for (const line of lines) {
|
||||
const clean = line.replace(/^(full:|keyword:|regex:)/, "");
|
||||
const clean = line.replace(/^(full:|keyword:|regex:)/, "").replace(/^\*?\./, "");
|
||||
if (/^(full:|keyword:|regex:)/.test(line) && !clean) {
|
||||
return _("Invalid domain: empty prefix value");
|
||||
}
|
||||
@@ -1183,30 +1188,30 @@ function createParentalContent(section) {
|
||||
}
|
||||
return true;
|
||||
};
|
||||
o.write = function (sectionId, value) {
|
||||
const lines = `${value || ""}`
|
||||
.split(/\r?\n/)
|
||||
.map((l) => l.trim())
|
||||
.filter(Boolean);
|
||||
const existingList = normalizeListValues(
|
||||
uci.get(UCI_PACKAGE, sectionId, "blocked_domains"),
|
||||
);
|
||||
for (const d of lines) {
|
||||
if (!existingList.includes(d)) {
|
||||
uci.add_list(UCI_PACKAGE, sectionId, "blocked_domains", d);
|
||||
}
|
||||
}
|
||||
for (const d of existingList) {
|
||||
if (!lines.includes(d)) {
|
||||
uci.remove_list(UCI_PACKAGE, sectionId, "blocked_domains", d);
|
||||
}
|
||||
}
|
||||
};
|
||||
o.load = function (sectionId) {
|
||||
o.cfgvalue = function (sectionId) {
|
||||
return normalizeListValues(
|
||||
uci.get(UCI_PACKAGE, sectionId, "blocked_domains"),
|
||||
).join("\n");
|
||||
};
|
||||
o.load = o.cfgvalue;
|
||||
o.formvalue = function (sectionId) {
|
||||
const node = document.getElementById(this.cbid(sectionId));
|
||||
return node ? node.value : null;
|
||||
};
|
||||
o.write = function (sectionId, value) {
|
||||
const lines = [];
|
||||
for (const raw of `${value || ""}`.split(/\r?\n/)) {
|
||||
const l = raw.trim();
|
||||
if (l && !lines.includes(l)) {
|
||||
lines.push(l);
|
||||
}
|
||||
}
|
||||
if (lines.length === 0) {
|
||||
uci.unset(UCI_PACKAGE, sectionId, "blocked_domains");
|
||||
} else {
|
||||
uci.set(UCI_PACKAGE, sectionId, "blocked_domains", lines);
|
||||
}
|
||||
};
|
||||
o.remove = function (sectionId) {
|
||||
uci.unset(UCI_PACKAGE, sectionId, "blocked_domains");
|
||||
};
|
||||
@@ -1240,18 +1245,23 @@ function createParentalContent(section) {
|
||||
if (!merged.includes(d)) merged.push(d);
|
||||
}
|
||||
textarea.value = merged.join("\n");
|
||||
textarea.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
textarea.dispatchEvent(new Event("change", { bubbles: true }));
|
||||
});
|
||||
presetRow.appendChild(btn);
|
||||
});
|
||||
container.appendChild(presetRow);
|
||||
|
||||
const cbid = this.cbid(sectionId);
|
||||
const textarea = E("textarea", {
|
||||
id: `cbid.tachyon.${sectionId}.blocked_domains`,
|
||||
id: cbid,
|
||||
name: cbid,
|
||||
class: "cbi-input-textarea",
|
||||
style: "width:100%;min-height:110px;box-sizing:border-box;",
|
||||
placeholder: "youtube.com\ngooglevideo.com",
|
||||
});
|
||||
if (cfgvalue) textarea.value = cfgvalue;
|
||||
const strVal = Array.isArray(cfgvalue) ? cfgvalue.join("\n") : (cfgvalue || "");
|
||||
if (strVal) textarea.value = strVal;
|
||||
container.appendChild(textarea);
|
||||
return container;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user