From 0ee3c06c777123734c6e18af6b89768e130035d1 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 1 Jan 2020 15:57:33 +0000 Subject: [PATCH 01/27] Fix tooltip percentage computation. While we're at it, also put the blocked queries under permitted ones and show them in gray instead of blue. Signed-off-by: DL6ER --- scripts/pi-hole/js/index.js | 38 +++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 026b73943..9871a939a 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -160,8 +160,8 @@ function updateQueriesOverTime() { timeLineChart.data.labels.push(d); var blocked = data.ads_over_time[1][hour]; var permitted = data.domains_over_time[1][hour] - blocked; - timeLineChart.data.datasets[0].data.push(permitted); - timeLineChart.data.datasets[1].data.push(blocked); + timeLineChart.data.datasets[0].data.push(blocked); + timeLineChart.data.datasets[1].data.push(permitted); } } @@ -764,6 +764,9 @@ $(document).ready(function() { updateSummaryData(); + var blockedColor = "#999999"; + var permittedColor = "#00a65a"; + var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); timeLineChart = new Chart(ctx, { type: "bar", @@ -771,22 +774,22 @@ $(document).ready(function() { labels: [], datasets: [ { - label: "Permitted DNS Queries", + label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0, 166, 90,.8)", - borderColor: "rgba(0, 166, 90,.8)", - pointBorderColor: "rgba(0, 166, 90,.8)", + backgroundColor: blockedColor, + borderColor: blockedColor, + pointBorderColor: blockedColor, pointRadius: 1, pointHoverRadius: 5, data: [], pointHitRadius: 5 }, { - label: "Blocked DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,1)", - borderColor: "rgba(0,192,239,1)", - pointBorderColor: "rgba(0,192,239,1)", + backgroundColor: permittedColor, + borderColor: permittedColor, + pointBorderColor: permittedColor, pointRadius: 1, pointHoverRadius: 5, data: [], @@ -798,6 +801,9 @@ $(document).ready(function() { tooltips: { enabled: true, mode: "x-axis", + itemSort: function(a, b) { + return b.datasetIndex - a.datasetIndex; + }, callbacks: { title: function(tooltipItem) { var label = tooltipItem[0].xLabel; @@ -806,15 +812,15 @@ $(document).ready(function() { var m = parseInt(time[2], 10) || 0; var from = padNumber(h) + ":" + padNumber(m - 5) + ":00"; var to = padNumber(h) + ":" + padNumber(m + 4) + ":59"; - return "Upstreams from " + from + " to " + to; + return "Queries from " + from + " to " + to; }, label: function(tooltipItems, data) { - if (tooltipItems.datasetIndex === 1) { + if (tooltipItems.datasetIndex === 0) { var percentage = 0.0; - var total = parseInt(data.datasets[0].data[tooltipItems.index]); - var blocked = parseInt(data.datasets[1].data[tooltipItems.index]); - if (total > 0) { - percentage = (100.0 * blocked) / total; + var permitted = parseInt(data.datasets[1].data[tooltipItems.index]); + var blocked = parseInt(data.datasets[0].data[tooltipItems.index]); + if (permitted + blocked > 0) { + percentage = (100.0 * blocked) / (permitted + blocked); } return ( From ac1e68acdedb7376678fbf8703bb4a03bde59bbc Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 1 Jan 2020 18:20:42 +0000 Subject: [PATCH 02/27] Apply the same changes to the long-term graph page. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 59 ++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index aab3eb777..b57ead4b1 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -160,23 +160,23 @@ function updateQueriesOverTime() { for (hour in dates) { if (Object.prototype.hasOwnProperty.call(dates, hour)) { var date, - dom = 0, - ads = 0; + total = 0, + blocked = 0; date = new Date(1000 * dates[hour]); var idx = data.domains_over_time[0].indexOf(dates[hour].toString()); if (idx > -1) { - dom = data.domains_over_time[1][idx]; + total = data.domains_over_time[1][idx]; } idx = data.ads_over_time[0].indexOf(dates[hour].toString()); if (idx > -1) { - ads = data.ads_over_time[1][idx]; + blocked = data.ads_over_time[1][idx]; } timeLineChart.data.labels.push(date); - timeLineChart.data.datasets[0].data.push(dom - ads); - timeLineChart.data.datasets[1].data.push(ads); + timeLineChart.data.datasets[0].data.push(blocked); + timeLineChart.data.datasets[1].data.push(total - blocked); } } @@ -190,28 +190,30 @@ function updateQueriesOverTime() { $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); + var blockedColor = "#999999"; + var permittedColor = "#00a65a"; timeLineChart = new Chart(ctx, { type: "bar", data: { labels: [], datasets: [ { - label: "Permitted DNS Queries", + label: "Blocked DNS Queries", fill: true, - backgroundColor: "rgba(0, 166, 90,.8)", - borderColor: "rgba(0, 166, 90,.8)", - pointBorderColor: "rgba(0, 166, 90,.8)", + backgroundColor: blockedColor, + borderColor: blockedColor, + pointBorderColor: blockedColor, pointRadius: 1, pointHoverRadius: 5, data: [], pointHitRadius: 5 }, { - label: "Blocked DNS Queries", + label: "Permitted DNS Queries", fill: true, - backgroundColor: "rgba(0,192,239,1)", - borderColor: "rgba(0,192,239,1)", - pointBorderColor: "rgba(0,192,239,1)", + backgroundColor: permittedColor, + borderColor: permittedColor, + pointBorderColor: permittedColor, pointRadius: 1, pointHoverRadius: 5, data: [], @@ -222,6 +224,9 @@ $(document).ready(function() { options: { tooltips: { enabled: true, + itemSort: function(a, b) { + return b.datasetIndex - a.datasetIndex; + }, mode: "x-axis", callbacks: { title: function(tooltipItem) { @@ -232,8 +237,8 @@ $(document).ready(function() { "-" + padNumber(time.getMonth() + 1) + "-" + - padNumber(time.getDate()) + - " " + + padNumber(time.getDate()); + var from_time = padNumber(time.getHours()) + ":" + padNumber(time.getMinutes()) + @@ -245,22 +250,28 @@ $(document).ready(function() { "-" + padNumber(time.getMonth() + 1) + "-" + - padNumber(time.getDate()) + - " " + + padNumber(time.getDate()); + var until_time = padNumber(time.getHours()) + ":" + padNumber(time.getMinutes()) + ":" + padNumber(time.getSeconds()); - return "Queries from " + from_date + " to " + until_date; + if (from_date === until_date) { + return "Queries from " + from_time + " to " + until_time; + } else { + return ( + "Queries from " + from_date + " " + from_time + " to " + until_date + " " + until_time + ); + } }, label: function(tooltipItems, data) { - if (tooltipItems.datasetIndex === 1) { + if (tooltipItems.datasetIndex === 0) { var percentage = 0.0; - var total = parseInt(data.datasets[0].data[tooltipItems.index]); - var blocked = parseInt(data.datasets[1].data[tooltipItems.index]); - if (total > 0) { - percentage = (100.0 * blocked) / total; + var permitted = parseInt(data.datasets[1].data[tooltipItems.index]); + var blocked = parseInt(data.datasets[0].data[tooltipItems.index]); + if (permitted + blocked > 0) { + percentage = (100.0 * blocked) / (permitted + blocked); } return ( From f2713a9b3d9a986bdccd82bcb00a93ad93f7cbe0 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 2 Jan 2020 13:24:45 +0000 Subject: [PATCH 03/27] Always show date (but only once if the interval is on the same date), break long lines on small displays, and abbreviate gray color definition. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 26 ++++++++++++++++++++------ scripts/pi-hole/js/index.js | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index b57ead4b1..8636244db 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -190,7 +190,7 @@ function updateQueriesOverTime() { $(document).ready(function() { var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); - var blockedColor = "#999999"; + var blockedColor = "#999"; var permittedColor = "#00a65a"; timeLineChart = new Chart(ctx, { type: "bar", @@ -258,12 +258,26 @@ $(document).ready(function() { ":" + padNumber(time.getSeconds()); if (from_date === until_date) { - return "Queries from " + from_time + " to " + until_time; - } else { - return ( - "Queries from " + from_date + " " + from_time + " to " + until_date + " " + until_time - ); + // Abbreviated form for intervals on the same day + return "Queries from " + from_time + " to " + until_time + " on " + from_date; } + + // Full tooltip for intervals spanning more than one date. + // We split title in two lines on small screens + if ($(window).width() < 992) { + from_date += "\n"; + } + + return ( + "Queries from " + + from_date + + " " + + from_time + + " to " + + until_date + + " " + + until_time + ).split("\n "); }, label: function(tooltipItems, data) { if (tooltipItems.datasetIndex === 0) { diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index 9871a939a..4f61e62b0 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -764,7 +764,7 @@ $(document).ready(function() { updateSummaryData(); - var blockedColor = "#999999"; + var blockedColor = "#999"; var permittedColor = "#00a65a"; var ctx = document.getElementById("queryOverTimeChart").getContext("2d"); From 4337dabff646d39ddab1ddd4f2f04ed4a8f0b9fa Mon Sep 17 00:00:00 2001 From: DL6ER Date: Thu, 2 Jan 2020 13:28:01 +0000 Subject: [PATCH 04/27] Always break tooltip title into two lines on narrow screens. Signed-off-by: DL6ER --- scripts/pi-hole/js/db_graph.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js index 8636244db..e39f39b3e 100644 --- a/scripts/pi-hole/js/db_graph.js +++ b/scripts/pi-hole/js/db_graph.js @@ -257,12 +257,20 @@ $(document).ready(function() { padNumber(time.getMinutes()) + ":" + padNumber(time.getSeconds()); + if (from_date === until_date) { // Abbreviated form for intervals on the same day - return "Queries from " + from_time + " to " + until_time + " on " + from_date; + // We split title in two lines on small screens + if ($(window).width() < 992) { + until_time += "\n"; + } + + return ("Queries from " + from_time + " to " + until_time + " on " + from_date).split( + "\n " + ); } - // Full tooltip for intervals spanning more than one date. + // Full tooltip for intervals spanning more than one day // We split title in two lines on small screens if ($(window).width() < 992) { from_date += "\n"; From 4f824bec7845c75c60b957f8b44d598d2e2efcc7 Mon Sep 17 00:00:00 2001 From: Adam Warner Date: Tue, 18 Feb 2020 08:41:06 +0000 Subject: [PATCH 05/27] Fix potential code injection on MAC address validator Co-authored-by: DL6ER Signed-off-by: Adam Warner --- scripts/pi-hole/php/savesettings.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/scripts/pi-hole/php/savesettings.php b/scripts/pi-hole/php/savesettings.php index 6804f6a8b..8ea24bf8d 100644 --- a/scripts/pi-hole/php/savesettings.php +++ b/scripts/pi-hole/php/savesettings.php @@ -53,7 +53,15 @@ function validDomainWildcard($domain_name) function validMAC($mac_addr) { // Accepted input format: 00:01:02:1A:5F:FF (characters may be lower case) - return (preg_match('/([a-fA-F0-9]{2}[:]?){6}/', $mac_addr) == 1); + return !filter_var($mac_addr, FILTER_VALIDATE_MAC) === false; +} + +function formatMAC($mac_addr) +{ + preg_match("/([0-9a-fA-F]{2}[:]){5}([0-9a-fA-F]{2})/", $mac_addr, $matches); + if(count($matches) > 0) + return $matches[0]; + return null; } function validEmail($email) From fd983a2b68ac5f3aa8a54fa7df5f2155430772bc Mon Sep 17 00:00:00 2001 From: Th3M3 Date: Sun, 15 Mar 2020 21:43:16 +0100 Subject: [PATCH 06/27] improve multiselect Signed-off-by: Th3M3 --- scripts/pi-hole/js/groups-adlists.js | 97 +- scripts/pi-hole/js/groups-clients.js | 100 +- scripts/pi-hole/js/groups-common.js | 21 +- scripts/pi-hole/js/groups-domains.js | 100 +- scripts/pi-hole/php/header.php | 4 +- style/pi-hole.css | 5 + .../bootstrap/css/bootstrap-multiselect.css | 1 - .../bootstrap/css/bootstrap-select.min.css | 6 + .../bootstrap/js/bootstrap-multiselect.js | 1716 ----------------- .../bootstrap/js/bootstrap-select.min.js | 9 + 10 files changed, 218 insertions(+), 1841 deletions(-) delete mode 100644 style/vendor/bootstrap/css/bootstrap-multiselect.css create mode 100644 style/vendor/bootstrap/css/bootstrap-select.min.css delete mode 100644 style/vendor/bootstrap/js/bootstrap-multiselect.js create mode 100644 style/vendor/bootstrap/js/bootstrap-select.min.js diff --git a/scripts/pi-hole/js/groups-adlists.js b/scripts/pi-hole/js/groups-adlists.js index 92dcc2b6c..7415b5529 100644 --- a/scripts/pi-hole/js/groups-adlists.js +++ b/scripts/pi-hole/js/groups-adlists.js @@ -26,6 +26,7 @@ function get_groups() { $(document).ready(function() { $("#btnAdd").on("click", addAdlist); + utils.bsSelect_defaults(); get_groups(); }); @@ -47,6 +48,8 @@ function initTable() { ], drawCallback: function() { $('button[id^="deleteAdlist_"]').on("click", deleteAdlist); + // Remove visible dropdown to prevent orphaning + $("body > .bootstrap-select.dropdown").remove(); }, rowCallback: function(row, data) { $(row).attr("data-id", data.id); @@ -88,61 +91,74 @@ function initTable() { $("td:eq(3)", row).empty(); $("td:eq(3)", row).append( - '
' + - '
' + '' ); var selectEl = $("#multiselect_" + data.id, row); // Add all known groups for (var i = 0; i < groups.length; i++) { - var extra = ""; + var data_sub = ""; if (!groups[i].enabled) { - extra = " (disabled)"; + data_sub = 'data-subtext="(disabled)"'; } selectEl.append( - $("