086200aa89cab648b5e94741ba0934d0722ac195
[project/luci.git] / applications / luci-app-adblock-fast / htdocs / luci-static / resources / view / adblock-fast / overview.js
1 // Copyright 2023 MOSSDeF, Stan Grishin <stangri@melmac.ca>
2 // This code wouldn't have been possible without help from:
3 // - [@stokito](https://github.com/stokito)
4 // - [@vsviridov](https://github.com/vsviridov)
5
6 "use strict";
7 "require form";
8 "require view";
9 "require adblock-fast.status as adb";
10
11 var pkg = {
12 get Name() {
13 return "adblock-fast";
14 },
15 get URL() {
16 return "https://docs.openwrt.melmac.net/" + pkg.Name + "/";
17 },
18 humanFileSize: function (bytes, si = false, dp = 2) {
19 return `%${si ? 1000 : 1024}.${dp ?? 0}mB`.format(bytes);
20 },
21 };
22
23 return view.extend({
24 load: function () {
25 return Promise.all([
26 L.resolveDefault(adb.getFileUrlFilesizes(pkg.Name), {}),
27 L.resolveDefault(adb.getPlatformSupport(pkg.Name), {}),
28 L.resolveDefault(L.uci.load(pkg.Name), {}),
29 L.resolveDefault(L.uci.load("dhcp"), {}),
30 L.resolveDefault(L.uci.load("smartdns"), {}),
31 ]);
32 },
33
34 render: function (data) {
35 var reply = {
36 sizes: (data[0] && data[0][pkg.Name] && data[0][pkg.Name]["sizes"]) || [],
37 platform: (data[1] && data[1][pkg.Name]) || {
38 ipset_installed: false,
39 nft_installed: false,
40 dnsmasq_installed: false,
41 dnsmasq_ipset_support: false,
42 dnsmasq_nftset_support: false,
43 smartdns_installed: false,
44 smartdns_ipset_support: false,
45 smartdns_nftset_support: false,
46 unbound_installed: false,
47 leds: [],
48 },
49 };
50 var status, m, s1, s2, s3, o;
51
52 status = new adb.status();
53 m = new form.Map(pkg.Name, _("AdBlock-Fast - Configuration"));
54 s1 = m.section(form.NamedSection, "config", pkg.Name);
55 s1.tab("tab_basic", _("Basic Configuration"));
56 s1.tab("tab_advanced", _("Advanced Configuration"));
57
58 var text = _(
59 "DNS resolution option, see the %sREADME%s for details."
60 ).format(
61 '<a href="' + pkg.URL + '#dns-resolver-option" target="_blank">',
62 "</a>"
63 );
64 if (!reply.platform.dnsmasq_installed) {
65 text +=
66 "<br />" +
67 _("Please note that %s is not supported on this system.").format(
68 "<i>dnsmasq.addnhosts</i>"
69 );
70 text +=
71 "<br />" +
72 _("Please note that %s is not supported on this system.").format(
73 "<i>dnsmasq.conf</i>"
74 );
75 text +=
76 "<br />" +
77 _("Please note that %s is not supported on this system.").format(
78 "<i>dnsmasq.ipset</i>"
79 );
80 text +=
81 "<br />" +
82 _("Please note that %s is not supported on this system.").format(
83 "<i>dnsmasq.servers</i>"
84 );
85 } else {
86 if (!reply.platform.dnsmasq_ipset_support) {
87 text +=
88 "<br />" +
89 _("Please note that %s is not supported on this system.").format(
90 "<i>dnsmasq.ipset</i>"
91 );
92 }
93 if (!reply.platform.dnsmasq_nftset_support) {
94 text +=
95 "<br />" +
96 _("Please note that %s is not supported on this system.").format(
97 "<i>dnsmasq.nftset</i>"
98 );
99 }
100 }
101 if (!reply.platform.smartdns_installed) {
102 text =
103 text +
104 "<br />" +
105 _("Please note that %s is not supported on this system.").format(
106 "<i>smartdns.domainset</i>"
107 );
108 } else {
109 if (!reply.platform.smartdns_ipset_support) {
110 text +=
111 "<br />" +
112 _("Please note that %s is not supported on this system.").format(
113 "<i>smartdns.ipset</i>"
114 );
115 }
116 if (!reply.platform.smartdns_nftset_support) {
117 text +=
118 "<br />" +
119 _("Please note that %s is not supported on this system.").format(
120 "<i>smartdns.nftset</i>"
121 );
122 }
123 }
124 if (!reply.platform.unbound_installed) {
125 text =
126 text +
127 "<br />" +
128 _("Please note that %s is not supported on this system.").format(
129 "<i>unbound.adb_list</i>"
130 );
131 }
132
133 o = s1.taboption(
134 "tab_basic",
135 form.ListValue,
136 "dns",
137 _("DNS Service"),
138 text
139 );
140 if (reply.platform.dnsmasq_installed) {
141 o.value("dnsmasq.addnhosts", _("dnsmasq additional hosts"));
142 o.value("dnsmasq.conf", _("dnsmasq config"));
143 if (reply.platform.dnsmasq_ipset_support) {
144 o.value("dnsmasq.ipset", _("dnsmasq ipset"));
145 }
146 if (reply.platform.dnsmasq_nftset_support) {
147 o.value("dnsmasq.nftset", _("dnsmasq nft set"));
148 }
149 o.value("dnsmasq.servers", _("dnsmasq servers file"));
150 }
151 if (reply.platform.smartdns_installed) {
152 o.value("smartdns.domainset", _("smartdns domain set"));
153 if (reply.platform.smartdns_ipset_support) {
154 o.value("smartdns.ipset", _("smartdns ipset"));
155 }
156 if (reply.platform.smartdns_nftset_support) {
157 o.value("smartdns.nftset", _("smartdns nft set"));
158 }
159 }
160 if (reply.platform.unbound_installed) {
161 o.value("unbound.adb_list", _("unbound adblock list"));
162 }
163 o.default = "dnsmasq.servers";
164
165 o = s1.taboption(
166 "tab_basic",
167 form.Value,
168 "dnsmasq_config_file_url",
169 _("Dnsmasq Config File URL"),
170 _(
171 "URL to the external dnsmasq config file, see the %sREADME%s for details."
172 ).format(
173 '<a href="' + pkg.URL + '#dnsmasq_config_file_url" target="_blank">',
174 "</a>"
175 )
176 );
177 o.depends("dns", "dnsmasq.conf");
178
179 o = s1.taboption(
180 "tab_basic",
181 form.ListValue,
182 "dnsmasq_instance",
183 _("Use AdBlocking on the dnsmasq instance(s)"),
184 _(
185 "You can limit the AdBlocking to a specific dnsmasq instance(s) (%smore information%s)."
186 ).format(
187 '<a href="' + pkg.URL + "#dnsmasq_instance" + '" target="_blank">',
188 "</a>"
189 )
190 );
191 o.value("*", _("AdBlock on all instances"));
192
193 Object.values(L.uci.sections("dhcp", "dnsmasq")).forEach(function (
194 element
195 ) {
196 var description;
197 var key;
198 if (element[".name"] === L.uci.resolveSID("dhcp", element[".name"])) {
199 key = element[".index"];
200 description = "dnsmasq[" + element[".index"] + "]";
201 } else {
202 key = element[".name"];
203 description = element[".name"];
204 }
205 o.value(key, _("AdBlock on %s only").format(description));
206 });
207 o.value("-", _("No AdBlock on dnsmasq"));
208 o.default = "*";
209 o.depends("dns", "dnsmasq.addnhosts");
210 o.depends("dns", "dnsmasq.servers");
211 o.retain = true;
212
213 o = s1.taboption(
214 "tab_basic",
215 form.ListValue,
216 "smartdns_instance",
217 _("Use AdBlocking on the SmartDNS instance(s)"),
218 _(
219 "You can limit the AdBlocking to a specific SmartDNS instance(s) (%smore information%s)."
220 ).format(
221 '<a href="' + pkg.URL + "#smartdns_instance" + '" target="_blank">',
222 "</a>"
223 )
224 );
225 o.value("*", _("AdBlock on all instances"));
226
227 Object.values(L.uci.sections("smartdns", "smartdns")).forEach(function (
228 element
229 ) {
230 var description;
231 var key;
232 if (element[".name"] === L.uci.resolveSID("smartdns", element[".name"])) {
233 key = element[".index"];
234 description = "smartdns[" + element[".index"] + "]";
235 } else {
236 key = element[".name"];
237 description = element[".name"];
238 }
239 o.value(key, _("AdBlock on %s only").format(description));
240 });
241 o.value("-", _("No AdBlock on SmartDNS"));
242 o.default = "*";
243 o.depends("dns", "smartdns.domainset");
244 o.depends("dns", "smartdns.ipset");
245 o.depends("dns", "smartdns.nftset");
246 o.retain = true;
247
248 o = s1.taboption(
249 "tab_basic",
250 form.ListValue,
251 "force_dns",
252 _("Force Router DNS"),
253 _("Forces Router DNS use on local devices, also known as DNS Hijacking.")
254 );
255 o.value("0", _("Let local devices use their own DNS servers if set"));
256 o.value("1", _("Force Router DNS server to all local devices"));
257 o.default = "1";
258
259 o = s1.taboption(
260 "tab_basic",
261 form.ListValue,
262 "verbosity",
263 _("Output Verbosity Setting"),
264 _("Controls system log and console output verbosity.")
265 );
266 o.value("0", _("Suppress output"));
267 o.value("1", _("Some output"));
268 o.value("2", _("Verbose output"));
269 o.default = "2";
270
271 if (reply.platform.leds.length) {
272 o = s1.taboption(
273 "tab_basic",
274 form.ListValue,
275 "led",
276 _("LED to indicate status"),
277 _(
278 "Pick the LED not already used in %sSystem LED Configuration%s."
279 ).format('<a href="' + L.url("admin", "system", "leds") + '">', "</a>")
280 );
281 o.value("", _("none"));
282 reply.platform.leds.forEach((element) => {
283 o.value(element);
284 });
285 }
286
287 o = s1.taboption(
288 "tab_advanced",
289 form.ListValue,
290 "config_update_enabled",
291 _("Automatic Config Update"),
292 _("Perform config update before downloading the block/allow-lists.")
293 );
294 o.value("0", _("Disable"));
295 o.value("1", _("Enable"));
296 o.default = "0";
297
298 o = s1.taboption(
299 "tab_advanced",
300 form.ListValue,
301 "ipv6_enabled",
302 _("IPv6 Support"),
303 _("Add IPv6 entries to block-list.")
304 );
305 o.value("", _("Do not add IPv6 entries"));
306 o.value("1", _("Add IPv6 entries"));
307 o.depends("dns", "dnsmasq.addnhosts");
308 o.depends("dns", "dnsmasq.nftset");
309 o.default = "";
310 o.rmempty = true;
311 o.retain = true;
312
313 o = s1.taboption(
314 "tab_advanced",
315 form.Value,
316 "download_timeout",
317 _("Download time-out (in seconds)"),
318 _("Stop the download if it is stalled for set number of seconds.")
319 );
320 o.default = "20";
321 o.datatype = "range(1,60)";
322
323 o = s1.taboption(
324 "tab_advanced",
325 form.Value,
326 "curl_max_file_size",
327 _("Curl maximum file size (in bytes)"),
328 _(
329 "If curl is installed and detected, it would not download files bigger than this."
330 )
331 );
332 o.default = "";
333 o.datatype = "uinteger";
334 o.rmempty = true;
335
336 o = s1.taboption(
337 "tab_advanced",
338 form.Value,
339 "curl_retry",
340 _("Curl download retry"),
341 _(
342 "If curl is installed and detected, it would retry download this many times on timeout/fail."
343 )
344 );
345 o.default = "3";
346 o.datatype = "range(0,30)";
347
348 o = s1.taboption(
349 "tab_advanced",
350 form.ListValue,
351 "parallel_downloads",
352 _("Simultaneous processing"),
353 _(
354 "Launch all lists downloads and processing simultaneously, reducing service start time."
355 )
356 );
357 o.value("0", _("Do not use simultaneous processing"));
358 o.value("1", _("Use simultaneous processing"));
359 o.default = "1";
360
361 o = s1.taboption(
362 "tab_advanced",
363 form.ListValue,
364 "compressed_cache",
365 _("Store compressed cache file on router"),
366 _(
367 "Attempt to create a compressed cache of block-list in the persistent memory."
368 )
369 );
370 o.value("0", _("Do not store compressed cache"));
371 o.value("1", _("Store compressed cache"));
372 o.default = "0";
373
374 o = s1.taboption(
375 "tab_advanced",
376 form.Value,
377 "compressed_cache_dir",
378 _("Directory for compressed cache file"),
379 _(
380 "Directory for compressed cache file of block-list in the persistent memory."
381 )
382 );
383 o.datatype = "string";
384 o.rmempty = true;
385 o.default = "/etc";
386 o.depends("compressed_cache", "1");
387 o.retain = true;
388
389 o = s1.taboption(
390 "tab_advanced",
391 form.ListValue,
392 "debug",
393 _("Enable Debugging"),
394 _("Enables debug output to /tmp/adblock-fast.log.")
395 );
396 o.value("0", _("Disable Debugging"));
397 o.value("1", _("Enable Debugging"));
398 o.default = "0";
399
400 s2 = m.section(
401 form.NamedSection,
402 "config",
403 "adblock-fast",
404 _("AdBlock-Fast - Allowed and Blocked Domains")
405 );
406 o.addremove = true;
407 o.rmempty = true;
408
409 o = s2.option(
410 form.DynamicList,
411 "allowed_domain",
412 _("Allowed Domains"),
413 _("Individual domains to be allowed.")
414 );
415 o.addremove = true;
416
417 o = s2.option(
418 form.DynamicList,
419 "blocked_domain",
420 _("Blocked Domains"),
421 _("Individual domains to be blocked.")
422 );
423 o.addremove = true;
424
425 s3 = m.section(
426 form.GridSection,
427 "file_url",
428 _("AdBlock-Fast - Allowed and Blocked Lists URLs"),
429 _("URLs to file(s) containing lists to be allowed or blocked.")
430 );
431 s3.rowcolors = true;
432 s3.sortable = true;
433 s3.anonymous = true;
434 s3.addremove = true;
435
436 o = s3.option(form.DummyValue, "_size", _("Size"));
437 o.modalonly = false;
438 o.cfgvalue = function (section_id) {
439 let url = L.uci.get(pkg.Name, section_id, "url");
440 let ret = _("Unknown");
441 reply.sizes.forEach((element) => {
442 if (element.url === url) {
443 ret = element.size === 0 ? ret : pkg.humanFileSize(element.size);
444 }
445 });
446 return _("Size: %s").format(ret);
447 };
448
449 o = s3.option(form.Flag, "enabled", _("Enable"));
450 o.editable = true;
451 o.default = "1";
452
453 o = s3.option(form.ListValue, "action", _("Action"));
454 o.value("allow", _("Allow"));
455 o.value("block", _("Block"));
456 o.default = "block";
457 o.textvalue = function (section_id) {
458 var val = this.cfgvalue(section_id);
459 return val == "allow" ? _("Allow") : _("Block");
460 };
461
462 o = s3.option(form.Value, "url", _("URL"));
463 o.optional = false;
464
465 return Promise.all([status.render(), m.render()]);
466 },
467 });