luci-app-banip: sync with banIP 0.7.0
[project/luci.git] / applications / luci-app-banip / htdocs / luci-static / resources / view / banip / ipsetreport.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') === 'whitelist') {
11 L.ui.showModal(_('Whitelist IP/CIDR'), [
12 E('p', _('Add this IP/CIDR to your local whitelist.')),
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', 'spellcheck': 'false', 'id': 'whitelist', '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/banip/banip.whitelist'), '')
28 .then(function(res) {
29 var ip = document.getElementById('whitelist').value.trim().toLowerCase();
30 if (ip) {
31 var whitelist = res + ip + '\n';
32 fs.write('/etc/banip/banip.whitelist', whitelist);
33 ui.addNotification(null, E('p', _('Whitelist changes have been saved. Refresh your banIP lists that changes take effect.')), 'info');
34 }
35 L.hideModal();
36 });
37 })
38 }, _('Save'))
39 ])
40 ]);
41 document.getElementById('whitelist').focus();
42 }
43
44 if (ev === 'query') {
45 L.ui.showModal(_('IPSet Query'), [
46 E('p', _('Search the active banIP-related IPSets for a specific IP, CIDR or MAC address.')),
47 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
48 E('label', { 'style': 'padding-top:.5em', 'id': 'run' }, [
49 E('input', {
50 'class': 'cbi-input-text',
51 'placeholder': '192.168.0.1',
52 'style': 'width:300px',
53 'spellcheck': 'false',
54 'id': 'search'
55 })
56 ])
57 ]),
58 E('div', { 'class': 'left', 'style': 'display:flex; flex-direction:column' }, [
59 '\xa0',
60 E('h5', _('Result')),
61 E('textarea', {
62 'id': 'result',
63 'style': 'width: 100% !important; padding: 5px; font-family: monospace',
64 'readonly': 'readonly',
65 'wrap': 'off',
66 'rows': 20
67 })
68 ]),
69 E('div', { 'class': 'right' }, [
70 E('button', {
71 'class': 'btn',
72 'click': L.hideModal
73 }, _('Cancel')),
74 ' ',
75 E('button', {
76 'class': 'btn cbi-button-action',
77 'click': ui.createHandlerFn(this, function(ev) {
78 var ip = document.getElementById('search').value.trim().toLowerCase();
79 if (ip) {
80 document.getElementById('run').classList.add("spinning");
81 document.getElementById('search').value = ip;
82 document.getElementById('result').textContent = 'The query is running, please wait...';
83 L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['query', ip])).then(function(res) {
84 var result = document.getElementById('result');
85 if (res) {
86 result.textContent = res.trim();
87 } else {
88 result.textContent = _('No Query results!');
89 }
90 document.getElementById('run').classList.remove("spinning");
91 document.getElementById('search').value = '';
92 })
93 }
94 document.getElementById('search').focus();
95 })
96 }, _('Query'))
97 ])
98 ]);
99 document.getElementById('search').focus();
100 }
101 }
102
103 return view.extend({
104 load: function() {
105 return L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'json']),'');
106 },
107
108 render: function(ipsetreport) {
109 if (!ipsetreport) {
110 ipsetreport = '{}';
111 };
112 var content;
113 content = JSON.parse(ipsetreport);
114
115 var rows_ipsets = [];
116 var tbl_ipsets = E('table', { 'class': 'table', 'id': 'ipsets' }, [
117 E('tr', { 'class': 'tr table-titles' }, [
118 E('th', { 'class': 'th' }, _('Name')),
119 E('th', { 'class': 'th' }, _('Type')),
120 E('th', { 'class': 'th' }, _('Count SUM')),
121 E('th', { 'class': 'th' }, _('Count IP')),
122 E('th', { 'class': 'th' }, _('Count CIDR')),
123 E('th', { 'class': 'th' }, _('Count MAC')),
124 E('th', { 'class': 'th' }, _('Count ACC')),
125 E('th', { 'class': 'th' }, _('Entry Details')),
126 E('th', { 'class': 'th' }, _('')),
127 E('th', { 'class': 'th' }, _('Action'))
128 ])
129 ]);
130
131 if (content.ipsets) {
132 var button, member, urlprefix;
133 Object.keys(content.ipsets).forEach(function(key) {
134 rows_ipsets.push([
135 E('em', key),
136 E('em', content.ipsets[key].type),
137 E('em', content.ipsets[key].count),
138 E('em', content.ipsets[key].count_ip),
139 E('em', content.ipsets[key].count_cidr),
140 E('em', content.ipsets[key].count_mac),
141 E('em', content.ipsets[key].count_acc)
142 ]);
143 for (var i = 0; i < content.ipsets[key].member_acc.length; i++) {
144 if (key != 'maclist' && key.substr(0,9) != 'whitelist') {
145 urlprefix = content.ipsets[key].member_acc[i].member.includes('/') ? 'prefix/' : 'ip/';
146 member = '<a href="https://api.bgpview.io/' + urlprefix + encodeURIComponent(content.ipsets[key].member_acc[i].member) + '" target="_blank" rel="noreferrer noopener" title="IP/CIDR Lookup" >' + content.ipsets[key].member_acc[i].member + '</a>';
147 button = E('button', {
148 'class': 'cbi-button cbi-button-apply',
149 'style': 'word-break: inherit',
150 'name': 'whitelist',
151 'value': content.ipsets[key].member_acc[i].member,
152 'click': handleAction
153 }, [ _('Whitelist...')]);
154 } else {
155 member = content.ipsets[key].member_acc[i].member;
156 button = '';
157 }
158 rows_ipsets.push([
159 '',
160 '',
161 '',
162 '',
163 '',
164 '',
165 '',
166 member,
167 content.ipsets[key].member_acc[i].packets,
168 button
169 ]);
170 }
171 });
172 }
173 cbi_update_table(tbl_ipsets, rows_ipsets);
174
175 return E('div', { 'class': 'cbi-map', 'id': 'map' }, [
176 E('div', { 'class': 'cbi-section' }, [
177 E('p', _('This tab shows the last generated IPSet Report, press the \'Refresh\' button to get a current one.')),
178 E('p', '\xa0'),
179 E('div', { 'class': 'cbi-value' }, [
180 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Timestamp')),
181 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.timestamp || '-')
182 ]),
183 E('div', { 'class': 'cbi-value' }, [
184 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of all IPSets')),
185 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_set_sum || '-')
186 ]),
187 E('div', { 'class': 'cbi-value' }, [
188 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of all entries')),
189 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_sum || '-')
190 ]),
191 E('div', { 'class': 'cbi-value' }, [
192 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of IP entries')),
193 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_ip_sum || '-')
194 ]),
195 E('div', { 'class': 'cbi-value' }, [
196 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of CIDR entries')),
197 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_cidr_sum || '-')
198 ]),
199 E('div', { 'class': 'cbi-value' }, [
200 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of MAC entries')),
201 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_mac_sum || '-')
202 ]),
203 E('div', { 'class': 'cbi-value' }, [
204 E('div', { 'class': 'cbi-value-title', 'style': 'float:left;width:230px' }, _('Number of accessed entries')),
205 E('div', { 'class': 'cbi-value-title', 'id': 'start', 'style': 'float:left;color:#37c' }, content.cnt_acc_sum || '-')
206 ]),
207 E('div', { 'class': 'right' }, [
208 E('button', {
209 'class': 'cbi-button cbi-button-apply',
210 'click': ui.createHandlerFn(this, function() {
211 return handleAction('query');
212 })
213 }, [ _('IPSet Query...') ]),
214 '\xa0\xa0\xa0',
215 E('button', {
216 'class': 'cbi-button cbi-button-positive',
217 'click': ui.createHandlerFn(this, async function() {
218 L.resolveDefault(fs.exec_direct('/etc/init.d/banip', ['report', 'gen']),'');
219 var running = 1;
220 while (running === 1) {
221 await new Promise(r => setTimeout(r, 1000));
222 L.resolveDefault(fs.read_direct('/var/run/banip.pid')).then(function(res) {
223 if (!res) {
224 running = 0;
225 }
226 })
227 }
228 location.reload();
229 })
230 }, [ _('Refresh') ])
231 ]),
232 ]),
233 E('br'),
234 E('div', { 'class': 'cbi-section' }, [
235 E('div', { 'class': 'left' }, [
236 E('h3', _('IPSet details')),
237 tbl_ipsets
238 ])
239 ])
240 ]);
241 },
242 handleSaveApply: null,
243 handleSave: null,
244 handleReset: null
245 });