diff --git a/auditlog.php b/auditlog.php index 0cc746cc0..64bf3efbf 100644 --- a/auditlog.php +++ b/auditlog.php @@ -72,6 +72,7 @@ + + + + ": ">", - '"': """, - "'": "'" - }; - - return text.replace(/[&<>"']/g, function (m) { - return map[m]; - }); -} - function updateTopLists() { $.getJSON("api.php?topItems=audit", function (data) { if ("FTLnotrunning" in data) { @@ -38,7 +25,7 @@ function updateTopLists() { for (domain in data.top_queries) { if (Object.prototype.hasOwnProperty.call(data.top_queries, domain)) { // Sanitize domain - domain = escapeHtml(domain); + domain = utils.escapeHtml(domain); url = '' + domain + ""; domaintable.append( "" + @@ -57,7 +44,7 @@ function updateTopLists() { if (Object.prototype.hasOwnProperty.call(data.top_ads, domain)) { var input = domain.split(" "); // Sanitize domain - var printdomain = escapeHtml(input[0]); + var printdomain = utils.escapeHtml(input[0]); if (input.length > 1) { url = '": ">", - '"': """, - "'": "'" - }; - - return text.replace(/[&<>"']/g, function (m) { - return map[m]; - }); -} - function updateTopClientsChart() { $("#client-frequency .overlay").show(); $.getJSON("api_db.php?topClients&from=" + from + "&until=" + until, function (data) { @@ -84,10 +69,10 @@ function updateTopClientsChart() { for (client in data.top_sources) { if (Object.prototype.hasOwnProperty.call(data.top_sources, client)) { // Sanitize client - client = escapeHtml(client); - if (escapeHtml(client) !== client) { + client = utils.escapeHtml(client); + if (utils.escapeHtml(client) !== client) { // Make a copy with the escaped index if necessary - data.top_sources[escapeHtml(client)] = data.top_sources[client]; + data.top_sources[utils.escapeHtml(client)] = data.top_sources[client]; } if (client.indexOf("|") !== -1) { @@ -138,10 +123,10 @@ function updateTopDomainsChart() { for (domain in data.top_domains) { if (Object.prototype.hasOwnProperty.call(data.top_domains, domain)) { // Sanitize domain - domain = escapeHtml(domain); - if (escapeHtml(domain) !== domain) { + domain = utils.escapeHtml(domain); + if (utils.escapeHtml(domain) !== domain) { // Make a copy with the escaped index if necessary - data.top_domains[escapeHtml(domain)] = data.top_domains[domain]; + data.top_domains[utils.escapeHtml(domain)] = data.top_domains[domain]; } percentage = (data.top_domains[domain] / sum) * 100; @@ -185,10 +170,10 @@ function updateTopAdsChart() { for (ad in data.top_ads) { if (Object.prototype.hasOwnProperty.call(data.top_ads, ad)) { // Sanitize ad - ad = escapeHtml(ad); - if (escapeHtml(ad) !== ad) { + ad = utils.escapeHtml(ad); + if (utils.escapeHtml(ad) !== ad) { // Make a copy with the escaped index if necessary - data.top_ads[escapeHtml(ad)] = data.top_ads[ad]; + data.top_ads[utils.escapeHtml(ad)] = data.top_ads[ad]; } percentage = (data.top_ads[ad] / sum) * 100; diff --git a/scripts/pi-hole/js/index.js b/scripts/pi-hole/js/index.js index f2a51c833..e778c3380 100644 --- a/scripts/pi-hole/js/index.js +++ b/scripts/pi-hole/js/index.js @@ -5,12 +5,13 @@ * This file is copyright under the latest version of the EUPL. * Please see LICENSE file for your rights under this license. */ +/* global utils:false, Chart:false, updateSessionTimer:false */ + // Define global variables -/* global Chart:false, updateSessionTimer:false */ var timeLineChart, clientsChart; var queryTypePieChart, forwardDestinationPieChart; -var colors = [ +var THEME_COLORS = [ "#3c8dbc", "#f56954", "#00a65a", @@ -29,28 +30,6 @@ var colors = [ "#d2d6de" ]; -function padNumber(num) { - return ("00" + num).substr(-2, 2); -} - -// Helper function needed for converting the Objects to Arrays - -function objectToArray(p) { - var keys = Object.keys(p); - keys.sort(function (a, b) { - return a - b; - }); - - var arr = [], - idx = []; - for (var i = 0; i < keys.length; i++) { - arr.push(p[keys[i]]); - idx.push(keys[i]); - } - - return [idx, arr]; -} - var customTooltips = function (tooltip) { var tooltipEl = document.getElementById(this._chart.canvas.id + "-customTooltip"); if (!tooltipEl) { @@ -83,14 +62,12 @@ var customTooltips = function (tooltip) { tooltipEl.classList.remove("left", "right", "center", "top", "bottom"); tooltipEl.classList.add(tooltip.xAlign, tooltip.yAlign); - function getBody(bodyItem) { - return bodyItem.lines; - } - // Set Text if (tooltip.body) { var titleLines = tooltip.title || []; - var bodyLines = tooltip.body.map(getBody); + var bodyLines = tooltip.body.map(function (bodyItem) { + return bodyItem.lines; + }); var innerHtml = ""; titleLines.forEach(function (title) { @@ -101,9 +78,9 @@ var customTooltips = function (tooltip) { var devicePixel = (1 / window.devicePixelRatio).toFixed(1); bodyLines.forEach(function (body, i) { - var colors = tooltip.labelColors[i]; - var style = "background: " + colors.backgroundColor; - style += "; outline: 1px solid " + colors.backgroundColor; + var labelColors = tooltip.labelColors[i]; + var style = "background-color: " + labelColors.backgroundColor; + style += "; outline: 1px solid " + labelColors.backgroundColor; style += "; border: " + devicePixel + "px solid #fff"; var span = ""; @@ -244,8 +221,8 @@ function updateQueriesOverTime() { } // convert received objects to arrays - data.domains_over_time = objectToArray(data.domains_over_time); - data.ads_over_time = objectToArray(data.ads_over_time); + data.domains_over_time = utils.objectToArray(data.domains_over_time); + data.ads_over_time = utils.objectToArray(data.ads_over_time); // remove last data point since it not representative data.ads_over_time[0].splice(-1, 1); // Remove possibly already existing data @@ -312,7 +289,7 @@ function updateQueryTypesPie() { Object.keys(iter).forEach(function (key) { v.push(iter[key]); - c.push(colors[i++ % colors.length]); + c.push(THEME_COLORS[i++ % THEME_COLORS.length]); k.push(key); }); @@ -368,7 +345,7 @@ function updateClientsOverTime() { } // convert received objects to arrays - data.over_time = objectToArray(data.over_time); + data.over_time = utils.objectToArray(data.over_time); // remove last data point since it not representative data.over_time[0].splice(-1, 1); @@ -376,19 +353,12 @@ function updateClientsOverTime() { var plotdata = data.over_time[1]; var labels = []; var key, i, j; - for (key in data.clients) { - if (!Object.prototype.hasOwnProperty.call(data.clients, key)) { - continue; - } - var clientname; - if (data.clients[key].name.length > 0) { - clientname = data.clients[key].name; - } else { - clientname = data.clients[key].ip; + for (key in data.clients) { + if (Object.prototype.hasOwnProperty.call(data.clients, key)) { + var client = data.clients[key]; + labels.push(client.name.length > 0 ? client.name : client.ip); } - - labels.push(clientname); } // Remove possibly already existing data @@ -399,7 +369,7 @@ function updateClientsOverTime() { } // Collect values and colors, and labels - clientsChart.data.datasets[0].backgroundColor = colors[0]; + clientsChart.data.datasets[0].backgroundColor = THEME_COLORS[0]; clientsChart.data.datasets[0].pointRadius = 0; clientsChart.data.datasets[0].pointHitRadius = 5; clientsChart.data.datasets[0].pointHoverRadius = 5; @@ -410,8 +380,8 @@ function updateClientsOverTime() { data: [], // If we ran out of colors, make a random one backgroundColor: - i < colors.length - ? colors[i] + i < THEME_COLORS.length + ? THEME_COLORS[i] : "#" + (0x1000000 + Math.random() * 0xffffff).toString(16).substr(1, 6), pointRadius: 0, pointHitRadius: 5, @@ -428,11 +398,9 @@ function updateClientsOverTime() { } for (key in plotdata[j]) { - if (!Object.prototype.hasOwnProperty.call(plotdata[j], key)) { - continue; + if (Object.prototype.hasOwnProperty.call(plotdata[j], key)) { + clientsChart.data.datasets[key].data.push(plotdata[j][key]); } - - clientsChart.data.datasets[key].data.push(plotdata[j][key]); } var d = new Date(1000 * parseInt(timestamps[j])); @@ -477,7 +445,7 @@ function updateForwardDestinationsPie() { key = key.substr(0, key.indexOf("|")); } - values.push([key, value, colors[i++ % colors.length]]); + values.push([key, value, THEME_COLORS[i++ % THEME_COLORS.length]]); }); // Split data into individual arrays for the graphs @@ -528,21 +496,6 @@ function updateForwardDestinationsPie() { }); } -// Credit: http://stackoverflow.com/questions/1787322/htmlspecialchars-equivalent-in-javascript/4835406#4835406 -function escapeHtml(text) { - var map = { - "&": "&", - "<": "<", - ">": ">", - '"': """, - "'": "'" - }; - - return text.replace(/[&<>"']/g, function (m) { - return map[m]; - }); -} - function updateTopClientsChart() { $.getJSON("api.php?summaryRaw&getQuerySources&topClientsBlocked", function (data) { if ("FTLnotrunning" in data) { @@ -556,12 +509,12 @@ function updateTopClientsChart() { for (client in data.top_sources) { if (Object.prototype.hasOwnProperty.call(data.top_sources, client)) { // Sanitize client - if (escapeHtml(client) !== client) { + if (utils.escapeHtml(client) !== client) { // Make a copy with the escaped index if necessary - data.top_sources[escapeHtml(client)] = data.top_sources[client]; + data.top_sources[utils.escapeHtml(client)] = data.top_sources[client]; } - client = escapeHtml(client); + client = utils.escapeHtml(client); if (client.indexOf("|") !== -1) { idx = client.indexOf("|"); clientname = client.substr(0, idx); @@ -602,12 +555,12 @@ function updateTopClientsChart() { for (client in data.top_sources_blocked) { if (Object.prototype.hasOwnProperty.call(data.top_sources_blocked, client)) { // Sanitize client - if (escapeHtml(client) !== client) { + if (utils.escapeHtml(client) !== client) { // Make a copy with the escaped index if necessary - data.top_sources_blocked[escapeHtml(client)] = data.top_sources_blocked[client]; + data.top_sources_blocked[utils.escapeHtml(client)] = data.top_sources_blocked[client]; } - client = escapeHtml(client); + client = utils.escapeHtml(client); if (client.indexOf("|") !== -1) { idx = client.indexOf("|"); clientname = client.substr(0, idx); @@ -674,12 +627,12 @@ function updateTopLists() { for (domain in data.top_queries) { if (Object.prototype.hasOwnProperty.call(data.top_queries, domain)) { // Sanitize domain - if (escapeHtml(domain) !== domain) { + if (utils.escapeHtml(domain) !== domain) { // Make a copy with the escaped index if necessary - data.top_queries[escapeHtml(domain)] = data.top_queries[domain]; + data.top_queries[utils.escapeHtml(domain)] = data.top_queries[domain]; } - domain = escapeHtml(domain); + domain = utils.escapeHtml(domain); urlText = domain === "" ? "." : domain; url = '' + urlText + ""; percentage = (data.top_queries[domain] / data.dns_queries_today) * 100; @@ -707,12 +660,12 @@ function updateTopLists() { for (domain in data.top_ads) { if (Object.prototype.hasOwnProperty.call(data.top_ads, domain)) { // Sanitize domain - if (escapeHtml(domain) !== domain) { + if (utils.escapeHtml(domain) !== domain) { // Make a copy with the escaped index if necessary - data.top_ads[escapeHtml(domain)] = data.top_ads[domain]; + data.top_ads[utils.escapeHtml(domain)] = data.top_ads[domain]; } - domain = escapeHtml(domain); + domain = utils.escapeHtml(domain); urlText = domain === "" ? "." : domain; url = '' + urlText + ""; percentage = (data.top_ads[domain] / data.ads_blocked_today) * 100; @@ -806,7 +759,7 @@ function updateSummaryData(runOnce) { ); } - window.setTimeout(function () { + setTimeout(function () { $("span.glow").removeClass("glow"); }, 500); }) @@ -876,8 +829,8 @@ $(document).ready(function () { var time = label.match(/(\d?\d):?(\d?\d?)/); var h = parseInt(time[1], 10); var m = parseInt(time[2], 10) || 0; - var from = padNumber(h) + ":" + padNumber(m - 5) + ":00"; - var to = padNumber(h) + ":" + padNumber(m + 4) + ":59"; + var from = utils.padNumber(h) + ":" + utils.padNumber(m - 5) + ":00"; + var to = utils.padNumber(h) + ":" + utils.padNumber(m + 4) + ":59"; return "Queries from " + from + " to " + to; }, label: function (tooltipItems, data) { @@ -973,8 +926,8 @@ $(document).ready(function () { var time = label.match(/(\d?\d):?(\d?\d?)/); var h = parseInt(time[1], 10); var m = parseInt(time[2], 10) || 0; - var from = padNumber(h) + ":" + padNumber(m - 5) + ":00"; - var to = padNumber(h) + ":" + padNumber(m + 4) + ":59"; + var from = utils.padNumber(h) + ":" + utils.padNumber(m - 5) + ":00"; + var to = utils.padNumber(h) + ":" + utils.padNumber(m + 4) + ":59"; return "Client activity from " + from + " to " + to; }, label: function (tooltipItems, data) { diff --git a/scripts/pi-hole/js/utils.js b/scripts/pi-hole/js/utils.js index 5d09cee5d..fd03d70c1 100644 --- a/scripts/pi-hole/js/utils.js +++ b/scripts/pi-hole/js/utils.js @@ -7,7 +7,44 @@ /* global moment:false */ -var info = null; +// Credit: https://stackoverflow.com/a/4835406 +function escapeHtml(text) { + var map = { + "&": "&", + "<": "<", + ">": ">", + '"': """, + "'": "'" + }; + + return text.replace(/[&<>"']/g, function (m) { + return map[m]; + }); +} + +// Helper function for converting Objects to Arrays after sorting the keys +function objectToArray(obj) { + var arr = []; + var idx = []; + var keys = Object.keys(obj); + + keys.sort(function (a, b) { + return a - b; + }); + + for (var i = 0; i < keys.length; i++) { + arr.push(obj[keys[i]]); + idx.push(keys[i]); + } + + return [idx, arr]; +} + +function padNumber(num) { + return ("00" + num).substr(-2, 2); +} + +var info = null; // TODO clear this up; there shouldn't be a global var here function showAlert(type, icon, title, message) { var opts = {}; title = " " + title + "
"; @@ -172,6 +209,9 @@ function stateLoadCallback(itemName) { window.utils = (function () { return { + escapeHtml: escapeHtml, + objectToArray: objectToArray, + padNumber: padNumber, showAlert: showAlert, datetime: datetime, disableAll: disableAll,