summaryrefslogtreecommitdiffhomepage
path: root/applications/luci-app-banip/htdocs
diff options
context:
space:
mode:
Diffstat (limited to 'applications/luci-app-banip/htdocs')
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js15
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js15
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/custom.css3
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js305
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js421
-rw-r--r--applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js55
6 files changed, 612 insertions, 202 deletions
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js
index 07175a4fce..6b54f2946e 100644
--- a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/allowlist.js
@@ -11,23 +11,26 @@ return view.extend({
]);
},
handleSave: function (ev) {
- var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
+ let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
return fs.write('/etc/banip/banip.allowlist', value)
- .then(function (rc) {
+ .then(function () {
document.querySelector('textarea').value = value;
- ui.addNotification(null, E('p', _('Allowlist modifications have been saved, restart banIP that changes take effect.')), 'info');
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
+ ui.addNotification(null, E('p', _('Allowlist modifications have been saved, start the Domain Lookup or restart banIP that changes take effect.')), 'info');
}).catch(function (e) {
- ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)));
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
+ ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
});
},
render: function (allowlist) {
if (allowlist[0].size >= 100000) {
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
ui.addNotification(null, E('p', _('The allowlist is too big, unable to save modifications.')), 'error');
}
return E([
E('p', {},
- _('This is the local banIP allowlist that will permit certain MAC/IP/CIDR addresses.<br /> \
- <em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line.')),
+ _('This is the local banIP allowlist that will permit certain MAC-, IP-addresses or domain names.<br /> \
+ <em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line. Ranges in CIDR notation and MAC/IP-bindings are allowed.')),
E('p', {},
E('textarea', {
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js
index 75560fd6e1..8dede44e52 100644
--- a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/blocklist.js
@@ -11,23 +11,26 @@ return view.extend({
]);
},
handleSave: function (ev) {
- var value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
+ let value = ((document.querySelector('textarea').value || '').trim().toLowerCase().replace(/\r\n/g, '\n')) + '\n';
return fs.write('/etc/banip/banip.blocklist', value)
- .then(function (rc) {
+ .then(function () {
document.querySelector('textarea').value = value;
- ui.addNotification(null, E('p', _('Blocklist modifications have been saved, restart banIP that changes take effect.')), 'info');
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
+ ui.addNotification(null, E('p', _('Blocklist modifications have been saved, start the Domain Lookup or restart banIP that changes take effect.')), 'info');
}).catch(function (e) {
- ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)));
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
+ ui.addNotification(null, E('p', _('Unable to save modifications: %s').format(e.message)), 'error');
});
},
render: function (blocklist) {
if (blocklist[0].size >= 100000) {
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
ui.addNotification(null, E('p', _('The blocklist is too big, unable to save modifications.')), 'error');
}
return E([
E('p', {},
- _('This is the local banIP blocklist that will prevent certain MAC/IP/CIDR addresses.<br /> \
- <em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line.')),
+ _('This is the local banIP blocklist that will prevent certain MAC-, IP-addresses or domain names.<br /> \
+ <em><b>Please note:</b></em> add only exactly one MAC/IPv4/IPv6 address or domain name per line. Ranges in CIDR notation and MAC/IP-bindings are allowed.')),
E('p', {},
E('textarea', {
'style': 'width: 100% !important; padding: 5px; font-family: monospace',
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/custom.css b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/custom.css
new file mode 100644
index 0000000000..23c60c683d
--- /dev/null
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/custom.css
@@ -0,0 +1,3 @@
+.cbi-input-text {
+ width: 90% !important;
+}
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js
new file mode 100644
index 0000000000..0e4e682986
--- /dev/null
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/feeds.js
@@ -0,0 +1,305 @@
+'use strict';
+'require view';
+'require form';
+'require fs';
+'require ui';
+
+/*
+ include custom CSS
+*/
+document.querySelector('head').appendChild(E('link', {
+ 'rel': 'stylesheet',
+ 'type': 'text/css',
+ 'href': L.resource('view/banip/custom.css')
+}));
+
+/*
+ observe DOM changes
+*/
+const observer = new MutationObserver(function (mutations) {
+ if (mutations) {
+ const inputs = document.querySelectorAll('input');
+ inputs.forEach(function (input) {
+ input.setAttribute('autocomplete', 'off')
+ input.setAttribute('autocorrect', 'off')
+ input.setAttribute('autocapitalize', 'off')
+ input.setAttribute('spellcheck', false)
+ })
+ const labels = document.querySelectorAll('label[for^="widget.cbid.json"][for$="name"]');
+ labels.forEach(function (label) {
+ label.setAttribute("style", "font-weight: bold !important; color: #595 !important;");
+ })
+ L.resolveDefault(fs.stat('/etc/banip/banip.custom.feeds'), '').then(function (stat) {
+ const buttons = document.querySelectorAll('#btnClear, #btnCreate, #btnSave, #btnUpload, #btnDownload');
+ if (buttons[1] && buttons[2] && stat.size === 0) {
+ buttons[1].removeAttribute('disabled');
+ buttons[2].removeAttribute('disabled');
+ } else if (buttons[0] && buttons[3] && buttons[4] && stat.size > 0) {
+ buttons[0].removeAttribute('disabled');
+ buttons[3].removeAttribute('disabled');
+ buttons[4].removeAttribute('disabled');
+ }
+ });
+ }
+});
+
+const targetNode = document.getElementById('view');
+const observerConfig = {
+ childList: true,
+ subtree: true,
+ attributes: false,
+ characterData: false
+};
+observer.observe(targetNode, observerConfig);
+
+/*
+ button handling
+*/
+function handleEdit(ev) {
+ if (ev === 'upload') {
+ return ui.uploadFile('/etc/banip/banip.custom.feeds').then(function () {
+ L.resolveDefault(fs.read_direct('/etc/banip/banip.custom.feeds', 'json'), "").then(function (data) {
+ if (data) {
+ let dataLength = Object.keys(data).length || 0;
+ if (dataLength > 0) {
+ for (let i = 0; i < dataLength; i++) {
+ let feed = Object.keys(data)[i];
+ let descr = data[feed].descr;
+ if (feed && descr) {
+ continue;
+ }
+ fs.write('/etc/banip/banip.custom.feeds', null).then(function () {
+ ui.addNotification(null, E('p', _('Upload of the custom feed file failed.')), 'error');
+ });
+ return;
+ }
+ } else {
+ fs.write('/etc/banip/banip.custom.feeds', null).then(function () {
+ ui.addNotification(null, E('p', _('Upload of the custom feed file failed.')), 'error');
+ });
+ return;
+ }
+ location.reload();
+ } else {
+ fs.write('/etc/banip/banip.custom.feeds', null).then(function () {
+ ui.addNotification(null, E('p', _('Upload of the custom feed file failed.')), 'error');
+ });
+ }
+ });
+ }).catch(function () { });
+ }
+ if (ev === 'download') {
+ return fs.read_direct('/etc/banip/banip.custom.feeds', 'blob').then(function (blob) {
+ let url = window.URL.createObjectURL(blob),
+ date = new Date(),
+ name = 'banip.custom.feeds_%04d-%02d-%02d.json'.format(date.getFullYear(), date.getMonth() + 1, date.getDate()),
+ link = E('a', { 'style': 'display:none', 'href': url, 'download': name });
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ }).catch(function () { });
+ }
+ if (ev === 'create') {
+ return fs.read_direct('/etc/banip/banip.feeds', 'json').then(function (content) {
+ fs.write('/etc/banip/banip.custom.feeds', JSON.stringify(content)).then(function () {
+ location.reload();
+ });
+ });
+ }
+ if (ev === 'clear') {
+ return fs.write('/etc/banip/banip.custom.feeds', null).then(function () {
+ location.reload();
+ });
+ }
+ if (ev === 'save') {
+ const invalid = document.querySelectorAll('.cbi-input-invalid');
+ if (invalid.length > 0) {
+ document.body.scrollTop = document.documentElement.scrollTop = 0;
+ return ui.addNotification(null, E('p', _('Invalid input values, unable to save modifications.')), 'error');
+ }
+ }
+ let sumSubElements = [], exportJson;
+ const nodeKeys = document.querySelectorAll('[id^="widget.cbid.json"][id$="name"]');
+ for (let i = 0; i < nodeKeys.length; i++) {
+ let subElements = {};
+ let elements = document.querySelectorAll('[id^="widget.cbid.json.' + nodeKeys[i].id.split('.')[3] + '\."]');
+ for (const element of elements) {
+ let key = element.id.split('.')[4];
+ let value = element.value || "";
+ if (value === "") {
+ continue;
+ }
+ switch (key) {
+ case 'url_4':
+ subElements.url_4 = value;
+ break;
+ case 'rule_4':
+ subElements.rule_4 = value;
+ break;
+ case 'url_6':
+ subElements.url_6 = value;
+ break;
+ case 'rule_6':
+ subElements.rule_6 = value;
+ break;
+ case 'descr':
+ subElements.descr = value;
+ break;
+ case 'flag':
+ subElements.flag = value;
+ break;
+ }
+ }
+ if (nodeKeys[i].value !== "" && subElements.descr !== "") {
+ sumSubElements.push(nodeKeys[i].value, subElements);
+ }
+ }
+ if (sumSubElements.length > 0) {
+ exportJson = JSON.stringify(sumSubElements).replace(/^\[/, '{\n').replace(/\}]$/, '\n\t}\n}\n').replace(/,{"/g, ':{\n\t"').replace(/"},"/g, '"\n\t},\n"').replace(/","/g, '",\n\t"');
+ }
+ return fs.write('/etc/banip/banip.custom.feeds', exportJson).then(function () {
+ location.reload();
+ });
+}
+
+return view.extend({
+ load: function () {
+ return L.resolveDefault(fs.read_direct('/etc/banip/banip.custom.feeds', 'json'), "");
+ },
+
+ render: function (data) {
+ let m, s, o, feed, url_4, url_6, rule_4, rule_6, descr, flag;
+
+ m = new form.JSONMap(data, _('Custom Feed Editor'), _('With this editor you can upload your local custom feed file or fill up an initial one (a 1:1 copy of the version shipped with the package). \
+ The file is located at \'/etc/banip/banip.custom.feeds\'. \
+ Then you can edit this file, delete entries, add new ones or make a local backup. To go back to the maintainers version just empty the custom feed file again (do not delete it!).'));
+ for (let i = 0; i < Object.keys(m.data.data).length; i++) {
+ feed = Object.keys(m.data.data)[i];
+ url_4 = m.data.data[feed].url_4;
+ rule_4 = m.data.data[feed].rule_4;
+ url_6 = m.data.data[feed].url_6;
+ rule_6 = m.data.data[feed].rule_6;
+ descr = m.data.data[feed].descr;
+ flag = m.data.data[feed].flag;
+
+ s = m.section(form.TypedSection, feed, null);
+ s.addremove = true;
+ s.anonymous = true;
+
+ o = s.option(form.Value, 'name', _('Feed Name'));
+ o.ucioption = '.name';
+ o.datatype = 'and(minlength(3),maxlength(15))';
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return _('Empty field not allowed');
+ }
+ if (!value.match(/^[a-z0-9]+$/)) {
+ return _('Invalid characters');
+ }
+ return true;
+ }
+
+ o = s.option(form.Value, 'url_4', _('URLv4'));
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return true;
+ }
+ if (!value.match(/^(http:\/\/|https:\/\/)[A-Za-z0-9\/\.\-\?\&\+_@%=:~#]+$/)) {
+ return _('Protocol/URL format not supported');
+ }
+ return true;
+ }
+
+ o = s.option(form.Value, 'rule_4', _('Rulev4'));
+
+ o = s.option(form.Value, 'url_6', _('URLv6'));
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return true;
+ }
+ if (!value.match(/^(http:\/\/|https:\/\/)[A-Za-z0-9\/\.\-\?\&\+_@%=:~#]+$/)) {
+ return _('Protocol/URL format not supported');
+ }
+ return true;
+ }
+
+ o = s.option(form.Value, 'rule_6', _('Rulev6'));
+
+ o = s.option(form.Value, 'descr', _('Description'));
+ o.datatype = 'and(minlength(3),maxlength(30))';
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return _('Empty field not allowed');
+ }
+ return true;
+ }
+
+ o = s.option(form.Value, 'flag', _('Flag'));
+ o.datatype = 'and(minlength(2),maxlength(2))';
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return true;
+ }
+ if (!value.match(/^gz$/)) {
+ return _('Flag not supported');
+ }
+ return true;
+ }
+ }
+
+ s = m.section(form.NamedSection, 'global');
+ s.render = L.bind(function () {
+ return E('div', { class: 'right' }, [
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-action',
+ 'id': 'btnDownload',
+ 'disabled': 'disabled',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleEdit('download');
+ })
+ }, [_('Download Custom Feeds')]),
+ '\xa0\xa0\xa0',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-action',
+ 'id': 'btnUpload',
+ 'disabled': 'disabled',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleEdit('upload');
+ })
+ }, [_('Upload Custom Feeds')]),
+ '\xa0\xa0\xa0\xa0\xa0\xa0',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-action important',
+ 'id': 'btnCreate',
+ 'disabled': 'disabled',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleEdit('create');
+ })
+ }, [_('Fill Custom Feeds')]),
+ '\xa0\xa0\xa0',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-negative important',
+ 'id': 'btnClear',
+ 'disabled': 'disabled',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleEdit('clear');
+ })
+ }, [_('Clear Custom Feeds')]),
+ '\xa0\xa0\xa0',
+ E('button', {
+ 'class': 'btn cbi-button cbi-button-positive important',
+ 'id': 'btnSave',
+ 'disabled': 'disabled',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleEdit('save');
+ })
+ }, [_('Save Custom Feeds')])
+ ])
+ });
+ return m.render();
+ },
+ handleSaveApply: null,
+ handleSave: null,
+ handleReset: null
+});
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js
index 2b8899dc85..adefc3b18d 100644
--- a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/overview.js
@@ -17,6 +17,7 @@ function handleAction(ev) {
return view.extend({
load: function () {
return Promise.all([
+ L.resolveDefault(fs.read_direct('/etc/banip/banip.custom.feeds'), ''),
L.resolveDefault(fs.read_direct('/etc/banip/banip.feeds'), ''),
L.resolveDefault(fs.read_direct('/etc/banip/banip.countries'), ''),
uci.load('banip')
@@ -24,118 +25,124 @@ return view.extend({
},
render: function (result) {
- var m, s, o;
+ let m, s, o;
- m = new form.Map('banip', 'banIP', _('Configuration of the banIP package to ban incoming and outgoing ip addresses/subnets via sets in nftables. \
+ m = new form.Map('banip', 'banIP', _('Configuration of the banIP package to ban incoming and outgoing IPs via named nftables Sets. \
For further information <a href="https://github.com/openwrt/packages/blob/master/net/banip/files/README.md" target="_blank" rel="noreferrer noopener" >check the online documentation</a>'));
/*
poll runtime information
*/
- var rt_res, inf_stat, inf_version, inf_elements, inf_feeds, inf_feedarray, inf_devices, inf_devicearray
- var inf_subnets, inf_subnetarray, nft_infos, run_infos, inf_flags, last_run, inf_system
+ let buttons, rtRes, infStat, infVer, infElements, infFeeds, infDevices, infUplink, infSystem, nftInfos, runInfos, infFlags, last_run
pollData: poll.add(function () {
- return L.resolveDefault(fs.read_direct('/var/run/banip_runtime.json'), 'null').then(function (res) {
- rt_res = JSON.parse(res);
- inf_stat = document.getElementById('status');
- if (inf_stat && rt_res) {
- L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['status', 'update'])).then(function (update_res) {
- inf_stat.textContent = (rt_res.status + ' (' + update_res.trim() + ')' || '-');
- });
- if (rt_res.status === "processing") {
- if (!inf_stat.classList.contains("spinning")) {
- inf_stat.classList.add("spinning");
- }
- } else {
- if (inf_stat.classList.contains("spinning")) {
- inf_stat.classList.remove("spinning");
- }
+ return L.resolveDefault(fs.stat('/var/run/banip.lock')).then(function (stat) {
+ buttons = document.querySelectorAll('.cbi-button');
+ infStat = document.getElementById('status');
+ if (stat) {
+ for (let i = 0; i < buttons.length; i++) {
+ buttons[i].setAttribute('disabled', 'true');
}
- } else if (inf_stat) {
- inf_stat.textContent = '-';
- if (inf_stat.classList.contains("spinning")) {
- inf_stat.classList.remove("spinning");
+ if (infStat && !infStat.classList.contains('spinning')) {
+ infStat.classList.add('spinning');
}
- }
- inf_version = document.getElementById('version');
- if (inf_version && rt_res) {
- inf_version.textContent = rt_res.version || '-';
- }
- inf_elements = document.getElementById('elements');
- if (inf_elements && rt_res) {
- inf_elements.textContent = rt_res.element_count || '-';
- }
- inf_feeds = document.getElementById('feeds');
- inf_feedarray = [];
- if (inf_feeds && rt_res) {
- for (var i = 0; i < rt_res.active_feeds.length; i++) {
- if (i < rt_res.active_feeds.length - 1) {
- inf_feedarray += rt_res.active_feeds[i].feed + ', ';
- } else {
- inf_feedarray += rt_res.active_feeds[i].feed
- }
+ } else {
+ for (let i = 0; i < buttons.length; i++) {
+ buttons[i].removeAttribute('disabled');
+ }
+ if (infStat && infStat.classList.contains('spinning')) {
+ infStat.classList.remove('spinning');
}
- inf_feeds.textContent = inf_feedarray || '-';
}
- inf_devices = document.getElementById('devices');
- inf_devicearray = [];
- if (inf_devices && rt_res && rt_res.active_devices.length > 1) {
- for (var i = 0; i < rt_res.active_devices.length; i++) {
- if (i === 0 && rt_res.active_devices[i].device && rt_res.active_devices[i+1].interface) {
- inf_devicearray += rt_res.active_devices[i].device + ' ::: ' + rt_res.active_devices[i+1].interface;
- i++;
- }
- else if (i === 0) {
- inf_devicearray += rt_res.active_devices[i].device
- }
- else if (i > 0 && rt_res.active_devices[i].device && rt_res.active_devices[i+1].interface) {
- inf_devicearray += ', ' + rt_res.active_devices[i].device + ' ::: ' + rt_res.active_devices[i+1].interface;
- i++;
- }
- else if (i > 0 && rt_res.active_devices[i].device) {
- inf_devicearray += ', ' + rt_res.active_devices[i].device;
+ L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['status'])).then(function (result) {
+ if (result) {
+ rtRes = result.trim().split('\n');
+ if (rtRes) {
+ for (let i = 0; i < rtRes.length; i++) {
+ if (rtRes[i].match(/^\s+\+\sstatus\s+\:\s+(.*)$/)) {
+ rtRes.status = rtRes[i].match(/^\s+\+\sstatus\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\sversion\s+\:\s+(.*)$/)) {
+ rtRes.version = rtRes[i].match(/^\s+\+\sversion\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\selement_count\s+\:\s+(.*)$/)) {
+ rtRes.elementCount = rtRes[i].match(/^\s+\+\selement_count\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\sactive_feeds\s+\:\s+(.*)$/)) {
+ rtRes.activeFeeds = rtRes[i].match(/^\s+\+\sactive_feeds\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\sactive_devices\s+\:\s+(.*)$/)) {
+ rtRes.activeDevices = rtRes[i].match(/^\s+\+\sactive_devices\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\sactive_uplink\s+\:\s+(.*)$/)) {
+ rtRes.activeUplink = rtRes[i].match(/^\s+\+\sactive_uplink\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\snft_info\s+\:\s+(.*)$/)) {
+ rtRes.nftInfo = rtRes[i].match(/^\s+\+\snft_info\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\srun_info\s+\:\s+(.*)$/)) {
+ rtRes.runInfo = rtRes[i].match(/^\s+\+\srun_info\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\srun_flags\s+\:\s+(.*)$/)) {
+ rtRes.runFlags = rtRes[i].match(/^\s+\+\srun_flags\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\slast_run\s+\:\s+(.*)$/)) {
+ rtRes.lastRun = rtRes[i].match(/^\s+\+\slast_run\s+\:\s+(.*)$/)[1];
+ } else if (rtRes[i].match(/^\s+\+\ssystem_info\s+\:\s+(.*)$/)) {
+ rtRes.systemInfo = rtRes[i].match(/^\s+\+\ssystem_info\s+\:\s+(.*)$/)[1];
+ }
+ }
}
- else if (i > 0 && rt_res.active_devices[i].interface) {
- inf_devicearray += ', ' + rt_res.active_devices[i].interface;
+ if (rtRes) {
+ infStat = document.getElementById('status');
+ if (infStat) {
+ infStat.textContent = rtRes.status || '-';
+ }
+ infVer = document.getElementById('version');
+ if (infVer) {
+ infVer.textContent = rtRes.version || '-';
+ }
+ infElements = document.getElementById('elements');
+ if (infElements) {
+ infElements.textContent = rtRes.elementCount || '-';
+ }
+ infFeeds = document.getElementById('feeds');
+ if (infFeeds) {
+ infFeeds.textContent = rtRes.activeFeeds || '-';
+ }
+ infDevices = document.getElementById('devices');
+ if (infDevices) {
+ infDevices.textContent = rtRes.activeDevices || '-';
+ }
+ infUplink = document.getElementById('uplink');
+ if (infUplink) {
+ infUplink.textContent = rtRes.activeUplink || '-';
+ }
+ nftInfos = document.getElementById('nft');
+ if (nftInfos) {
+ nftInfos.textContent = rtRes.nftInfo || '-';
+ }
+ runInfos = document.getElementById('run');
+ if (runInfos) {
+ runInfos.textContent = rtRes.runInfo || '-';
+ }
+ infFlags = document.getElementById('flags');
+ if (infFlags) {
+ infFlags.textContent = rtRes.runFlags || '-';
+ }
+ last_run = document.getElementById('last');
+ if (last_run) {
+ last_run.textContent = rtRes.lastRun || '-';
+ }
+ infSystem = document.getElementById('system');
+ if (infSystem) {
+ infSystem.textContent = rtRes.systemInfo || '-';
+ }
}
- }
- inf_devices.textContent = inf_devicearray || '-';
- }
- inf_subnets = document.getElementById('subnets');
- inf_subnetarray = [];
- if (inf_subnets && rt_res) {
- for (var i = 0; i < rt_res.active_subnets.length; i++) {
- if (i < rt_res.active_subnets.length - 1) {
- inf_subnetarray += rt_res.active_subnets[i].subnet + ', ';
- } else {
- inf_subnetarray += rt_res.active_subnets[i].subnet
+ } else {
+ infStat = document.getElementById('status');
+ if (infStat) {
+ infStat.textContent = '-';
+ poll.stop();
+ if (infStat.classList.contains('spinning')) {
+ infStat.classList.remove('spinning');
+ }
}
}
- inf_subnets.textContent = inf_subnetarray || '-';
- }
- nft_infos = document.getElementById('nft');
- if (nft_infos && rt_res) {
- nft_infos.textContent = rt_res.nft_info || '-';
- }
- run_infos = document.getElementById('run');
- if (run_infos && rt_res) {
- run_infos.textContent = rt_res.run_info || '-';
- }
- inf_flags = document.getElementById('flags');
- if (inf_flags && rt_res) {
- inf_flags.textContent = rt_res.run_flags || '-';
- }
- last_run = document.getElementById('last');
- if (last_run && rt_res) {
- last_run.textContent = rt_res.last_run || '-';
- }
- inf_system = document.getElementById('system');
- if (inf_system && rt_res) {
- inf_system.textContent = rt_res.system_info || '-';
- }
+ });
});
- }, 1);
+ }, 2);
/*
runtime information and buttons
@@ -165,8 +172,8 @@ return view.extend({
E('div', { 'class': 'cbi-value-field', 'id': 'devices', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
- E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Subnets')),
- E('div', { 'class': 'cbi-value-field', 'id': 'subnets', 'style': 'color:#37c' }, '-')
+ E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Active Uplink')),
+ E('div', { 'class': 'cbi-value-field', 'id': 'uplink', 'style': 'color:#37c' }, '-')
]),
E('div', { 'class': 'cbi-value' }, [
E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('NFT Information')),
@@ -190,6 +197,13 @@ return view.extend({
]),
E('div', { class: 'right' }, [
E('button', {
+ 'class': 'btn cbi-button cbi-button-action',
+ 'click': ui.createHandlerFn(this, function () {
+ return handleAction('lookup');
+ })
+ }, [_('Domain Lookup')]),
+ '\xa0\xa0\xa0',
+ E('button', {
'class': 'btn cbi-button cbi-button-negative',
'click': ui.createHandlerFn(this, function () {
return handleAction('stop');
@@ -224,7 +238,7 @@ return view.extend({
s.tab('adv_chain', _('Chain/Set Settings'));
s.tab('adv_log', _('Log Settings'));
s.tab('adv_email', _('E-Mail Settings'));
- s.tab('feeds', _('Blocklist Feeds'));
+ s.tab('feeds', _('Feed Selection'));
/*
general settings tab
@@ -250,23 +264,20 @@ return view.extend({
o = s.taboption('general', widgets.DeviceSelect, 'ban_dev', _('Network Devices'), _('Select the WAN network device(s).'));
o.depends('ban_autodetect', '0');
- o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
o.retain = true;
- o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv4', _('Network Interfaces'), _('Select the logical WAN IPv4 network interface(s).'));
+ o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv4', _('IPv4 Network Interfaces'), _('Select the logical WAN IPv4 network interface(s).'));
o.depends('ban_autodetect', '0');
- o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
o.retain = true;
- o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv6', _('Network Interfaces'), _('Select the logical WAN IPv6 network interface(s).'));
+ o = s.taboption('general', widgets.NetworkSelect, 'ban_ifv6', _('IPv6 Network Interfaces'), _('Select the logical WAN IPv6 network interface(s).'));
o.depends('ban_autodetect', '0');
- o.unspecified = true;
o.multiple = true;
o.nocreate = true;
o.optional = true;
@@ -286,38 +297,34 @@ return view.extend({
o.optional = true;
o.retain = true;
- o = s.taboption('general', widgets.NetworkSelect, 'ban_trigger', _('Startup Trigger Interface'), _('List of available network interfaces to trigger the banIP start.'));
- o.unspecified = true;
+ o = s.taboption('general', widgets.NetworkSelect, 'ban_trigger', _('Reload Trigger Interface'), _('List of available reload trigger interface(s).'));
o.multiple = true;
o.nocreate = true;
o.rmempty = true;
- o = s.taboption('general', form.Value, 'ban_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds before banIP processing actually starts.'));
+ o = s.taboption('general', form.Value, 'ban_triggerdelay', _('Trigger Delay'), _('Additional trigger delay in seconds during interface reload and boot.'));
o.placeholder = '10';
o.datatype = 'range(1,300)';
o.rmempty = true;
- o = s.taboption('general', form.Flag, 'ban_deduplicate', _('Deduplicate IPs'), _('Deduplicate IP addresses across all active sets and and tidy up the local blocklist.'));
- o.default = 1
- o.rmempty = false;
-
- o = s.taboption('general', form.Flag, 'ban_loginput', _('Log WAN-Input'), _('Log suspicious incoming WAN packets (dropped).'));
- o.default = 1
- o.rmempty = false;
-
- o = s.taboption('general', form.Flag, 'ban_logforwardwan', _('Log WAN-Forward'), _('Log suspicious forwarded WAN packets (dropped).'));
- o.default = 1
- o.rmempty = false;
+ o = s.taboption('general', form.ListValue, 'ban_fetchretry', _('Download Retries'), _('Number of download attempts in case of an error (not supported by uclient-fetch).'));
+ o.value('1', _('1'));
+ o.value('3', _('3'));
+ o.value('5', _('5 (default)'));
+ o.value('10', _('10'));
+ o.value('20', _('20'));
+ o.optional = true;
+ o.rmempty = true;
- o = s.taboption('general', form.Flag, 'ban_logforwardlan', _('Log LAN-Forward'), _('Log suspicious forwarded LAN packets (rejected).'));
- o.rmempty = false;
+ o = s.taboption('general', form.Flag, 'ban_fetchinsecure', _('Download Insecure'), _('Don\'t check SSL server certificates during download.'));
+ o.rmempty = true;
/*
additional settings tab
*/
o = s.taboption('advanced', form.DummyValue, '_sub');
o.rawhtml = true;
- o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
+ o.default = '<em><b>' + _('Changes on this tab needs a banIP service restart to take effect.') + '</b></em>';
o = s.taboption('advanced', form.ListValue, 'ban_nicelimit', _('Nice Level'), _('The selected priority will be used for banIP background processing.'));
o.value('-20', _('Highest Priority'));
@@ -328,7 +335,7 @@ return view.extend({
o.optional = true;
o.rmempty = true;
- o = s.taboption('advanced', form.ListValue, 'ban_filelimit', _('Max Open Files'), _('Increase the maximal number of open files, e.g. to handle the amount of temporary split files while loading the sets.'));
+ o = s.taboption('advanced', form.ListValue, 'ban_filelimit', _('Max Open Files'), _('Increase the maximal number of open files, e.g. to handle the amount of temporary split files while loading the Sets.'));
o.value('512', _('512'));
o.value('1024', _('1024 (default)'));
o.value('2048', _('2048'));
@@ -345,7 +352,7 @@ return view.extend({
o.optional = true;
o.rmempty = true;
- o = s.taboption('advanced', form.ListValue, 'ban_splitsize', _('Set Split Size'), _('Split external set loading after every n members to save RAM.'));
+ o = s.taboption('advanced', form.ListValue, 'ban_splitsize', _('Set Split Size'), _('Split external Set loading after every n members to save RAM.'));
o.value('256');
o.value('512');
o.value('1024');
@@ -366,27 +373,28 @@ return view.extend({
o.placeholder = '/tmp/banIP-report';
o.rmempty = true;
+ o = s.taboption('advanced', form.Flag, 'ban_deduplicate', _('Deduplicate IPs'), _('Deduplicate IP addresses across all active Sets and tidy up the local blocklist.'));
+ o.default = 1
+ o.rmempty = false;
+
o = s.taboption('advanced', form.Flag, 'ban_reportelements', _('Report Elements'), _('List Set elements in the status and report, disable this to reduce the CPU load.'));
o.default = 1
o.optional = true;
- o = s.taboption('advanced', form.Flag, 'ban_fetchinsecure', _('Download Insecure'), _('Don\'t check SSL server certificates during download.'));
- o.rmempty = true;
-
/*
advanced chain/set settings tab
*/
o = s.taboption('adv_chain', form.DummyValue, '_sub');
o.rawhtml = true;
- o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
+ o.default = '<em><b>' + _('Changes on this tab needs a banIP service restart to take effect.') + '</b></em>';
- o = s.taboption('adv_chain', form.ListValue, 'ban_nftpolicy', _('Set Policy'), _('Set the nft policy for banIP-related sets.'));
+ o = s.taboption('adv_chain', form.ListValue, 'ban_nftpolicy', _('NFT Set Policy'), _('Set the nft policy for banIP-related Sets.'));
o.value('memory', _('memory (default)'));
o.value('performance', _('performance'));
o.optional = true;
o.rmempty = true;
- o = s.taboption('adv_chain', form.ListValue, 'ban_nftpriority', _('Chain Priority'), _('Set the nft chain priority within the banIP table. Please note: lower values means higher priority.'));
+ o = s.taboption('adv_chain', form.ListValue, 'ban_nftpriority', _('NFT Chain Priority'), _('Set the nft chain priority within the banIP table. Please note: lower values means higher priority.'));
o.value('0', _('0'));
o.value('-100', _('-100'));
o.value('-200', _('-200 (default)'));
@@ -395,12 +403,42 @@ return view.extend({
o.optional = true;
o.rmempty = true;
+ o = s.taboption('adv_chain', widgets.DeviceSelect, 'ban_vlanallow', _('Allow VLAN Forwards'), _('Always allow certain VLAN forwards.'));
+ o.multiple = true;
+ o.nocreate = true;
+ o.optional = true;
+ o.rmempty = true;
+
+ o = s.taboption('adv_chain', widgets.DeviceSelect, 'ban_vlanblock', _('Block VLAN Forwards'), _('Always block certain VLAN forwards.'));
+ o.multiple = true;
+ o.nocreate = true;
+ o.optional = true;
+ o.rmempty = true;
+
+ o = s.taboption('adv_chain', form.ListValue, 'ban_blocktype', _('Block Type'), _('Drop packets silently or actively reject the traffic on WAN-Input and WAN-Forward chains.'));
+ o.value('drop', _('drop (default)'));
+ o.value('reject', _('reject'));
+ o.optional = true;
+ o.rmempty = true;
+
+ o = s.taboption('adv_chain', form.ListValue, 'ban_blockpolicy', _('Default Block Policy'), _('By default each feed is active in all supported chains. Limit the default block policy to a certain chain.'));
+ o.value('input', _('WAN-Input Chain'));
+ o.value('forwardwan', _('WAN-Forward Chain'));
+ o.value('forwardlan', _('LAN-Forward Chain'));
+ o.optional = true;
+ o.rmempty = true;
+
+ let feed, feeds, descr;
if (result[0]) {
- var feed, feeds;
feeds = JSON.parse(result[0]);
-
+ } else if (result[1]) {
+ feeds = JSON.parse(result[1]);
+ }
+ if (feeds) {
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockinput', _('WAN-Input Chain'), _('Limit certain feeds to the WAN-Input chain.'));
- for (var i = 0; i < Object.keys(feeds).length; i++) {
+ o.value('allowlist', _('local allowlist'));
+ o.value('blocklist', _('local blocklist'));
+ for (let i = 0; i < Object.keys(feeds).length; i++) {
feed = Object.keys(feeds)[i].trim();
o.value(feed);
}
@@ -408,7 +446,9 @@ return view.extend({
o.rmempty = true;
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockforwardwan', _('WAN-Forward Chain'), _('Limit certain feeds to the WAN-Forward chain.'));
- for (var i = 0; i < Object.keys(feeds).length; i++) {
+ o.value('allowlist', _('local allowlist'));
+ o.value('blocklist', _('local blocklist'));
+ for (let i = 0; i < Object.keys(feeds).length; i++) {
feed = Object.keys(feeds)[i].trim();
o.value(feed);
}
@@ -416,7 +456,9 @@ return view.extend({
o.rmempty = true;
o = s.taboption('adv_chain', form.MultiValue, 'ban_blockforwardlan', _('LAN-Forward Chain'), _('Limit certain feeds to the LAN-Forward chain.'));
- for (var i = 0; i < Object.keys(feeds).length; i++) {
+ o.value('allowlist', _('local allowlist'));
+ o.value('blocklist', _('local blocklist'));
+ for (let i = 0; i < Object.keys(feeds).length; i++) {
feed = Object.keys(feeds)[i].trim();
o.value(feed);
}
@@ -424,23 +466,14 @@ return view.extend({
o.rmempty = true;
}
- o = s.taboption('adv_chain', form.ListValue, 'ban_nftexpiry', _('Blocklist Expiry'), _('Expiry time for auto added blocklist set members.'));
- o.value('10s');
- o.value('1m');
- o.value('5m');
- o.value('1h');
- o.value('2h');
- o.optional = true;
- o.rmempty = true;
-
/*
advanced log settings tab
*/
o = s.taboption('adv_log', form.DummyValue, '_sub');
o.rawhtml = true;
- o.default = '<em><b>Changes on this tab needs a banIP service restart to take effect.</b></em>';
+ o.default = '<em><b>' + _('Changes on this tab needs a banIP service restart to take effect.') + '</b></em>';
- o = s.taboption('adv_log', form.ListValue, 'ban_nftloglevel', _('Log Level'), _('Set the syslog level for NFT logging.'));
+ o = s.taboption('adv_log', form.ListValue, 'ban_nftloglevel', _('NFT Log Level'), _('Set the syslog level for NFT logging.'));
o.value('emerg', _('emerg'));
o.value('alert', _('alert'));
o.value('crit', _('crit'));
@@ -449,11 +482,26 @@ return view.extend({
o.value('notice', _('notice'));
o.value('info', _('info'));
o.value('debug', _('debug'));
- o.value('audit', _('audit'));
o.optional = true;
o.rmempty = true;
- o = s.taboption('adv_log', form.ListValue, 'ban_loglimit', _('Log Limit'), _('Parse only the last stated number of log entries for suspicious events.'));
+ o = s.taboption('adv_log', form.Flag, 'ban_loginput', _('Log WAN-Input'), _('Log suspicious incoming WAN packets (dropped).'));
+ o.default = 1
+ o.rmempty = false;
+
+ o = s.taboption('adv_log', form.Flag, 'ban_logforwardwan', _('Log WAN-Forward'), _('Log suspicious forwarded WAN packets (dropped).'));
+ o.default = 1
+ o.rmempty = false;
+
+ o = s.taboption('adv_log', form.Flag, 'ban_logforwardlan', _('Log LAN-Forward'), _('Log suspicious forwarded LAN packets (rejected).'));
+ o.rmempty = false;
+
+ o = s.taboption('adv_log', form.Value, 'ban_logreadfile', _('Logfile Location'), _('Location for parsing the log file, e.g. via syslog-ng, to deactivate the standard parsing via logread.'));
+ o.placeholder = '/var/log/messages';
+ o.rmempty = true;
+
+ o = s.taboption('adv_log', form.ListValue, 'ban_loglimit', _('Log Limit'), _('Parse only the last stated number of log entries for suspicious events. To disable the log monitor at all set it to \'0\'.'));
+ o.value('0', _('0 (disable)'));
o.value('50', _('50'));
o.value('100', _('100 (default)'));
o.value('250', _('250'));
@@ -476,7 +524,10 @@ return view.extend({
*/
o = s.taboption('adv_email', form.DummyValue, '_sub');
o.rawhtml = true;
- o.default = '<em><b>To enable email notifications, set up the \'msmtp\' package and specify a vaild E-Mail receiver address.</b></em>';
+ o.default = '<em><b>' + _('To enable email notifications, set up the \'msmtp\' package and specify a vaild E-Mail receiver address.') + '</b></em>';
+
+ o = s.taboption('adv_email', form.Flag, 'ban_mailnotification', _('E-Mail Notification'), _('Receive E-Mail notifications with every banIP run.'));
+ o.rmempty = true;
o = s.taboption('adv_email', form.Value, 'ban_mailreceiver', _('E-Mail Receiver Address'), _('Receiver address for banIP notification E-Mails, this information is required to enable E-Mail functionality.'));
o.placeholder = 'name@example.com';
@@ -496,35 +547,29 @@ return view.extend({
o.rmempty = true;
/*
- blocklist feeds tab
+ feeds tab
*/
o = s.taboption('feeds', form.DummyValue, '_sub');
o.rawhtml = true;
- o.default = '<em><b>List of supported and fully pre-configured banIP feeds.</b></em>';
-
- if (result[0]) {
- var focus, feed, feeds;
- feeds = JSON.parse(result[0]);
+ o.default = '<em><b>' + _('External blocklist feeds') + '</b></em>';
- o = s.taboption('feeds', form.MultiValue, 'ban_feed', _('Feed Selection'));
- for (var i = 0; i < Object.keys(feeds).length; i++) {
+ if (feeds) {
+ o = s.taboption('feeds', form.MultiValue, 'ban_feed', _('Blocklist Feed Selection'));
+ for (let i = 0; i < Object.keys(feeds).length; i++) {
feed = Object.keys(feeds)[i].trim();
- focus = feeds[feed].focus.trim();
- o.value(feed, feed + ' (' + focus + ')');
+ descr = feeds[feed].descr.trim() || '-';
+ o.value(feed, feed + ' (' + descr + ')');
}
o.optional = true;
o.rmempty = true;
}
- /*
- prepare country data
- */
- var code, country, countries = [];
- if (result[1]) {
- countries = result[1].trim().split('\n');
+ let code, country, countries = [];
+ if (result[2]) {
+ countries = result[2].trim().split('\n');
o = s.taboption('feeds', form.MultiValue, 'ban_country', _('Countries'));
- for (var i = 0; i < countries.length; i++) {
+ for (let i = 0; i < countries.length; i++) {
code = countries[i].match(/^(\w+);/)[1].trim();
country = countries[i].match(/^\w+;(.*$)/)[1].trim();
o.value(code, country);
@@ -538,14 +583,58 @@ return view.extend({
o.optional = true;
o.rmempty = true;
- o = s.taboption('feeds', form.Flag, 'ban_autoallowlist', _('Auto Allowlist'), _('Automatically transfers uplink IPs to the banIP allowlist.'));
+ o = s.taboption('feeds', form.DummyValue, '_feeds');
+ o.rawhtml = true;
+ o.default = '<hr style="width: 200px; height: 1px;" /><em><b>' + _('External allowlist feeds') + '</b></em>';
+
+ o = s.taboption('feeds', form.DynamicList, 'ban_allowurl', _('Allowlist Feed Selection'));
+ o.optional = true;
+ o.rmempty = true;
+ o.validate = function (section_id, value) {
+ if (!value) {
+ return true;
+ }
+ if (!value.match(/^(http:\/\/|https:\/\/)[A-Za-z0-9\/\.\-_\?\&\+=:~#]+$/)) {
+ return _('Protocol/URL format not supported');
+ }
+ return true;
+ }
+
+ o = s.taboption('feeds', form.DummyValue, '_feeds');
+ o.rawhtml = true;
+ o.default = '<hr style="width: 200px; height: 1px;" /><em><b>' + _('Local feed settings') + '</b></em>';
+
+ o = s.taboption('feeds', form.Flag, 'ban_autoallowlist', _('Auto Allowlist'), _('Automatically add resolved domains and uplink IPs to the local banIP allowlist.'));
o.default = 1
o.rmempty = false;
- o = s.taboption('feeds', form.Flag, 'ban_autoblocklist', _('Auto Blocklist'), _('Automatically transfers suspicious IPs to the banIP blocklist.'));
+ o = s.taboption('feeds', form.ListValue, 'ban_autoallowuplink', _('Auto Allow Uplink'), _('Limit the uplink autoallow function.'));
+ o.depends('ban_autoallowlist', '1');
+ o.value('disable', _('Disable'));
+ o.value('subnet', _('Subnet (default)'));
+ o.value('ip', _('IP'));
+ o.optional = true;
+ o.rmempty = true;
+
+ o = s.taboption('feeds', form.Flag, 'ban_autoblocklist', _('Auto Blocklist'), _('Automatically add resolved domains and suspicious IPs to the local banIP blocklist.'));
o.default = 1
o.rmempty = false;
+ o = s.taboption('feeds', form.Flag, 'ban_autoblocksubnet', _('Auto Block Subnet'), _('Automatically add entire subnets to the blocklist Set based on an additional RDAP request with the suspicious IP.'));
+ o.default = 0
+ o.optional = true;
+ o.rmempty = true;
+
+ o = s.taboption('feeds', form.ListValue, 'ban_nftexpiry', _('Blocklist Set Expiry'), _('Expiry time for auto added blocklist Set members.'));
+ o.value('10s');
+ o.value('1m');
+ o.value('5m');
+ o.value('1h');
+ o.value('2h');
+ o.value('1d');
+ o.optional = true;
+ o.rmempty = true;
+
o = s.taboption('feeds', form.Flag, 'ban_allowlistonly', _('Allowlist Only'), _('Restrict the internet access from/to a small number of secure IPs.'));
o.rmempty = false;
diff --git a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js
index 2d39586435..97d8e2b243 100644
--- a/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js
+++ b/applications/luci-app-banip/htdocs/luci-static/resources/view/banip/setreport.js
@@ -41,13 +41,13 @@ function handleAction(report, ev) {
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function (ev) {
- var ip = document.getElementById('search').value.trim().toLowerCase();
+ let ip = document.getElementById('search').value.trim().toLowerCase();
if (ip) {
document.getElementById('run').classList.add("spinning");
document.getElementById('search').value = ip;
document.getElementById('result').textContent = 'The search is running, please wait...';
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['search', ip])).then(function (res) {
- var result = document.getElementById('result');
+ let result = document.getElementById('result');
if (res) {
result.textContent = res.trim();
} else {
@@ -65,13 +65,17 @@ function handleAction(report, ev) {
document.getElementById('search').focus();
}
if (ev === 'survey') {
- var content, selectO;
+ let content, selectOption;
- content = JSON.parse(report[1]);
- selectO = [E('option', { value: '' }, [_('-- Set Selection --')])];
- for (var i = 0; i < Object.keys(content.nftables).length; i++) {
- if (content.nftables[i].set !== undefined && content.nftables[i].set.name !== undefined) {
- selectO.push(E('option', { 'value': content.nftables[i].set.name }, content.nftables[i].set.name));
+ if (report[1]) {
+ content = JSON.parse(report[1]);
+ } else {
+ content = "";
+ }
+ selectOption = [E('option', { value: '' }, [_('-- Set Selection --')])];
+ for (let i = 0; i < Object.keys(content.nftables).length; i++) {
+ if (content.nftables[i].set && content.nftables[i].set.name !== undefined && content.nftables[i].set.table !== undefined && content.nftables[i].set.table === 'banIP') {
+ selectOption.push(E('option', { 'value': content.nftables[i].set.name }, content.nftables[i].set.name));
}
}
L.ui.showModal(_('Set Survey'), [
@@ -80,7 +84,7 @@ function handleAction(report, ev) {
E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em', 'id': 'run' }, [
E('h5', _('Set')),
E('select', { 'class': 'cbi-input-select', 'id': 'set' },
- selectO
+ selectOption
)
]),
]),
@@ -104,12 +108,12 @@ function handleAction(report, ev) {
E('button', {
'class': 'btn cbi-button-action',
'click': ui.createHandlerFn(this, function (ev) {
- var set = document.getElementById('set').value;
+ let set = document.getElementById('set').value;
if (set) {
document.getElementById('run').classList.add("spinning");
document.getElementById('result').textContent = 'The survey is running, please wait...';
L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['survey', set])).then(function (res) {
- var result = document.getElementById('result');
+ let result = document.getElementById('result');
if (res) {
result.textContent = res.trim();
} else {
@@ -131,17 +135,21 @@ function handleAction(report, ev) {
return view.extend({
load: function () {
return Promise.all([
- L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']), '{}'),
- L.resolveDefault(fs.exec_direct('/usr/sbin/nft', ['-tj', 'list', 'ruleset']), '{}')
+ L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']), ''),
+ L.resolveDefault(fs.exec_direct('/usr/sbin/nft', ['-tj', 'list', 'ruleset']), '')
]);
},
render: function (report) {
- var content;
- content = JSON.parse(report[0]);
+ let content, rowSets, tblSets;
- var rows_sets = [];
- var tbl_sets = E('table', { 'class': 'table', 'id': 'sets' }, [
+ if (report[0]) {
+ content = JSON.parse(report[0]);
+ } else {
+ content = "";
+ }
+ rowSets = [];
+ tblSets = E('table', { 'class': 'table', 'id': 'sets' }, [
E('tr', { 'class': 'tr table-titles' }, [
E('th', { 'class': 'th' }, _('Set')),
E('th', { 'class': 'th right', 'style': 'padding-right: 20px' }, _('Elements')),
@@ -152,12 +160,12 @@ return view.extend({
]);
if (content.sets) {
- var cnt1, cnt2, cnt3;
+ let cnt1, cnt2, cnt3;
Object.keys(content.sets).forEach(function (key) {
cnt1 = content.sets[key].cnt_input ? ': (' + content.sets[key].cnt_input + ')' : '';
cnt2 = content.sets[key].cnt_forwardwan ? ': (' + content.sets[key].cnt_forwardwan + ')' : '';
cnt3 = content.sets[key].cnt_forwardlan ? ': (' + content.sets[key].cnt_forwardlan + ')' : '';
- rows_sets.push([
+ rowSets.push([
E('em', key),
E('em', { 'style': 'padding-right: 20px' }, content.sets[key].cnt_elements),
E('em', content.sets[key].input + cnt1),
@@ -165,7 +173,7 @@ return view.extend({
E('em', content.sets[key].lan_forward + cnt3)
]);
});
- rows_sets.push([
+ rowSets.push([
E('em', { 'style': 'font-weight: bold' }, content.sum_sets),
E('em', { 'style': 'font-weight: bold; padding-right: 20px' }, content.sum_setelements),
E('em', { 'style': 'font-weight: bold' }, content.sum_setinput + ' (' + content.sum_cntinput + ')'),
@@ -173,7 +181,7 @@ return view.extend({
E('em', { 'style': 'font-weight: bold' }, content.sum_setforwardlan + ' (' + content.sum_cntforwardlan + ')')
]);
}
- cbi_update_table(tbl_sets, rows_sets);
+ cbi_update_table(tblSets, rowSets);
return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
E('div', { 'class': 'cbi-section' }, [
@@ -208,8 +216,7 @@ return view.extend({
'\xa0\xa0\xa0',
E('button', {
'class': 'btn cbi-button cbi-button-positive',
- 'click': ui.createHandlerFn(this, async function () {
- L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']), '');
+ 'click': ui.createHandlerFn(this, function () {
location.reload();
})
}, [_('Refresh')])
@@ -220,7 +227,7 @@ return view.extend({
E('div', { 'class': 'cbi-section' }, [
E('div', { 'class': 'left' }, [
E('h3', _('Set details')),
- tbl_sets
+ tblSets
])
])
]);