Skip to content

Commit

Permalink
Merge pull request #372 from pi-hole/devel
Browse files Browse the repository at this point in the history
[RELEASE] Pi-hole Admin Page v2.4
  • Loading branch information
AzureMarker authored Jan 29, 2017
2 parents 7be7956 + 11c28bc commit 406877d
Show file tree
Hide file tree
Showing 26 changed files with 784 additions and 226 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
Pi-hole Admin Dashboard
============
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/938b4d9e61b7487da77cf63ba05c683d)](https://www.codacy.com/app/Pi-hole/AdminLTE?utm_source=github.com&utm_medium=referral&utm_content=pi-hole/AdminLTE&utm_campaign=badger)
[![Join the chat at https://gitter.im/pi-hole/AdminLTE](https://badges.gitter.im/pi-hole/AdminLTE.svg)](https://gitter.im/pi-hole/AdminLTE?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)

[![Donate](https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif "AdminLTE Presentation")](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=3J2L3Z4DHW9UY "Donate")
Expand All @@ -8,8 +9,7 @@ Using **[AdminLTE](https://almsaeedstudio.com)**, this project will create a Web

From this interface, you will be able to see stats on how well your Pi-hole is performing. You will also be able to update the lists used to block ads.

![Pi-hole Web interface](http://i.imgur.com/5lLAUGo.png)
![Fully responsive](http://i.imgur.com/fHuWR6E.png)
![Pi-hole Web interface](http://i.imgur.com/EgGZXbT.png)

## API
A read-only API can be accessed at `/admin/api.php`. With either no parameters or `api.php?summary` it returns the following JSON:
Expand All @@ -22,6 +22,9 @@ A read-only API can be accessed at `/admin/api.php`. With either no parameters o
}
```

There are many more parameters, such as `summaryRaw`, `overTimeData`, `topItems`, `recentItems`, `getQueryTypes`, `getForwardDestinations`, `getQuerySources`, and finally `getAllQueries`.
There are many more parameters, such as `summaryRaw`, `overTimeData10mins`, ` topClients` or `getQuerySources`, `getQueryTypes`, `getForwardDestinations`, and `getAllQueries`.
Together with a token it is also possible to enable and disable (also with a set timeout) blocking via the API.

`getAllQueries` can optionally be set with one of these values to return JSON hash ordered as value implies: `orderByClientDomainTime`, `orderByClientTimeDomain`, `orderByTimeClientDomain`, `orderByTimeDomainClient`, `orderByDomainClientTime` or `orderByDomainTimeClient`.
<hr>
<img src="https://assets.pi-hole.net/static/BStackLogo.png" height="80"><br>
We use BrowserStack for multi-platform multi-browser testing.
16 changes: 8 additions & 8 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,20 +89,20 @@
$data = array_merge($data, getGravity());
}

if (isset($_GET['tailLog'])) {
if (isset($_GET['tailLog']) && $auth) {
$data = array_merge($data, tailPiholeLog($_GET['tailLog']));
}

function filterArray(&$inArray) {
$outArray = array();
foreach ($inArray as $key=>$value) {
if (is_array($value)) {
$outArray[htmlspecialchars($key)] = filterArray($value);
$outArray = array();
foreach ($inArray as $key=>$value) {
if (is_array($value)) {
$outArray[htmlspecialchars($key)] = filterArray($value);
} else {
$outArray[htmlspecialchars($key)] = htmlspecialchars($value);
$outArray[htmlspecialchars($key)] = !is_numeric($value) ? htmlspecialchars($value) : $value;
}
}
return $outArray;
}
return $outArray;
}

$data = filterArray($data);
Expand Down
32 changes: 20 additions & 12 deletions help.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
<li>and others</li>
</ul>
</li>
<li>Query Types: Shows to which upstream DNS the permitted requests have been forwarded to.</li>
<li>Forward Destinations: Shows to which upstream DNS the permitted requests have been forwarded to.</li>
<li>Top Domains: Ranking of requested sites by number of DNS lookups.</li>
<li>Top Advertisers: Ranking of requested advertisements by number of DNS lookups.</li>
<li>Top Clients: Ranking of how many DNS requests each client has made on the local network.</li>
Expand All @@ -70,39 +70,47 @@
<div class="row">
<div class="col-md-12">
<h2>White- / Blacklist</h2>
<p>Add or remove domains (or subdomains) from the white-/blacklist. If a domain is added to e.g. the whitelist, any possible entry of the same domain will be automatically removed from the blacklist and vice versa. Adding wildcards using the web UI is currently <em>not</em> supported.</p>
<p>Add or remove domains (or subdomains) from the white-/blacklist. If a domain is added to e.g. the whitelist, any possible entry of the same domain will be automatically removed from the blacklist and vice versa.</p>
<p>Wildcard blacklisting is supported (entering <tt>something.de</tt> will block this domain including all subdomains like <tt>a.bb.c.999.something.de</tt>). Note that wildcard whitelisting is <em>not</em> supported.</p>
<p>You can white-/blacklist multiple entries at a time if you separate the domains by spaces.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Update Lists</h2>
<p>Will download any updates from the third-party ad-serving domain lists that we source. By default, this command runs once a week via cron.</p>
<h2>Disable / Enable</h2>
Disables/enables Pi-Hole blocking completely. You may have to wait a few minutes for the changes to reach all of your devices. The change will be reflected by a changed status (top left)
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Query adlists</h2>
This function is useful to find out what list a domain appears on. Since we don't control what the third-parties put on the block lists, you may find that a domain you normally visit stops working. If this is the case, you could run this command to scan for strings in the list of blocked domains and it will return the list the domain is found on. This proved useful a while back when the Mahakala list was adding apple.com and microsoft.com to their block list.</p>
<h2>Tools &rarr; Update Lists</h2>
<p>Will download any updates from the third-party ad-serving domain lists that we source. By default, this command runs once a week via cron (Sunday at 01:59).</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Disable / Enable</h2>
Disables/enables Pi-Hole blocking completely. You may have to wait a few minutes for the changes to reach all of your devices. The change will be reflected by a changed status (top left)
<h2>Tools &rarr; Query adlists</h2>
This function is useful to find out what list a domain appears on. Since we don't control what the third-parties put on the block lists, you may find that a domain you normally visit stops working. If this is the case, you could run this command to scan for strings in the list of blocked domains and it will return the list the domain is found on. This proved useful a while back when the Mahakala list was adding <tt>apple.com</tt> and <tt>microsoft.com</tt> to their block list.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Tools &rarr; Tail pihole.log</h2>
Live tailing of the raw Pi-hole log.</p>
</div>
</div>
<div class="row">
<div class="col-md-12">
<h2>Settings</h2>
Change settings for the Pi-Hole
<h4>Networking</h4>
Displays information about the interfaces of the Pi-Hole. No changes possible
Displays information about the interfaces of the Pi-Hole. No changes possible.
<h4>Pi-Hole DHCP Server</h4>
Using this setting you can enable/disable the DHCP server of the Pi-Hole. Note that you should disable any other DHCP server on your network to avoid IP addresses being used more than once. You have to give the range of IPs that DHCP will serve and the IP of the local router (gateway). If the DHCP server is active, the current leases are shown on the settings page.
Using this setting you can enable/disable the DHCP server of the Pi-Hole. Note that you should disable any other DHCP server on your network to avoid IP addresses being used more than once. You have to give the range of IPs that DHCP will serve and the IP of the local router (gateway). If the DHCP server is active, the current leases are shown on the settings page. IPv4 DHCP will always be activated, IPv6 (stateless + statefull) can be enabled.
<h4>Upstream DNS Servers</h4>
Customize used upstream DNS servers + advanced settings
Customize used upstream DNS servers + advanced settings for DNS servers. Note that any number of DNS servers may be enabled at a time.
<h4>Query Logging</h4>
Enabled/disable query logging on your Pi-hole
Enabled/disable query logging on your Pi-hole + provide option to flush the log
<h4>API</h4>
Change settings which apply to the API as well as the web UI<br>
Note that Top Clients have to be given as IP addresses
Expand Down
17 changes: 16 additions & 1 deletion list.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,18 @@ function getFullName() {
<div class="form-group input-group">
<input id="domain" type="text" class="form-control" placeholder="Add a domain (example.com or sub.example.com)">
<span class="input-group-btn">
<?php if($list === "black") { ?>
<button id="btnAdd" class="btn btn-default" type="button">Add (exact)</button>
<button id="btnAddWildcard" class="btn btn-default" type="button">Add (wildcard)</button>
<?php }else{ ?>
<button id="btnAdd" class="btn btn-default" type="button">Add</button>
<?php } ?>
<button id="btnRefresh" class="btn btn-default" type="button">Refresh</button>
}
</span>
</div>
<?php if($list === "white") { ?>
<p>Note that whitelisting domains which are blocked using the wildcard method won't work.</p><?php } ?>

<!-- Alerts -->
<div id="alInfo" class="alert alert-info alert-dismissible fade in" role="alert" hidden="true">
Expand All @@ -45,11 +53,18 @@ function getFullName() {
</div>
<div id="alFailure" class="alert alert-danger alert-dismissible fade in" role="alert" hidden="true">
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Failure! Something went wrong.
Failure! Something went wrong.<br/><span id="err"></span>
</div>

<!-- Domain List -->
<?php if($list === "black") { ?>
<h3>Exact blocking</h3>
<?php } ?>
<ul class="list-group" id="list"></ul>
<?php if($list === "black") { ?>
<h3>Wildcard blocking</h3>
<ul class="list-group" id="list-wildcard"></ul>
<?php } ?>

<?php
require "scripts/pi-hole/php/footer.php";
Expand Down
2 changes: 1 addition & 1 deletion queries.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
</div>
<div id="alFailure" class="alert alert-danger alert-dismissible fade in" role="alert" hidden="true">
<button type="button" class="close" data-hide="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
Failure! Something went wrong.
Failure! Something went wrong.<span id="err"></span>
</div>

<div class="row">
Expand Down
42 changes: 33 additions & 9 deletions scripts/pi-hole/js/footer.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ $("body").on("click", function(event) {

function piholeChanged(action)
{
const status = $("#status");
const ena = $("#pihole-enable");
const dis = $("#pihole-disable");
var status = $("#status");
var ena = $("#pihole-enable");
var dis = $("#pihole-disable");

switch(action) {
case "enabled":
Expand All @@ -33,7 +33,7 @@ function piholeChanged(action)

function piholeChange(action, duration)
{
const token = encodeURIComponent($("#token").html());
var token = encodeURIComponent($("#token").html());
var btnStatus;

switch(action) {
Expand Down Expand Up @@ -62,25 +62,25 @@ function piholeChange(action, duration)
}

// Handle Enable/Disable
$("#pihole-enable").on("click", (e) => {
$("#pihole-enable").on("click", function(e){
e.preventDefault();
piholeChange("enable","");
});
$("#pihole-disable-permanently").on("click", (e) => {
$("#pihole-disable-permanently").on("click", function(e){
e.preventDefault();
piholeChange("disable","0");
});
$("#pihole-disable-10s").on("click", (e) => {
$("#pihole-disable-10s").on("click", function(e){
e.preventDefault();
piholeChange("disable","10");
setTimeout(function(){piholeChanged("enabled");},10000);
});
$("#pihole-disable-30s").on("click", (e) => {
$("#pihole-disable-30s").on("click", function(e){
e.preventDefault();
piholeChange("disable","30");
setTimeout(function(){piholeChanged("enabled");},30000);
});
$("#pihole-disable-5m").on("click", (e) => {
$("#pihole-disable-5m").on("click", function(e){
e.preventDefault();
piholeChange("disable","300");
setTimeout(function(){piholeChanged("enabled");},300000);
Expand Down Expand Up @@ -204,3 +204,27 @@ $(document).keypress(function(e) {
$("#loginform").submit();
}
});

function testCookies()
{
if (navigator.cookieEnabled)
{
return true;
}

// set and read cookie
document.cookie = "cookietest=1";
var ret = document.cookie.indexOf("cookietest=") !== -1;

// delete cookie
document.cookie = "cookietest=1; expires=Thu, 01-Jan-1970 00:00:01 GMT";

return ret;
}

$(function() {
if(!testCookies() && $("#cookieInfo").length)
{
$("#cookieInfo").show();
}
});
9 changes: 8 additions & 1 deletion scripts/pi-hole/js/gravity.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ function eventsource() {
var alInfo = $("#alInfo");
var alSuccess = $("#alSuccess");
var ta = $("#output");

// IE does not support EventSource - exit early
if (typeof EventSource !== "function") {
ta.show();
ta.html("Updating lists of ad-serving domains is not supported with this browser!");
return;
}
var source = new EventSource("scripts/pi-hole/php/gravity.sh.php");

ta.html("");
Expand All @@ -27,7 +34,7 @@ function eventsource() {
}, false);
}

$("#gravityBtn").on("click", () => {
$("#gravityBtn").on("click", function(){
$("#gravityBtn").attr("disabled", true);
eventsource();
});
Expand Down
12 changes: 8 additions & 4 deletions scripts/pi-hole/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,22 +132,25 @@ function escapeHtml(text) {
function updateTopClientsChart() {
$.getJSON("api.php?summaryRaw&getQuerySources", function(data) {
var clienttable = $("#client-frequency").find("tbody:last");
var domain, percentage, domainname;
var domain, percentage, domainname, domainip;
for (domain in data.top_sources) {

if ({}.hasOwnProperty.call(data.top_sources, domain)){
// Sanitize domain
domain = escapeHtml(domain);
if(domain.indexOf("|") > -1)
{
domainname = domain.substr(0, domain.indexOf("|"));
var idx = domain.indexOf("|");
domainname = domain.substr(0, idx);
domainip = domain.substr(idx+1, domain.length-idx);
}
else
{
domainname = domain;
domainip = domain;
}

var url = "<a href=\"queries.php?client="+domain+"\">"+domainname+"</a>";
var url = "<a href=\"queries.php?client="+domain+"\" title=\""+domainip+"\">"+domainname+"</a>";
percentage = data.top_sources[domain] / data.dns_queries_today * 100;
clienttable.append("<tr> <td>" + url +
"</td> <td>" + data.top_sources[domain] + "</td> <td> <div class=\"progress progress-sm\" title=\""+percentage.toFixed(1)+"%\"> <div class=\"progress-bar progress-bar-blue\" style=\"width: " +
Expand All @@ -172,7 +175,8 @@ function updateForwardDestinations() {
c.push(colors.shift());
if(key.indexOf("|") > -1)
{
key = key.substr(0, key.indexOf("|"));
var idx = key.indexOf("|");
key = key.substr(0, idx)+" ("+key.substr(idx+1, key.length-idx)+")";
}
forwardDestinationChart.data.labels.push(key);
});
Expand Down
Loading

0 comments on commit 406877d

Please sign in to comment.