v0.32.5
This commit is contained in:
1 parent
8b9ca4db44
commit
00218a72df
35 files changed
+790
-870
No files matched your search
@@ -222,6 +222,7 @@
|
||||
const addButton = $("acl-profile-rule-add"), importButton = $("acl-profile-import-rules");
|
||||
const previewDefault = $("acl-profile-preview-default"), previewFlow = $("acl-profile-preview-flow"), previewNote = $("acl-profile-preview-note");
|
||||
const countryHelp = $("acl-profile-country-help"), countryLabel = $("acl-profile-country-label"), ipHelp = $("acl-profile-ip-help");
|
||||
const dnsHint = i18n("p", "aclDnsHelp", "fine"); ipHelp?.after(dnsHint);
|
||||
const modeInputs = [...form.querySelectorAll('input[name="acl-profile-mode"]')];
|
||||
const i18n = (tag, key, cls) => { const node = el(tag, t(key), cls); node.dataset.i18n = key; return node; };
|
||||
const selectedMode = () => modeInputs.find(node => node.checked)?.value || "allow_exceptions";
|
||||
@@ -240,6 +241,13 @@
|
||||
if (network.includes(":")) return `${network}/128`;
|
||||
return network;
|
||||
}
|
||||
const ruleKind = value => /[a-z]/i.test(value) && value.includes(".") && !value.includes(":") && !value.includes("/") ? "dns" : "ip";
|
||||
function syncRuleKind(row) {
|
||||
const kind = row.querySelector(".acl-profile-rule-type").value;
|
||||
const network = row.querySelector(".acl-profile-rule-network");
|
||||
network.maxLength = kind === "dns" ? 253 : 64;
|
||||
network.placeholder = kind === "dns" ? "office.example.ddns.net" : "10.0.0.0/8 or 203.0.113.5";
|
||||
}
|
||||
function addRule(rule = null, mark = true) {
|
||||
if (ruleRows.children.length >= 128) { toast(t("vhRowLimit"), true); return; }
|
||||
const mode = selectedMode(), fallbackAction = mode === "custom" ? "allow" : guidedAction(mode);
|
||||
@@ -250,11 +258,18 @@
|
||||
for (const actionValue of ["allow", "deny"]) { const option = el("option", t(actionValue === "allow" ? "aclAllow" : "vhDeny")); option.value = actionValue; actionSelect.append(option); }
|
||||
actionSelect.value = value.action || fallbackAction; actionLabel.append(actionSelect);
|
||||
const actionBadge = el("span", "", "acl-profile-rule-action-badge"); actionLabel.append(actionBadge);
|
||||
const typeLabel = el("label"); typeLabel.append(i18n("span", "aclRuleType"));
|
||||
const kind = el("select"); kind.className = "acl-profile-rule-type";
|
||||
for (const [id, key] of [["ip", "aclRuleIp"], ["dns", "aclRuleDns"]]) {
|
||||
const item = i18n("option", key); item.value = id; kind.append(item);
|
||||
}
|
||||
kind.value = ruleKind(value.network || ""); typeLabel.append(kind);
|
||||
const networkLabel = el("label"); networkLabel.append(i18n("span", "aclNetwork"));
|
||||
const network = el("input"); network.className = "acl-profile-rule-network"; network.type = "text"; network.required = true; network.maxLength = 64; network.autocomplete = "off"; network.spellcheck = false; network.placeholder = "10.0.0.0/8 or 203.0.113.5"; network.value = value.network || ""; networkLabel.append(network);
|
||||
const network = el("input"); network.className = "acl-profile-rule-network"; network.type = "text"; network.required = true; network.autocomplete = "off"; network.spellcheck = false; network.value = value.network || ""; networkLabel.append(network);
|
||||
network.addEventListener("blur", () => { const normalized = normalizeNetwork(network.value); if (normalized !== network.value) { network.value = normalized; syncRulesText(); renderPreview(); } });
|
||||
kind.addEventListener("change", () => { network.value = ""; syncRuleKind(row); syncRulesText(); dirty = true; syncPolicy(); network.focus(); });
|
||||
const remove = action(t("remove"), () => { row.remove(); syncRulesText(); dirty = true; syncPolicy(); }); remove.classList.add("acl-profile-rule-remove");
|
||||
row.append(actionLabel, networkLabel, remove); ruleRows.append(row);
|
||||
row.append(actionLabel, typeLabel, networkLabel, remove); ruleRows.append(row); syncRuleKind(row);
|
||||
if (mark) { syncRulesText(); dirty = true; }
|
||||
syncRuleRows();
|
||||
}
|
||||
@@ -370,6 +385,9 @@
|
||||
function refreshTranslations() {
|
||||
$("acl-profile-editing").textContent = t(editing ? "aclProfileEdit" : "aclProfileNew");
|
||||
for (const row of ruleRows.children) {
|
||||
const network = row.querySelector(".acl-profile-rule-network");
|
||||
const kind = row.querySelector(".acl-profile-rule-type");
|
||||
if (kind) { kind.value = ruleKind(network?.value || ""); syncRuleKind(row); }
|
||||
const select = row.querySelector(".acl-profile-rule-action");
|
||||
if (select?.options?.length >= 2) {
|
||||
select.options[0].textContent = t("aclAllow");
|
||||
@@ -433,6 +451,8 @@
|
||||
}
|
||||
const finalMode = selectedMode(), expectedAction = finalMode === "custom" ? null : guidedAction(finalMode);
|
||||
const aclRules = collectRuleRows().map(rule => ({ ...rule, action: expectedAction || rule.action }));
|
||||
if (aclRules.some(rule => rule.action === "deny" && ruleKind(rule.network) === "dns"))
|
||||
throw fieldError(ruleRows, t("aclDnsAllowOnly"));
|
||||
if (aclRules.some(rule => !rule.network)) { const input = [...ruleRows.querySelectorAll(".acl-profile-rule-network")].find(node => !node.value.trim()); throw fieldError(input || rules, t("ruleSyntax")); }
|
||||
for (const [row, rule] of [...ruleRows.children].map((row, index) => [row, aclRules[index]])) row.querySelector(".acl-profile-rule-network").value = rule.network;
|
||||
const finalDefault = finalMode === "custom" ? aclDefault.value : guidedDefault(finalMode);
|
||||
|
||||
+183
-679
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user