From 8ddebe8f14fc973328ab56abb3fe9257f1d1cb49 Mon Sep 17 00:00:00 2001 From: DL6ER Date: Wed, 1 Feb 2023 22:18:43 +0100 Subject: [PATCH] Query Log: Use responsive design for query details Signed-off-by: DL6ER --- package.json | 7 +- scripts/pi-hole/js/messages.js | 27 ++----- scripts/pi-hole/js/queries.js | 131 +++++++++++++++++++-------------- scripts/pi-hole/js/utils.js | 1 - 4 files changed, 88 insertions(+), 78 deletions(-) diff --git a/package.json b/package.json index b276f5ea..dc66de04 100644 --- a/package.json +++ b/package.json @@ -19,9 +19,10 @@ "prettier:check": "prettier -l \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**/*.js\"", "prettier:fix": "prettier --write \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**/*.js\"", "xo": "xo", - "xo:fix": "npm run xo -- --fix", - "test": "npm run prettier:check && npm run xo", - "testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo" + "xo:check": "npm run xo -- \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**\" \"*.php\"", + "xo:fix": "npm run xo -- --fix \"style/*.css\" \"style/themes/*.css\" \"scripts/pi-hole/**\" \"*.php\"", + "test": "npm run prettier:check && npm run xo:check", + "testpr": "npm run prettier:fix && git diff --ws-error-highlight=all --color=always --exit-code && npm run xo:check" }, "devDependencies": { "autoprefixer": "^10.4.13", diff --git a/scripts/pi-hole/js/messages.js b/scripts/pi-hole/js/messages.js index dc952d34..50d582f1 100644 --- a/scripts/pi-hole/js/messages.js +++ b/scripts/pi-hole/js/messages.js @@ -7,7 +7,6 @@ /* global utils:false */ var table; -var token = $("#token").text(); function renderTimestamp(data, type) { // Display and search content @@ -19,7 +18,7 @@ function renderTimestamp(data, type) { return data; } -function htmlPass(data, type) { +function htmlPass(data, _type) { return data; } @@ -199,33 +198,28 @@ function deleteMessage() { // Exploit prevention: Return early for non-numeric IDs for (var id in ids) { - if (Object.hasOwnProperty.call(ids, id) && typeof ids[id] !== "number") return; - delMsg(ids); + if (Object.hasOwnProperty.call(ids, id)) { + if (typeof ids[id] !== "number") return; + delMsg(ids); + } } } function delMsg(id) { - utils.disableAll(); utils.showAlert("info", "", "Deleting message..."); $.ajax({ url: "/api/info/messages/" + id, - method: "DELETE" + method: "DELETE", }) .done(function (response) { utils.enableAll(); - console.log(response); if (response === undefined) { utils.showAlert("success", "far fa-trash-alt", "Successfully deleted message", ""); table.row(id).remove().draw(false).ajax.reload(null, false); } else { - utils.showAlert( - "error", - "", - "Error while deleting message: " + id, - response.message - ); + utils.showAlert("error", "", "Error while deleting message: " + id, response.message); } // Clear selection after deletion @@ -237,12 +231,7 @@ function delMsg(id) { ) .fail(function (jqXHR, exception) { utils.enableAll(); - utils.showAlert( - "error", - "", - "Error while deleting message: " + id, - jqXHR.responseText - ); + utils.showAlert("error", "", "Error while deleting message: " + id, 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 28769464..85f4b63f 100644 --- a/scripts/pi-hole/js/queries.js +++ b/scripts/pi-hole/js/queries.js @@ -16,7 +16,16 @@ var dateformat = "MMMM Do YYYY, HH:mm"; var table = null; var cursor = null; -var filters = ["client_ip", "client_name", "domain", "upstream", "type", "status", "reply", "dnssec"]; +var filters = [ + "client_ip", + "client_name", + "domain", + "upstream", + "type", + "status", + "reply", + "dnssec", +]; $(function () { $("#querytime").daterangepicker( @@ -33,21 +42,21 @@ $(function () { Today: [moment().startOf("day"), moment().endOf("day")], Yesterday: [ moment().subtract(1, "days").startOf("day"), - moment().subtract(1, "days").endOf("day") + moment().subtract(1, "days").endOf("day"), ], "Last 7 Days": [moment().subtract(6, "days"), moment().endOf("day")], "Last 30 Days": [moment().subtract(29, "days"), moment().endOf("day")], "This Month": [moment().startOf("month"), moment().endOf("month")], "Last Month": [ moment().subtract(1, "month").startOf("month"), - moment().subtract(1, "month").endOf("month") + moment().subtract(1, "month").endOf("month"), ], "This Year": [moment().startOf("year"), moment().endOf("year")], - "All Time": [moment(beginningOfTime), moment(endOfTime)] + "All Time": [moment(beginningOfTime), moment(endOfTime)], }, opens: "center", showDropdowns: true, - autoUpdateInput: true + autoUpdateInput: true, }, function (startt, endt) { from = moment(startt).utc().valueOf() / 1000; @@ -79,28 +88,28 @@ function parseQueryStatus(data) { switch (data.status) { case "GRAVITY": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (gravity)"; buttontext = ''; break; case "FORWARDED": colorClass = "text-green"; - icon = "fa-solid fa-check"; + icon = "fa-solid fa-upload"; fieldtext = "Forwarded to " + data.upstream; buttontext = ''; break; case "CACHE": colorClass = "text-green"; - icon = "fa-solid fa-check"; + icon = "fa-regular fa-database"; fieldtext = "Cached"; buttontext = ''; break; case "REGEX": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (regex)"; regexLink = data.regex > 0; buttontext = @@ -108,32 +117,32 @@ function parseQueryStatus(data) { break; case "DENYLIST": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (exact)"; buttontext = ''; break; case "EXTERNAL_BLOCKED_IP": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (external, IP)"; buttontext = ""; break; case "EXTERNAL_BLOCKED_NULL": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (external, NULL)"; buttontext = ""; break; case "EXTERNAL_BLOCKED_NXRA": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (external, NXRA)"; buttontext = ""; break; case "GRAVITY_CNAME": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (gravity, CNAME)"; buttontext = ''; @@ -141,7 +150,7 @@ function parseQueryStatus(data) { break; case "REGEX_CNAME": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (regex diened, CNAME)"; regexLink = data.regex > 0; buttontext = @@ -150,7 +159,7 @@ function parseQueryStatus(data) { break; case "DENYLIST_CNAME": colorClass = "text-red"; - icon = "fa-solid fa-hand"; + icon = "fa-solid fa-ban"; fieldtext = "Blocked (exact diened, CNAME)"; buttontext = ''; @@ -158,19 +167,19 @@ function parseQueryStatus(data) { break; case "RETRIED": colorClass = "text-green"; - icon = "fa-solid fa-check"; + icon = "fa-solid fa-redo"; // fa-repeat fieldtext = "Retried"; buttontext = ""; break; case "RETRIED_DNSSEC": colorClass = "text-green"; - icon = "fa-solid fa-check"; + icon = "fa-solid fa-redo"; // fa-repeat fieldtext = "Retried (ignored)"; buttontext = ""; break; case "IN_PROGRESS": colorClass = "text-green"; - icon = "fa-solid fa-check"; + icon = "fa-solid fa-redo"; fieldtext = "OK (already forwarded)"; buttontext = ''; @@ -188,7 +197,7 @@ function parseQueryStatus(data) { colorClass: colorClass, icon: icon, isCNAME: isCNAME, - regexLink: regexLink + regexLink: regexLink, }; } @@ -209,7 +218,6 @@ function formatInfo(data) { case "ABANDONED": dnssecClass = "text-red"; break; - case "UNKNOWN": default: // No DNSSEC or UNKNOWN dnssecStatus = "N/A"; @@ -218,13 +226,17 @@ function formatInfo(data) { // Parse Query Status var queryStatus = parseQueryStatus(data); + var divStart = '
'; var statusInfo = ""; if (queryStatus.colorClass !== false) { statusInfo = - 'Query status:' + - queryStatus.fieldtext; + queryStatus.fieldtext + + "
"; } var regexInfo = "", @@ -236,75 +248,84 @@ function formatInfo(data) { 'target="_blank">Regex ID ' + data.regex + ""; - regexInfo = - 'Query was blocked by:' + regexLink; + regexInfo = divStart + "Query was blocked by:" + regexLink + ""; } if (queryStatus.isCNAME) { cnameInfo = - 'Query was blocked during CNAME inspection of' + - data.cname; + divStart + "Query was blocked during CNAME inspection of  " + data.cname + ""; } // Show TTL if applicable var ttlInfo = ""; if (data.ttl > 0) { ttlInfo = - 'Time-to-live (TTL):' + + divStart + + "Time-to-live (TTL):  " + moment.duration(data.ttl, "s").humanize() + " (" + data.ttl + - "s)"; + "s)"; } // Show client information, show hostname only if available var ipInfo = - data.client.name !== null && data.client.length > 0 ? data.client.name + " (" + data.client.ip + ")" : data.client.ip; - var clientInfo = 'Client:' + ipInfo; + data.client.name !== null && data.client.name.length > 0 + ? utils.escapeHtml(data.client.name) + " (" + data.client.ip + ")" + : data.client.ip; + var clientInfo = divStart + "Client:  " + ipInfo + ""; // Show DNSSEC status if applicable var dnssecInfo = ""; if (dnssecClass !== false) { dnssecInfo = - 'DNSSEC status:' + - dnssecStatus; + dnssecStatus + + ""; } // Show long-term database information if applicable var dbInfo = ""; if (data.dbid !== false) { - dbInfo = 'Database ID:' + data.id; + dbInfo = divStart + "Database ID:  " + data.id + ""; } // Always show reply info, add reply delay if applicable var replyInfo = ""; if (data.reply.type !== "UNKNOWN") { - replyInfo = 'Reply type:' + data.reply.type; + replyInfo = divStart + "Reply:  " + data.reply.type; if (data.reply.time >= 0 && data.reply.type !== "UNKNOWN") { replyInfo += - 'Reply delay:' + - (data.reply.time < 1.0 ? (1e3*data.reply.time).toFixed(1) + " ms" : (data.reply.time).toFixed(1) + " s"); + " (" + + (data.reply.time < 1 + ? (1e3 * data.reply.time).toFixed(1) + " ms)" + : data.reply.time.toFixed(1) + " s)"); } + + replyInfo += ""; } else { - replyInfo = 'Reply type:No reply received'; + replyInfo = divStart + "Reply:  No reply received"; } // Compile extra info for displaying return ( - "" + - '
Query received on:  ' + - moment.unix(data.time).format("Y-MM-DD []HH:mm:ss.SSS z") + - statusInfo + + '
' + + divStart + + "Query received on:  " + + moment.unix(data.time).format("Y-MM-DD HH:mm:ss.SSS z") + + "
" + clientInfo + + dnssecInfo + + statusInfo + cnameInfo + regexInfo + ttlInfo + - dnssecInfo + replyInfo + dbInfo + - "
" + "" ); } @@ -370,7 +391,6 @@ function getSuggestions(dict) { $.get( "/api/queries/suggestions", function (data) { - console.log(data); for (var key in filters) { if (Object.hasOwnProperty.call(filters, key)) { var f = filters[key]; @@ -434,7 +454,7 @@ $(function () { width: "100%", tags: sel < 3, // Only the first three are allowed to freely specify input placeholder: "Select...", - allowClear: true + allowClear: true, }); } } @@ -454,7 +474,7 @@ $(function () { var json = jQuery.parseJSON(d); cursor = json.cursor; // Extract cursor from original data return d; - } + }, }, serverSide: true, dom: @@ -474,16 +494,16 @@ $(function () { } return data; - } + }, }, { data: "status", width: "1%" }, { data: "type", width: "5%" }, { data: "domain", width: "50%" }, - { data: "client.ip", width: "34%", type: "ip-address", render: $.fn.dataTable.render.text() } + { data: "client.ip", width: "34%", type: "ip-address", render: $.fn.dataTable.render.text() }, ], lengthMenu: [ [10, 25, 50, 100, -1], - [10, 25, 50, 100, "All"] + [10, 25, 50, 100, "All"], ], stateSave: true, stateSaveCallback: function (settings, data) { @@ -495,8 +515,10 @@ $(function () { rowCallback: function (row, data) { var querystatus = parseQueryStatus(data); - if(querystatus.icon !== false) { - $("td:eq(1)", row).html(""); + if (querystatus.icon !== false) { + $("td:eq(1)", row).html( + "" + ); } else if (querystatus.colorClass !== false) { $(row).addClass(querystatus.colorClass); } @@ -514,11 +536,10 @@ $(function () { // Show hostname instead of IP if available if (data.client.name !== null && data.client.name !== "") { $("td:eq(4)", row).text(data.client.name); - } - else { + } else { $("td:eq(4)", row).text(data.client.ip); } - } + }, }); $("#all-queries tbody").on("click", "button", function () { diff --git a/scripts/pi-hole/js/utils.js b/scripts/pi-hole/js/utils.js index fac36809..36c296fc 100644 --- a/scripts/pi-hole/js/utils.js +++ b/scripts/pi-hole/js/utils.js @@ -366,7 +366,6 @@ function checkMessages() { : false; var url = "/api/info/messages" + (ignoreNonfatal ? "?filter_dnsmasq_warnings=true" : ""); $.getJSON(url, function (data) { - console.log(data); if (data.messages.length > 0) { var more = '\nAccess "Tools/Pi-hole diganosis" for further details.'; var title =