336 lines
8.5 KiB
JavaScript
336 lines
8.5 KiB
JavaScript
|
/**
|
||
|
* dmarc-srg - A php parser, viewer and summary report generator for incoming DMARC reports.
|
||
|
* Copyright (C) 2020 Aleksey Andreev (liuch)
|
||
|
*
|
||
|
* Available at:
|
||
|
* https://github.com/liuch/dmarc-srg
|
||
|
*
|
||
|
* This program is free software: you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License as published by the Free
|
||
|
* Software Foundation, either version 3 of the License.
|
||
|
*
|
||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||
|
* more details.
|
||
|
*
|
||
|
* You should have received a copy of the GNU General Public License along with
|
||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
class Router {
|
||
|
}
|
||
|
|
||
|
Router.start = function() {
|
||
|
Router._initial_header = document.querySelector("h1").textContent;
|
||
|
|
||
|
document.getElementsByTagName("body")[0].addEventListener("keydown", function(event) {
|
||
|
if (event.code == "Escape" && !event.shiftKey && !event.ctrlKey && !event.altKey) {
|
||
|
let cbtn = document.querySelector(".close-btn.active");
|
||
|
if (cbtn) {
|
||
|
cbtn.click();
|
||
|
event.preventDefault();
|
||
|
}
|
||
|
document.querySelectorAll("div.popup-menu:not(.hidden)").forEach(function(m) {
|
||
|
m.classList.add("hidden");
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
|
||
|
window.addEventListener("click", function(event) {
|
||
|
if (!event.target.closest("div.popup-menu")) {
|
||
|
document.querySelectorAll("div.popup-menu:not(.hidden)").forEach(function(m) {
|
||
|
m.classList.add("hidden");
|
||
|
});
|
||
|
}
|
||
|
let mm_toggle = document.getElementById("main-menu-toggle");
|
||
|
if (mm_toggle.checked) {
|
||
|
if (event.target.tagName == "A" || !event.target.closest("#main-menu-button")) {
|
||
|
mm_toggle.checked = false;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
document.getElementById("main-menu-button").addEventListener("click", function(event) {
|
||
|
let el = event.target;
|
||
|
if (el.tagName === "A") {
|
||
|
let href = el.getAttribute("href");
|
||
|
if (href !== "") {
|
||
|
event.preventDefault();
|
||
|
window.history.pushState(null, "", href);
|
||
|
Router.go();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
window.addEventListener("popstate", function(event) {
|
||
|
let m = Router._url2module();
|
||
|
if (m) {
|
||
|
let p = m.pointer;
|
||
|
if (p && p.onpopstate) {
|
||
|
if (p.title) {
|
||
|
Router.update_title(p.title());
|
||
|
}
|
||
|
p.onpopstate(event.state);
|
||
|
} else {
|
||
|
Router.go();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
document.getElementById("main-menu").addEventListener("click", function(event) {
|
||
|
let el = event.target.closest("ul>li");
|
||
|
if (el) {
|
||
|
el.classList.toggle("closed");
|
||
|
}
|
||
|
});
|
||
|
|
||
|
document.querySelector(".menu-box .about a").addEventListener("click", function(event) {
|
||
|
event.preventDefault();
|
||
|
setTimeout(function() {
|
||
|
let dlg = new AboutDialog({
|
||
|
authors: [
|
||
|
{ name: "Aleksey Andreev", url: "https://github.com/liuch", years: "2021-2022" }
|
||
|
],
|
||
|
documentation: [
|
||
|
{ ancor: "README on GitHub", url: "https://github.com/liuch/dmarc-srg/blob/master/README.md" }
|
||
|
],
|
||
|
source_code: [
|
||
|
{ ancor: "DmarcSrg on GitHub", url: "https://github.com/liuch/dmarc-srg" }
|
||
|
]
|
||
|
});
|
||
|
document.getElementById("main-block").appendChild(dlg.element());
|
||
|
dlg.show().finally(function() {
|
||
|
dlg.element().remove();
|
||
|
});
|
||
|
}, 0);
|
||
|
});
|
||
|
|
||
|
Router.go();
|
||
|
};
|
||
|
|
||
|
Router.go = function(url) {
|
||
|
Status.instance().update({ settings: [ "ui.datetime.offset", "ui.ipv4.url", "ui.ipv6.url" ] }).then(function(d) {
|
||
|
if (d) {
|
||
|
Router._update_menu(d.authenticated);
|
||
|
if (d.settings) {
|
||
|
if (d.settings["ui.datetime.offset"]) {
|
||
|
Common.tuneDateTimeOutput(d.settings["ui.datetime.offset"]);
|
||
|
}
|
||
|
Common.ipv4_url = d.settings["ui.ipv4.url"] || '';
|
||
|
Common.ipv6_url = d.settings["ui.ipv6.url"] || '';
|
||
|
}
|
||
|
if (d.error_code !== -2) {
|
||
|
try {
|
||
|
Common.checkResult(d);
|
||
|
} catch (err) {
|
||
|
Common.displayError(err);
|
||
|
}
|
||
|
let module = Router._url2module(url);
|
||
|
if (module) {
|
||
|
if (!module.pointer)
|
||
|
module.start(module);
|
||
|
let p = module.pointer;
|
||
|
if (p.oncleardata)
|
||
|
p.oncleardata();
|
||
|
else
|
||
|
Router._clear_data();
|
||
|
if (p.title)
|
||
|
Router.update_title(p.title());
|
||
|
if (p.display)
|
||
|
p.display();
|
||
|
if (p.update)
|
||
|
p.update();
|
||
|
}
|
||
|
}
|
||
|
if (d.state && d.state !== "Ok" && !d.error_code && d.message) {
|
||
|
Notification.add({ type: "warn", text: d.message, delay: 20000 });
|
||
|
}
|
||
|
if (d.version !== Router._app_ver) {
|
||
|
Router._app_ver = d.version;
|
||
|
Router.update_title();
|
||
|
}
|
||
|
if (d.php_version) {
|
||
|
Router.php_version = d.php_version;
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
};
|
||
|
|
||
|
Router.app_name = function(version) {
|
||
|
let name = "DmarcSrg";
|
||
|
if (version && Router._app_ver) {
|
||
|
name += " " + Router._app_ver;
|
||
|
}
|
||
|
return name;
|
||
|
}
|
||
|
|
||
|
Router.update_title = function(str) {
|
||
|
let title1 = Router.app_name(false);
|
||
|
let title2 = str || Router._title || null;
|
||
|
if (str) {
|
||
|
Router._title = str;
|
||
|
}
|
||
|
document.title = title1 + (title2 && (": " + title2) || "");
|
||
|
let h1 = document.querySelector("h1");
|
||
|
if (str === "") {
|
||
|
h1.textContent = Router._initial_header || "";
|
||
|
} else if (str) {
|
||
|
h1.textContent = title2 || "";
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Router._update_menu = function(authenticated) {
|
||
|
let m_el = document.getElementById("main-menu");
|
||
|
let l_el = m_el.querySelector("#auth-action");
|
||
|
if (l_el) {
|
||
|
l_el.remove();
|
||
|
}
|
||
|
{
|
||
|
let subs = m_el.querySelectorAll(".submenu .selected")
|
||
|
for (let i = 0; i < subs.length; ++i) {
|
||
|
subs[i].classList.remove("selected");
|
||
|
}
|
||
|
let href = document.location.origin + document.location.pathname;
|
||
|
let f1 = false;
|
||
|
for (let i = 0; i < m_el.children.length; ++i) {
|
||
|
let smenu = m_el.children[i];
|
||
|
if (smenu !== l_el) {
|
||
|
let f2 = false;
|
||
|
if (!f1) {
|
||
|
let a_ls = smenu.querySelectorAll("ul>li>a");
|
||
|
for (let k = 0; k < a_ls.length; ++k) {
|
||
|
let a = a_ls[k];
|
||
|
if (a.href === href) {
|
||
|
f1 = true;
|
||
|
f2 = true;
|
||
|
a.parentElement.classList.add("selected")
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (f2) {
|
||
|
smenu.classList.remove("closed");
|
||
|
}
|
||
|
else {
|
||
|
smenu.classList.add("closed");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if (authenticated !== "disabled") {
|
||
|
l_el = document.createElement("li");
|
||
|
l_el.setAttribute("id", "auth-action");
|
||
|
let a_el = document.createElement("a");
|
||
|
a_el.setAttribute("href", "");
|
||
|
if (authenticated == "yes") {
|
||
|
a_el.appendChild(document.createTextNode("Log out"));
|
||
|
a_el.addEventListener("click", function(event) {
|
||
|
event.preventDefault();
|
||
|
if (!this.classList.contains("disabled")) {
|
||
|
let m_el = this;
|
||
|
m_el.classList.add("disabled");
|
||
|
window.fetch("logout.php", {
|
||
|
method: "POST",
|
||
|
cache: "no-store",
|
||
|
headers: Object.assign(HTTP_HEADERS, HTTP_HEADERS_POST),
|
||
|
credentials: "same-origin",
|
||
|
body: JSON.stringify({})
|
||
|
}).then(function(resp) {
|
||
|
if (!resp.ok)
|
||
|
throw new Error("Failed to log out");
|
||
|
return resp.json();
|
||
|
}).then(function(data) {
|
||
|
Common.checkResult(data);
|
||
|
Status.instance().reset();
|
||
|
Router._clear_data();
|
||
|
Router._update_menu("no");
|
||
|
Router.update_title("");
|
||
|
}).catch(function(err) {
|
||
|
Common.displayError(err);
|
||
|
m_el.classList.remove("disabled");
|
||
|
Notification.add({ type: "error", text: err.message });
|
||
|
});
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
else if (authenticated == "no") {
|
||
|
a_el.appendChild(document.createTextNode("Log in"));
|
||
|
a_el.addEventListener("click", function(event) {
|
||
|
event.preventDefault();
|
||
|
LoginDialog.start({ nousername: true });
|
||
|
});
|
||
|
}
|
||
|
l_el.appendChild(a_el);
|
||
|
m_el.appendChild(l_el);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Router._clear_data = function() {
|
||
|
remove_all_children(document.getElementById("main-block"));
|
||
|
remove_all_children(document.getElementById("detail-block"));
|
||
|
};
|
||
|
|
||
|
Router._modules = {
|
||
|
list: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new ReportList();
|
||
|
}
|
||
|
},
|
||
|
report: {
|
||
|
start: function(m) {
|
||
|
m.pointer = ReportWidget.instance();
|
||
|
}
|
||
|
},
|
||
|
admin: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new Admin();
|
||
|
}
|
||
|
},
|
||
|
files: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new Files();
|
||
|
}
|
||
|
},
|
||
|
domains: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new DomainList();
|
||
|
}
|
||
|
},
|
||
|
logs: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new Logs();
|
||
|
}
|
||
|
},
|
||
|
summary: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new Summary();
|
||
|
}
|
||
|
},
|
||
|
settings: {
|
||
|
start: function(m) {
|
||
|
m.pointer = new Settings();
|
||
|
}
|
||
|
}
|
||
|
};
|
||
|
|
||
|
Router._url2module = function(url) {
|
||
|
let rr = /([^\/]*)$/.exec(url || document.location.pathname);
|
||
|
return rr && Router._modules[Router._routes[rr[1]]] || null;
|
||
|
};
|
||
|
|
||
|
Router._routes = {
|
||
|
"": "list",
|
||
|
"list.php": "list",
|
||
|
"logs.php": "logs",
|
||
|
"admin.php": "admin",
|
||
|
"files.php": "files",
|
||
|
"report.php": "report",
|
||
|
"domains.php": "domains",
|
||
|
"summary.php": "summary",
|
||
|
"settings.php": "settings"
|
||
|
};
|
||
|
|
||
|
window.onload = Router.start;
|
||
|
|