From 7fd5ec77440a2d0a3922f80379986b382df5cc77 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sat, 4 Feb 2023 18:30:30 +0100 Subject: [PATCH] Generate dns_upstreams table from received dns_servers data Signed-off-by: DL6ER --- scripts/pi-hole/js/settings.js | 390 +++++++++++++++++++++++++-------- 1 file changed, 297 insertions(+), 93 deletions(-) diff --git a/scripts/pi-hole/js/settings.js b/scripts/pi-hole/js/settings.js index 5643ddaf..7dfbef9a 100644 --- a/scripts/pi-hole/js/settings.js +++ b/scripts/pi-hole/js/settings.js @@ -5,8 +5,7 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ -/* global utils:false, checkMessages:false, apiFailure:false */ -var token = $("#token").text(); +/* global utils:false, apiFailure:false */ var hostinfoTimer = null; function updateHostInfo() { @@ -71,6 +70,256 @@ function updateCacheInfo() { }); } +function addAllowedValues(allowed) { + if (typeof allowed === "object") { + return ( + "

Available options:

" + ); + } else if (typeof allowed === "string") { + return "

Allowed value: " + utils.escapeHtml(allowed) + "

"; + } +} + +function generateDNSServers() { + // Build array from multiline string, one item per line + var servers = $("#dns-servers").text().split("\n"); + console.log(servers); +} + +function fillDNSupstreams(value, servers) { + var row = + '
' + + '
' + + '
' + + '

Upstream DNS Servers

' + + "
" + + '
' + + '
' + + '
' + + '' + + "" + + "" + + '' + + '' + + "" + + "" + + "" + + ""; + servers.forEach(element => { + row += ""; + // Build checkboxes for IPv4 and IPv6 + const variants = [element.v4, element.v6]; + for (let v = 0; v < 2; v++) { + const variant = variants[v]; + for (let index = 0; index < 2; index++) { + if (variant.length > index) { + row += '" + + "
IPv4IPv6Name
"; + }); + // Close table + row += + "
" + + "

ECS (Extended Client Subnet) defines a mechanism for recursive resolvers to send partial client IP address information to authoritative DNS name servers. Content Delivery Networks (CDNs) and latency-sensitive services use this to give geo-located responses when responding to name lookups coming through public DNS resolvers. Note that ECS may result in reduced privacy.

" + + "

Custom DNS servers can be added by specifying the IP address (and optionally the port number separated by a #) of the server. If the port number is not specified, the default port 53 will be used. The following box contains one server per line:

"; + // Append textbox showing the current values + row += + '' + + '
' + + ' " + + "
" + + "
" + + "
" + + "
" + + "
" + + "
"; + + $("#dns-content").append(row); +} + +function generateRow(topic, key, value, fullConfig = null) { + if (topic === "dns" && key === "upstreams") { + console.log(value, fullConfig); + fillDNSupstreams(value, fullConfig.dns_servers); + return; + } + + if (!("description" in value)) { + Object.keys(value).forEach(function (subkey) { + var subvalue = value[subkey]; + row = generateRow(topic, key + "." + subkey, subvalue); + }); + return; + } + + var row = + '
" + + '
' + + '
' + + '

' + + key + + (value.modified ? '  ' : "") + + (value.flags.advanced + ? '  ' + : "") + + "

" + + "

" + + utils.escapeHtml(value.description).replace("\n", "
") + + "

" + + "
" + + '
' + + '
' + + '
' + + '
'; + var resetToDefault = ""; + if (value.modified) { + resetToDefault = + ''; + } + + switch (value.type) { + case "string": { + row += + '' + + '
' + + ' ' + + resetToDefault + + addAllowedValues(value.allowed) + + "
"; + + break; + } + + case "boolean": { + row += + '' + + '
' + + ' " + + resetToDefault + + "
"; + + break; + } + + case "integer": { + row += + '' + + '
' + + ' ' + + resetToDefault + + "
"; + + break; + } + + case "unsigned integer": { + row += + '' + + '
' + + ' ' + + resetToDefault + + "
"; + + break; + } + + case "unsigned integer (16 bit)": { + row += + '' + + '
' + + ' ' + + resetToDefault + + "
"; + + break; + } + + case "string array": { + row += + '' + + '
' + + ' " + + resetToDefault + + "
"; + + break; + } + + case "enum (string)": { + row += + '' + + '
' + + ' " + + resetToDefault + + "
" + + '
' + + addAllowedValues(value.allowed) + + "
"; + + break; + } + + default: { + row += "TYPE " + value.type + " NOT DEFINED"; + } + } + + row += "
"; + $("#" + topic + "-content").append(row); +} + function createDynamicConfigTabs() { $.ajax({ url: "/api/config?detailed=true", @@ -85,28 +334,50 @@ function createDynamicConfigTabs() { // Create the tabs for the dynamic config topics data.topics.forEach(function (topic) { - var nav = '
  • '; + var nav = + '
  • "; navTabs.append(nav); - var content = '
    \ -
    \ -
    \ -
    \ -
    \ -

    ' + topic.title + '

    \ -

    ' + topic.description + '

    \ -

    \ -
    \ -
    \ -
    \ -
    \ -
    \ -
    \ - \ -
    \ -
    \ -
    \ -
    \ -
    '; + var content = + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '
    ' + + '

    ' + + topic.title + + "

    " + + "

    " + + topic.description + + "

    " + + '

    ' + + "
    " + + '
    ' + + '
    ' + + '
    ' + + "
    " + + '
    ' + + '' + + "
    " + + "
    " + + "
    " + + "
    " + + "
    "; tabContent.append(content); }); @@ -116,78 +387,11 @@ function createDynamicConfigTabs() { Object.keys(data.config).forEach(function (topic) { Object.keys(data.config[topic]).forEach(function (key) { var value = data.config[topic][key]; - console.log(topic, value); - if('description' in value) { - var row = '
    \ -
    \ -
    \ -

    ' + key + (value.modified ? '  ':'') + (value.flags.advanced ? '  ':'') + '

    \ -

    ' + utils.escapeHtml(value.description).replace("\n","
    ") + '

    \ -
    \ -
    \ -
    \ -
    \ -
    '; - var resetToDefault = ''; - if(value.modified) { - resetToDefault = ''; - } - if(value['type'] == "string") { - row += ' \ -
    \ - ' + resetToDefault + '\ -

    Allowed value: ' + utils.escapeHtml(value.allowed) + '

    \ -
    '; - } else if(value['type'] == "boolean") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    '; - } else if(value['type'] == "integer") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    '; - } else if(value['type'] == "unsigned integer") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    '; - } else if(value['type'] == "unsigned integer (16 bit)") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    '; - } else if(value['type'] == "string array") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    '; - } else if(value['type'] == "enum (string)") { - row += ' \ -
    \ - ' + resetToDefault + '\ -
    \ -
    \ -

    Available options:

    • ' + value.allowed.map(function(option) { return '' + option.item + ': ' + utils.escapeHtml(option.description); }).join('
    • ') + '

    \ -
    '; - } else { - row += "TYPE " + value.type + " NOT DEFINED"; - } - row +='
    \ -
    \ -
    \ -
    '; - } - $("#" + topic + "-content").append(row); + generateRow(topic, key, value, data); }); - $('#settings-' + topic + '-overlay').hide(); + $("#settings-" + topic + "-overlay").hide(); - $("input[id^='advanced-settings-toggle']").on("click", function(data) { + $("input[id^='advanced-settings-toggle']").on("click", function (data) { var checked = data.target.checked; // Synchronize all advanced settings checkboxes $("input[id^='advanced-settings-toggle']").prop("checked", checked);