treewide: import utility classes explicitly
[project/luci.git] / applications / luci-app-adblock / htdocs / luci-static / resources / view / adblock / dnsreport.js
1 'use strict';
2 'require view';
3 'require fs';
4 'require ui';
5
6 /*
7 button handling
8 */
9 function handleAction(ev) {
10 if (ev.target && ev.target.getAttribute('name') === 'blacklist') {
11 L.ui.showModal(_('Add Blacklist Domain'), [
12 E('p', _('Add this (sub-)domain to your local blacklist.')),
13 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
14 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
15 E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'blacklist', 'value': ev.target.getAttribute('value') }, [])
16 ])
17 ]),
18 E('div', { 'class': 'right' }, [
19 E('button', {
20 'class': 'btn',
21 'click': L.hideModal
22 }, _('Cancel')),
23 ' ',
24 E('button', {
25 'class': 'btn cbi-button-action',
26 'click': ui.createHandlerFn(this, function(ev) {
27 L.resolveDefault(fs.read_direct('/etc/adblock/adblock.blacklist'), '')
28 .then(function(res) {
29 var domain = document.getElementById('blacklist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
30 var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
31 if (res.search(pattern) === -1) {
32 var blacklist = res + domain + '\n';
33 fs.write('/etc/adblock/adblock.blacklist', blacklist);
34 ui.addNotification(null, E('p', _('Blacklist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
35 }
36 L.hideModal();
37 });
38 })
39 }, _('Save'))
40 ])
41 ]);
42 document.getElementById('blacklist').focus();
43 }
44
45 if (ev.target && ev.target.getAttribute('name') === 'whitelist') {
46 L.ui.showModal(_('Add Whitelist Domain'), [
47 E('p', _('Add this (sub-)domain to your local whitelist.')),
48 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
49 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
50 E('input', { 'class': 'cbi-input-text', 'style': 'width:300px', 'id': 'whitelist', 'value': ev.target.getAttribute('value') }, [])
51 ])
52 ]),
53 E('div', { 'class': 'right' }, [
54 E('button', {
55 'class': 'btn',
56 'click': L.hideModal
57 }, _('Cancel')),
58 ' ',
59 E('button', {
60 'class': 'btn cbi-button-action',
61 'click': ui.createHandlerFn(this, function(ev) {
62 L.resolveDefault(fs.read_direct('/etc/adblock/adblock.whitelist'), '')
63 .then(function(res) {
64 var domain = document.getElementById('whitelist').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
65 var pattern = new RegExp('^' + domain.replace(/[\.]/g,'\\.') + '$', 'm');
66 if (res.search(pattern) === -1) {
67 var whitelist = res + domain + '\n';
68 fs.write('/etc/adblock/adblock.whitelist', whitelist);
69 ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your adblock lists that changes take effect.')), 'info');
70 }
71 L.hideModal();
72 });
73 })
74 }, _('Save'))
75 ])
76 ]);
77 document.getElementById('whitelist').focus();
78 }
79
80 if (ev === 'query') {
81 L.ui.showModal(_('Blocklist Query'), [
82 E('p', _('Query active blocklists and backups for a specific domain.')),
83 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
84 E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
85 E('input', {
86 'class': 'cbi-input-text',
87 'placeholder': 'google.com',
88 'style': 'width:300px',
89 'id': 'search'
90 })
91 ])
92 ]),
93 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
94 '\xa0',
95 E('h5', _('Result')),
96 E('textarea', {
97 'id': 'result',
98 'style': 'width: 100% !important; padding: 5px; font-family: monospace',
99 'readonly': 'readonly',
100 'wrap': 'off',
101 'rows': 20
102 })
103 ]),
104 E('div', { 'class': 'right' }, [
105 E('button', {
106 'class': 'btn',
107 'click': L.hideModal
108 }, _('Cancel')),
109 ' ',
110 E('button', {
111 'class': 'btn cbi-button-action',
112 'click': ui.createHandlerFn(this, function(ev) {
113 var domain = document.getElementById('search').value.trim().toLowerCase().replace(/[^a-z0-9\.\-]/g,'');
114 if (domain) {
115 document.getElementById('run').classList.add("spinning");
116 document.getElementById('search').value = domain;
117 document.getElementById('result').textContent = 'The query is running, please wait...';
118 L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['query', domain])).then(function(res) {
119 var result = document.getElementById('result');
120 if (res) {
121 result.textContent = res.trim();
122 } else {
123 result.textContent = _('No Query results!');
124 }
125 document.getElementById('run').classList.remove("spinning");
126 document.getElementById('search').value = '';
127 })
128 }
129 document.getElementById('search').focus();
130 })
131 }, _('Query'))
132 ])
133 ]);
134 document.getElementById('search').focus();
135 }
136
137 if (ev === 'refresh') {
138 L.ui.showModal(_('Refresh DNS Report'), [
139 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
140 E('label', { 'class': 'cbi-input-select', 'style': 'padding-top:.5em' }, [
141 E('select', { 'class': 'cbi-input-select', 'id': 'count' }, [
142 E('option', { 'value': '50' }, '50'),
143 E('option', { 'value': '100' }, '100'),
144 E('option', { 'value': '150' }, '150'),
145 E('option', { 'value': '250' }, '250'),
146 E('option', { 'value': '500' }, '500')
147 ]),
148 '\xa0\xa0\xa0',
149 _('max. result set size')
150 ])
151 ]),
152 E('label', { 'class': 'cbi-input-text', 'style': 'padding-top:.5em' }, [
153 E('input', { 'class': 'cbi-input-text', 'id': 'search' }, [
154 ]),
155 '\xa0\xa0\xa0',
156 _('Filter criteria like date, domain or client (optional)')
157 ]),
158 E('div', { 'class': 'right' }, [
159 E('button', {
160 'class': 'btn',
161 'click': L.hideModal
162 }, _('Cancel')),
163 ' ',
164 E('button', {
165 'class': 'btn cbi-button-action',
166 'id': 'refresh',
167 'click': ui.createHandlerFn(this, async function(ev) {
168 var count = document.getElementById('count').value;
169 var search = document.getElementById('search').value.trim().replace(/[^a-z0-9\.\-]/g,'') || '+';
170 L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', search, count, 'true', 'json']),'');
171 var running = 1;
172 while (running === 1) {
173 await new Promise(r => setTimeout(r, 1000));
174 L.resolveDefault(fs.read_direct('/var/run/adblock.pid')).then(function(res) {
175 if (!res) {
176 running = 0;
177 }
178 })
179 }
180 L.hideModal();
181 location.reload();
182 })
183 }, _('Refresh'))
184 ])
185 ]);
186 document.getElementById('refresh').focus();
187 }
188 }
189
190 return view.extend({
191 load: function() {
192 return L.resolveDefault(fs.exec_direct('/etc/init.d/adblock', ['report', '+', '50', 'false', 'json']),'');
193 },
194
195 render: function(dnsreport) {
196 if (!dnsreport) {
197 dnsreport = '{ "data": "" }';
198 };
199 var content;
200 content = JSON.parse(dnsreport);
201
202 var rows_top = [];
203 var tbl_top = E('div', { 'class': 'table', 'id': 'top_10' }, [
204 E('div', { 'class': 'tr table-titles' }, [
205 E('div', { 'class': 'th right' }, _('Count')),
206 E('div', { 'class': 'th' }, _('Name / IP Address')),
207 E('div', { 'class': 'th right' }, _('Count')),
208 E('div', { 'class': 'th' }, _('Domain')),
209 E('div', { 'class': 'th right' }, _('Count')),
210 E('div', { 'class': 'th' }, _('Blocked Domain'))
211 ])
212 ]);
213
214 var max = 0;
215 if (content.data.top_clients && content.data.top_domains && content.data.top_blocked) {
216 max = Math.max(content.data.top_clients.length, content.data.top_domains.length, content.data.top_blocked.length);
217 }
218 for (var i = 0; i < max; i++) {
219 var a_cnt = '\xa0', a_addr = '\xa0', b_cnt = '\xa0', b_addr = '\xa0', c_cnt = '\xa0', c_addr = '\xa0';
220 if (content.data.top_clients[i]) {
221 a_cnt = content.data.top_clients[i].count;
222 }
223 if (content.data.top_clients[i]) {
224 a_addr = content.data.top_clients[i].address;
225 }
226 if (content.data.top_domains[i]) {
227 b_cnt = content.data.top_domains[i].count;
228 }
229 if (content.data.top_domains[i]) {
230 b_addr = content.data.top_domains[i].address;
231 }
232 if (content.data.top_blocked[i]) {
233 c_cnt = content.data.top_blocked[i].count;
234 }
235 if (content.data.top_blocked[i]) {
236 c_addr = content.data.top_blocked[i].address;
237 }
238 rows_top.push([
239 a_cnt,
240 a_addr,
241 b_cnt,
242 b_addr,
243 c_cnt,
244 c_addr
245 ]);
246 }
247 cbi_update_table(tbl_top, rows_top);
248
249 var rows_requests = [];
250 var tbl_requests = E('div', { 'class': 'table', 'id': 'requests' }, [
251 E('div', { 'class': 'tr table-titles' }, [
252 E('div', { 'class': 'th' }, _('Date')),
253 E('div', { 'class': 'th' }, _('Time')),
254 E('div', { 'class': 'th' }, _('Client')),
255 E('div', { 'class': 'th' }, _('Domain')),
256 E('div', { 'class': 'th' }, _('Answer')),
257 E('div', { 'class': 'th' }, _('Action'))
258 ])
259 ]);
260
261 max = 0;
262 if (content.data.requests) {
263 var button;
264 max = content.data.requests.length;
265 for (var i = 0; i < max; i++) {
266 if (content.data.requests[i].rc === 'NX') {
267 button = E('button', {
268 'class': 'cbi-button cbi-button-apply',
269 'style': 'word-break: inherit',
270 'name': 'whitelist',
271 'value': content.data.requests[i].domain,
272 'click': handleAction
273 }, [ _('Whitelist...') ]);
274 } else {
275 button = E('button', {
276 'class': 'cbi-button cbi-button-apply',
277 'style': 'word-break: inherit',
278 'name': 'blacklist',
279 'value': content.data.requests[i].domain,
280 'click': handleAction
281 }, [ _('Blacklist...') ]);
282 }
283 rows_requests.push([
284 content.data.requests[i].date,
285 content.data.requests[i].time,
286 content.data.requests[i].client,
287 content.data.requests[i].domain,
288 content.data.requests[i].rc,
289 button
290 ]);
291 }
292 }
293 cbi_update_table(tbl_requests, rows_requests);
294
295 return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
296 E('div', { 'class': 'cbi-section' }, [
297 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
298 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('Start Date')),
299 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 || '-'))]),
300 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
301 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('End Date')),
302 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 || '-'))]),
303 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
304 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (total)')),
305 E('div', { 'class': 'cbi-value-field', 'id': 'total', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, content.data.total || '-')]),
306 E('div', { 'class': 'cbi-value', 'style': 'margin-bottom:5px' }, [
307 E('label', { 'class': 'cbi-value-title', 'style': 'padding-top:0rem' }, _('DNS Requests (blocked)')),
308 E('div', { 'class': 'cbi-value-field', 'id': 'blocked', 'style': 'margin-bottom:5px;margin-left:200px;color:#37c' }, (content.data.blocked || '-') + ' (' + (content.data.percent || '-') + ')')]),
309 E('div', { 'class': 'right' }, [
310 E('button', {
311 'class': 'cbi-button cbi-button-apply',
312 'click': ui.createHandlerFn(this, function() {
313 return handleAction('query');
314 })
315 }, [ _('Blocklist Query...') ]),
316 '\xa0\xa0\xa0',
317 E('button', {
318 'class': 'cbi-button cbi-button-apply',
319 'click': ui.createHandlerFn(this, function() {
320 return handleAction('refresh');
321 })
322 }, [ _('Refresh...') ])
323 ]),
324 ]),
325 E('div', { 'class': 'cbi-section' }, [
326 E('div', { 'class': 'left' }, [
327 E('h3', _('Top 10 Statistics')),
328 tbl_top
329 ])
330 ]),
331 E('br'),
332 E('div', { 'class': 'cbi-section' }, [
333 E('div', { 'class': 'left' }, [
334 E('h3', _('Latest DNS Requests')),
335 tbl_requests
336 ])
337 ])
338 ]);
339 },
340 handleSaveApply: null,
341 handleSave: null,
342 handleReset: null
343 });