123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405 |
- // Copyright 2023 MOSSDeF, Stan Grishin <stangri@melmac.ca>
- // This code wouldn't have been possible without help from:
- // - [@jow-](https://github.com/jow-)
- // - [@stokito](https://github.com/stokito)
- // - [@vsviridov](https://github.com/vsviridov)
- // noinspection JSAnnotator
- "use strict";
- "require form";
- "require rpc";
- "require view";
- "require https-dns-proxy.status as hdp";
- var pkg = hdp.pkg;
- return view.extend({
- load: function () {
- return Promise.all([
- L.resolveDefault(hdp.getPlatformSupport(pkg.Name), {}),
- L.resolveDefault(hdp.getProviders(pkg.Name), {}),
- L.resolveDefault(L.uci.load(pkg.Name), {}),
- L.resolveDefault(L.uci.load("dhcp"), {}),
- ]);
- },
- render: function (data) {
- var reply = {
- platform: (data[0] && data[0][pkg.Name]) || {
- http2_support: null,
- http3_support: null,
- },
- providers: (data[1] && data[1][pkg.Name]) || { providers: [] },
- };
- reply.providers.sort(function (a, b) {
- return _(a.title).localeCompare(_(b.title));
- });
- reply.providers.push({
- title: "Custom",
- template: "{option}",
- params: { option: { type: "text" } },
- });
- var status, m, s, o, p;
- var text;
- status = new hdp.status();
- m = new form.Map(pkg.Name, _("HTTPS DNS Proxy - Configuration"));
- s = m.section(form.NamedSection, "config", pkg.Name);
- o = s.option(
- form.ListValue,
- "dnsmasq_config_update_option",
- _("Update DNSMASQ Config on Start/Stop"),
- _(
- "If update option is selected, the %s'DNS Forwards' section of DHCP and DNS%s will be automatically updated to use selected DoH providers (%smore information%s)."
- ).format(
- '<a href="' + L.url("admin", "network", "dhcp") + '">',
- "</a>",
- '<a href="' + pkg.URL + "#default-settings" + '" target="_blank">',
- "</a>"
- )
- );
- o.value("*", _("Update all configs"));
- o.value("+", _("Update select configs"));
- o.value("-", _("Do not update configs"));
- o.default = "*";
- o.retain = true;
- o.cfgvalue = function (section_id) {
- let val = this.map.data.get(
- this.map.config,
- section_id,
- "dnsmasq_config_update"
- );
- if (val && val[0]) {
- switch (val[0]) {
- case "*":
- case "-":
- return val[0];
- default:
- return "+";
- }
- } else return "*";
- };
- o.write = function (section_id, formvalue) {
- L.uci.set(pkg.Name, section_id, "dnsmasq_config_update", formvalue);
- };
- o = s.option(
- form.MultiValue,
- "dnsmasq_config_update",
- _("Select the DNSMASQ Configs to update")
- );
- Object.values(L.uci.sections("dhcp", "dnsmasq")).forEach(function (
- element
- ) {
- var description;
- var key;
- if (element[".name"] === L.uci.resolveSID("dhcp", element[".name"])) {
- key = element[".index"];
- description = "dnsmasq[" + element[".index"] + "]";
- } else {
- key = element[".name"];
- description = element[".name"];
- }
- o.value(key, description);
- });
- o.depends("dnsmasq_config_update_option", "+");
- o.retain = true;
- o = s.option(
- form.ListValue,
- "force_dns",
- _("Force Router DNS"),
- _(
- "Forces Router DNS use on local devices, also known as DNS Hijacking. Only works on `lan` interface by default (%smore information%s)."
- ).format(
- '<a href="' + pkg.URL + "#force_dns" + '" target="_blank">',
- "</a>"
- )
- );
- o.value("0", _("Let local devices use their own DNS servers if set"));
- o.value("1", _("Force Router DNS server to all local devices"));
- o.default = "1";
- o = s.option(
- form.ListValue,
- "canary_domains_icloud",
- _("Canary Domains iCloud"),
- _(
- "Blocks access to iCloud Private Relay resolvers, forcing local devices to use router for DNS resolution (%smore information%s)."
- ).format(
- '<a href="' + pkg.URL + "#canary_domains_icloud" + '" target="_blank">',
- "</a>"
- )
- );
- o.value("0", _("Let local devices use iCloud Private Relay"));
- o.value("1", _("Force Router DNS server to all local devices"));
- o.depends("force_dns", "1");
- o.default = "1";
- o = s.option(
- form.ListValue,
- "canary_domains_mozilla",
- _("Canary Domains Mozilla"),
- _(
- "Blocks access to Mozilla Encrypted resolvers, forcing local devices to use router for DNS resolution (%smore information%s)."
- ).format(
- '<a href="' +
- pkg.URL +
- "#canary_domains_mozilla" +
- '" target="_blank">',
- "</a>"
- )
- );
- o.value("0", _("Let local devices use Mozilla Private Relay"));
- o.value("1", _("Force Router DNS server to all local devices"));
- o.depends("force_dns", "1");
- o.default = "1";
- text = "";
- if (!reply.platform.http2_support)
- text +=
- _(
- "Please note that %s is not supported on this system (%smore information%s)."
- ).format(
- "<i>HTTP/2</i>",
- '<a href="' + pkg.URL + "#http2-support" + '" target="_blank">',
- "</a>"
- ) + "<br />";
- if (!reply.platform.http3_support)
- text +=
- _(
- "Please note that %s is not supported on this system (%smore information%s)."
- ).format(
- "<i>HTTP/3 (QUIC)</i>",
- '<a href="' + pkg.URL + "#http3-quic-support" + '" target="_blank">',
- "</a>"
- ) + "<br />";
- s = m.section(
- form.GridSection,
- "https-dns-proxy",
- _("HTTPS DNS Proxy - Instances"),
- text
- );
- s.rowcolors = true;
- s.sortable = true;
- s.anonymous = true;
- s.addremove = true;
- s.sectiontitle = (section_id) => {
- var provText;
- var found;
- reply.providers.forEach((prov) => {
- var option;
- let regexp = pkg.templateToRegexp(prov.template);
- let resolver = L.uci.get(pkg.Name, section_id, "resolver_url");
- resolver = resolver === undefined ? null : resolver;
- if (!found && resolver && regexp.test(resolver)) {
- found = true;
- provText = _(prov.title);
- let match = resolver.match(regexp);
- if (match[1] != null) {
- if (
- prov.params &&
- prov.params.option &&
- prov.params.option.options
- ) {
- prov.params.option.options.forEach((opt) => {
- if (opt.value === match[1]) {
- option = _(opt.description);
- }
- });
- provText += " (" + option + ")";
- } else {
- if (match[1] !== "") provText += " (" + match[1] + ")";
- }
- }
- }
- });
- return provText || _("Unknown");
- };
- var _provider;
- _provider = s.option(form.ListValue, "_provider", _("Provider"));
- _provider.modalonly = true;
- _provider.cfgvalue = function (section_id) {
- let resolver = this.map.data.get(
- this.map.config,
- section_id,
- "resolver_url"
- );
- if (resolver === undefined || resolver === null) return null;
- let found;
- let ret;
- reply.providers.forEach((prov, i) => {
- let regexp = pkg.templateToRegexp(prov.template);
- if (!found && regexp.test(resolver)) {
- found = true;
- ret = prov.template;
- }
- });
- return ret || "";
- };
- _provider.write = function (section_id, formvalue) {
- L.uci.set(pkg.Name, section_id, "resolver_url", formvalue);
- };
- reply.providers.forEach((prov, i) => {
- if (prov.http2_only && !reply.platform.http2_support) return;
- if (prov.http3_only && !reply.platform.http3_support) return;
- _provider.value(prov.template, _(prov.title));
- if (
- prov.params &&
- prov.params.option &&
- prov.params.option.type &&
- prov.params.option.type === "select"
- ) {
- let optName = prov.params.option.description || _("Parameter");
- var _paramList = s.option(form.ListValue, "_paramList_" + i, optName);
- _paramList.template = prov.template;
- _paramList.modalonly = true;
- if (prov.params.option.default) {
- _paramList.default = prov.params.option.default;
- }
- prov.params.option.options.forEach((opt) => {
- let val = opt.value || "";
- let descr = opt.description || "";
- _paramList.value(val, descr);
- });
- _paramList.depends("_provider", prov.template);
- _paramList.write = function (section_id, formvalue) {
- let template = this.map.data.get(
- this.map.config,
- section_id,
- "resolver_url"
- );
- if (!formvalue && _paramList.template !== template) return 0;
- let resolver = pkg.templateToResolver(_paramList.template, {
- option: formvalue || "",
- });
- L.uci.set(pkg.Name, section_id, "resolver_url", resolver);
- };
- _paramList.remove = _paramList.write;
- } else if (
- prov.params &&
- prov.params.option &&
- prov.params.option.type &&
- prov.params.option.type === "text"
- ) {
- let optName = prov.params.option.description || _("Parameter");
- var _paramText = s.option(form.Value, "_paramText_" + i, optName);
- _paramText.template = prov.template;
- _paramText.modalonly = true;
- _paramText.depends("_provider", prov.template);
- _paramText.optional = !(
- prov.params.option.default && prov.params.option.default !== ""
- );
- _paramText.cfgvalue = function (section_id) {
- let resolver = this.map.data.get(
- this.map.config,
- section_id,
- "resolver_url"
- );
- if (resolver === undefined || resolver === null) return null;
- let regexp = pkg.templateToRegexp(prov.template);
- let match = resolver.match(regexp);
- return (match && match[1]) || null;
- };
- _paramText.write = function (section_id, formvalue) {
- let template = this.map.data.get(
- this.map.config,
- section_id,
- "resolver_url"
- );
- if (!formvalue && _paramText.template !== template) return 0;
- let resolver = pkg.templateToResolver(_paramText.template, {
- option: formvalue || "",
- });
- L.uci.set(pkg.Name, section_id, "resolver_url", resolver);
- };
- _paramText.remove = _paramText.write;
- }
- });
- o = s.option(form.Value, "bootstrap_dns", _("Bootstrap DNS"));
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "listen_addr", _("Listen Address"));
- o.datatype = "ipaddr";
- o.default = "";
- o.optional = true;
- o.placeholder = "127.0.0.1";
- o = s.option(form.Value, "listen_port", _("Listen Port"));
- o.datatype = "port";
- o.default = "";
- o.optional = true;
- o.placeholder = "5053";
- o = s.option(form.Value, "user", _("Run As User"));
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "group", _("Run As Group"));
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "dscp_codepoint", _("DSCP Codepoint"));
- o.datatype = "and(uinteger, range(0,63))";
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "verbosity", _("Logging Verbosity"));
- o.datatype = "and(uinteger, range(0,4))";
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "logfile", _("Logging File Path"));
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "polling_interval", _("Polling Interval"));
- o.datatype = "and(uinteger, range(5,3600))";
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.Value, "proxy_server", _("Proxy Server"));
- o.default = "";
- o.modalonly = true;
- o.optional = true;
- o = s.option(form.ListValue, "use_http1", _("Use HTTP/1"));
- o.modalonly = true;
- o.optional = true;
- o.rmempty = true;
- o.value("", _("Use negotiated HTTP version"));
- o.value("1", _("Force use of HTTP/1"));
- o.default = "";
- o = s.option(
- form.ListValue,
- "use_ipv6_resolvers_only",
- _("Use IPv6 resolvers")
- );
- o.modalonly = true;
- o.optional = true;
- o.rmempty = true;
- o.value("", _("Use any family DNS resolvers"));
- o.value("1", _("Force use of IPv6 DNS resolvers"));
- o.default = "";
- return Promise.all([status.render(), m.render()]);
- },
- });
|