diff --git a/api.php b/api.php
index 23fe88d7..62ece967 100644
--- a/api.php
+++ b/api.php
@@ -13,14 +13,10 @@ require_once("scripts/pi-hole/php/database.php");
require_once("scripts/pi-hole/php/auth.php");
check_cors();
-$FTL_IP = "127.0.0.1";
-
$data = array();
// Common API functions
-if (isset($_GET['status'])) {
- $data = array_merge($data, array("status" => piholeStatusAPI()));
-} elseif (isset($_GET['enable']) && $auth) {
+if (isset($_GET['enable']) && $auth) {
if(isset($_GET["auth"]))
{
if($_GET["auth"] !== $pwhash)
diff --git a/api_FTL.php b/api_FTL.php
index b7bcf9fe..a596a73d 100644
--- a/api_FTL.php
+++ b/api_FTL.php
@@ -6,429 +6,355 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license */
-
-if(!isset($api))
-{
- die("Direct call to api_FTL.php is not allowed!");
+if (!isset($api)) {
+ die("Direct call to api_FTL.php is not allowed!");
}
-// $FTL_IP is defined in api.php
-$socket = connectFTL($FTL_IP);
-
-if(!is_resource($socket))
-{
- $data = array_merge($data, array("FTLnotrunning" => true));
+if (isset($_GET['type'])) {
+ $data["type"] = "FTL";
}
-else
-{
- if (isset($_GET['type'])) {
- $data["type"] = "FTL";
- }
- if (isset($_GET['version'])) {
- $data["version"] = 3;
- }
+if (isset($_GET['version'])) {
+ $data["version"] = 3;
+}
- if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) {
- require_once("scripts/pi-hole/php/gravity.php");
- sendRequestFTL("stats");
- $return = getResponseFTL();
+if (isset($_GET['status'])) {
+ $return = callFTLAPI("stats");
- $stats = [];
- foreach($return as $line) {
- $tmp = explode(" ",$line);
+ if (in_array("status enabled", $return)) {
+ $data = array_merge($data, array("status" => "enabled"));
+ } else {
+ $data = array_merge($data, array("status" => "disabled"));
+ }
+}
- if($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1])) {
- // Expect string response
- $stats[$tmp[0]] = $tmp[1];
- } elseif ($tmp[0] === "status") {
- // Expect string response
- $stats[$tmp[0]] = piholeStatusAPI();
- } elseif (isset($_GET['summary'])) {
- // "summary" expects a formmated string response
- if($tmp[0] !== "ads_percentage_today") {
- $stats[$tmp[0]] = number_format($tmp[1]);
- } else {
- $stats[$tmp[0]] = number_format($tmp[1], 1, '.', '');
- }
- } else {
- // Expect float response
- $stats[$tmp[0]] = floatval($tmp[1]);
- }
+if (isset($_GET['summary']) || isset($_GET['summaryRaw']) || !count($_GET)) {
+ require_once("scripts/pi-hole/php/gravity.php");
- }
- $stats['gravity_last_updated'] = gravity_last_update(true);
- $data = array_merge($data,$stats);
- }
+ $return = callFTLAPI("stats");
- if (isset($_GET["getMaxlogage"]) && $auth) {
- sendRequestFTL("maxlogage");
- // Convert seconds to hours and rounds to one decimal place.
- $ret = round(intval(getResponseFTL()[0]) / 3600, 1);
- // Return 24h if value is 0, empty, null or non numeric.
- $ret = $ret ?: 24;
+ $stats = [];
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
- $data = array_merge($data, array("maxlogage" => $ret));
- }
+ if ($tmp[0] === "domains_being_blocked" && !is_numeric($tmp[1]) || $tmp[0] === "status") {
+ // Expect string response
+ $stats[$tmp[0]] = $tmp[1];
+ } elseif (isset($_GET['summary'])) {
+ // "summary" expects a formmated string response
+ if ($tmp[0] !== "ads_percentage_today") {
+ $stats[$tmp[0]] = number_format($tmp[1]);
+ } else {
+ $stats[$tmp[0]] = number_format($tmp[1], 1, '.', '');
+ }
+ } else {
+ // Expect float response
+ $stats[$tmp[0]] = floatval($tmp[1]);
+ }
- if (isset($_GET['overTimeData10mins']))
- {
- sendRequestFTL("overTime");
- $return = getResponseFTL();
+ }
+ $stats['gravity_last_updated'] = gravity_last_update(true);
+ $data = array_merge($data,$stats);
+}
- $domains_over_time = array();
- $ads_over_time = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $domains_over_time[intval($tmp[0])] = intval($tmp[1]);
- $ads_over_time[intval($tmp[0])] = intval($tmp[2]);
- }
- $result = array('domains_over_time' => $domains_over_time,
- 'ads_over_time' => $ads_over_time);
- $data = array_merge($data, $result);
- }
+if (isset($_GET["getMaxlogage"]) && $auth) {
+ $return = callFTLAPI("stats");
- if (isset($_GET['topItems']) && $auth)
- {
- if($_GET['topItems'] === "audit")
- {
- sendRequestFTL("top-domains for audit");
- }
- else if(is_numeric($_GET['topItems']))
- {
- sendRequestFTL("top-domains (".$_GET['topItems'].")");
- }
- else
- {
- sendRequestFTL("top-domains");
- }
+ // Convert seconds to hours and rounds to one decimal place.
+ $ret = round(intval($return[0]) / 3600, 1);
+ // Return 24h if value is 0, empty, null or non numeric.
+ $ret = $ret ?: 24;
- $return = getResponseFTL();
- $top_queries = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- if(count($tmp) == 2) $tmp[2]="";
- $domain = utf8_encode($tmp[2]);
- $top_queries[$domain] = intval($tmp[1]);
- }
+ $data = array_merge($data, array("maxlogage" => $ret));
+}
- if($_GET['topItems'] === "audit")
- {
- sendRequestFTL("top-ads for audit");
- }
- else if(is_numeric($_GET['topItems']))
- {
- sendRequestFTL("top-ads (".$_GET['topItems'].")");
- }
- else
- {
- sendRequestFTL("top-ads");
- }
+if (isset($_GET['overTimeData10mins'])) {
+ $return = callFTLAPI("overTime");
- $return = getResponseFTL();
- $top_ads = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $domain = utf8_encode($tmp[2]);
- if(count($tmp) > 3)
- $top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]);
- else
- $top_ads[$domain] = intval($tmp[1]);
- }
+ $domains_over_time = array();
+ $ads_over_time = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $domains_over_time[intval($tmp[0])] = intval($tmp[1]);
+ $ads_over_time[intval($tmp[0])] = intval($tmp[2]);
+ }
- $result = array('top_queries' => $top_queries,
- 'top_ads' => $top_ads);
+ $result = array(
+ 'domains_over_time' => $domains_over_time,
+ 'ads_over_time' => $ads_over_time
+ );
- $data = array_merge($data, $result);
- }
+ $data = array_merge($data, $result);
+}
- if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth)
- {
+if (isset($_GET['topItems']) && $auth) {
+ if ($_GET['topItems'] === "audit") {
+ $return = callFTLAPI("top-domains for audit");
+ } elseif (is_numeric($_GET['topItems'])) {
+ $return = callFTLAPI("top-domains (".$_GET['topItems'].")");
+ } else {
+ $return = callFTLAPI("top-domains");
+ }
- if(isset($_GET['topClients']))
- {
- $number = $_GET['topClients'];
- }
- elseif(isset($_GET['getQuerySources']))
- {
- $number = $_GET['getQuerySources'];
- }
+ $top_queries = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ if (count($tmp) == 2) {
+ $tmp[2]="";
+ }
+ $domain = utf8_encode($tmp[2]);
+ $top_queries[$domain] = intval($tmp[1]);
+ }
- if(is_numeric($number))
- {
- sendRequestFTL("top-clients (".$number.")");
- }
- else
- {
- sendRequestFTL("top-clients");
- }
+ if ($_GET['topItems'] === "audit") {
+ $return = callFTLAPI("top-ads for audit");
+ } elseif (is_numeric($_GET['topItems'])) {
+ $return = callFTLAPI("top-ads (".$_GET['topItems'].")");
+ } else {
+ $return = callFTLAPI("top-ads");
+ }
- $return = getResponseFTL();
- $top_clients = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $clientip = utf8_encode($tmp[2]);
- if(count($tmp) > 3 && strlen($tmp[3]) > 0)
- {
- $clientname = utf8_encode($tmp[3]);
- $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
- }
- else
- $top_clients[$clientip] = intval($tmp[1]);
- }
+ $top_ads = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $domain = utf8_encode($tmp[2]);
+ if (count($tmp) > 3) {
+ $top_ads[$domain." (".$tmp[3].")"] = intval($tmp[1]);
+ } else {
+ $top_ads[$domain] = intval($tmp[1]);
+ }
+ }
- $result = array('top_sources' => $top_clients);
- $data = array_merge($data, $result);
- }
+ $result = array(
+ 'top_queries' => $top_queries,
+ 'top_ads' => $top_ads
+ );
- if (isset($_GET['topClientsBlocked']) && $auth)
- {
+ $data = array_merge($data, $result);
+}
- if(isset($_GET['topClientsBlocked']))
- {
- $number = $_GET['topClientsBlocked'];
- }
+if ((isset($_GET['topClients']) || isset($_GET['getQuerySources'])) && $auth) {
- if(is_numeric($number))
- {
- sendRequestFTL("top-clients blocked (".$number.")");
- }
- else
- {
- sendRequestFTL("top-clients blocked");
- }
+ if (isset($_GET['topClients'])) {
+ $number = $_GET['topClients'];
+ } elseif (isset($_GET['getQuerySources'])) {
+ $number = $_GET['getQuerySources'];
+ }
- $return = getResponseFTL();
- $top_clients = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $clientip = utf8_encode($tmp[2]);
- if(count($tmp) > 3 && strlen($tmp[3]) > 0)
- {
- $clientname = utf8_encode($tmp[3]);
- $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
- }
- else
- $top_clients[$clientip] = intval($tmp[1]);
- }
+ if (is_numeric($number)) {
+ $return = callFTLAPI("top-clients (".$number.")");
+ } else {
+ $return = callFTLAPI("top-clients");
+ }
- $result = array('top_sources_blocked' => $top_clients);
- $data = array_merge($data, $result);
- }
+ $top_clients = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $clientip = utf8_encode($tmp[2]);
+ if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
+ $clientname = utf8_encode($tmp[3]);
+ $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
+ } else {
+ $top_clients[$clientip] = intval($tmp[1]);
+ }
+ }
- if (isset($_GET['getForwardDestinations']) && $auth)
- {
- if($_GET['getForwardDestinations'] === "unsorted")
- {
- sendRequestFTL("forward-dest unsorted");
- }
- else
- {
- sendRequestFTL("forward-dest");
- }
- $return = getResponseFTL();
- $forward_dest = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $forwardip = utf8_encode($tmp[2]);
- if(count($tmp) > 3 && strlen($tmp[3]) > 0)
- {
- $forwardname = utf8_encode($tmp[3]);
- $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
- }
- else
- $forward_dest[$forwardip] = floatval($tmp[1]);
- }
+ $result = array('top_sources' => $top_clients);
+ $data = array_merge($data, $result);
+}
- $result = array('forward_destinations' => $forward_dest);
- $data = array_merge($data, $result);
- }
+if (isset($_GET['topClientsBlocked']) && $auth) {
- if (isset($_GET['getQueryTypes']) && $auth)
- {
- sendRequestFTL("querytypes");
- $return = getResponseFTL();
- $querytypes = array();
- foreach($return as $ret)
- {
- $tmp = explode(": ",$ret);
- // Reply cannot contain non-ASCII characters
- $querytypes[$tmp[0]] = floatval($tmp[1]);
- }
+ if (isset($_GET['topClientsBlocked'])) {
+ $number = $_GET['topClientsBlocked'];
+ }
- $result = array('querytypes' => $querytypes);
- $data = array_merge($data, $result);
- }
+ if (is_numeric($number)) {
+ $return = callFTLAPI("top-clients blocked (".$number.")");
+ } else {
+ $return = callFTLAPI("top-clients blocked");
+ }
- if (isset($_GET['getCacheInfo']) && $auth)
- {
- sendRequestFTL("cacheinfo");
- $return = getResponseFTL();
- $cacheinfo = array();
- foreach($return as $ret)
- {
- $tmp = explode(": ",$ret);
- // Reply cannot contain non-ASCII characters
- $cacheinfo[$tmp[0]] = floatval($tmp[1]);
- }
+ $top_clients = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $clientip = utf8_encode($tmp[2]);
+ if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
+ $clientname = utf8_encode($tmp[3]);
+ $top_clients[$clientname."|".$clientip] = intval($tmp[1]);
+ } else {
+ $top_clients[$clientip] = intval($tmp[1]);
+ }
+ }
- $result = array('cacheinfo' => $cacheinfo);
- $data = array_merge($data, $result);
- }
+ $result = array('top_sources_blocked' => $top_clients);
+ $data = array_merge($data, $result);
+}
- if (isset($_GET['getAllQueries']) && $auth)
- {
- if(isset($_GET['from']) && isset($_GET['until']))
- {
- // Get limited time interval
- sendRequestFTL("getallqueries-time ".$_GET['from']." ".$_GET['until']);
- }
- else if(isset($_GET['domain']))
- {
- // Get specific domain only
- sendRequestFTL("getallqueries-domain ".$_GET['domain']);
- }
- else if(isset($_GET['client']) && (isset($_GET['type']) && $_GET['type'] === "blocked"))
- {
- // Get specific client only
- sendRequestFTL("getallqueries-client-blocked ".$_GET['client']);
- }
- else if(isset($_GET['client']))
- {
- // Get specific client only
- sendRequestFTL("getallqueries-client ".$_GET['client']);
- }
- else if(isset($_GET['querytype']))
- {
- // Get specific query type only
- sendRequestFTL("getallqueries-qtype ".$_GET['querytype']);
- }
- else if(isset($_GET['forwarddest']))
- {
- // Get specific forward destination only
- sendRequestFTL("getallqueries-forward ".$_GET['forwarddest']);
- }
- else if(is_numeric($_GET['getAllQueries']))
- {
- sendRequestFTL("getallqueries (".$_GET['getAllQueries'].")");
- }
- else
- {
- // Get all queries
- sendRequestFTL("getallqueries");
- }
- $return = getResponseFTL();
- $allQueries = array();
- foreach($return as $line)
- {
- $tmp = str_getcsv($line," ");
- // UTF-8 encode domain
- $tmp[2] = utf8_encode(str_replace("~"," ",$tmp[2]));
- // UTF-8 encode client host name
- $tmp[3] = utf8_encode($tmp[3]);
- array_push($allQueries,$tmp);
- }
+if (isset($_GET['getForwardDestinations']) && $auth) {
+ if ($_GET['getForwardDestinations'] === "unsorted") {
+ $return = callFTLAPI("forward-dest unsorted");
+ } else {
+ $return = callFTLAPI("forward-dest");
+ }
- $result = array('data' => $allQueries);
- $data = array_merge($data, $result);
- }
+ $forward_dest = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $forwardip = utf8_encode($tmp[2]);
+ if (count($tmp) > 3 && strlen($tmp[3]) > 0) {
+ $forwardname = utf8_encode($tmp[3]);
+ $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
+ } else {
+ $forward_dest[$forwardip] = floatval($tmp[1]);
+ }
+ }
- if(isset($_GET["recentBlocked"]) && $auth)
- {
- sendRequestFTL("recentBlocked");
- die(utf8_encode(getResponseFTL()[0]));
- unset($data);
- }
+ $result = array('forward_destinations' => $forward_dest);
+ $data = array_merge($data, $result);
+}
- if (isset($_GET['getForwardDestinationNames']) && $auth)
- {
- sendRequestFTL("forward-names");
- $return = getResponseFTL();
- $forward_dest = array();
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- $forwardip = utf8_encode($tmp[2]);
- if(count($tmp) > 3)
- {
- $forwardname = utf8_encode($tmp[3]);
- $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
- }
- else
- {
- $forward_dest[$forwardip] = floatval($tmp[1]);
- }
- }
+if (isset($_GET['getQueryTypes']) && $auth) {
+ $return = callFTLAPI("querytypes");
- $result = array('forward_destinations' => $forward_dest);
- $data = array_merge($data, $result);
- }
+ $querytypes = array();
+ foreach ($return as $ret) {
+ $tmp = explode(": ",$ret);
+ // Reply cannot contain non-ASCII characters
+ $querytypes[$tmp[0]] = floatval($tmp[1]);
+ }
- if (isset($_GET['overTimeDataQueryTypes']) && $auth)
- {
- sendRequestFTL("QueryTypesoverTime");
- $return = getResponseFTL();
- $over_time = array();
+ $result = array('querytypes' => $querytypes);
+ $data = array_merge($data, $result);
+}
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- for ($i=0; $i < count($tmp)-1; $i++) {
- $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
- }
- }
- $result = array('over_time' => $over_time);
- $data = array_merge($data, $result);
- }
+if (isset($_GET['getCacheInfo']) && $auth) {
+ $return = callFTLAPI("cacheinfo");
+ $cacheinfo = array();
+ foreach ($return as $ret) {
+ $tmp = explode(": ",$ret);
+ // Reply cannot contain non-ASCII characters
+ $cacheinfo[$tmp[0]] = floatval($tmp[1]);
+ }
- if (isset($_GET['getClientNames']) && $auth)
- {
- sendRequestFTL("client-names");
- $return = getResponseFTL();
- $client_names = array();
- foreach($return as $line)
- {
- $tmp = explode(" ", $line);
- $client_names[] = array(
- "name" => utf8_encode($tmp[0]),
- "ip" => utf8_encode($tmp[1])
- );
- }
+ $result = array('cacheinfo' => $cacheinfo);
+ $data = array_merge($data, $result);
+}
- $result = array('clients' => $client_names);
- $data = array_merge($data, $result);
- }
+if (isset($_GET['getAllQueries']) && $auth) {
+ if (isset($_GET['from']) && isset($_GET['until'])) {
+ // Get limited time interval
+ $return = callFTLAPI("getallqueries-time ".$_GET['from']." ".$_GET['until']);
+ } elseif (isset($_GET['domain'])) {
+ // Get specific domain only
+ $return = callFTLAPI("getallqueries-domain ".$_GET['domain']);
+ } elseif (isset($_GET['client']) && (isset($_GET['type']) && $_GET['type'] === "blocked")) {
+ // Get specific client only
+ $return = callFTLAPI("getallqueries-client-blocked ".$_GET['client']);
+ } elseif (isset($_GET['client'])) {
+ // Get specific client only
+ $return = callFTLAPI("getallqueries-client ".$_GET['client']);
+ } elseif (isset($_GET['querytype'])) {
+ // Get specific query type only
+ $return = callFTLAPI("getallqueries-qtype ".$_GET['querytype']);
+ } elseif (isset($_GET['forwarddest'])) {
+ // Get specific forward destination only
+ $return = callFTLAPI("getallqueries-forward ".$_GET['forwarddest']);
+ } elseif (is_numeric($_GET['getAllQueries'])) {
+ $return = callFTLAPI("getallqueries (".$_GET['getAllQueries'].")");
+ } else {
+ // Get all queries
+ $return = callFTLAPI("getallqueries");
+ }
- if (isset($_GET['overTimeDataClients']) && $auth)
- {
- sendRequestFTL("ClientsoverTime");
- $return = getResponseFTL();
- $over_time = array();
+ $allQueries = array();
+ foreach ($return as $line) {
+ $tmp = str_getcsv($line," ");
+ // UTF-8 encode domain
+ $tmp[2] = utf8_encode(str_replace("~"," ",$tmp[2]));
+ // UTF-8 encode client host name
+ $tmp[3] = utf8_encode($tmp[3]);
+ array_push($allQueries,$tmp);
+ }
- foreach($return as $line)
- {
- $tmp = explode(" ",$line);
- for ($i=0; $i < count($tmp)-1; $i++) {
- $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
- }
- }
- $result = array('over_time' => $over_time);
- $data = array_merge($data, $result);
- }
+ $result = array('data' => $allQueries);
+ $data = array_merge($data, $result);
+}
- if (isset($_GET['delete_lease']) && $auth)
- {
- sendRequestFTL("delete-lease ".$_GET['delete_lease']);
- $return = getResponseFTL();
- $data["delete_lease"] = $return[0];
- }
+if (isset($_GET["recentBlocked"]) && $auth) {
+ die(utf8_encode(callFTLAPI("recentBlocked")[0]));
+ unset($data);
+}
- disconnectFTL();
+if (isset($_GET['getForwardDestinationNames']) && $auth) {
+ $return = callFTLAPI("forward-names");
+
+ $forward_dest = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ $forwardip = utf8_encode($tmp[2]);
+ if (count($tmp) > 3) {
+ $forwardname = utf8_encode($tmp[3]);
+ $forward_dest[$forwardname."|".$forwardip] = floatval($tmp[1]);
+ } else {
+ $forward_dest[$forwardip] = floatval($tmp[1]);
+ }
+ }
+
+ $result = array('forward_destinations' => $forward_dest);
+ $data = array_merge($data, $result);
+}
+
+if (isset($_GET['overTimeDataQueryTypes']) && $auth) {
+ $return = callFTLAPI("QueryTypesoverTime");
+ $over_time = array();
+
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ for ($i=0; $i < count($tmp)-1; $i++) {
+ $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
+ }
+ }
+ $result = array('over_time' => $over_time);
+ $data = array_merge($data, $result);
+}
+
+if (isset($_GET['getClientNames']) && $auth) {
+ $return = callFTLAPI("client-names");
+ $client_names = array();
+ foreach ($return as $line) {
+ $tmp = explode(" ", $line);
+ $client_names[] = array(
+ "name" => utf8_encode($tmp[0]),
+ "ip" => utf8_encode($tmp[1])
+ );
+ }
+
+ $result = array('clients' => $client_names);
+ $data = array_merge($data, $result);
+}
+
+if (isset($_GET['overTimeDataClients']) && $auth) {
+ $return = callFTLAPI("ClientsoverTime");
+ $over_time = array();
+
+ foreach ($return as $line) {
+ $tmp = explode(" ",$line);
+ for ($i=0; $i < count($tmp)-1; $i++) {
+ $over_time[intval($tmp[0])][$i] = floatval($tmp[$i+1]);
+ }
+ }
+ $result = array('over_time' => $over_time);
+ $data = array_merge($data, $result);
+}
+
+if (isset($_GET['delete_lease']) && $auth) {
+ $return = callFTLAPI("delete-lease ".$_GET['delete_lease']);
+ $data["delete_lease"] = $return[0];
+}
+
+if (isset($_GET['dns-port']) && $auth) {
+ $return = callFTLAPI("dns-port");
+ $data["dns-port"] = $return[0];
}
?>
diff --git a/api_db.php b/api_db.php
index 6f45433a..511f55d0 100644
--- a/api_db.php
+++ b/api_db.php
@@ -319,7 +319,7 @@ if (isset($_GET['getGraphData']) && $auth)
if(isset($_GET["interval"]))
{
$q = intval($_GET["interval"]);
- if($q > 10)
+ if($q >= 10)
$interval = $q;
}
diff --git a/auditlog.php b/auditlog.php
index 9825cb01..fd1219ed 100644
--- a/auditlog.php
+++ b/auditlog.php
@@ -76,7 +76,6 @@
-
-
-
-
-
-
diff --git a/groups-adlists.php b/groups-adlists.php
index 04ec7294..5a4688e5 100644
--- a/groups-adlists.php
+++ b/groups-adlists.php
@@ -81,7 +81,6 @@
-
">
-
">
-
">
-
-
| ID |
+ |
Time |
Type |
Message |
@@ -31,7 +32,7 @@
Data3 |
Data4 |
Data5 |
- Action |
+ |
@@ -43,7 +44,6 @@
-
-
diff --git a/package-lock.json b/package-lock.json
index 453fd561..0d804874 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -282,48 +282,48 @@
}
},
"autoprefixer": {
- "version": "10.4.2",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz",
- "integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==",
+ "version": "10.4.4",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.4.tgz",
+ "integrity": "sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA==",
"dev": true,
"requires": {
- "browserslist": "^4.19.1",
- "caniuse-lite": "^1.0.30001297",
- "fraction.js": "^4.1.2",
+ "browserslist": "^4.20.2",
+ "caniuse-lite": "^1.0.30001317",
+ "fraction.js": "^4.2.0",
"normalize-range": "^0.1.2",
"picocolors": "^1.0.0",
"postcss-value-parser": "^4.2.0"
},
"dependencies": {
"browserslist": {
- "version": "4.19.1",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.1.tgz",
- "integrity": "sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A==",
+ "version": "4.20.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
+ "integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==",
"dev": true,
"requires": {
- "caniuse-lite": "^1.0.30001286",
- "electron-to-chromium": "^1.4.17",
+ "caniuse-lite": "^1.0.30001317",
+ "electron-to-chromium": "^1.4.84",
"escalade": "^3.1.1",
- "node-releases": "^2.0.1",
+ "node-releases": "^2.0.2",
"picocolors": "^1.0.0"
}
},
"caniuse-lite": {
- "version": "1.0.30001298",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001298.tgz",
- "integrity": "sha512-AcKqikjMLlvghZL/vfTHorlQsLDhGRalYf1+GmWCf5SCMziSGjRYQW/JEksj14NaYHIR6KIhrFAy0HV5C25UzQ==",
+ "version": "1.0.30001319",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001319.tgz",
+ "integrity": "sha512-xjlIAFHucBRSMUo1kb5D4LYgcN1M45qdKP++lhqowDpwJwGkpIRTt5qQqnhxjj1vHcI7nrJxWhCC1ATrCEBTcw==",
"dev": true
},
"electron-to-chromium": {
- "version": "1.4.38",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.38.tgz",
- "integrity": "sha512-WhHt3sZazKj0KK/UpgsbGQnUUoFeAHVishzHFExMxagpZgjiGYSC9S0ZlbhCfSH2L2i+2A1yyqOIliTctMx7KQ==",
+ "version": "1.4.88",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.88.tgz",
+ "integrity": "sha512-oA7mzccefkvTNi9u7DXmT0LqvhnOiN2BhSrKerta7HeUC1cLoIwtbf2wL+Ah2ozh5KQd3/1njrGrwDBXx6d14Q==",
"dev": true
},
"node-releases": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.1.tgz",
- "integrity": "sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA==",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.2.tgz",
+ "integrity": "sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==",
"dev": true
}
}
@@ -1516,9 +1516,9 @@
"dev": true
},
"fraction.js": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.2.tgz",
- "integrity": "sha512-o2RiJQ6DZaR/5+Si0qJUIy637QMRudSi9kU/FFzx9EZazrIdnBgpU+3sEWCxAVhH2RtxW2Oz+T4p2o8uOPVcgA==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
+ "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
"dev": true
},
"fs-extra": {
@@ -2477,9 +2477,9 @@
"dev": true
},
"nanoid": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz",
- "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==",
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz",
+ "integrity": "sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==",
"dev": true
},
"natural-compare": {
@@ -2757,12 +2757,12 @@
"dev": true
},
"postcss": {
- "version": "8.4.6",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz",
- "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==",
+ "version": "8.4.12",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
+ "integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
"dev": true,
"requires": {
- "nanoid": "^3.2.0",
+ "nanoid": "^3.3.1",
"picocolors": "^1.0.0",
"source-map-js": "^1.0.2"
}
@@ -2825,9 +2825,9 @@
"dev": true
},
"prettier": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.5.1.tgz",
- "integrity": "sha512-vBZcPRUR5MZJwoyi3ZoyQlc1rXeEck8KgeC9AwwOn+exuxLxq5toTRDTSaVrXHxelDMHy9zlicw8u66yxoSUFg==",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.0.tgz",
+ "integrity": "sha512-m2FgJibYrBGGgQXNzfd0PuDGShJgRavjUoRCw1mZERIWVSXF0iLzLm+aOqTAbLnC3n6JzUhAA8uZnFVghHJ86A==",
"dev": true
},
"prettier-linter-helpers": {
diff --git a/package.json b/package.json
index 63a65ab6..6bba05e2 100644
--- a/package.json
+++ b/package.json
@@ -24,11 +24,11 @@
"testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo"
},
"devDependencies": {
- "autoprefixer": "^10.4.2",
+ "autoprefixer": "^10.4.4",
"eslint-plugin-compat": "^4.0.2",
- "postcss": "^8.4.6",
+ "postcss": "^8.4.12",
"postcss-cli": "^9.1.0",
- "prettier": "2.5.1",
+ "prettier": "2.6.0",
"xo": "^0.48.0"
},
"browserslist": [
@@ -52,7 +52,7 @@
"plugin:compat/recommended"
],
"parserOptions": {
- "ecmaVersion": 5,
+ "ecmaVersion": "latest",
"sourceType": "script"
},
"prettier": true,
diff --git a/queries.php b/queries.php
index 256e2c96..1b008f6a 100644
--- a/queries.php
+++ b/queries.php
@@ -46,7 +46,19 @@ if(isset($_GET["all"]))
}
else if(isset($_GET["client"]))
{
- $showing .= " queries for client ".htmlentities($_GET["client"]);
+ // Add switch between showing all queries and blocked only
+ if (isset($_GET["type"]) && $_GET["type"] === "blocked")
+ {
+ // Show blocked queries for this client + link to all
+ $showing .= " blocked queries for client ".htmlentities($_GET["client"]);
+ $showing .= ", show all";
+ }
+ else
+ {
+ // Show All queries for this client + link to show only blocked
+ $showing .= " all queries for client ".htmlentities($_GET["client"]);
+ $showing .= ", show blocked only";
+ }
}
else if(isset($_GET["forwarddest"]))
{
@@ -164,7 +176,6 @@ if(strlen($showing) > 0)
-
-
diff --git a/scripts/pi-hole/js/db_graph.js b/scripts/pi-hole/js/db_graph.js
index 19676417..ebf43bc9 100644
--- a/scripts/pi-hole/js/db_graph.js
+++ b/scripts/pi-hole/js/db_graph.js
@@ -8,9 +8,9 @@
/* global utils:false, Chart:false, moment:false */
var start__ = moment().subtract(7, "days");
-var from = moment(start__).utc().valueOf() / 1000;
+var from = Math.round(moment(start__).utc().valueOf() / 1000);
var end__ = moment();
-var until = moment(end__).utc().valueOf() / 1000;
+var until = Math.round(moment(end__).utc().valueOf() / 1000);
var interval = 0;
var dateformat = "MMMM Do YYYY, HH:mm";
@@ -51,8 +51,8 @@ $(function () {
autoUpdateInput: false,
},
function (startt, endt) {
- from = moment(startt).utc().valueOf() / 1000;
- until = moment(endt).utc().valueOf() / 1000;
+ from = Math.round(moment(startt).utc().valueOf() / 1000);
+ until = Math.round(moment(endt).utc().valueOf() / 1000);
}
);
});
@@ -63,32 +63,80 @@ function compareNumbers(a, b) {
return a - b;
}
+function computeInterval(from, until) {
+ // Compute interval to obtain about 200 values
+ var num = 200;
+ // humanly understandable intervals (in seconds)
+ var intervals = [
+ 10,
+ 20,
+ 30,
+ 60,
+ 120,
+ 180,
+ 300,
+ 600,
+ 900,
+ 1200,
+ 1800,
+ 3600,
+ 3600 * 2,
+ 3600 * 3,
+ 3600 * 4,
+ 3600 * 6,
+ 3600 * 8,
+ 3600 * 12,
+ 3600 * 24,
+ 3600 * 24 * 7,
+ 3600 * 24 * 30,
+ ];
+
+ var duration = until - from;
+ if (duration / (num * intervals[0]) < 1) {
+ return intervals[0];
+ }
+
+ var preverr = Number.MAX_VALUE,
+ err;
+ for (var i = 0; i < intervals.length; i++) {
+ err = Math.abs(1 - duration / (num * intervals[i]));
+ // pick the interval with least deviation
+ // from selected duration
+ if (preverr < err) {
+ return intervals[i - 1];
+ }
+
+ preverr = err;
+ }
+
+ return intervals[intervals.length - 1];
+}
+
function updateQueriesOverTime() {
var timeoutWarning = $("#timeoutWarning");
$("#queries-over-time .overlay").show();
timeoutWarning.show();
- // Compute interval to obtain about 200 values
- var num = 200;
- interval = (until - from) / num;
+ interval = computeInterval(from, until);
// Default displaying axis scaling
timeLineChart.options.scales.xAxes[0].time.unit = "hour";
+ var duration = until - from;
// Xaxis scaling based on selected daterange
- if (num * interval > 4 * 365 * 24 * 60 * 60) {
+ if (duration > 4 * 365 * 24 * 60 * 60) {
// If the requested data is more than 4 years, set ticks interval to year
timeLineChart.options.scales.xAxes[0].time.unit = "year";
- } else if (num * interval >= 366 * 24 * 60 * 60) {
+ } else if (duration >= 366 * 24 * 60 * 60) {
// If the requested data is more than 1 year, set ticks interval to quarter
timeLineChart.options.scales.xAxes[0].time.unit = "quarter";
- } else if (num * interval >= 92 * 24 * 60 * 60) {
+ } else if (duration >= 92 * 24 * 60 * 60) {
// If the requested data is more than 3 months, set ticks interval to months
timeLineChart.options.scales.xAxes[0].time.unit = "month";
- } else if (num * interval >= 31 * 24 * 60 * 60) {
+ } else if (duration >= 31 * 24 * 60 * 60) {
// If the requested data is 1 month or more, set ticks interval to weeks
timeLineChart.options.scales.xAxes[0].time.unit = "week";
- } else if (num * interval > 3 * 24 * 60 * 60) {
+ } else if (duration > 3 * 24 * 60 * 60) {
// If the requested data is more than 3 days (72 hours), set ticks interval to days
timeLineChart.options.scales.xAxes[0].time.unit = "day";
}
diff --git a/scripts/pi-hole/js/debug.js b/scripts/pi-hole/js/debug.js
index 1ed17b3b..14ed46be 100644
--- a/scripts/pi-hole/js/debug.js
+++ b/scripts/pi-hole/js/debug.js
@@ -40,6 +40,8 @@ function eventsource() {
"message",
function (e) {
ta.append(e.data);
+ // scroll page to the bottom (to the last received data)
+ $("html, body").scrollTop($(document).height());
},
false
);
@@ -49,6 +51,7 @@ function eventsource() {
"error",
function () {
source.close();
+ $("#output").removeClass("loading");
},
false
);
@@ -57,5 +60,6 @@ function eventsource() {
$("#debugBtn").on("click", function () {
$("#debugBtn").prop("disabled", true);
$("#upload").prop("disabled", true);
+ $("#output").addClass("loading");
eventsource();
});
diff --git a/scripts/pi-hole/js/footer.js b/scripts/pi-hole/js/footer.js
index 94dcf9a2..a01c4228 100644
--- a/scripts/pi-hole/js/footer.js
+++ b/scripts/pi-hole/js/footer.js
@@ -5,6 +5,7 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
+/* global utils:false */
//The following functions allow us to display time until pi-hole is enabled after disabling.
//Works between all pages
@@ -30,7 +31,7 @@ function piholeChanged(action) {
break;
case "disabled":
- status.html(" Offline");
+ status.html(" Blocking disabled");
ena.show();
dis.hide();
break;
@@ -101,28 +102,6 @@ function piholeChange(action, duration) {
}
}
-function checkMessages() {
- var ignoreNonfatal = localStorage
- ? localStorage.getItem("hideNonfatalDnsmasqWarnings_chkbox") === "true"
- : false;
- $.getJSON("api_db.php?status" + (ignoreNonfatal ? "&ignore=DNSMASQ_WARN" : ""), function (data) {
- if ("message_count" in data && data.message_count > 0) {
- var title =
- data.message_count > 1
- ? "There are " + data.message_count + " warnings. Click for further details."
- : "There is one warning. Click for further details.";
-
- $("#pihole-diagnosis").prop("title", title);
- $("#pihole-diagnosis-count").text(data.message_count);
- $("#pihole-diagnosis").removeClass("hidden");
- } else {
- $("#pihole-diagnosis").prop("title", "");
- $("#pihole-diagnosis-count").text(0);
- $("#pihole-diagnosis").addClass("hidden");
- }
- });
-}
-
function testCookies() {
if (navigator.cookieEnabled) {
return true;
@@ -242,9 +221,9 @@ $(function () {
initCPUtemp();
// Run check immediately after page loading ...
- checkMessages();
+ utils.checkMessages();
// ... and once again with five seconds delay
- setTimeout(checkMessages, 5000);
+ setTimeout(utils.checkMessages, 5000);
});
// Handle Enable/Disable
diff --git a/scripts/pi-hole/js/messages.js b/scripts/pi-hole/js/messages.js
index 37c13b01..a13de4fa 100644
--- a/scripts/pi-hole/js/messages.js
+++ b/scripts/pi-hole/js/messages.js
@@ -145,6 +145,7 @@ $(function () {
order: [[0, "asc"]],
columns: [
{ data: "id", visible: false },
+ { data: null, visible: true, width: "15px" },
{ data: "timestamp", width: "8%", render: renderTimestamp },
{ data: "type", width: "8%" },
{ data: "message", orderable: false, render: renderMessage },
@@ -153,9 +154,17 @@ $(function () {
{ data: "blob3", visible: false },
{ data: "blob4", visible: false },
{ data: "blob5", visible: false },
- { data: null, width: "80px", orderable: false },
+ { data: null, width: "22px", orderable: false },
],
columnDefs: [
+ {
+ targets: 1,
+ orderable: false,
+ className: "select-checkbox",
+ render: function () {
+ return "";
+ },
+ },
{
targets: "_all",
render: $.fn.dataTable.render.text(),
@@ -163,6 +172,11 @@ $(function () {
],
drawCallback: function () {
$('button[id^="deleteMessage_"]').on("click", deleteMessage);
+
+ // Hide buttons if all messages were deleted
+ var hasRows = this.api().rows({ filter: "applied" }).data().length > 0;
+ $(".datatable-bt").css("visibility", hasRows ? "visible" : "hidden");
+
// Remove visible dropdown to prevent orphaning
$("body > .bootstrap-select.dropdown").remove();
},
@@ -171,16 +185,63 @@ $(function () {
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
+ delMsg(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"],
@@ -201,7 +262,7 @@ $(function () {
}
// Reset visibility of ID and blob columns
- var hiddenCols = [0, 4, 5, 6, 7, 8];
+ var hiddenCols = [0, 5, 6, 7, 8, 9];
for (var key in hiddenCols) {
if (Object.prototype.hasOwnProperty.call(hiddenCols, key)) {
data.columns[hiddenCols[key]].visible = false;
@@ -212,42 +273,94 @@ $(function () {
return data;
},
});
+ table.on("init select deselect", function () {
+ changeButtonStates();
+ });
});
+// Show only the appropriate buttons
+function changeButtonStates() {
+ 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");
+ }
+}
+
+// Remove 'bnt-group' class from container, to avoid grouping
+$.fn.dataTable.Buttons.defaults.dom.container.className = "dt-buttons";
+
function deleteMessage() {
- var tr = $(this).closest("tr");
- var id = tr.attr("data-id");
+ // Passes the button data-del-id attribute as ID
+ var ids = [parseInt($(this).attr("data-del-id"), 10)];
+ delMsg(ids);
+}
+
+function delMsg(ids) {
+ // Check input validity
+ if (!Array.isArray(ids)) return;
+
+ // Exploit prevention: Return early for non-numeric IDs
+ for (var id in ids) {
+ if (Object.hasOwnProperty.call(ids, id) && typeof ids[id] !== "number") return;
+ }
utils.disableAll();
- utils.showAlert("info", "", "Deleting message with ID " + parseInt(id, 10), "...");
+ var idstring = ids.join(", ");
+ utils.showAlert("info", "", "Deleting messages: " + idstring, "...");
+
$.ajax({
url: "scripts/pi-hole/php/message.php",
method: "post",
dataType: "json",
- data: { action: "delete_message", id: id, token: token },
- success: function (response) {
+ data: { action: "delete_message", id: JSON.stringify(ids), token: token },
+ })
+ .done(function (response) {
utils.enableAll();
if (response.success) {
- utils.showAlert("success", "far fa-trash-alt", "Successfully deleted message # ", id);
- table.row(tr).remove().draw(false).ajax.reload(null, false);
- } else {
utils.showAlert(
- "error",
- "",
- "Error while deleting message with ID " + id,
- response.message
+ "success",
+ "far fa-trash-alt",
+ "Successfully deleted messages: " + idstring,
+ ""
);
+ 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 message: " + idstring, response.message);
}
- },
- error: function (jqXHR, exception) {
+
+ // Clear selection after deletion
+ table.rows().deselect();
+ changeButtonStates();
+ })
+ .done(
+ utils.checkMessages // Update icon warnings count
+ )
+ .fail(function (jqXHR, exception) {
utils.enableAll();
- utils.showAlert(
- "error",
- "",
- "Error while deleting message with ID " + id,
- jqXHR.responseText
- );
+ utils.showAlert("error", "", "Error while deleting message: " + idstring, jqXHR.responseText);
console.log(exception); // eslint-disable-line no-console
- },
- });
+ });
}
diff --git a/scripts/pi-hole/js/queries.js b/scripts/pi-hole/js/queries.js
index 091a6f98..a9b06485 100644
--- a/scripts/pi-hole/js/queries.js
+++ b/scripts/pi-hole/js/queries.js
@@ -450,7 +450,7 @@ $(function () {
$("#all-queries tbody").on("click", "button", function () {
var data = tableApi.row($(this).parents("tr")).data();
- if (data[4] === "2" || data[4] === "3") {
+ if (data[4] === "2" || data[4] === "3" || data[4] === "14") {
utils.addFromQueryLog(data[2], "black");
} else {
utils.addFromQueryLog(data[2], "white");
diff --git a/scripts/pi-hole/js/utils.js b/scripts/pi-hole/js/utils.js
index b9e1a573..d8f33b96 100644
--- a/scripts/pi-hole/js/utils.js
+++ b/scripts/pi-hole/js/utils.js
@@ -360,6 +360,26 @@ function colorBar(percentage, total, cssClass) {
return ' ' + bar + "
";
}
+function checkMessages() {
+ var ignoreNonfatal = localStorage
+ ? localStorage.getItem("hideNonfatalDnsmasqWarnings_chkbox") === "true"
+ : false;
+ $.getJSON("api_db.php?status" + (ignoreNonfatal ? "&ignore=DNSMASQ_WARN" : ""), function (data) {
+ if ("message_count" in data && data.message_count > 0) {
+ var title =
+ data.message_count > 1
+ ? "There are " + data.message_count + " warnings. Click for further details."
+ : "There is one warning. Click for further details.";
+
+ $("#pihole-diagnosis").prop("title", title);
+ $("#pihole-diagnosis-count").text(data.message_count);
+ $("#pihole-diagnosis").removeClass("hidden");
+ } else {
+ $("#pihole-diagnosis").addClass("hidden");
+ }
+ });
+}
+
window.utils = (function () {
return {
escapeHtml: escapeHtml,
@@ -382,5 +402,6 @@ window.utils = (function () {
addFromQueryLog: addFromQueryLog,
addTD: addTD,
colorBar: colorBar,
+ checkMessages: checkMessages,
};
})();
diff --git a/scripts/pi-hole/php/FTL.php b/scripts/pi-hole/php/FTL.php
index 958ac7be..e066f41b 100644
--- a/scripts/pi-hole/php/FTL.php
+++ b/scripts/pi-hole/php/FTL.php
@@ -6,88 +6,93 @@
* This file is copyright under the latest version of the EUPL.
* Please see LICENSE file for your rights under this license. */
-$piholeFTLConfFile = "/etc/pihole/pihole-FTL.conf";
+const DEFAULT_FTLCONFFILE = "/etc/pihole/pihole-FTL.conf";
+const DEFAULT_FTL_IP = "127.0.0.1";
+const DEFAULT_FTL_PORT = 4711;
-function piholeFTLConfig()
-{
- static $piholeFTLConfig;
- global $piholeFTLConfFile;
+function piholeFTLConfig($piholeFTLConfFile = DEFAULT_FTLCONFFILE, $force = false) {
+ static $piholeFTLConfig;
- if(isset($piholeFTLConfig))
- {
- return $piholeFTLConfig;
- }
+ if (isset($piholeFTLConfig) && !$force) {
+ return $piholeFTLConfig;
+ }
- if(is_readable($piholeFTLConfFile))
- {
- $piholeFTLConfig = parse_ini_file($piholeFTLConfFile);
- }
- else
- {
- $piholeFTLConfig = array();
- }
+ if (is_readable($piholeFTLConfFile)) {
+ $piholeFTLConfig = parse_ini_file($piholeFTLConfFile);
+ } else {
+ $piholeFTLConfig = array();
+ }
- return $piholeFTLConfig;
+ return $piholeFTLConfig;
}
-function connectFTL($address, $port=4711)
-{
- if($address == "127.0.0.1")
- {
- $config = piholeFTLConfig();
- // Read port
- $portfileName = isset($config['PORTFILE']) ? $config['PORTFILE'] : '';
- if ($portfileName != '')
- {
- $portfileContents = file_get_contents($portfileName);
- if(is_numeric($portfileContents))
- $port = intval($portfileContents);
- }
- }
+function connectFTL($address, $port) {
+ if ($address == DEFAULT_FTL_IP) {
+ $config = piholeFTLConfig();
+ // Read port
+ $portfileName = isset($config['PORTFILE']) ? $config['PORTFILE'] : '';
+ if ($portfileName != '') {
+ $portfileContents = file_get_contents($portfileName);
+ if (is_numeric($portfileContents)) {
+ $port = intval($portfileContents);
+ }
+ }
+ }
- // Open Internet socket connection
- $socket = @fsockopen($address, $port, $errno, $errstr, 1.0);
+ // Open Internet socket connection
+ $socket = @fsockopen($address, $port, $errno, $errstr, 1.0);
- return $socket;
+ return $socket;
}
-function sendRequestFTL($requestin)
-{
- global $socket;
-
- $request = ">".$requestin;
- fwrite($socket, $request) or die('{"error":"Could not send data to server"}');
+function sendRequestFTL($requestin, $socket) {
+ $request = ">".$requestin;
+ fwrite($socket, $request) or die('{"error":"Could not send data to server"}');
}
-function getResponseFTL()
-{
- global $socket;
+function getResponseFTL($socket) {
+ $response = [];
- $response = [];
+ $errCount = 0;
+ while (true) {
+ $out = fgets($socket);
+ if ($out == "") {
+ $errCount++;
+ }
- $errCount = 0;
- while(true)
- {
- $out = fgets($socket);
- if ($out == "") $errCount++;
- if ($errCount > 100) {
- // Tried 100 times, but never got proper reply, fail to prevent busy loop
- die('{"error":"Tried 100 times to connect to FTL server, but never got proper reply. Please check Port and logs!"}');
- }
- if(strrpos($out,"---EOM---") !== false)
- break;
+ if ($errCount > 100) {
+ // Tried 100 times, but never got proper reply, fail to prevent busy loop
+ die('{"error":"Tried 100 times to connect to FTL server, but never got proper reply. Please check Port and logs!"}');
+ }
- $out = rtrim($out);
- if(strlen($out) > 0)
- $response[] = $out;
- }
+ if (strrpos($out,"---EOM---") !== false) {
+ break;
+ }
- return $response;
+ $out = rtrim($out);
+ if (strlen($out) > 0) {
+ $response[] = $out;
+ }
+ }
+
+ return $response;
}
-function disconnectFTL()
-{
- global $socket;
- fclose($socket);
+function disconnectFTL($socket) {
+ fclose($socket);
+}
+
+function callFTLAPI($request, $FTL_IP = DEFAULT_FTL_IP, $port = DEFAULT_FTL_PORT) {
+ $socket = connectFTL($FTL_IP, $port);
+
+ if (!is_resource($socket)) {
+ $data = array("FTLnotrunning" => true);
+ } else {
+ sendRequestFTL($request, $socket);
+ $data = getResponseFTL($socket);
+ }
+ disconnectFTL($socket);
+
+ return $data;
}
?>
diff --git a/scripts/pi-hole/php/api_token.php b/scripts/pi-hole/php/api_token.php
index 1fb4aa7c..a05e3a41 100644
--- a/scripts/pi-hole/php/api_token.php
+++ b/scripts/pi-hole/php/api_token.php
@@ -1,3 +1,9 @@
+
+