From b209eb6167c177df3a522d43090d5f4c04d5ca19 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Wed, 20 Apr 2022 19:28:44 -0300 Subject: [PATCH 01/85] Using the correct dimensions Signed-off-by: RD WebDesign --- scripts/pi-hole/php/header.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/php/header.php b/scripts/pi-hole/php/header.php index aa59eb7ff..cc2095a33 100644 --- a/scripts/pi-hole/php/header.php +++ b/scripts/pi-hole/php/header.php @@ -569,7 +569,7 @@ function pidofFTL() class="active"> - + @@ -588,7 +588,7 @@ function pidofFTL() class="active"> - + From 58492c9be96c42096096087f267ef495511c18f6 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Fri, 22 Apr 2022 02:32:56 -0300 Subject: [PATCH 02/85] Add content type header Signed-off-by: RD WebDesign --- api_FTL.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api_FTL.php b/api_FTL.php index 98b2ee7b2..9a091ac34 100644 --- a/api_FTL.php +++ b/api_FTL.php @@ -306,6 +306,9 @@ if (array_key_exists("FTLnotrunning", $return)) { $data = array("FTLnotrunning" => true); } else { + // Set the header + header('Content-type: application/json'); + // Start the JSON string echo '{"data":['; $first = true; From 17e59dde033aa24b56497c77ec65de3c6ccb1adc Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Fri, 22 Apr 2022 17:04:45 +0100 Subject: [PATCH 03/85] Add codespell.yml Signed-off-by: Adam Warner --- .codespellignore | 0 .github/workflows/codespell.yml | 19 +++++++++++++++++++ 2 files changed, 19 insertions(+) create mode 100644 .codespellignore create mode 100644 .github/workflows/codespell.yml diff --git a/.codespellignore b/.codespellignore new file mode 100644 index 000000000..e69de29bb diff --git a/.github/workflows/codespell.yml b/.github/workflows/codespell.yml new file mode 100644 index 000000000..14c4b9464 --- /dev/null +++ b/.github/workflows/codespell.yml @@ -0,0 +1,19 @@ +name: Codespell +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + +jobs: + spell-check: + if: github.event.pull_request.draft == false + runs-on: ubuntu-latest + steps: + - + name: Checkout repository + uses: actions/checkout@v3 + - + name: Spell-Checking + uses: codespell-project/actions-codespell@master + with: + ignore_words_file: .codespellignore + skip: ./scripts/vendor,./style/vendor From 242654e149ea739850f36ad6bd7f1214284d376e Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Fri, 22 Apr 2022 17:17:59 +0100 Subject: [PATCH 04/85] Fix some suggestions / ignore others Signed-off-by: Adam Warner --- .codespellignore | 2 ++ scripts/pi-hole/php/func.php | 4 ++-- scripts/pi-hole/php/groups.php | 2 +- scripts/pi-hole/php/message.php | 2 +- scripts/pi-hole/php/teleporter.php | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/.codespellignore b/.codespellignore index e69de29bb..60e61ec68 100644 --- a/.codespellignore +++ b/.codespellignore @@ -0,0 +1,2 @@ +ede +EDE \ No newline at end of file diff --git a/scripts/pi-hole/php/func.php b/scripts/pi-hole/php/func.php index 8724b06a5..eae3c5244 100644 --- a/scripts/pi-hole/php/func.php +++ b/scripts/pi-hole/php/func.php @@ -286,7 +286,7 @@ function deleteAllCustomDNSEntries($reload="") $reload = $_REQUEST['reload']; $existingEntries = getCustomDNSEntries(); - // passing false to pihole_execute stops pihole from reloading after each enty has been deleted + // passing false to pihole_execute stops pihole from reloading after each entry has been deleted foreach ($existingEntries as $entry) { pihole_execute("-a removecustomdns ".$entry->ip." ".$entry->domain." ".$reload); } @@ -438,7 +438,7 @@ function deleteAllCustomCNAMEEntries($reload="") $reload = $_REQUEST['reload']; $existingEntries = getCustomCNAMEEntries(); - // passing false to pihole_execute stops pihole from reloading after each enty has been deleted + // passing false to pihole_execute stops pihole from reloading after each entry has been deleted foreach ($existingEntries as $entry) { pihole_execute("-a removecustomcname ".$entry->domain." ".$entry->target." ".$reload); } diff --git a/scripts/pi-hole/php/groups.php b/scripts/pi-hole/php/groups.php index b57258f74..6156a3a01 100644 --- a/scripts/pi-hole/php/groups.php +++ b/scripts/pi-hole/php/groups.php @@ -721,7 +721,7 @@ function JSON_error($message = null) // First execute INSERT OR IGNORE statement to create a record for // this domain (ignore if already existing) if (!$insert_stmt->execute()) { - throw new Exception('While executing INSERT OT IGNORE: ' . $db->lastErrorMsg() . '
'. + throw new Exception('While executing INSERT OR IGNORE: ' . $db->lastErrorMsg() . '
'. 'Added ' . $added . " out of ". $total . " domains"); } diff --git a/scripts/pi-hole/php/message.php b/scripts/pi-hole/php/message.php index 67132ece7..f971c9244 100644 --- a/scripts/pi-hole/php/message.php +++ b/scripts/pi-hole/php/message.php @@ -47,7 +47,7 @@ function JSON_error($message = null) $ids = json_decode($_POST['id']); if(!is_array($ids)) throw new Exception('Invalid payload: id is not an array'); - // Explot prevention: Ensure all entries in the ID array are integers + // Exploit prevention: Ensure all entries in the ID array are integers foreach($ids as $value) { if (!is_numeric($value)) throw new Exception('Invalid payload: id contains non-numeric entries'); diff --git a/scripts/pi-hole/php/teleporter.php b/scripts/pi-hole/php/teleporter.php index 774d10c7f..5532d00a7 100644 --- a/scripts/pi-hole/php/teleporter.php +++ b/scripts/pi-hole/php/teleporter.php @@ -631,7 +631,7 @@ function noun($num) archive_add_file("/etc/","hosts","etc/"); archive_add_directory("/etc/dnsmasq.d/","dnsmasq.d/"); - $archive->compress(Phar::GZ); // Creates a gziped copy + $archive->compress(Phar::GZ); // Creates a gzipped copy unlink($archive_file_name); // Unlink original tar file as it is not needed anymore $archive_file_name .= ".gz"; // Append ".gz" extension to ".tar" From f8ab31f43193e55cdcb90f8a16b29628d228cdf7 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Thu, 21 Apr 2022 20:21:49 -0300 Subject: [PATCH 05/85] Allow delete multiple items - Group pages - add checkboxes, buttons and functions to groups page; - add checkboxes, buttons and functions to clients page; - add checkboxes, buttons and functions to domains page; - add checkboxes, buttons and functions to adlists page; - move function to `utils.js`; - fix CSS after insert a new table column; Signed-off-by: RD WebDesign --- groups-adlists.php | 1 + groups-clients.php | 1 + groups-domains.php | 1 + groups.php | 1 + scripts/pi-hole/js/groups-adlists.js | 181 ++++++++++++++++------ scripts/pi-hole/js/groups-clients.js | 184 +++++++++++++++++------ scripts/pi-hole/js/groups-domains.js | 217 +++++++++++++++++++-------- scripts/pi-hole/js/groups.js | 181 +++++++++++++++++----- scripts/pi-hole/js/utils.js | 28 ++++ scripts/pi-hole/php/groups.php | 87 ++++++----- style/pi-hole.css | 33 ++-- 11 files changed, 678 insertions(+), 237 deletions(-) diff --git a/groups-adlists.php b/groups-adlists.php index 5a4688e55..c5aacdd9c 100644 --- a/groups-adlists.php +++ b/groups-adlists.php @@ -63,6 +63,7 @@ ID + Address Status Comment diff --git a/groups-clients.php b/groups-clients.php index 2257b0ded..c48c85854 100644 --- a/groups-clients.php +++ b/groups-clients.php @@ -70,6 +70,7 @@ ID + Client Comment Group assignment diff --git a/groups-domains.php b/groups-domains.php index 3877c89a9..a2040307d 100644 --- a/groups-domains.php +++ b/groups-domains.php @@ -121,6 +121,7 @@ ID + Domain/RegEx Type Status diff --git a/groups.php b/groups.php index 22e741e7b..7c70549f3 100644 --- a/groups.php +++ b/groups.php @@ -61,6 +61,7 @@ ID + Name Status Description diff --git a/scripts/pi-hole/js/groups-adlists.js b/scripts/pi-hole/js/groups-adlists.js index 1ff87a0dc..f41f93103 100644 --- a/scripts/pi-hole/js/groups-adlists.js +++ b/scripts/pi-hole/js/groups-adlists.js @@ -117,8 +117,9 @@ function initTable() { order: [[0, "asc"]], columns: [ { data: "id", visible: false }, - { data: "status", searchable: false, class: "details-control" }, - { data: "address" }, + { data: null, visible: true, orderable: false, width: "15px" }, + { data: "status", searchable: false, orderable: false, class: "details-control" }, + { data: "address", orderable: false }, { data: "enabled", searchable: false }, { data: "comment" }, { data: "groups", searchable: false }, @@ -126,8 +127,11 @@ function initTable() { ], columnDefs: [ { - targets: [0, 2], - orderable: false, + targets: 1, + className: "select-checkbox", + render: function () { + return ""; + }, }, { targets: "_all", @@ -135,6 +139,10 @@ function initTable() { }, ], drawCallback: function () { + // Hide buttons if all messages were deleted + var hasRows = this.api().rows({ filter: "applied" }).data().length > 0; + $(".datatable-bt").css("visibility", hasRows ? "visible" : "hidden"); + $('button[id^="deleteAdlist_"]').on("click", deleteAdlist); // Remove visible dropdown to prevent orphaning $("body > .bootstrap-select.dropdown").remove(); @@ -176,19 +184,19 @@ function initTable() { extra = ""; } - $("td:eq(0)", row).addClass("list-status-" + statusCode); - $("td:eq(0)", row).html( + $("td:eq(1)", row).addClass("list-status-" + statusCode); + $("td:eq(1)", row).html( "" + extra ); if (data.address.startsWith("file://")) { // Local files cannot be downloaded from a distant client so don't show // a link to such a list here - $("td:eq(1)", row).html( + $("td:eq(2)", row).html( '' + data.address + "" ); } else { - $("td:eq(1)", row).html( + $("td:eq(2)", row).html( '
" ); var statusEl = $("#status_" + data.id, row); @@ -212,13 +220,13 @@ function initTable() { }); statusEl.on("change", editAdlist); - $("td:eq(3)", row).html(''); + $("td:eq(4)", row).html(''); var commentEl = $("#comment_" + data.id, row); commentEl.val(utils.unescapeHtml(data.comment)); commentEl.on("change", editAdlist); - $("td:eq(4)", row).empty(); - $("td:eq(4)", row).append( + $("td:eq(5)", row).empty(); + $("td:eq(5)", row).append( '' ); var selectEl = $("#multiselect_" + data.id, row); @@ -285,20 +293,67 @@ function initTable() { var button = '"; - $("td:eq(5)", row).html(button); + $("td:eq(6)", row).html(button); }, dom: - "<'row'<'col-sm-12'f>>" + - "<'row'<'col-sm-4'l><'col-sm-8'p>>" + + "<'row'<'col-sm-6'l><'col-sm-6'f>>" + + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + - "<'row'<'col-sm-5'i><'col-sm-7'p>>", + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + + "<'row'<'col-sm-12'i>>", lengthMenu: [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"], ], + select: { + style: "multi", + selector: "td:not(:last-child)", + info: false, + }, + buttons: [ + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectAll", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectMore", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + extend: "selectNone", + text: '', + titleAttr: "Deselect All", + className: "btn-sm datatable-bt removeAll", + }, + { + text: '', + titleAttr: "Delete Selected", + className: "btn-sm datatable-bt deleteSelected", + action: function () { + // For each ".selected" row ... + var ids = []; + $("tr.selected").each(function () { + // ... add the row identified by "data-id". + ids.push(parseInt($(this).attr("data-id"), 10)); + }); + // Delete all selected rows at once + delItems(ids); + }, + }, + ], stateSave: true, stateDuration: 0, stateSaveCallback: function (settings, data) { @@ -319,6 +374,10 @@ function initTable() { }, }); + table.on("init select deselect", function () { + utils.changeBulkDeleteStates(table); + }); + table.on("order.dt", function () { var order = table.order(); if (order[0][0] !== 0 || order[0][1] !== "asc") { @@ -327,6 +386,7 @@ function initTable() { $("#resetButton").addClass("hidden"); } }); + $("#resetButton").on("click", function () { table.order([[0, "asc"]]).draw(); $("#resetButton").addClass("hidden"); @@ -358,6 +418,66 @@ function initTable() { } } +// Remove 'bnt-group' class from container, to avoid grouping +$.fn.dataTable.Buttons.defaults.dom.container.className = "dt-buttons"; + +function deleteAdlist() { + // Passes the button data-del-id attribute as ID + var ids = [parseInt($(this).attr("data-del-id"), 10)]; + delItems(ids); +} + +function delItems(ids) { + // Check input validity + if (!Array.isArray(ids)) return; + + var address = ""; + + // Exploit prevention: Return early for non-numeric IDs + for (var id of ids) { + if (typeof id !== "number") return; + address += "
  • " + utils.escapeHtml($("#address_" + id).text()) + "
  • "; + } + + utils.disableAll(); + var idstring = ids.join(", "); + utils.showAlert("info", "", "Deleting Adlists: " + idstring, "..."); + + $.ajax({ + url: "scripts/pi-hole/php/groups.php", + method: "post", + dataType: "json", + data: { action: "delete_adlist", id: JSON.stringify(ids), token: token }, + }) + .done(function (response) { + utils.enableAll(); + if (response.success) { + utils.showAlert( + "success", + "far fa-trash-alt", + "Successfully deleted adlists: " + idstring, + "
      " + address + "
    " + ); + for (var id in ids) { + if (Object.hasOwnProperty.call(ids, id)) { + table.row(id).remove().draw(false).ajax.reload(null, false); + } + } + } else { + utils.showAlert("error", "", "Error while deleting adlists: " + idstring, response.message); + } + + // Clear selection after deletion + table.rows().deselect(); + utils.changeBulkDeleteStates(table); + }) + .fail(function (jqXHR, exception) { + utils.enableAll(); + utils.showAlert("error", "", "Error while deleting adlists: " + idstring, jqXHR.responseText); + console.log(exception); // eslint-disable-line no-console + }); +} + function addAdlist() { var address = utils.escapeHtml($("#new_address").val()); var comment = utils.escapeHtml($("#new_comment").val()); @@ -490,32 +610,3 @@ function editAdlist() { }, }); } - -function deleteAdlist() { - var tr = $(this).closest("tr"); - var id = tr.attr("data-id"); - var address = utils.escapeHtml(tr.find("#address_" + id).text()); - - utils.disableAll(); - utils.showAlert("info", "", "Deleting adlist...", address); - $.ajax({ - url: "scripts/pi-hole/php/groups.php", - method: "post", - dataType: "json", - data: { action: "delete_adlist", id: id, token: token }, - success: function (response) { - utils.enableAll(); - if (response.success) { - utils.showAlert("success", "far fa-trash-alt", "Successfully deleted adlist ", address); - table.row(tr).remove().draw(false).ajax.reload(null, false); - } else { - utils.showAlert("error", "", "Error while deleting adlist with ID " + id, response.message); - } - }, - error: function (jqXHR, exception) { - utils.enableAll(); - utils.showAlert("error", "", "Error while deleting adlist with ID " + id, jqXHR.responseText); - console.log(exception); // eslint-disable-line no-console - }, - }); -} diff --git a/scripts/pi-hole/js/groups-clients.js b/scripts/pi-hole/js/groups-clients.js index a29074260..444e55c3d 100644 --- a/scripts/pi-hole/js/groups-clients.js +++ b/scripts/pi-hole/js/groups-clients.js @@ -92,18 +92,31 @@ function initTable() { order: [[0, "asc"]], columns: [ { data: "id", visible: false }, + { data: null, visible: true, width: "15px" }, { data: "ip", type: "ip-address" }, { data: "comment" }, { data: "groups", searchable: false }, { data: "name", width: "22px", orderable: false }, ], columnDefs: [ + { + targets: 1, + orderable: false, + className: "select-checkbox", + render: function () { + return ""; + }, + }, { targets: "_all", render: $.fn.dataTable.render.text(), }, ], drawCallback: function () { + // Hide buttons if all messages were deleted + var hasRows = this.api().rows({ filter: "applied" }).data().length > 0; + $(".datatable-bt").css("visibility", hasRows ? "visible" : "hidden"); + $('button[id^="deleteClient_"]').on("click", deleteClient); // Remove visible dropdown to prevent orphaning $("body > .bootstrap-select.dropdown").remove(); @@ -134,15 +147,15 @@ function initTable() { '" class="breakall">' + data.name + ""; - $("td:eq(0)", row).html(ipName); + $("td:eq(1)", row).html(ipName); - $("td:eq(1)", row).html(''); + $("td:eq(2)", row).html(''); var commentEl = $("#comment_" + data.id, row); commentEl.val(utils.unescapeHtml(data.comment)); commentEl.on("change", editClient); - $("td:eq(2)", row).empty(); - $("td:eq(2)", row).append( + $("td:eq(3)", row).empty(); + $("td:eq(3)", row).append( '' ); var selectEl = $("#multiselect_" + data.id, row); @@ -209,16 +222,63 @@ function initTable() { var button = '"; - $("td:eq(3)", row).html(button); + $("td:eq(4)", row).html(button); + }, + select: { + style: "multi", + selector: "td:not(:last-child)", + info: false, }, + buttons: [ + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectAll", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectMore", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + extend: "selectNone", + text: '', + titleAttr: "Deselect All", + className: "btn-sm datatable-bt removeAll", + }, + { + text: '', + titleAttr: "Delete Selected", + className: "btn-sm datatable-bt deleteSelected", + action: function () { + // For each ".selected" row ... + var ids = []; + $("tr.selected").each(function () { + // ... add the row identified by "data-id". + ids.push(parseInt($(this).attr("data-id"), 10)); + }); + // Delete all selected rows at once + delItems(ids); + }, + }, + ], dom: - "<'row'<'col-sm-12'f>>" + - "<'row'<'col-sm-4'l><'col-sm-8'p>>" + + "<'row'<'col-sm-6'l><'col-sm-6'f>>" + + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + - "<'row'<'col-sm-5'i><'col-sm-7'p>>", + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + + "<'row'<'col-sm-12'i>>", lengthMenu: [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"], @@ -252,6 +312,10 @@ function initTable() { input.setAttribute("spellcheck", false); } + table.on("init select deselect", function () { + utils.changeBulkDeleteStates(table); + }); + table.on("order.dt", function () { var order = table.order(); if (order[0][0] !== 0 || order[0][1] !== "asc") { @@ -267,6 +331,75 @@ function initTable() { }); } +// Remove 'bnt-group' class from container, to avoid grouping +$.fn.dataTable.Buttons.defaults.dom.container.className = "dt-buttons"; + +function deleteClient() { + // Passes the button data-del-id attribute as ID + var ids = [parseInt($(this).attr("data-del-id"), 10)]; + delItems(ids); +} + +function delItems(ids) { + // Check input validity + if (!Array.isArray(ids)) return; + + var items = ""; + var name = ""; + + for (var id of ids) { + // Exploit prevention: Return early for non-numeric IDs + if (typeof id !== "number") return; + + // Retrieve details + name = utils.escapeHtml($("#name_" + id).text()); + if (name.length > 0) { + name = " (" + utils.escapeHtml($("#name_" + id).text()) + ")"; + } + + // Add client + items += "
  • " + utils.escapeHtml($("#ip_" + id).text()) + name + "
  • "; + } + + utils.disableAll(); + var idstring = ids.join(", "); + utils.showAlert("info", "", "Deleting clients: " + idstring, "..."); + + $.ajax({ + url: "scripts/pi-hole/php/groups.php", + method: "post", + dataType: "json", + data: { action: "delete_client", id: JSON.stringify(ids), token: token }, + }) + .done(function (response) { + utils.enableAll(); + if (response.success) { + utils.showAlert( + "success", + "far fa-trash-alt", + "Successfully deleted clients: " + idstring, + "
      " + items + "
    " + ); + for (var id in ids) { + if (Object.hasOwnProperty.call(ids, id)) { + table.row(id).remove().draw(false).ajax.reload(null, false); + } + } + } else { + utils.showAlert("error", "", "Error while deleting clients: " + idstring, response.message); + } + + // Clear selection after deletion + table.rows().deselect(); + utils.changeBulkDeleteStates(table); + }) + .fail(function (jqXHR, exception) { + utils.enableAll(); + utils.showAlert("error", "", "Error while deleting clients: " + idstring, jqXHR.responseText); + console.log(exception); // eslint-disable-line no-console + }); +} + function addClient() { var ip = utils.escapeHtml($("#select").val().trim()); var comment = utils.escapeHtml($("#new_comment").val()); @@ -389,38 +522,3 @@ function editClient() { }, }); } - -function deleteClient() { - var tr = $(this).closest("tr"); - var id = tr.attr("data-id"); - var ip = utils.escapeHtml(tr.find("#ip_" + id).text()); - var name = utils.escapeHtml(tr.find("#name_" + id).text()); - - if (name.length > 0) { - ip += " (" + name + ")"; - } - - utils.disableAll(); - utils.showAlert("info", "", "Deleting client...", ip); - $.ajax({ - url: "scripts/pi-hole/php/groups.php", - method: "post", - dataType: "json", - data: { action: "delete_client", id: id, token: token }, - success: function (response) { - utils.enableAll(); - if (response.success) { - utils.showAlert("success", "far fa-trash-alt", "Successfully deleted client ", ip); - table.row(tr).remove().draw(false).ajax.reload(null, false); - reloadClientSuggestions(); - } else { - utils.showAlert("error", "", "Error while deleting client with ID " + id, response.message); - } - }, - error: function (jqXHR, exception) { - utils.enableAll(); - utils.showAlert("error", "", "Error while deleting client with ID " + id, jqXHR.responseText); - console.log(exception); // eslint-disable-line no-console - }, - }); -} diff --git a/scripts/pi-hole/js/groups-domains.js b/scripts/pi-hole/js/groups-domains.js index 2faa9a832..6a9440cf4 100644 --- a/scripts/pi-hole/js/groups-domains.js +++ b/scripts/pi-hole/js/groups-domains.js @@ -69,6 +69,7 @@ function initTable() { order: [[0, "asc"]], columns: [ { data: "id", visible: false }, + { data: null, visible: true, orderable: false, width: "15px" }, { data: "domain" }, { data: "type", searchable: false }, { data: "enabled", searchable: false }, @@ -77,12 +78,24 @@ function initTable() { { data: null, width: "22px", orderable: false }, ], columnDefs: [ + { + targets: 1, + orderable: false, + className: "select-checkbox", + render: function () { + return ""; + }, + }, { targets: "_all", render: $.fn.dataTable.render.text(), }, ], drawCallback: function () { + // Hide buttons if all messages were deleted + var hasRows = this.api().rows({ filter: "applied" }).data().length > 0; + $(".datatable-bt").css("visibility", hasRows ? "visible" : "hidden"); + $('button[id^="deleteDomain_"]').on("click", deleteDomain); // Remove visible dropdown to prevent orphaning $("body > .bootstrap-select.dropdown").remove(); @@ -96,7 +109,7 @@ function initTable() { utils.datetime(data.date_modified, false) + "\nDatabase ID: " + data.id; - $("td:eq(0)", row).html( + $("td:eq(1)", row).html( 'Regex blacklist"; } - $("td:eq(1)", row).html( + $("td:eq(2)", row).html( '" ); var statusEl = $("#status_" + data.id, row); @@ -153,15 +166,15 @@ function initTable() { }); statusEl.on("change", editDomain); - $("td:eq(3)", row).html(''); + $("td:eq(4)", row).html(''); var commentEl = $("#comment_" + data.id, row); commentEl.val(utils.unescapeHtml(data.comment)); commentEl.on("change", editDomain); // Show group assignment field only if in full domain management mode - if (table.column(5).visible()) { - $("td:eq(4)", row).empty(); - $("td:eq(4)", row).append( + if (table.column(6).visible()) { + $("td:eq(5)", row).empty(); + $("td:eq(5)", row).append( '' ); var selectEl = $("#multiselect_" + data.id, row); @@ -234,20 +247,67 @@ function initTable() { var button = '"; - if (table.column(5).visible()) { - $("td:eq(5)", row).html(button); + if (table.column(6).visible()) { + $("td:eq(6)", row).html(button); } else { - $("td:eq(4)", row).html(button); + $("td:eq(5)", row).html(button); } }, + select: { + style: "multi", + selector: "td:not(:last-child)", + info: false, + }, + buttons: [ + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectAll", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectMore", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + extend: "selectNone", + text: '', + titleAttr: "Deselect All", + className: "btn-sm datatable-bt removeAll", + }, + { + text: '', + titleAttr: "Delete Selected", + className: "btn-sm datatable-bt deleteSelected", + action: function () { + // For each ".selected" row ... + var ids = []; + $("tr.selected").each(function () { + // ... add the row identified by "data-id". + ids.push(parseInt($(this).attr("data-id"), 10)); + }); + // Delete all selected rows at once + delItems(ids); + }, + }, + ], dom: - "<'row'<'col-sm-12'f>>" + - "<'row'<'col-sm-4'l><'col-sm-8'p>>" + + "<'row'<'col-sm-6'l><'col-sm-6'f>>" + + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + - "<'row'<'col-sm-5'i><'col-sm-7'p>>", + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + + "<'row'<'col-sm-12'i>>", lengthMenu: [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"], @@ -268,7 +328,7 @@ function initTable() { // Reset visibility of ID column data.columns[0].visible = false; // Show group assignment column only on full page - data.columns[5].visible = showtype === "all"; + data.columns[6].visible = showtype === "all"; // Apply loaded state to table return data; }, @@ -294,6 +354,10 @@ function initTable() { input.setAttribute("spellcheck", false); } + table.on("init select deselect", function () { + utils.changeBulkDeleteStates(table); + }); + table.on("order.dt", function () { var order = table.order(); if (order[0][0] !== 0 || order[0][1] !== "asc") { @@ -302,12 +366,85 @@ function initTable() { $("#resetButton").addClass("hidden"); } }); + $("#resetButton").on("click", function () { table.order([[0, "asc"]]).draw(); $("#resetButton").addClass("hidden"); }); } +// Remove 'bnt-group' class from container, to avoid grouping +$.fn.dataTable.Buttons.defaults.dom.container.className = "dt-buttons"; + +function deleteDomain() { + // Passes the button data-del-id attribute as ID + var ids = [parseInt($(this).attr("data-del-id"), 10)]; + delItems(ids); +} + +function delItems(ids) { + // Check input validity + if (!Array.isArray(ids)) return; + + var items = ""; + var type = ""; + var typeID = ""; + + for (var id of ids) { + // Exploit prevention: Return early for non-numeric IDs + if (typeof id !== "number") return; + + // Retrieve domain type + typeID = $("#type_" + id).val(); + if (typeID === "0" || typeID === "1") { + type = " (domain)"; + } else if (typeID === "2" || typeID === "3") { + type = " (regex)"; + } + + // Add item + items += "
  • " + utils.escapeHtml($("#domain_" + id).text()) + type + "
  • "; + } + + utils.disableAll(); + var idstring = ids.join(", "); + utils.showAlert("info", "", "Deleting items: " + idstring, "..."); + + $.ajax({ + url: "scripts/pi-hole/php/groups.php", + method: "post", + dataType: "json", + data: { action: "delete_domain", id: JSON.stringify(ids), token: token }, + }) + .done(function (response) { + utils.enableAll(); + if (response.success) { + utils.showAlert( + "success", + "far fa-trash-alt", + "Successfully deleted items: " + idstring, + "
      " + items + "
    " + ); + for (var id in ids) { + if (Object.hasOwnProperty.call(ids, id)) { + table.row(id).remove().draw(false).ajax.reload(null, false); + } + } + } else { + utils.showAlert("error", "", "Error while deleting items: " + idstring, response.message); + } + + // Clear selection after deletion + table.rows().deselect(); + utils.changeBulkDeleteStates(table); + }) + .fail(function (jqXHR, exception) { + utils.enableAll(); + utils.showAlert("error", "", "Error while deleting items: " + idstring, jqXHR.responseText); + console.log(exception); // eslint-disable-line no-console + }); +} + function addDomain() { var action = this.id; var tabHref = $('a[data-toggle="tab"][aria-expanded="true"]').attr("href"); @@ -490,55 +627,3 @@ function editDomain() { }, }); } - -function deleteDomain() { - var tr = $(this).closest("tr"); - var id = tr.attr("data-id"); - var domain = utils.escapeHtml(tr.find("#domain_" + id).text()); - var type = tr.find("#type_" + id).val(); - - var domainRegex; - if (type === "0" || type === "1") { - domainRegex = "domain"; - } else if (type === "2" || type === "3") { - domainRegex = "regex"; - } - - utils.disableAll(); - utils.showAlert("info", "", "Deleting " + domainRegex + "...", domain); - $.ajax({ - url: "scripts/pi-hole/php/groups.php", - method: "post", - dataType: "json", - data: { action: "delete_domain", id: id, token: token }, - success: function (response) { - utils.enableAll(); - if (response.success) { - utils.showAlert( - "success", - "far fa-trash-alt", - "Successfully deleted " + domainRegex, - domain - ); - table.row(tr).remove().draw(false).ajax.reload(null, false); - } else { - utils.showAlert( - "error", - "", - "Error while deleting " + domainRegex + " with ID " + id, - response.message - ); - } - }, - error: function (jqXHR, exception) { - utils.enableAll(); - utils.showAlert( - "error", - "", - "Error while deleting " + domainRegex + " with ID " + id, - jqXHR.responseText - ); - console.log(exception); // eslint-disable-line no-console - }, - }); -} diff --git a/scripts/pi-hole/js/groups.js b/scripts/pi-hole/js/groups.js index 8b7e3b63b..d9c811f3f 100644 --- a/scripts/pi-hole/js/groups.js +++ b/scripts/pi-hole/js/groups.js @@ -22,18 +22,31 @@ $(function () { order: [[0, "asc"]], columns: [ { data: "id", visible: false }, + { data: null, visible: true, width: "15px" }, { data: "name" }, { data: "enabled", searchable: false }, { data: "description" }, { data: null, width: "22px", orderable: false }, ], columnDefs: [ + { + targets: 1, + orderable: false, + className: "select-checkbox", + render: function () { + return ""; + }, + }, { targets: "_all", render: $.fn.dataTable.render.text(), }, ], drawCallback: function () { + // Hide buttons if all messages were deleted + var hasRows = this.api().rows({ filter: "applied" }).data().length > 0; + $(".datatable-bt").css("visibility", hasRows ? "visible" : "hidden"); + $('button[id^="deleteGroup_"]').on("click", deleteGroup); }, rowCallback: function (row, data) { @@ -45,7 +58,7 @@ $(function () { utils.datetime(data.date_modified, false) + "\nDatabase ID: " + data.id; - $("td:eq(0)", row).html( + $("td:eq(1)", row).html( '' ); var nameEl = $("#name_" + data.id, row); @@ -53,7 +66,7 @@ $(function () { nameEl.on("change", editGroup); var disabled = data.enabled === 0; - $("td:eq(1)", row).html( + $("td:eq(2)", row).html( '" ); var statusEl = $("#status_" + data.id, row); @@ -66,28 +79,75 @@ $(function () { }); statusEl.on("change", editGroup); - $("td:eq(2)", row).html(''); + $("td:eq(3)", row).html(''); var desc = data.description !== null ? data.description : ""; var descEl = $("#desc_" + data.id, row); descEl.val(utils.unescapeHtml(desc)); descEl.on("change", editGroup); - $("td:eq(3)", row).empty(); + $("td:eq(4)", row).empty(); if (data.id !== 0) { var button = '"; - $("td:eq(3)", row).html(button); + $("td:eq(4)", row).html(button); } }, + select: { + style: "multi", + selector: "td:not(:last-child)", + info: false, + }, + buttons: [ + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectAll", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + text: '', + titleAttr: "Select All", + className: "btn-sm datatable-bt selectMore", + action: function () { + table.rows({ page: "current" }).select(); + }, + }, + { + extend: "selectNone", + text: '', + titleAttr: "Deselect All", + className: "btn-sm datatable-bt removeAll", + }, + { + text: '', + titleAttr: "Delete Selected", + className: "btn-sm datatable-bt deleteSelected", + action: function () { + // For each ".selected" row ... + var ids = []; + $("tr.selected").each(function () { + // ... add the row identified by "data-id". + ids.push(parseInt($(this).attr("data-id"), 10)); + }); + // Delete all selected rows at once + delItems(ids); + }, + }, + ], dom: - "<'row'<'col-sm-12'f>>" + - "<'row'<'col-sm-4'l><'col-sm-8'p>>" + + "<'row'<'col-sm-6'l><'col-sm-6'f>>" + + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + "<'row'<'col-sm-12'<'table-responsive'tr>>>" + - "<'row'<'col-sm-5'i><'col-sm-7'p>>", + "<'row'<'col-sm-3'B><'col-sm-9'p>>" + + "<'row'<'col-sm-12'i>>", lengthMenu: [ [10, 25, 50, 100, -1], [10, 25, 50, 100, "All"], @@ -106,7 +166,7 @@ $(function () { } // Reset visibility of ID column - data.columns[0].visible = false; + data.columns[1].visible = false; // Apply loaded state to table return data; }, @@ -121,6 +181,10 @@ $(function () { input.setAttribute("spellcheck", false); } + table.on("init select deselect", function () { + utils.changeBulkDeleteStates(table); + }); + table.on("order.dt", function () { var order = table.order(); if (order[0][0] !== 0 || order[0][1] !== "asc") { @@ -129,12 +193,82 @@ $(function () { $("#resetButton").addClass("hidden"); } }); + $("#resetButton").on("click", function () { table.order([[0, "asc"]]).draw(); $("#resetButton").addClass("hidden"); }); }); +// Remove 'bnt-group' class from container, to avoid grouping +$.fn.dataTable.Buttons.defaults.dom.container.className = "dt-buttons"; + +function deleteGroup() { + // Passes the button data-del-id attribute as ID + var ids = [parseInt($(this).attr("data-del-id"), 10)]; + delItems(ids); +} + +function delItems(ids) { + // Check input validity + if (!Array.isArray(ids)) return; + + var items = ""; + var name = ""; + + for (var id of ids) { + // Exploit prevention: Return early for non-numeric IDs + if (typeof id !== "number") return; + + // Retrieve details + name = utils.escapeHtml($("#name_" + id).text()); + if (name.length > 0) { + name = " (" + utils.escapeHtml($("#name_" + id).text()) + ")"; + } + + // Add item + items += "
  • " + utils.escapeHtml($("#ip_" + id).text()) + name + "
  • "; + } + + utils.disableAll(); + var idstring = ids.join(", "); + utils.showAlert("info", "", "Deleting groups: " + idstring, "..."); + + $.ajax({ + url: "scripts/pi-hole/php/groups.php", + method: "post", + dataType: "json", + data: { action: "delete_group", id: JSON.stringify(ids), token: token }, + }) + .done(function (response) { + utils.enableAll(); + if (response.success) { + utils.showAlert( + "success", + "far fa-trash-alt", + "Successfully deleted groups: " + idstring, + "
      " + items + "
    " + ); + for (var id in ids) { + if (Object.hasOwnProperty.call(ids, id)) { + table.row(id).remove().draw(false).ajax.reload(null, false); + } + } + } else { + utils.showAlert("error", "", "Error while deleting groups: " + idstring, response.message); + } + + // Clear selection after deletion + table.rows().deselect(); + utils.changeBulkDeleteStates(table); + }) + .fail(function (jqXHR, exception) { + utils.enableAll(); + utils.showAlert("error", "", "Error while deleting groups: " + idstring, jqXHR.responseText); + console.log(exception); // eslint-disable-line no-console + }); +} + function addGroup() { var name = utils.escapeHtml($("#new_name").val()); var desc = utils.escapeHtml($("#new_desc").val()); @@ -246,32 +380,3 @@ function editGroup() { }, }); } - -function deleteGroup() { - var tr = $(this).closest("tr"); - var id = tr.attr("data-id"); - var name = utils.escapeHtml(tr.find("#name_" + id).val()); - - utils.disableAll(); - utils.showAlert("info", "", "Deleting group...", name); - $.ajax({ - url: "scripts/pi-hole/php/groups.php", - method: "post", - dataType: "json", - data: { action: "delete_group", id: id, token: token }, - success: function (response) { - utils.enableAll(); - if (response.success) { - utils.showAlert("success", "far fa-trash-alt", "Successfully deleted group ", name); - table.row(tr).remove().draw(false); - } else { - utils.showAlert("error", "", "Error while deleting group with ID " + id, response.message); - } - }, - error: function (jqXHR, exception) { - utils.enableAll(); - utils.showAlert("error", "", "Error while deleting group with ID " + id, jqXHR.responseText); - console.log(exception); // eslint-disable-line no-console - }, - }); -} diff --git a/scripts/pi-hole/js/utils.js b/scripts/pi-hole/js/utils.js index f6d2434a9..16aa44739 100644 --- a/scripts/pi-hole/js/utils.js +++ b/scripts/pi-hole/js/utils.js @@ -381,6 +381,33 @@ function checkMessages() { }); } +// Show only the appropriate delete buttons in datatables +function changeBulkDeleteStates(table) { + var allRows = table.rows({ filter: "applied" }).data().length; + var pageLength = table.page.len(); + var selectedRows = table.rows(".selected").data().length; + + if (selectedRows === 0) { + // Nothing selected + $(".selectAll").removeClass("hidden"); + $(".selectMore").addClass("hidden"); + $(".removeAll").addClass("hidden"); + $(".deleteSelected").addClass("hidden"); + } else if (selectedRows >= pageLength || selectedRows === allRows) { + // Whole page is selected (or all available messages were selected) + $(".selectAll").addClass("hidden"); + $(".selectMore").addClass("hidden"); + $(".removeAll").removeClass("hidden"); + $(".deleteSelected").removeClass("hidden"); + } else { + // Some rows are selected, but not all + $(".selectAll").addClass("hidden"); + $(".selectMore").removeClass("hidden"); + $(".removeAll").addClass("hidden"); + $(".deleteSelected").removeClass("hidden"); + } +} + window.utils = (function () { return { escapeHtml: escapeHtml, @@ -404,5 +431,6 @@ window.utils = (function () { addTD: addTD, colorBar: colorBar, checkMessages: checkMessages, + changeBulkDeleteStates: changeBulkDeleteStates, }; })(); diff --git a/scripts/pi-hole/php/groups.php b/scripts/pi-hole/php/groups.php index b57258f74..967c0772b 100644 --- a/scripts/pi-hole/php/groups.php +++ b/scripts/pi-hole/php/groups.php @@ -153,21 +153,26 @@ function JSON_error($message = null) } elseif ($_POST['action'] == 'delete_group') { // Delete group identified by ID try { + $ids = json_decode($_POST['id']); + // Exploit prevention: Ensure all entries in the ID array are integers + foreach($ids as $value) { + if (!is_numeric($value)) { + throw new Exception('Invalid payload: id'); + } + } + $table_name = ['domainlist_by_group', 'client_by_group', 'adlist_by_group', 'group']; $table_keys = ['group_id', 'group_id', 'group_id', 'id']; + for ($i = 0; $i < count($table_name); $i++) { $table = $table_name[$i]; $key = $table_keys[$i]; - $stmt = $db->prepare("DELETE FROM \"$table\" WHERE $key = :id;"); + $stmt = $db->prepare("DELETE FROM ".$table." WHERE ".$key." IN ('.implode(",",$ids).')'"); if (!$stmt) { throw new Exception("While preparing DELETE FROM $table statement: " . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception("While binding id to DELETE FROM $table statement: " . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception("While executing DELETE FROM $table statement: " . $db->lastErrorMsg()); } @@ -463,30 +468,32 @@ function JSON_error($message = null) } elseif ($_POST['action'] == 'delete_client') { // Delete client identified by ID try { + $ids = json_decode($_POST['id']); + // Exploit prevention: Ensure all entries in the ID array are integers + foreach($ids as $value) { + if (!is_numeric($value)) { + throw new Exception('Invalid payload: id'); + } + } + $db->query('BEGIN TRANSACTION;'); - $stmt = $db->prepare('DELETE FROM client_by_group WHERE client_id=:id'); + // Delete from: client_by_group + $stmt = $db->prepare('DELETE FROM client_by_group WHERE client_id IN ('.implode(",",$ids).')'); if (!$stmt) { throw new Exception('While preparing client_by_group statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to client_by_group statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing client_by_group statement: ' . $db->lastErrorMsg()); } - $stmt = $db->prepare('DELETE FROM client WHERE id=:id'); + // Delete from: client + $stmt = $db->prepare('DELETE FROM client WHERE id IN ('.implode(",",$ids).')'); if (!$stmt) { throw new Exception('While preparing client statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to client statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing client statement: ' . $db->lastErrorMsg()); } @@ -847,30 +854,32 @@ function JSON_error($message = null) } elseif ($_POST['action'] == 'delete_domain') { // Delete domain identified by ID try { + $ids = json_decode($_POST['id']); + // Exploit prevention: Ensure all entries in the ID array are integers + foreach($ids as $value) { + if (!is_numeric($value)) { + throw new Exception('Invalid payload: id'); + } + } + $db->query('BEGIN TRANSACTION;'); - $stmt = $db->prepare('DELETE FROM domainlist_by_group WHERE domainlist_id=:id'); + // Delete from: domainlist_by_group + $stmt = $db->prepare('DELETE FROM domainlist_by_group WHERE domainlist_id IN ('.implode(",",$ids).')'); if (!$stmt) { throw new Exception('While preparing domainlist_by_group statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to domainlist_by_group statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing domainlist_by_group statement: ' . $db->lastErrorMsg()); } - $stmt = $db->prepare('DELETE FROM domainlist WHERE id=:id'); + // Delete from: domainlist + $stmt = $db->prepare('DELETE FROM domainlist WHERE id IN ('.implode(",",$ids).')'); if (!$stmt) { throw new Exception('While preparing domainlist statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to domainlist statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing domainlist statement: ' . $db->lastErrorMsg()); } @@ -1128,30 +1137,38 @@ function JSON_error($message = null) } elseif ($_POST['action'] == 'delete_adlist') { // Delete adlist identified by ID try { + // Accept only an array + $ids = json_decode($_POST['id']); + if (!is_array($ids)) { + throw new Exception('Invalid payload: id is not an array'); + } + + // Exploit prevention: Ensure all entries in the ID array are integers + foreach ($ids as $value) { + if (!is_numeric($value)) { + throw new Exception('Invalid payload: id contains non-numeric entries'); + } + } + $db->query('BEGIN TRANSACTION;'); - $stmt = $db->prepare('DELETE FROM adlist_by_group WHERE adlist_id=:id'); + // Delete from: adlists_by_group + $stmt = $db->prepare('DELETE FROM adlist_by_group WHERE adlist_id IN ('.implode(",",$ids).')'); + if (!$stmt) { throw new Exception('While preparing adlist_by_group statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to adlist_by_group statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing adlist_by_group statement: ' . $db->lastErrorMsg()); } - $stmt = $db->prepare('DELETE FROM adlist WHERE id=:id'); + // Delete from: adlists + $stmt = $db->prepare('DELETE FROM adlist WHERE id IN ('.implode(",",$ids).')'); if (!$stmt) { throw new Exception('While preparing adlist statement: ' . $db->lastErrorMsg()); } - if (!$stmt->bindValue(':id', intval($_POST['id']), SQLITE3_INTEGER)) { - throw new Exception('While binding id to adlist statement: ' . $db->lastErrorMsg()); - } - if (!$stmt->execute()) { throw new Exception('While executing adlist statement: ' . $db->lastErrorMsg()); } diff --git a/style/pi-hole.css b/style/pi-hole.css index 85960018b..5d1a35701 100644 --- a/style/pi-hole.css +++ b/style/pi-hole.css @@ -620,12 +620,12 @@ li:not(.menu-open) .treeview-menu .warning-count { } #domainsTable tr { display: flex; - padding: 15px 0; + padding: 5px 0; flex-wrap: wrap; box-sizing: border-box; align-items: end; border: 1px solid rgba(127, 127, 127, 0.4); - margin: 10px 0; + margin: 15px 0; border-radius: 6px; } #domainsTable td { @@ -634,14 +634,23 @@ li:not(.menu-open) .treeview-menu .warning-count { display: block; border: none; box-sizing: border-box; - order: 2; + order: 3; text-align: right; padding: 4px 8px; } - #domainsTable td:nth-child(2n) { + #domainsTable td:nth-child(2n + 1) { width: calc(100% - 120px); } - #domainsTable td:first-child { + #domainsTable td:nth-child(1) { + width: 40px; + order: 0; + text-align: left; + padding: 5px 0 30px; + border-bottom: 1px solid rgba(127, 127, 127, 0.25); + margin-bottom: 5px; + flex: 0 0 auto; + } + #domainsTable td:nth-child(2) { width: calc(100% - 40px); order: 1; text-align: left; @@ -651,13 +660,13 @@ li:not(.menu-open) .treeview-menu .warning-count { } #domainsTable td:last-child { width: 40px; - order: 1; + order: 0; padding-bottom: 10px; border-bottom: 1px solid rgba(127, 127, 127, 0.25); margin-bottom: 5px; } - #domainsTable td:nth-child(2), - #domainsTable td:nth-child(4) { + #domainsTable td:nth-child(3), + #domainsTable td:nth-child(5) { text-align: left; } #domainsTable td::before { @@ -665,12 +674,16 @@ li:not(.menu-open) .treeview-menu .warning-count { font-weight: bold; font-size: smaller; } - #domainsTable td:nth-child(2)::before { + #domainsTable td:nth-child(3)::before { content: "Type:"; } - #domainsTable td:nth-child(4)::before { + #domainsTable td:nth-child(5)::before { content: "Comment:"; } + #domainsTable tr.selected td.select-checkbox::after, + #domainsTable tr.selected th.select-checkbox::after { + transform: rotate(45deg) translate(5px, 1px); + } } @media screen and (min-width: 767px) { #domainsTable select.form-control { From d3aafaa30fed47b93b3057963d64159a560ab3ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 23 Apr 2022 14:07:37 +0200 Subject: [PATCH 06/85] Pass config file path when reloading pihole-FTL.conf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- settings.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.php b/settings.php index 420aae36e..200ac0605 100644 --- a/settings.php +++ b/settings.php @@ -10,7 +10,7 @@ require_once "scripts/pi-hole/php/FTL.php"; // Reread ini file as things might have been changed $setupVars = parse_ini_file("/etc/pihole/setupVars.conf"); -$piholeFTLConf = piholeFTLConfig(true); +$piholeFTLConf = piholeFTLConfig("/etc/pihole/pihole-FTL.conf" ,true); // Handling of PHP internal errors $last_error = error_get_last(); From a097d63b3ba69662f32f5b09c3fde2c6342b342f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sat, 23 Apr 2022 19:44:11 +0200 Subject: [PATCH 07/85] Use DEFAULT_FTLCONFFILE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- settings.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/settings.php b/settings.php index 200ac0605..3cf7f4238 100644 --- a/settings.php +++ b/settings.php @@ -9,8 +9,9 @@ require "scripts/pi-hole/php/savesettings.php"; require_once "scripts/pi-hole/php/FTL.php"; // Reread ini file as things might have been changed +// DEFAULT_FTLCONFFILE is set in "scripts/pi-hole/php/FTL.php"; $setupVars = parse_ini_file("/etc/pihole/setupVars.conf"); -$piholeFTLConf = piholeFTLConfig("/etc/pihole/pihole-FTL.conf" ,true); +$piholeFTLConf = piholeFTLConfig(DEFAULT_FTLCONFFILE ,true); // Handling of PHP internal errors $last_error = error_get_last(); From 4d6481ffa963dd4d1fe1fb49e6ecec0126728d30 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 24 Apr 2022 09:16:13 +0200 Subject: [PATCH 08/85] Add QUERY_SPECIAL_DOMAIN as new query status Signed-off-by: DL6ER --- scripts/pi-hole/js/db_queries.js | 7 ++++++- scripts/pi-hole/js/queries.js | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index aba0ea41b..91300be07 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -292,8 +292,13 @@ $(function () { "Blocked (database is busy)"; blocked = true; break; + case 16: + fieldtext = + "Blocked (special domain)"; + blocked = true; + break; default: - fieldtext = "Unknown"; + fieldtext = "Unknown (" + parseInt(data[4], 10) + ")"; } $(row).addClass(blocked === true ? "blocked-row" : "allowed-row"); diff --git a/scripts/pi-hole/js/queries.js b/scripts/pi-hole/js/queries.js index 851efd945..b603db661 100644 --- a/scripts/pi-hole/js/queries.js +++ b/scripts/pi-hole/js/queries.js @@ -218,6 +218,11 @@ $(function () { "Blocked (database is busy)"; blocked = true; break; + case "16": + fieldtext = + "Blocked (special domain)"; + blocked = true; + break; default: fieldtext = "Unknown (" + parseInt(data[4], 10) + ")"; } From c4481cacb5052dd8deb1ca42b160bd7e69e0221b Mon Sep 17 00:00:00 2001 From: DL6ER Date: Sun, 24 Apr 2022 15:52:40 +0200 Subject: [PATCH 09/85] Review comments Signed-off-by: DL6ER --- db_queries.php | 1 + scripts/pi-hole/js/db_queries.js | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/db_queries.php b/db_queries.php index 8ce45f10d..e283b01ca 100644 --- a/db_queries.php +++ b/db_queries.php @@ -56,6 +56,7 @@

    +

    diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 91300be07..f502dff49 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -146,6 +146,10 @@ function getQueryTypes() { queryType.push(15); } + if ($("#type_special_domain").prop("checked")) { + queryType.push(16); + } + return queryType.join(","); } @@ -184,7 +188,7 @@ function refreshTableData() { var APIstring = "api_db.php?getAllQueries&from=" + from + "&until=" + until; // Check if query type filtering is enabled var queryType = getQueryTypes(); - if (queryType !== "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15") { + if (queryType !== "1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16") { APIstring += "&types=" + queryType; } From 9113471054dd027f971a1de69aebb72ac4da272f Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 26 Apr 2022 13:07:58 -0300 Subject: [PATCH 10/85] Fix dropdown background color (dark theme) Signed-off-by: RD WebDesign --- style/themes/default-dark.css | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/style/themes/default-dark.css b/style/themes/default-dark.css index 63e39849c..252cfc8bf 100644 --- a/style/themes/default-dark.css +++ b/style/themes/default-dark.css @@ -503,6 +503,11 @@ fieldset[disabled] .form-control { background-color: #353c42; opacity: 1; } +.dropdown-menu { + background-color: #22282d; + color: #bec5cb; + border: 1px solid #4c5761; +} .navbar-custom-menu > .navbar-nav > li > .dropdown-menu { background-color: #4c5761; color: #bec5cb; From 0e04ba0fe4280dfb6aaf407102d76fc14a0d8f89 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 26 Apr 2022 15:02:13 -0300 Subject: [PATCH 11/85] Show "other" destination as the last graphic item - Show the item only if it's different than zero Signed-off-by: RD WebDesign --- scripts/pi-hole/js/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 9849d7aa1..7c9e3721d 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -538,8 +538,11 @@ function updateForwardDestinationsPie() { values.push([key, value, THEME_COLORS[i++ % THEME_COLORS.length]]); }); - // Move the "other" element to the end of the array - values.push(values.splice(values.indexOf("other"), 1)[0]); + // Show "Other" destination as the last graphic item and only if it's different than zero + var other = values.splice(values.findIndex(arr => arr.includes("other")), 1)[0]; + if (other[1] != 0) { + values.push(other); + } // Split data into individual arrays for the graphs values.forEach(function (value) { From a04fb0b7269bea0c05d02c6d5e3a3e20b7017c93 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 26 Apr 2022 15:20:43 -0300 Subject: [PATCH 12/85] Fix prettier Signed-off-by: RD WebDesign --- scripts/pi-hole/js/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 7c9e3721d..07c7aeb67 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -539,7 +539,10 @@ function updateForwardDestinationsPie() { }); // Show "Other" destination as the last graphic item and only if it's different than zero - var other = values.splice(values.findIndex(arr => arr.includes("other")), 1)[0]; + var other = values.splice( + values.findIndex(arr => arr.includes("other")), + 1 + )[0]; if (other[1] != 0) { values.push(other); } From 83ff9a9ee5d2849b5b91ed0ec6b10ae91291b702 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 26 Apr 2022 15:30:17 -0300 Subject: [PATCH 13/85] Fix `xo` Signed-off-by: RD WebDesign --- scripts/pi-hole/js/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 07c7aeb67..44f1a7f9a 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -543,7 +543,7 @@ function updateForwardDestinationsPie() { values.findIndex(arr => arr.includes("other")), 1 )[0]; - if (other[1] != 0) { + if (other[1] !== 0) { values.push(other); } From fae9e4b0be246fb088c3139a7b942a25744ad32a Mon Sep 17 00:00:00 2001 From: martinbrose <13284268+martinbrose@users.noreply.github.com> Date: Thu, 28 Apr 2022 05:19:43 +0100 Subject: [PATCH 14/85] =?UTF-8?q?Added=20information=20about=20group=20ass?= =?UTF-8?q?ignment=20of=20whitelisted/blacklisted=20d=E2=80=A6=20(#2186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added information about group assignment of whitelisted/blacklisted domains Signed-off-by: martinbrose <13284268+martinbrose@users.noreply.github.com> Co-authored-by: yubiuser Co-authored-by: Adam Warner --- groups-domains.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/groups-domains.php b/groups-domains.php index 3877c89a9..7724fb89a 100644 --- a/groups-domains.php +++ b/groups-domains.php @@ -88,6 +88,16 @@
    +
    - - - - -
    diff --git a/dns_records.php b/dns_records.php index 1782d1463..dcf9cf25e 100644 --- a/dns_records.php +++ b/dns_records.php @@ -1,12 +1,13 @@ - @@ -54,23 +55,6 @@
    - - - - -
    diff --git a/scripts/pi-hole/js/customcname.js b/scripts/pi-hole/js/customcname.js index 7645ebdc4..de0e1dab6 100644 --- a/scripts/pi-hole/js/customcname.js +++ b/scripts/pi-hole/js/customcname.js @@ -10,35 +10,6 @@ var table; var token = $("#token").text(); -function showAlert(type, message) { - var alertElement = null; - var messageElement = null; - - switch (type) { - case "info": - alertElement = $("#alInfo"); - break; - case "success": - alertElement = $("#alSuccess"); - break; - case "warning": - alertElement = $("#alWarning"); - messageElement = $("#warn"); - break; - case "error": - alertElement = $("#alFailure"); - messageElement = $("#err"); - break; - default: - return; - } - - if (messageElement !== null) messageElement.html(message); - - alertElement.fadeIn(200); - alertElement.delay(8000).fadeOut(2000); -} - $(function () { $("#btnAdd").on("click", addCustomCNAME); @@ -99,19 +70,26 @@ function addCustomCNAME() { var domain = utils.escapeHtml($("#domain").val()); var target = utils.escapeHtml($("#target").val()); - showAlert("info"); + utils.disableAll(); + utils.showAlert("info", "", "Adding custom CNAME record...", ""); + $.ajax({ url: "scripts/pi-hole/php/customcname.php", method: "post", dataType: "json", data: { action: "add", domain: domain, target: target, token: token }, success: function (response) { + utils.enableAll(); if (response.success) { - showAlert("success"); + utils.showAlert("success", "far fa-check-circle", "Custom CNAME added", domain + ": " + target); table.ajax.reload(); - } else showAlert("error", response.message); + } else { + utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); + } }, error: function () { + utils.enableAll(); + utils.showAlert("error", "fas fa-times", "Error while adding custom CNAME record", ""); showAlert("error", "Error while adding this custom CNAME record"); }, }); @@ -121,20 +99,26 @@ function deleteCustomCNAME() { var domain = $(this).attr("data-domain"); var target = $(this).attr("data-target"); - showAlert("info"); + utils.disableAll(); + utils.showAlert("info", "", "Deleting custom CNAME record...", ""); + $.ajax({ url: "scripts/pi-hole/php/customcname.php", method: "post", dataType: "json", data: { action: "delete", domain: domain, target: target, token: token }, success: function (response) { + utils.enableAll(); if (response.success) { - showAlert("success"); + utils.showAlert("success", "far fa-check-circle", "Custom CNAME deleted", domain + ": " + target); table.ajax.reload(); - } else showAlert("error", response.message); + } else { + utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); + } }, error: function (jqXHR, exception) { - showAlert("error", "Error while deleting this custom CNAME record"); + utils.enableAll(); + utils.showAlert("error", "fas fa-times", "Error while deleting custom CNAME record", ""); console.log(exception); // eslint-disable-line no-console }, }); diff --git a/scripts/pi-hole/js/customdns.js b/scripts/pi-hole/js/customdns.js index c0e1d9f77..5043520b5 100644 --- a/scripts/pi-hole/js/customdns.js +++ b/scripts/pi-hole/js/customdns.js @@ -10,35 +10,6 @@ var table; var token = $("#token").text(); -function showAlert(type, message) { - var alertElement = null; - var messageElement = null; - - switch (type) { - case "info": - alertElement = $("#alInfo"); - break; - case "success": - alertElement = $("#alSuccess"); - break; - case "warning": - alertElement = $("#alWarning"); - messageElement = $("#warn"); - break; - case "error": - alertElement = $("#alFailure"); - messageElement = $("#err"); - break; - default: - return; - } - - if (messageElement !== null) messageElement.html(message); - - alertElement.fadeIn(200); - alertElement.delay(8000).fadeOut(2000); -} - $(function () { $("#btnAdd").on("click", addCustomDNS); @@ -98,20 +69,26 @@ function addCustomDNS() { var ip = utils.escapeHtml($("#ip").val()); var domain = utils.escapeHtml($("#domain").val()); - showAlert("info"); + utils.disableAll(); + utils.showAlert("info", "", "Adding custom DNS entry...", ""); + $.ajax({ url: "scripts/pi-hole/php/customdns.php", method: "post", dataType: "json", data: { action: "add", ip: ip, domain: domain, token: token }, success: function (response) { + utils.enableAll(); if (response.success) { - showAlert("success"); + utils.showAlert("success", "far fa-check-circle", "Custom DNS added", domain + ": " + ip); table.ajax.reload(); - } else showAlert("error", response.message); + } else { + utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); + } }, error: function () { - showAlert("error", "Error while adding this custom DNS entry"); + utils.enableAll(); + utils.showAlert("error", "fas fa-times", "Error while adding custom DNS entry", ""); }, }); } @@ -120,20 +97,26 @@ function deleteCustomDNS() { var ip = $(this).attr("data-ip"); var domain = $(this).attr("data-domain"); - showAlert("info"); + utils.disableAll(); + utils.showAlert("info", "", "Deleting custom DNS entry...", ""); + $.ajax({ url: "scripts/pi-hole/php/customdns.php", method: "post", dataType: "json", data: { action: "delete", domain: domain, ip: ip, token: token }, success: function (response) { + utils.enableAll(); if (response.success) { - showAlert("success"); + utils.showAlert("success", "far fa-check-circle", "Custom DNS deleted", domain + ": " + ip); table.ajax.reload(); - } else showAlert("error", response.message); + } else { + utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); + } }, error: function (jqXHR, exception) { - showAlert("error", "Error while deleting this custom DNS entry"); + utils.enableAll(); + utils.showAlert("error", "fas fa-times", "Error while deleting custom DNS entry", ""); console.log(exception); // eslint-disable-line no-console }, }); From d0b9588fff250e2b5062e32acfabd2e412c57fb3 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 16 May 2022 01:50:05 -0300 Subject: [PATCH 31/85] Fix prettier Signed-off-by: RD WebDesign --- scripts/pi-hole/js/customcname.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/js/customcname.js b/scripts/pi-hole/js/customcname.js index de0e1dab6..0248ab5c9 100644 --- a/scripts/pi-hole/js/customcname.js +++ b/scripts/pi-hole/js/customcname.js @@ -81,7 +81,12 @@ function addCustomCNAME() { success: function (response) { utils.enableAll(); if (response.success) { - utils.showAlert("success", "far fa-check-circle", "Custom CNAME added", domain + ": " + target); + utils.showAlert( + "success", + "far fa-check-circle", + "Custom CNAME added", + domain + ": " + target + ); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); @@ -110,7 +115,12 @@ function deleteCustomCNAME() { success: function (response) { utils.enableAll(); if (response.success) { - utils.showAlert("success", "far fa-check-circle", "Custom CNAME deleted", domain + ": " + target); + utils.showAlert( + "success", + "far fa-check-circle", + "Custom CNAME deleted", + domain + ": " + target + ); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); From 7cb2231bdd2a1d0dff44eca7998fdc64fc3db8b4 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 16 May 2022 01:53:11 -0300 Subject: [PATCH 32/85] Removing old function call Signed-off-by: RD WebDesign --- scripts/pi-hole/js/customcname.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/pi-hole/js/customcname.js b/scripts/pi-hole/js/customcname.js index 0248ab5c9..09556695d 100644 --- a/scripts/pi-hole/js/customcname.js +++ b/scripts/pi-hole/js/customcname.js @@ -95,7 +95,6 @@ function addCustomCNAME() { error: function () { utils.enableAll(); utils.showAlert("error", "fas fa-times", "Error while adding custom CNAME record", ""); - showAlert("error", "Error while adding this custom CNAME record"); }, }); } From d12ec5f88537e8e8724208eddc6929df59cb3a3f Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 17 May 2022 15:54:01 -0300 Subject: [PATCH 33/85] Clean text fields after success. Signed-off-by: RD WebDesign --- scripts/pi-hole/js/customcname.js | 8 ++++++++ scripts/pi-hole/js/customdns.js | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/scripts/pi-hole/js/customcname.js b/scripts/pi-hole/js/customcname.js index 09556695d..e78e4a7ea 100644 --- a/scripts/pi-hole/js/customcname.js +++ b/scripts/pi-hole/js/customcname.js @@ -87,6 +87,10 @@ function addCustomCNAME() { "Custom CNAME added", domain + ": " + target ); + + // Clean up field values and reload table data + $("#domain").val(""); + $("#target").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); @@ -120,6 +124,10 @@ function deleteCustomCNAME() { "Custom CNAME deleted", domain + ": " + target ); + + // Clean up field values and reload table data + $("#domain").val(""); + $("#target").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); diff --git a/scripts/pi-hole/js/customdns.js b/scripts/pi-hole/js/customdns.js index 5043520b5..865f54b02 100644 --- a/scripts/pi-hole/js/customdns.js +++ b/scripts/pi-hole/js/customdns.js @@ -81,6 +81,10 @@ function addCustomDNS() { utils.enableAll(); if (response.success) { utils.showAlert("success", "far fa-check-circle", "Custom DNS added", domain + ": " + ip); + + // Clean up field values and reload table data + $("#domain").val(""); + $("#id").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); @@ -109,6 +113,10 @@ function deleteCustomDNS() { utils.enableAll(); if (response.success) { utils.showAlert("success", "far fa-check-circle", "Custom DNS deleted", domain + ": " + ip); + + // Clean up field values and reload table data + $("#domain").val(""); + $("#id").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); From e9f638a888752ae6612ea32258b4542dcb40f2a2 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 17 May 2022 16:33:44 -0300 Subject: [PATCH 34/85] Keep field values when deleting + Fix typo Signed-off-by: RD WebDesign --- scripts/pi-hole/js/customcname.js | 4 ---- scripts/pi-hole/js/customdns.js | 6 +----- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/scripts/pi-hole/js/customcname.js b/scripts/pi-hole/js/customcname.js index e78e4a7ea..e0f317602 100644 --- a/scripts/pi-hole/js/customcname.js +++ b/scripts/pi-hole/js/customcname.js @@ -124,10 +124,6 @@ function deleteCustomCNAME() { "Custom CNAME deleted", domain + ": " + target ); - - // Clean up field values and reload table data - $("#domain").val(""); - $("#target").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); diff --git a/scripts/pi-hole/js/customdns.js b/scripts/pi-hole/js/customdns.js index 865f54b02..b87828835 100644 --- a/scripts/pi-hole/js/customdns.js +++ b/scripts/pi-hole/js/customdns.js @@ -84,7 +84,7 @@ function addCustomDNS() { // Clean up field values and reload table data $("#domain").val(""); - $("#id").val(""); + $("#ip").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); @@ -113,10 +113,6 @@ function deleteCustomDNS() { utils.enableAll(); if (response.success) { utils.showAlert("success", "far fa-check-circle", "Custom DNS deleted", domain + ": " + ip); - - // Clean up field values and reload table data - $("#domain").val(""); - $("#id").val(""); table.ajax.reload(); } else { utils.showAlert("error", "fas fa-times", "Failure! Something went wrong", response.message); From 522d05ad9ca1fd3c72764254e9050fc7a1e7c6a4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 21 May 2022 10:04:38 +0000 Subject: [PATCH 35/85] Bump xo from 0.48.0 to 0.49.0 Bumps [xo](https://github.com/xojs/xo) from 0.48.0 to 0.49.0. - [Release notes](https://github.com/xojs/xo/releases) - [Commits](https://github.com/xojs/xo/compare/v0.48.0...v0.49.0) --- updated-dependencies: - dependency-name: xo dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 517 ++++++++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 294 insertions(+), 225 deletions(-) diff --git a/package-lock.json b/package-lock.json index ae4ce750e..7a1b7a1c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,9 @@ "dev": true }, "@babel/highlight": { - "version": "7.16.10", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.16.10.tgz", - "integrity": "sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==", + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", + "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.16.7", @@ -31,34 +31,34 @@ } }, "@eslint/eslintrc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.1.0.tgz", - "integrity": "sha512-C1DfL7XX4nPqGd6jcP01W9pVM1HYCuUkFk1432D7F0v3JSlUIeOYn9oCoi3eoLZ+iwBSb29BMFxxny0YrrEZqg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz", + "integrity": "sha512-UWW0TMTmk2d7hLcWD1/e2g5HDM/HQ3csaLSqXCfqwh4uNDuNqlaKWXmEsL4Cs41Z0KnILNvwbHAah3C2yt06kw==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.3.1", - "globals": "^13.9.0", - "ignore": "^4.0.6", + "espree": "^9.3.2", + "globals": "^13.15.0", + "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" }, "dependencies": { "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", "dev": true } } }, "@humanwhocodes/config-array": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.3.tgz", - "integrity": "sha512-3xSMlXHh03hCcCmFc0rbKp3Ivt2PFEJnQUJDDMTJQ2wkECZWdq4GePs2ctc5H8zV+cHPaq8k2vU8mrQjA6iHdQ==", + "version": "0.9.5", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz", + "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==", "dev": true, "requires": { "@humanwhocodes/object-schema": "^1.2.1", @@ -121,15 +121,15 @@ "dev": true }, "@types/json-schema": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.9.tgz", - "integrity": "sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==", + "version": "7.0.11", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", + "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", "dev": true }, "@types/minimist": { @@ -151,9 +151,9 @@ "dev": true }, "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", "dev": true }, "acorn-jsx": { @@ -225,18 +225,18 @@ "array-find": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", - "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "integrity": "sha512-kO/vVCacW9mnpn3WPWbTVlEnOabK2L7LWi2HViURtCM46y1zb6I8UMjx4LgbiqadTgHnLInUronwn3ampNTJtQ==", "dev": true }, "array-includes": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.4.tgz", - "integrity": "sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.5.tgz", + "integrity": "sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.1", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5", "get-intrinsic": "^1.1.1", "is-string": "^1.0.7" } @@ -248,14 +248,15 @@ "dev": true }, "array.prototype.flat": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz", - "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", "dev": true, "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" } }, "arrify": { @@ -373,11 +374,20 @@ } }, "builtin-modules": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.2.0.tgz", - "integrity": "sha512-lGzLKcioL90C7wMczpkY0n/oART3MbBa8R9OFGE1rJxoVI86u4WAGfEk8Wjv10eKSyTHVGkSo3bvBylCEtk7LA==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", "dev": true }, + "builtins": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-4.1.0.tgz", + "integrity": "sha512-1bPRZQtmKaO6h7qV1YHXNtr6nCK28k0Zo95KM4dXfILcZZwoHJBN1m3lfLv9LPkcOZlrSr+J1bzMaZFO98Yq0w==", + "dev": true, + "requires": { + "semver": "^7.0.0" + } + }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -480,15 +490,15 @@ } }, "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", "dev": true }, "clean-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", - "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", "dev": true, "requires": { "escape-string-regexp": "^1.0.5" @@ -569,9 +579,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -620,12 +630,13 @@ "dev": true }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "dependency-graph": { @@ -685,9 +696,9 @@ } }, "env-editor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-1.0.0.tgz", - "integrity": "sha512-SRy6e7u1tZgohoxL952q9+kbRkkUrzi63dB7J4zr6wOSMQrCD0KJUNhMZajGTNQfdY68PaStfmIzh7To/FKilQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-1.1.0.tgz", + "integrity": "sha512-7AXskzN6T7Q9TFcKAGJprUbpQa4i1VsAetO9rdBqbGMGlragTziBgWt4pVYJMBWHQlLoX0buy6WFikzPH4Qjpw==", "dev": true }, "error-ex": { @@ -700,31 +711,43 @@ } }, "es-abstract": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.19.1.tgz", - "integrity": "sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "requires": { "call-bind": "^1.0.2", "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", "get-intrinsic": "^1.1.1", "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "has-symbols": "^1.0.2", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", "internal-slot": "^1.0.3", "is-callable": "^1.2.4", - "is-negative-zero": "^2.0.1", + "is-negative-zero": "^2.0.2", "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.1", + "is-shared-array-buffer": "^1.0.2", "is-string": "^1.0.7", - "is-weakref": "^1.0.1", - "object-inspect": "^1.11.0", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", "object-keys": "^1.1.1", "object.assign": "^4.1.2", - "string.prototype.trimend": "^1.0.4", - "string.prototype.trimstart": "^1.0.4", - "unbox-primitive": "^1.0.1" + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + } + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" } }, "es-to-primitive": { @@ -751,12 +774,12 @@ "dev": true }, "eslint": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.9.0.tgz", - "integrity": "sha512-PB09IGwv4F4b0/atrbcMFboF/giawbBLVC7fyDamk5Wtey4Jh2K+rYaBhCAbUyEI4QzB1ly09Uglc9iCtFaG2Q==", + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.16.0.tgz", + "integrity": "sha512-MBndsoXY/PeVTDJeWsYj7kLZ5hQpJOfMYLsF6LicLHQWbRDG19lK5jOix4DPl8yY4SUFcE3txy86OzFLWT+yoA==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.1.0", + "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", "ajv": "^6.10.0", "chalk": "^4.0.0", @@ -767,14 +790,14 @@ "eslint-scope": "^7.1.1", "eslint-utils": "^3.0.0", "eslint-visitor-keys": "^3.3.0", - "espree": "^9.3.1", + "espree": "^9.3.2", "esquery": "^1.4.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", - "globals": "^13.6.0", + "globals": "^13.15.0", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", @@ -783,7 +806,7 @@ "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.1", "regexpp": "^3.2.0", @@ -862,15 +885,15 @@ } }, "eslint-config-prettier": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz", - "integrity": "sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==", + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", + "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", "dev": true }, "eslint-config-xo": { - "version": "0.40.0", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.40.0.tgz", - "integrity": "sha512-msI1O0JGxeK2bbExg3U6EGaWKcjhOFzEjwzObywG/DC5GSNZTOyJT+b2l9MZGBeZsVdxfIGwdXTNeWXl8cN9iw==", + "version": "0.41.0", + "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.41.0.tgz", + "integrity": "sha512-cyTc182COQVdalOi5105h0Cw/Qb52IRGyIZLmUICIauANm9Upmv81UEsuFkdKnvwr4NtU95qjdk3g4/kNspA6g==", "dev": true, "requires": { "confusing-browser-globals": "1.0.11" @@ -1110,9 +1133,9 @@ } }, "eslint-plugin-import": { - "version": "2.25.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.25.4.tgz", - "integrity": "sha512-/KJBASVFxpu0xg1kIBn9AUa8hQVnszpwgE7Ld0lKAlx7Ie87yzEzCgSkekt+le/YVhiaosO4Y14GDAOc41nfxA==", + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", "dev": true, "requires": { "array-includes": "^3.1.4", @@ -1120,14 +1143,14 @@ "debug": "^2.6.9", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.2", + "eslint-module-utils": "^2.7.3", "has": "^1.0.3", - "is-core-module": "^2.8.0", + "is-core-module": "^2.8.1", "is-glob": "^4.0.3", - "minimatch": "^3.0.4", + "minimatch": "^3.1.2", "object.values": "^1.1.5", - "resolve": "^1.20.0", - "tsconfig-paths": "^3.12.0" + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" }, "dependencies": { "debug": { @@ -1224,9 +1247,9 @@ } }, "eslint-plugin-unicorn": { - "version": "40.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-40.1.0.tgz", - "integrity": "sha512-y5doK2DF9Sr5AqKEHbHxjFllJ167nKDRU01HDcWyv4Tnmaoe9iNxMrBnaybZvWZUaE3OC5Unu0lNIevYamloig==", + "version": "42.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-42.0.0.tgz", + "integrity": "sha512-ixBsbhgWuxVaNlPTT8AyfJMlhyC5flCJFjyK3oKE8TRrwBnaHvUbuIkCM1lqg8ryYrFStL/T557zfKzX4GKSlg==", "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.15.7", @@ -1285,19 +1308,23 @@ "dev": true }, "esm-utils": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/esm-utils/-/esm-utils-2.2.0.tgz", - "integrity": "sha512-kYj4yNRo4W3by0f1mj4AfRh1nsRTTpQG921Ik3AfyUq6upGlkI1fnMLypHn6XtFzZPdCYH1k9mtQA5MyZF9m+w==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/esm-utils/-/esm-utils-4.0.0.tgz", + "integrity": "sha512-1x5H25/8BQWV94T8+KRb1gcSdVQ3g+8P0NikggAujVaurUa0cOoR+UO8ie3y29iQO70HjNA93c9ie+qqI/8zzw==", + "dev": true, + "requires": { + "import-meta-resolve": "1.1.1", + "url-or-path": "2.1.0" + } }, "espree": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.1.tgz", - "integrity": "sha512-bvdyLmJMfwkV3NCRl5ZhJf22zBFo1y8bYh3VYb+bfzqNB4Je68P2sSuXyuFquzWLebHpNd2/d5uv7yoP9ISnGQ==", + "version": "9.3.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz", + "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==", "dev": true, "requires": { - "acorn": "^8.7.0", - "acorn-jsx": "^5.3.1", + "acorn": "^8.7.1", + "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.3.0" } }, @@ -1551,12 +1578,30 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1603,15 +1648,15 @@ } }, "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -1626,9 +1671,9 @@ } }, "globals": { - "version": "13.12.1", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz", - "integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==", + "version": "13.15.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.15.0.tgz", + "integrity": "sha512-bpzcOlgDhMG070Av0Vy5Owklpv1I6+j96GhUI7Rh7IzDCKLzboflLrrfqMu8NquDbiR4EOQk7XzJwqVJxicxog==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -1670,9 +1715,9 @@ } }, "has-bigints": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", - "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", "dev": true }, "has-flag": { @@ -1681,10 +1726,19 @@ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true }, + "has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } + }, "has-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, "has-tostringtag": { @@ -1750,6 +1804,15 @@ "resolve-from": "^5.0.0" } }, + "import-meta-resolve": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-1.1.1.tgz", + "integrity": "sha512-JiTuIvVyPaUg11eTrNDx5bgQ/yMKMZffc7YSjvQeSMXy58DO2SQ8BtAf3xteZvmzvjYh14wnqNjL8XVeDy2o9A==", + "dev": true, + "requires": { + "builtins": "^4.0.0" + } + }, "import-modules": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-2.1.0.tgz", @@ -1867,9 +1930,9 @@ "dev": true }, "is-core-module": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", - "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", "dev": true, "requires": { "has": "^1.0.3" @@ -1949,9 +2012,9 @@ "dev": true }, "is-number-object": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.6.tgz", - "integrity": "sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", "dev": true, "requires": { "has-tostringtag": "^1.0.0" @@ -2003,10 +2066,13 @@ } }, "is-shared-array-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz", - "integrity": "sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } }, "is-stream": { "version": "2.0.1", @@ -2117,13 +2183,10 @@ "dev": true }, "json5": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", - "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", + "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "dev": true }, "jsonfile": { "version": "6.1.0", @@ -2167,9 +2230,9 @@ }, "dependencies": { "type-fest": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.11.2.tgz", - "integrity": "sha512-reW2Y2Mpn0QNA/5fvtm5doROLwDPu2zOm5RtY7xQQS05Q7xgC8MOZ3yPNaP9m/s/sNjjFQtHo7VCNqYW2iI+Ig==", + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.12.2.tgz", + "integrity": "sha512-qt6ylCGpLjZ7AaODxbpyBZSs9fCI9SkL3Z9q2oxMBQhs/uyY+VD8jHA8ULCGmWQJlBgqvO3EJeAngOHD8zQCrQ==", "dev": true } } @@ -2437,9 +2500,9 @@ "dev": true }, "minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -2465,7 +2528,7 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", "dev": true } } @@ -2536,9 +2599,9 @@ } }, "obj-props": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.3.0.tgz", - "integrity": "sha512-k2Xkjx5wn6eC3537SWAXHzB6lkI81kS+icMKMkh4nG3w7shWG6MaWOBrNvhWVOszrtL5uxdfymQQfPUxwY+2eg==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.4.0.tgz", + "integrity": "sha512-p7p/7ltzPDiBs6DqxOrIbtRdwxxVRBj5ROukeNb9RgA+fawhrz5n2hpNz8DDmYR//tviJSj7nUnlppGmONkjiQ==", "dev": true }, "object-inspect": { @@ -3002,6 +3065,17 @@ "integrity": "sha512-s2aEVuLhvnVJW6s/iPgEGK6R+/xngd2jNQ+xy4bXNDKxZKJH6jpPHY6kVeVv1IeLCHgswRj+Kl3ELaDjG6V1iw==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "regexpp": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", @@ -3161,23 +3235,25 @@ } }, "string.prototype.trimend": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", - "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "string.prototype.trimstart": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", - "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", "dev": true, "requires": { "call-bind": "^1.0.2", - "define-properties": "^1.1.3" + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { @@ -3296,14 +3372,14 @@ "dev": true }, "tsconfig-paths": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.12.0.tgz", - "integrity": "sha512-e5adrnOYT6zqVnWqZu7i/BQ3BnhzvGbjEjejFXO20lKIKpwTaupkCPgEfv4GZK1IBciJUEhYs3J3p75FdaTFVg==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", "dev": true, "requires": { "@types/json5": "^0.0.29", "json5": "^1.0.1", - "minimist": "^1.2.0", + "minimist": "^1.2.6", "strip-bom": "^3.0.0" }, "dependencies": { @@ -3334,20 +3410,20 @@ "dev": true }, "typescript": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz", - "integrity": "sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==", + "version": "4.6.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.4.tgz", + "integrity": "sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==", "dev": true }, "unbox-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", - "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has-bigints": "^1.0.1", - "has-symbols": "^1.0.2", + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", "which-boxed-primitive": "^1.0.2" } }, @@ -3372,6 +3448,12 @@ "punycode": "^2.1.0" } }, + "url-or-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/url-or-path/-/url-or-path-2.1.0.tgz", + "integrity": "sha512-dsBD6GbytSMj9YDb3jVzSRENwFh50oUORnWBeSHfo0Lnwv2KMm/J4npyGy1P9rivUPsUGLjTA53XqAFqpe0nww==", + "dev": true + }, "v8-compile-cache": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", @@ -3434,47 +3516,47 @@ "dev": true }, "xo": { - "version": "0.48.0", - "resolved": "https://registry.npmjs.org/xo/-/xo-0.48.0.tgz", - "integrity": "sha512-f0sbQGJoML3nwOLG7EIAJroBypmLokoGJqTPN+bI/oogKLMciqWBEiFh9Vpxnfwxafq1AkHoWrQZQWSflDCG1w==", + "version": "0.49.0", + "resolved": "https://registry.npmjs.org/xo/-/xo-0.49.0.tgz", + "integrity": "sha512-dDj1bYy3LJ/8C2XItw/lFVckZtO68C2YCx9TR8xfSLVcmael3y0SkeFse/3OMUPMvG5jG44bQ2CAI6wFTpRqVg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.0.5", + "@eslint/eslintrc": "^1.2.3", "@typescript-eslint/eslint-plugin": "*", "@typescript-eslint/parser": "*", "arrify": "^3.0.0", "cosmiconfig": "^7.0.1", "define-lazy-prop": "^3.0.0", - "eslint": "^8.8.0", - "eslint-config-prettier": "^8.3.0", - "eslint-config-xo": "^0.40.0", + "eslint": "^8.15.0", + "eslint-config-prettier": "^8.5.0", + "eslint-config-xo": "^0.41.0", "eslint-config-xo-typescript": "*", "eslint-formatter-pretty": "^4.1.0", "eslint-import-resolver-webpack": "^0.13.2", "eslint-plugin-ava": "^13.2.0", "eslint-plugin-eslint-comments": "^3.2.0", - "eslint-plugin-import": "^2.25.4", + "eslint-plugin-import": "^2.26.0", "eslint-plugin-no-use-extend-native": "^0.5.0", "eslint-plugin-node": "^11.1.0", "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-unicorn": "^40.1.0", - "esm-utils": "^2.0.1", + "eslint-plugin-unicorn": "^42.0.0", + "esm-utils": "^4.0.0", "find-cache-dir": "^3.3.2", "find-up": "^6.3.0", "get-stdin": "^9.0.0", "globby": "^13.1.1", "imurmurhash": "^0.1.4", "json-stable-stringify-without-jsonify": "^1.0.1", - "json5": "^2.2.0", + "json5": "^2.2.1", "lodash-es": "^4.17.21", "meow": "^10.1.2", - "micromatch": "^4.0.4", + "micromatch": "^4.0.5", "open-editor": "^4.0.0", - "prettier": "^2.5.1", - "semver": "^7.3.5", + "prettier": "^2.6.2", + "semver": "^7.3.7", "slash": "^4.0.0", "to-absolute-glob": "^2.0.2", - "typescript": "^4.5.5" + "typescript": "^4.6.4" }, "dependencies": { "@nodelib/fs.scandir": { @@ -3501,79 +3583,72 @@ } }, "@types/json-schema": { - "version": "7.0.9", + "version": "7.0.11", "bundled": true, "dev": true }, "@typescript-eslint/eslint-plugin": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/type-utils": "5.11.0", - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", + "@typescript-eslint/scope-manager": "5.24.0", + "@typescript-eslint/type-utils": "5.24.0", + "@typescript-eslint/utils": "5.24.0", + "debug": "^4.3.4", "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", + "ignore": "^5.2.0", "regexpp": "^3.2.0", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" - }, - "dependencies": { - "ignore": { - "version": "5.2.0", - "bundled": true, - "dev": true - } } }, "@typescript-eslint/parser": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", - "debug": "^4.3.2" + "@typescript-eslint/scope-manager": "5.24.0", + "@typescript-eslint/types": "5.24.0", + "@typescript-eslint/typescript-estree": "5.24.0", + "debug": "^4.3.4" } }, "@typescript-eslint/scope-manager": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0" + "@typescript-eslint/types": "5.24.0", + "@typescript-eslint/visitor-keys": "5.24.0" } }, "@typescript-eslint/type-utils": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/utils": "5.11.0", - "debug": "^4.3.2", + "@typescript-eslint/utils": "5.24.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" } }, "@typescript-eslint/types": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/visitor-keys": "5.11.0", - "debug": "^4.3.2", - "globby": "^11.0.4", + "@typescript-eslint/types": "5.24.0", + "@typescript-eslint/visitor-keys": "5.24.0", + "debug": "^4.3.4", + "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.5", + "semver": "^7.3.7", "tsutils": "^3.21.0" }, "dependencies": { @@ -3590,11 +3665,6 @@ "slash": "^3.0.0" } }, - "ignore": { - "version": "5.2.0", - "bundled": true, - "dev": true - }, "slash": { "version": "3.0.0", "bundled": true, @@ -3603,25 +3673,25 @@ } }, "@typescript-eslint/utils": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.11.0", - "@typescript-eslint/types": "5.11.0", - "@typescript-eslint/typescript-estree": "5.11.0", + "@typescript-eslint/scope-manager": "5.24.0", + "@typescript-eslint/types": "5.24.0", + "@typescript-eslint/typescript-estree": "5.24.0", "eslint-scope": "^5.1.1", "eslint-utils": "^3.0.0" } }, "@typescript-eslint/visitor-keys": { - "version": "5.11.0", + "version": "5.24.0", "bundled": true, "dev": true, "requires": { - "@typescript-eslint/types": "5.11.0", - "eslint-visitor-keys": "^3.0.0" + "@typescript-eslint/types": "5.24.0", + "eslint-visitor-keys": "^3.3.0" } }, "array-union": { @@ -3638,7 +3708,7 @@ } }, "debug": { - "version": "4.3.3", + "version": "4.3.4", "bundled": true, "dev": true, "requires": { @@ -3661,7 +3731,7 @@ } }, "eslint-config-xo-typescript": { - "version": "0.50.0", + "version": "0.51.1", "bundled": true, "dev": true }, @@ -3697,7 +3767,7 @@ } }, "eslint-visitor-keys": { - "version": "3.2.0", + "version": "3.3.0", "bundled": true, "dev": true }, @@ -3780,8 +3850,7 @@ }, "ignore": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "bundled": true, "dev": true }, "is-extglob": { @@ -3825,12 +3894,12 @@ "dev": true }, "micromatch": { - "version": "4.0.4", + "version": "4.0.5", "bundled": true, "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "p-limit": { @@ -3891,7 +3960,7 @@ } }, "semver": { - "version": "7.3.5", + "version": "7.3.7", "bundled": true, "dev": true, "requires": { diff --git a/package.json b/package.json index 231e24c44..ac6558309 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "postcss": "^8.4.12", "postcss-cli": "^9.1.0", "prettier": "2.6.2", - "xo": "^0.48.0" + "xo": "^0.49.0" }, "browserslist": [ "defaults", From 3d42934e62a2080086c31362c1dce3cb4c62b7f8 Mon Sep 17 00:00:00 2001 From: yubiuser Date: Sat, 21 May 2022 18:27:53 +0200 Subject: [PATCH 36/85] Remove unused case --- scripts/pi-hole/js/groups-adlists.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/pi-hole/js/groups-adlists.js b/scripts/pi-hole/js/groups-adlists.js index 5ecc0b9ba..be37a9035 100644 --- a/scripts/pi-hole/js/groups-adlists.js +++ b/scripts/pi-hole/js/groups-adlists.js @@ -172,7 +172,6 @@ function initTable() { case 4: statusIcon = "fa-times"; break; - case 0: default: statusIcon = "fa-question-circle"; break; From 0ee25345a8838ae6fbaf44c88592f9a22786e6ac Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 22 May 2022 02:36:41 -0300 Subject: [PATCH 37/85] Remove empty line before PHP opening tag Signed-off-by: RD WebDesign --- scripts/pi-hole/php/network.php | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/pi-hole/php/network.php b/scripts/pi-hole/php/network.php index b3f6dd7c7..02af7b2d2 100644 --- a/scripts/pi-hole/php/network.php +++ b/scripts/pi-hole/php/network.php @@ -1,4 +1,3 @@ - Date: Sun, 22 May 2022 12:13:48 +0000 Subject: [PATCH 38/85] Bump postcss from 8.4.12 to 8.4.14 Bumps [postcss](https://github.com/postcss/postcss) from 8.4.12 to 8.4.14. - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss/compare/8.4.12...8.4.14) --- updated-dependencies: - dependency-name: postcss dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 14 +++++++------- package.json | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7a1b7a1c7..cf6bd4bce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2540,9 +2540,9 @@ "dev": true }, "nanoid": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz", - "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==", + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", "dev": true }, "natural-compare": { @@ -2820,12 +2820,12 @@ "dev": true }, "postcss": { - "version": "8.4.12", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz", - "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==", + "version": "8.4.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", + "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", "dev": true, "requires": { - "nanoid": "^3.3.1", + "nanoid": "^3.3.4", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } diff --git a/package.json b/package.json index ac6558309..8dc97b153 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "devDependencies": { "autoprefixer": "^10.4.4", "eslint-plugin-compat": "^4.0.2", - "postcss": "^8.4.12", + "postcss": "^8.4.14", "postcss-cli": "^9.1.0", "prettier": "2.6.2", "xo": "^0.49.0" From 4795aaf4acd3ab37fb55f6ec79c83daaa18936c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 May 2022 15:39:45 +0000 Subject: [PATCH 39/85] Bump autoprefixer from 10.4.4 to 10.4.7 Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.4 to 10.4.7. - [Release notes](https://github.com/postcss/autoprefixer/releases) - [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md) - [Commits](https://github.com/postcss/autoprefixer/compare/10.4.4...10.4.7) --- updated-dependencies: - dependency-name: autoprefixer dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 40 ++++++++++++++++++++-------------------- package.json | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/package-lock.json b/package-lock.json index cf6bd4bce..d902e727a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -283,13 +283,13 @@ } }, "autoprefixer": { - "version": "10.4.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.4.tgz", - "integrity": "sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA==", + "version": "10.4.7", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz", + "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==", "dev": true, "requires": { - "browserslist": "^4.20.2", - "caniuse-lite": "^1.0.30001317", + "browserslist": "^4.20.3", + "caniuse-lite": "^1.0.30001335", "fraction.js": "^4.2.0", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", @@ -297,34 +297,34 @@ }, "dependencies": { "browserslist": { - "version": "4.20.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz", - "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==", + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001317", - "electron-to-chromium": "^1.4.84", + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", "escalade": "^3.1.1", - "node-releases": "^2.0.2", + "node-releases": "^2.0.3", "picocolors": "^1.0.0" } }, "caniuse-lite": { - "version": "1.0.30001319", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz", - "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==", + "version": "1.0.30001342", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001342.tgz", + "integrity": "sha512-bn6sOCu7L7jcbBbyNhLg0qzXdJ/PMbybZTH/BA6Roet9wxYRm6Tr9D0s0uhLkOZ6MSG+QU6txUgdpr3MXIVqjA==", "dev": true }, "electron-to-chromium": { - "version": "1.4.88", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.88.tgz", - "integrity": "sha512-oA7mzccefkvTNi9u7DXmT0LqvhnOiN2BhSrKerta7HeUC1cLoIwtbf2wL+Ah2ozh5KQd3/1njrGrwDBXx6d14Q==", + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", "dev": true }, "node-releases": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz", - "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", "dev": true } } diff --git a/package.json b/package.json index 8dc97b153..d692bdd73 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,7 @@ "testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo" }, "devDependencies": { - "autoprefixer": "^10.4.4", + "autoprefixer": "^10.4.7", "eslint-plugin-compat": "^4.0.2", "postcss": "^8.4.14", "postcss-cli": "^9.1.0", From db8ccf4a24b0f7d5fc144984497c75701e08706e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 24 May 2022 10:08:13 +0200 Subject: [PATCH 40/85] Drop IE 11 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d692bdd73..271859b9e 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ }, "browserslist": [ "defaults", - "Explorer >= 11" + "not IE 11" ], "prettier": { "arrowParens": "avoid", From 7cfca502bc950840ebea34e5627ed880382c8324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 24 May 2022 11:12:47 +0200 Subject: [PATCH 41/85] Remove unused eslint compat rule MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- scripts/pi-hole/js/debug.js | 1 - scripts/pi-hole/js/gravity.js | 1 - scripts/pi-hole/js/queryads.js | 1 - 3 files changed, 3 deletions(-) diff --git a/scripts/pi-hole/js/debug.js b/scripts/pi-hole/js/debug.js index 14ed46be3..d1699cf1e 100644 --- a/scripts/pi-hole/js/debug.js +++ b/scripts/pi-hole/js/debug.js @@ -29,7 +29,6 @@ function eventsource() { return; } - // eslint-disable-next-line compat/compat var source = new EventSource("scripts/pi-hole/php/debug.php?&token=" + token + "&" + checked); // Reset and show field diff --git a/scripts/pi-hole/js/gravity.js b/scripts/pi-hole/js/gravity.js index 90f02c080..993dddbac 100644 --- a/scripts/pi-hole/js/gravity.js +++ b/scripts/pi-hole/js/gravity.js @@ -17,7 +17,6 @@ function eventsource() { return; } - // eslint-disable-next-line compat/compat var source = new EventSource("scripts/pi-hole/php/gravity.sh.php"); ta.html(""); diff --git a/scripts/pi-hole/js/queryads.js b/scripts/pi-hole/js/queryads.js index a97eadd92..cb8625aca 100644 --- a/scripts/pi-hole/js/queryads.js +++ b/scripts/pi-hole/js/queryads.js @@ -53,7 +53,6 @@ function eventsource() { return; } - // eslint-disable-next-line compat/compat var source = new EventSource( "scripts/pi-hole/php/queryads.php?domain=" + domain.toLowerCase() + "&" + exact ); From a75e8fc1d31ab920b01a5efae69694c07d3e94b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Thu, 26 May 2022 23:34:52 +0200 Subject: [PATCH 42/85] Also check wildcard domains for validity before adding MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- scripts/pi-hole/php/groups.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/scripts/pi-hole/php/groups.php b/scripts/pi-hole/php/groups.php index 157fc50b3..4fdcdc88e 100644 --- a/scripts/pi-hole/php/groups.php +++ b/scripts/pi-hole/php/groups.php @@ -640,15 +640,9 @@ function verify_ID_array($arr) } } - if(isset($_POST['type']) && strlen($_POST['type']) === 2 && $_POST['type'][1] === 'W') - { - // Apply wildcard-style formatting - $domain = "(\\.|^)".str_replace(".","\\.",$domain)."$"; - } - - if($type === ListType::whitelist || $type === ListType::blacklist) + if( ! ($_POST['type'] == '2' || $_POST['type'] == '3')) { - // If adding to the exact lists, we convert the domain lower case and check whether it is valid + // If not adding a RegEx, we convert the domain lower case and check whether it is valid $domain = strtolower($domain); $msg = ""; if(!validDomain($domain, $msg)) @@ -664,6 +658,12 @@ function verify_ID_array($arr) } } + if(isset($_POST['type']) && strlen($_POST['type']) === 2 && $_POST['type'][1] === 'W') + { + // Apply wildcard-style formatting + $domain = "(\\.|^)".str_replace(".","\\.",$domain)."$"; + } + // First try to delete any occurrences of this domain if we're in // replace mode. Only do this when the domain to be replaced is in // the default group! Otherwise, we would shuffle group settings and @@ -996,7 +996,7 @@ function verify_ID_array($arr) if (!$stmt->execute()) { if ($db->lastErrorCode() == 19) { - // ErrorCode 19 is "Constraint violation", here the unique constraint of `address` + // ErrorCode 19 is "Constraint violation", here the unique constraint of `address` // is violated (https://www.sqlite.org/rescode.html#constraint). // If the list is already in database, add to ignored list, but don't throw error $ignored++; From 98a0e82946f678e664f0849ea8c5eb077039b8b9 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sat, 28 May 2022 18:40:23 -0300 Subject: [PATCH 43/85] Replace `queries` with `query_storage` - use client names, when available; - use column names instead of indexes; Signed-off-by: RD WebDesign --- api_db.php | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/api_db.php b/api_db.php index 3649b7685..9309721d2 100644 --- a/api_db.php +++ b/api_db.php @@ -64,7 +64,18 @@ { $from = intval($_GET["from"]); $until = intval($_GET["until"]); - $dbquery = "SELECT timestamp, type, domain, client, status, forward, reply_type, reply_time, dnssec FROM queries WHERE timestamp >= :from AND timestamp <= :until "; + + // Use table "query_storage" + // - replace domain ID with domain + // - replace client ID with client name + // - replace forward ID with forward destination + $dbquery = "SELECT timestamp, type,"; + $dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,"; + $dbquery .= " CASE typeof(client) WHEN 'integer' THEN (SELECT name FROM client_by_id c WHERE c.id = q.client) ELSE client END client,"; + $dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,"; + $dbquery .= " status, reply_type, reply_time, dnssec"; + $dbquery .= " FROM query_storage q"; + $dbquery .= " WHERE timestamp >= :from AND timestamp <= :until "; if(isset($_GET["types"])) { $types = $_GET["types"]; @@ -93,7 +104,7 @@ if (!is_bool($results)) { $first = true; - while ($row = $results->fetchArray()) { + while ($row = $results->fetchArray(SQLITE3_ASSOC)) { // Insert a comma before the next record (except on the first one) if (!$first) { echo ","; @@ -102,15 +113,16 @@ } // Format, encode, transform each field (if necessary). - $time = $row[0]; - $query_type = getQueryTypeStr($row[1]); // Convert query type ID to name - $domain = utf8_encode(str_replace("~"," ",$row[2])); - $client = $row[3]; - $status = $row[4]; - $destination = utf8_encode($row[5]); - $reply_type = $row[6]; - $reply_time = $row[7]; - $dnssec = $row[8]; + $time = $row["timestamp"]; + $query_type = getQueryTypeStr($row["type"]); // Convert query type ID to name + $domain = utf8_encode(str_replace("~"," ",$row["domain"])); + $client = $row["client"]; + $status = $row["status"]; + $destination = utf8_encode($row["forward"]); + $reply_type = $row["reply_type"]; + $reply_time = $row["reply_time"]; + $dnssec = $row["dnssec"]; + $client_id = $row["client_id"]; // Insert into array and output it in JSON format echo json_encode([$time, $query_type, $domain, $client, $status, $destination, $reply_type, $reply_time, $dnssec]); From 6300c551b0fc3c3b8addc3e5ff9f4d447432c40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Sun, 29 May 2022 21:18:01 +0200 Subject: [PATCH 44/85] Change lighttpd log file names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- scripts/pi-hole/js/db_queries.js | 2 +- scripts/pi-hole/php/auth.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index f502dff49..0d9a3ac30 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -84,7 +84,7 @@ function handleAjaxError(xhr, textStatus) { alert( "An unknown error occurred while loading the data.\n" + xhr.responseText + - "\nCheck the server's log files (/var/log/lighttpd/error.log) for details.\n\nYou may need to increase PHP memory limit." + + "\nCheck the server's log files (/var/log/lighttpd/error-pihole.log) for details.\n\nYou may need to increase PHP memory limit." + "\n\nYou can find more info in pi-hole's FAQ:\nhttps://docs.pi-hole.net/main/faq/#error-while-loading-data-from-the-long-term-database" ); } diff --git a/scripts/pi-hole/php/auth.php b/scripts/pi-hole/php/auth.php index fbf6b76ca..8bbf8342f 100644 --- a/scripts/pi-hole/php/auth.php +++ b/scripts/pi-hole/php/auth.php @@ -9,7 +9,7 @@ require_once('func.php'); $ERRORLOG = getenv('PHP_ERROR_LOG'); if (empty($ERRORLOG)) { - $ERRORLOG = '/var/log/lighttpd/error.log'; + $ERRORLOG = '/var/log/lighttpd/error-pihole.log'; if (!file_exists($ERRORLOG) || !is_writable($ERRORLOG)) { $ERRORLOG = '/var/log/apache2/error.log'; From da85d1b4e7d1f567dad33f134d2abf2f23e62bf0 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 29 May 2022 17:48:59 -0300 Subject: [PATCH 45/85] Use IP if there is no client name Signed-off-by: RD WebDesign --- api_db.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/api_db.php b/api_db.php index 9309721d2..20a4a0aca 100644 --- a/api_db.php +++ b/api_db.php @@ -71,7 +71,9 @@ // - replace forward ID with forward destination $dbquery = "SELECT timestamp, type,"; $dbquery .= " CASE typeof(domain) WHEN 'integer' THEN (SELECT domain FROM domain_by_id d WHERE d.id = q.domain) ELSE domain END domain,"; - $dbquery .= " CASE typeof(client) WHEN 'integer' THEN (SELECT name FROM client_by_id c WHERE c.id = q.client) ELSE client END client,"; + $dbquery .= " CASE typeof(client) WHEN 'integer' THEN ("; + $dbquery .= " SELECT CASE TRIM(name) WHEN '' THEN c.ip ELSE c.name END name FROM client_by_id c WHERE c.id = q.client"; + $dbquery .= " ) ELSE client END client,"; $dbquery .= " CASE typeof(forward) WHEN 'integer' THEN (SELECT forward FROM forward_by_id f WHERE f.id = q.forward) ELSE forward END forward,"; $dbquery .= " status, reply_type, reply_time, dnssec"; $dbquery .= " FROM query_storage q"; From 2dd5fb816bafb6f4e00dbf0e7338f4531bf8e941 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Sun, 29 May 2022 19:14:44 -0300 Subject: [PATCH 46/85] Fix DNSSEC info Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 7b9c6dc42..708c26e4c 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -230,19 +230,19 @@ $(function () { var replyid = parseInt(data[6], 10); var dnssecStatus; switch (data[8]) { - case "1": + case 1: dnssecStatus = '
    SECURE'; break; - case "2": + case 2: dnssecStatus = '
    INSECURE'; break; - case "3": + case 3: dnssecStatus = '
    BOGUS'; break; - case "4": + case 4: dnssecStatus = '
    ABANDONED'; break; - case "5": + case 5: dnssecStatus = '
    UNKNOWN'; break; default: @@ -270,7 +270,7 @@ $(function () { replyid === 0 ? "OK (sent to " : "OK (answered by "; - fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + dnssecStatus + ")"; + fieldtext += (data.length > 5 && data[5] !== "N/A" ? data[5] : "") + ")" + dnssecStatus; buttontext = ''; break; @@ -334,7 +334,7 @@ $(function () { break; case 14: fieldtext = - "OK (already forwarded)"; + "OK (already forwarded)" + dnssecStatus; buttontext = ''; break; From fad13b11517e93e6af1628f4afd47603210e1160 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 30 May 2022 01:11:52 -0300 Subject: [PATCH 47/85] Fixing prettier line break Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 708c26e4c..7dcae4b06 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -334,7 +334,8 @@ $(function () { break; case 14: fieldtext = - "OK (already forwarded)" + dnssecStatus; + "OK (already forwarded)" + + dnssecStatus; buttontext = ''; break; From cd4152058b011625f66fe7c436c232dacda662d6 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Mon, 30 May 2022 13:14:03 -0300 Subject: [PATCH 48/85] Use the same types, as returned by FTL Signed-off-by: RD WebDesign --- scripts/pi-hole/php/func.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/pi-hole/php/func.php b/scripts/pi-hole/php/func.php index c60433244..f4e0274c3 100644 --- a/scripts/pi-hole/php/func.php +++ b/scripts/pi-hole/php/func.php @@ -475,7 +475,7 @@ function returnError($message = "", $json = true) function getQueryTypeStr($querytype) { - $qtypes = ["A (IPv4)", "AAAA (IPv6)", "ANY", "SRV", "SOA", "PTR", "TXT", "NAPTR", "MX", "DS", "RRSIG", "DNSKEY", "NS", "OTHER", "SVCB", "HTTPS"]; + $qtypes = ["A", "AAAA", "ANY", "SRV", "SOA", "PTR", "TXT", "NAPTR", "MX", "DS", "RRSIG", "DNSKEY", "NS", "OTHER", "SVCB", "HTTPS"]; $qtype = intval($querytype); if($qtype > 0 && $qtype <= count($qtypes)) return $qtypes[$qtype-1]; From 4a0224317fb700bef586c34e164f9b464d899f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20K=C3=B6nig?= Date: Tue, 31 May 2022 14:05:57 +0200 Subject: [PATCH 49/85] Make it clearer where to find the debug token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Christian König --- debug.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debug.php b/debug.php index 9c316905e..6b9a01da2 100644 --- a/debug.php +++ b/debug.php @@ -13,7 +13,7 @@
    - +

    Once you click this button a debug log will be generated and can automatically be uploaded if we detect a working internet connection.

    From 33c5450ba4c0ef61e0c7b75f697a97e1c00cfaed Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Tue, 31 May 2022 15:16:04 -0300 Subject: [PATCH 50/85] Use consistent output for both query lists Signed-off-by: RD WebDesign --- scripts/pi-hole/js/db_queries.js | 3 ++- scripts/pi-hole/js/queries.js | 11 +++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_queries.js b/scripts/pi-hole/js/db_queries.js index 7dcae4b06..004004693 100644 --- a/scripts/pi-hole/js/db_queries.js +++ b/scripts/pi-hole/js/db_queries.js @@ -307,7 +307,8 @@ $(function () { blocked = true; break; case 9: - fieldtext = "Blocked (gravity, CNAME)"; + fieldtext = + "Blocked (gravity, CNAME)"; buttontext = ''; blocked = true; diff --git a/scripts/pi-hole/js/queries.js b/scripts/pi-hole/js/queries.js index b603db661..18f09d729 100644 --- a/scripts/pi-hole/js/queries.js +++ b/scripts/pi-hole/js/queries.js @@ -125,12 +125,10 @@ $(function () { case "2": fieldtext = replyid === 0 - ? "OK, sent to " - : "OK, answered by "; + ? "OK (sent to " + : "OK (answered by "; fieldtext += - "" + - (data.length > 10 && data[10] !== "N/A" ? data[10] : "") + - dnssecStatus; + (data.length > 10 && data[10] !== "N/A" ? data[10] : "") + ")" + dnssecStatus; buttontext = ''; break; @@ -174,7 +172,8 @@ $(function () { buttontext = ""; break; case "9": - fieldtext = "Blocked (gravity, CNAME)"; + fieldtext = + "Blocked (gravity, CNAME)"; blocked = true; buttontext = ''; From 730b6b093bf8257d833a6ecf258496ffd2e164b9 Mon Sep 17 00:00:00 2001 From: RD WebDesign Date: Wed, 1 Jun 2022 00:39:04 -0300 Subject: [PATCH 51/85] Use the correct endpoint for MAXLOGAGE Signed-off-by: RD WebDesign --- api_FTL.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api_FTL.php b/api_FTL.php index 9a091ac34..cb0a8574b 100644 --- a/api_FTL.php +++ b/api_FTL.php @@ -64,7 +64,7 @@ } if (isset($_GET["getMaxlogage"]) && $auth) { - $return = callFTLAPI("stats"); + $return = callFTLAPI("maxlogage"); if (array_key_exists("FTLnotrunning", $return)) { $data = array("FTLnotrunning" => true); } else { From eaef6f8733642bab717e869da63d19057f7af0b4 Mon Sep 17 00:00:00 2001 From: Anthony de Jong <11158888+anthony-de-jong@users.noreply.github.com> Date: Mon, 23 May 2022 18:31:03 +0000 Subject: [PATCH 52/85] Show suggested domains in group domains page Signed-off-by: Anthony de Jong <11158888+anthony-de-jong@users.noreply.github.com> --- groups-domains.php | 3 +- scripts/pi-hole/js/groups-domains.js | 53 ++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/groups-domains.php b/groups-domains.php index fa18be5ff..cad112549 100644 --- a/groups-domains.php +++ b/groups-domains.php @@ -48,7 +48,8 @@
    - + +
    diff --git a/scripts/pi-hole/js/groups-domains.js b/scripts/pi-hole/js/groups-domains.js index a165300b1..53dea30c1 100644 --- a/scripts/pi-hole/js/groups-domains.js +++ b/scripts/pi-hole/js/groups-domains.js @@ -51,14 +51,67 @@ $(function () { $("#new_domain").val(""); $("#wildcard_checkbox").prop("checked", false); } + + clearTimeout(suggestTimeout); + $("#suggest_domains").hide(); }); $("#add2black, #add2white").on("click", addDomain); + var suggestTimeout; + $("#new_domain").on("input", function (e) { + hideSuggestDomains(); + clearTimeout(suggestTimeout); + suggestTimeout = setTimeout(showSuggestDomains, 1000, e.target.value); + }); + utils.setBsSelectDefaults(); getGroups(); }); +function showSuggestDomains(value) { + function createButton(hostname) { + // Purposefully omit 'btn' class to save space on padding + return $('
    +

    Note:
    + The domain or regex filter will be automatically assigned to the Default Group.
    + Other groups can optionally be assigned + + within
    Group Management > Domains. + + in the list below (using Group assignment). +

    +