8 function handleAction(ev) {
9 if (ev.target && ev.target.getAttribute('name') === 'blacklist') {
10 L.ui.showModal(_('Add Blacklist Domain'), [
11 E('p', _('Add this (sub-)domain to your local blacklist.')),
12 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
13 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
14 E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'blacklist', 'value': ev.target.getAttribute('value') }, [])
17 E('div', { 'class': 'right' }, [
24 'class': 'btn cbi-button-action',
25 'click': ui.createHandlerFn(this, function(ev) {
26 L.resolveDefault(fs.read_direct('/etc/adblock/adblock.blacklist'), '')
28 var domain = document.getElementById('blacklist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
29 var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
30 if (res.search(pattern) === -1) {
31 var blacklist = res + domain + '\n';
32 fs.write('/etc/adblock/adblock.blacklist', blacklist);
33 ui.addNotification(null, E('p', _('Blacklist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
41 document.getElementById('blacklist').focus();
44 if (ev.target && ev.target.getAttribute('name') === 'whitelist') {
45 L.ui.showModal(_('Add Whitelist Domain'), [
46 E('p', _('Add this (sub-)domain to your local whitelist.')),
47 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
48 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
49 E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'whitelist', 'value': ev.target.getAttribute('value') }, [])
52 E('div', { 'class': 'right' }, [
59 'class': 'btn cbi-button-action',
60 'click': ui.createHandlerFn(this, function(ev) {
61 L.resolveDefault(fs.read_direct('/etc/adblock/adblock.whitelist'), '')
63 var domain = document.getElementById('whitelist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
64 var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
65 if (res.search(pattern) === -1) {
66 var whitelist = res + domain + '\n';
67 fs.write('/etc/adblock/adblock.whitelist', whitelist);
68 ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
76 document.getElementById('whitelist').focus();
80 L.ui.showModal(_('Blocklist Query'), [
81 E('p', _('Query active blocklists and backups for a specific domain.')),
82 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
83 E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
85 'class': 'cbi-input-text',
86 'placeholder': 'google.com',
87 'style': 'width:300px',
92 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
97 'style': 'width: 100% !important; padding: 5px; font-family: monospace',
98 'readonly': 'readonly',
103 E('div', { 'class': 'right' }, [
110 'class': 'btn cbi-button-action',
111 'click': ui.createHandlerFn(this, function(ev) {
112 var domain = document.getElementById('search').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
114 document.getElementById('run').classList.add("spinning");
115 document.getElementById('search').value = domain;
116 document.getElementById('result').textContent = 'The query is running, please wait...';
117 L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['query', domain])).then(function(res) {
118 var result = document.getElementById('result');
120 result.textContent = res.trim();
122 result.textContent = _('No Query results!');
124 document.getElementById('run').classList.remove("spinning");
125 document.getElementById('search').value = '';
128 document.getElementById('search').focus();
133 document.getElementById('search').focus();
136 if (ev === 'refresh') {
137 L.ui.showModal(_('Refresh DNS Report'), [
138 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
139 E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
140 E('select', { 'class': 'cbi-input-select', 'id': 'count' }, [
141 E('option', { 'value': '50' }, '50'),
142 E('option', { 'value': '100' }, '100'),
143 E('option', { 'value': '150' }, '150'),
144 E('option', { 'value': '250' }, '250'),
145 E('option', { 'value': '500' }, '500')
148 _('max. result set size')
151 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
152 E('input', { 'class': 'cbi-input-text', 'id': 'search' }, [
155 _('Filter criteria like date, domain or client (optional)')
157 E('div', { 'class': 'right' }, [
164 'class': 'btn cbi-button-action',
166 'click': ui.createHandlerFn(this, async function(ev) {
167 var count = document.getElementById('count').value;
168 var search = document.getElementById('search').value.trim().replace(/[^a-z0-9\.\-]/g,'') || '+';
169 L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', search, count, 'true', 'json']),'');
171 while (running === 1) {
172 await new Promise(r => setTimeout(r, 1000));
173 L.resolveDefault(fs.read_direct('/var/run/adblock.pid')).then(function(res) {
185 document.getElementById('refresh').focus();
189 return L.view.extend({
191 return L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', '+', '50', 'false', 'json']),'');
194 render: function(dnsreport) {
196 dnsreport = '{ "data": "" }';
199 content = JSON.parse(dnsreport);
202 var tbl_top = E('div', { 'class': 'table', 'id': 'top_10' }, [
203 E('div', { 'class': 'tr table-titles' }, [
204 E('div', { 'class': 'th right' }, _('Count')),
205 E('div', { 'class': 'th' }, _('Name / IP Address')),
206 E('div', { 'class': 'th right' }, _('Count')),
207 E('div', { 'class': 'th' }, _('Domain')),
208 E('div', { 'class': 'th right' }, _('Count')),
209 E('div', { 'class': 'th' }, _('Blocked Domain'))
214 if (content.data.top_clients && content.data.top_domains && content.data.top_blocked) {
215 max = Math.max(content.data.top_clients.length, content.data.top_domains.length, content.data.top_blocked.length);
217 for (var i = 0; i < max; i++) {
218 var a_cnt = '\xa0', a_addr = '\xa0', b_cnt = '\xa0', b_addr = '\xa0', c_cnt = '\xa0', c_addr = '\xa0';
219 if (content.data.top_clients[i]) {
220 a_cnt = content.data.top_clients[i].count;
222 if (content.data.top_clients[i]) {
223 a_addr = content.data.top_clients[i].address;
225 if (content.data.top_domains[i]) {
226 b_cnt = content.data.top_domains[i].count;
228 if (content.data.top_domains[i]) {
229 b_addr = content.data.top_domains[i].address;
231 if (content.data.top_blocked[i]) {
232 c_cnt = content.data.top_blocked[i].count;
234 if (content.data.top_blocked[i]) {
235 c_addr = content.data.top_blocked[i].address;
246 cbi_update_table(tbl_top, rows_top);
248 var rows_requests = [];
249 var tbl_requests = E('div', { 'class': 'table', 'id': 'requests' }, [
250 E('div', { 'class': 'tr table-titles' }, [
251 E('div', { 'class': 'th' }, _('Date')),
252 E('div', { 'class': 'th' }, _('Time')),
253 E('div', { 'class': 'th' }, _('Client')),
254 E('div', { 'class': 'th' }, _('Domain')),
255 E('div', { 'class': 'th' }, _('Answer')),
256 E('div', { 'class': 'th' }, _('Action'))
261 if (content.data.requests) {
263 max = content.data.requests.length;
264 for (var i = 0; i < max; i++) {
265 if (content.data.requests[i].rc === 'NX') {
266 button = E('button', {
267 'class': 'cbi-button cbi-button-apply',
268 'style': 'word-break: inherit',
270 'value': content.data.requests[i].domain,
271 'click': handleAction
272 }, [ _('Whitelist...') ]);
274 button = E('button', {
275 'class': 'cbi-button cbi-button-apply',
276 'style': 'word-break: inherit',
278 'value': content.data.requests[i].domain,
279 'click': handleAction
280 }, [ _('Blacklist...') ]);
283 content.data.requests[i].date,
284 content.data.requests[i].time,
285 content.data.requests[i].client,
286 content.data.requests[i].domain,
287 content.data.requests[i].rc,
292 cbi_update_table(tbl_requests, rows_requests);
294 return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
295 E('div', { 'class': 'cbi-section' }, [
296 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
297 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Start Date')),
298 E('div', { 'class': 'cbi-value-field', 'id': 'start', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.start_date || '-') + ', ' + (content.data.start_time || '-'))]),
299 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
300 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('End Date')),
301 E('div', { 'class': 'cbi-value-field', 'id': 'end', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.end_date || '-') + ', ' + (content.data.end_time || '-'))]),
302 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
303 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (total)')),
304 E('div', { 'class': 'cbi-value-field', 'id': 'total', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, content.data.total || '-')]),
305 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
306 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (blocked)')),
307 E('div', { 'class': 'cbi-value-field', 'id': 'blocked', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.blocked || '-') + ' (' + (content.data.percent || '-') + ')')]),
308 E('div', { 'class': 'right' }, [
310 'class': 'cbi-button cbi-button-apply',
311 'click': ui.createHandlerFn(this, function() {
312 return handleAction('query');
314 }, [ _('Blocklist Query...') ]),
317 'class': 'cbi-button cbi-button-apply',
318 'click': ui.createHandlerFn(this, function() {
319 return handleAction('refresh');
321 }, [ _('Refresh...') ])
324 E('div', { 'class': 'cbi-section' }, [
325 E('div', { 'class': 'left' }, [
326 E('h3', _('Top 10 Statistics')),
331 E('div', { 'class': 'cbi-section' }, [
332 E('div', { 'class': 'left' }, [
333 E('h3', _('Latest DNS Requests')),
339 handleSaveApply: null,