<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>Monitor password</title> <style> input, button { min-height: 10mm; min-width: 10mm; } </style> <script> var service_name = "monitor-password", // XXX hardcoded monitor_json_url = "/monitor.haljson", status_json_url = "/public/" + service_name + ".status.json", rerun_cgi_url = "/cgi-bin/monitor-run-promise.cgi?service=" + service_name, password_cgi_url_part = "/cgi-bin/monitor-password.cgi?password="; function newDeferred() { var d = { "promise": undefined, "resolve": undefined, "reject": undefined }; d.promise = new Promise(function (resolve, reject) { d.resolve = resolve; d.reject = reject; }); return d; } function xhr(param) { /*global XMLHttpRequest */ var d = newDeferred(), xhr = new XMLHttpRequest(), k, i, l, a; d.promise.cancel = function () { xhr.abort(); }; if (param.username) { xhr.open((param.method || "GET").toUpperCase(), param.url, true, param.username, param.password); } else { xhr.open((param.method || "GET").toUpperCase(), param.url, true); } xhr.responseType = param.responseType || ""; if (param.withCredentials !== undefined) { xhr.withCredentials = param.withCredentials; } if (param.headers) { a = Object.keys(param.headers); l = a.length; for (i = 0; i < l; i += 1) { k = a[i]; xhr.setRequestHeader(k, param.headers[k]); } } xhr.addEventListener("load", function (e) { var r, t = e.target, callback; if (param.noStatusCheck) { d.resolve(t); } else if (t.status < 400) { d.resolve(t); } else { r = new Error("HTTP: " + (t.status ? t.status + " " : "") + (t.statusText || "Unknown")); r.target = t; d.reject(r); } }, false); xhr.addEventListener("error", function (e) { return d.reject(new Error("HTTP: Error")); }, false); xhr.addEventListener("abort", function (e) { return d.reject(new Error("HTTP: Aborted")); }, false); xhr.send(param.data); return d.promise; } function unexpectedError(reason) { console.error(reason); alert(reason); } function MonitorPasswordInterface(config) { var it = this, statusP = document.createElement("p"), descriptionP = document.createElement("p"), form = document.createElement("form"), formPassword1Input = document.createElement("input"), formPassword2Input = document.createElement("input"), formChangePasswordButton = document.createElement("button"), errorH2 = document.createElement("h2"), errorPre = document.createElement("pre"), header = document.createElement("header"), h1 = document.createElement("h1"), h2 = document.createElement("h2"), a = document.createElement("a"), button = document.createElement("button"); this.element = config.rootElement || document.createElement("div"); this.statusP = statusP; this.descriptionP = descriptionP; this.formPassword1Input = formPassword1Input; this.formPassword2Input = formPassword2Input; this.formChangePasswordButton = formChangePasswordButton; this.errorH2 = errorH2; this.errorPre = errorPre; this.element.appendChild(header); header.appendChild(a); a.setAttribute("tabindex", "-1"); a.setAttribute("href", "/"); a.appendChild(button); button.textContent = "Home"; a = document.createElement("a"); button = document.createElement("button"); header.appendChild(a); a.setAttribute("tabindex", "-1"); a.setAttribute("href", ""); a.appendChild(button); button.textContent = "Refresh"; this.element.appendChild(h1); h1.textContent = "Monitor password"; this.element.appendChild(statusP); this.element.appendChild(descriptionP); this.element.appendChild(form); form.appendChild(formPassword1Input); formPassword1Input.setAttribute("type", "password"); form.onsubmit = this.onFormSubmit.bind(this); form.appendChild(document.createElement("br")); form.appendChild(formPassword2Input); formPassword2Input.setAttribute("type", "password"); form.appendChild(document.createElement("br")); form.appendChild(formChangePasswordButton); formChangePasswordButton.setAttribute("type", "submit"); formChangePasswordButton.textContent = "Change password"; this.element.appendChild(errorH2); errorH2.textContent = "Operational error"; errorH2.style.display = "none"; this.element.appendChild(errorPre); errorPre.style.display = "none"; this.loadStatusUi(); this.loadDescriptionUi(); this.loadErrorUi(); } MonitorPasswordInterface.prototype.loadStatusJson = function () { if (this.status_json_promise) { return; } this.status_json_promise = Promise.resolve().then(function () { return xhr({url: status_json_url, withCredentials: true, responseType: "json"}); }).then(function (xhr) { return xhr.response; }); this.status_json_promise.catch(function () { return; }).then(function () { setTimeout(function () { delete this.status_json_promise; }.bind(this), 1000); }.bind(this)); return this.status_json_promise; }; MonitorPasswordInterface.prototype.loadStatusUi = function () { this.loadStatusJson(); this.statusP.textContent = "Loading status..."; return this.status_json_promise.then(function (status_json) { if (status_json.status === "OK") { this.statusP.innerHTML = " "; } else { this.statusP.textContent = "/!\\ The password needs to be changed at least once! /!\\"; } }.bind(this), function (reason) { if (reason && reason.target && reason.target.status === 404) { this.statusP.textContent = "/!\\ The password needs to be changed at least once! /!\\"; return; } var message = reason && (reason.target && (reason.target.statusText || "Unknown") || reason.message); this.statusP.textContent = "Status Json Error: " + (message || "Unknown error"); }.bind(this)).catch(unexpectedError); }; MonitorPasswordInterface.prototype.loadDescriptionUi = function () { this.descriptionP.textContent = [ "The monitor password is the password used to connect to this interface.", "Here you can change the monitor password by filling the formular just below." ].join("\n"); }; MonitorPasswordInterface.prototype.loadErrorUi = function () { this.loadStatusJson(); this.errorPre.textContent = "Loading error output..."; return this.status_json_promise.then(function (status_json) { if (status_json.error) { this.errorH2.style.display = ""; this.errorPre.style.display = ""; this.errorPre.textContent = status_json.error; } else { this.errorH2.style.display = "none"; this.errorPre.style.display = "none"; this.errorPre.textContent = ""; } }.bind(this), function (reason) { var message = reason && (reason.target && (reason.target.statusText || "Unknown") || reason.message); this.errorPre.textContent = "Status Json Error: " + (message || "Unknown error"); }.bind(this)).catch(unexpectedError); }; MonitorPasswordInterface.prototype.onFormSubmit = function (event) { event.preventDefault(); event.stopPropagation(); this.execForm(); }; MonitorPasswordInterface.prototype.execForm = function () { if (this.formPassword1Input.value !== this.formPassword2Input.value) { this.statusP.textContent = "The two typed passwords should match!"; return; } this.statusP.textContent = "Changing password..."; var password = this.formPassword1Input.value; return Promise.resolve().then(function () { return xhr({url: password_cgi_url_part + password, method: "POST", withCredentials: true}); }).then(function () { this.statusP.textContent = "Password changed succesfully!"; this.formPassword1Input.value = this.formPassword2Input.value = ""; // rerun promise with new login (also does the relogin) xhr({url: rerun_cgi_url, method: "POST", withCredentials: true, username: "admin", password: password}); }.bind(this), function (reason) { var message = reason && (reason.target && (reason.target.statusText || "Unknown") || reason.message); this.statusP.textContent = "Status Json Error: " + (message || "Unknown error"); }.bind(this)); }; MonitorPasswordInterface.prototype.runPromiseNow = function () { this.runPromiseNowButton.disabled = true; var original_text = this.runPromiseNowButton.textContent; this.runPromiseNowButton.textContent = "Sending message..."; return Promise.resolve().then(function () { return xhr({url: rerun_cgi_url, method: "POST", withCredentials: true}); }).catch(unexpectedError).then(function () { this.runPromiseNowButton.textContent = original_text; }.bind(this)); }; /*global setTimeout */ setTimeout(function () { /*global document */ document.body.innerHTML = ""; return new MonitorPasswordInterface({rootElement: document.body}); }); </script> </head> <body> <h1>Monitor password</h1> <noscript>Javascript should be enabled</noscript> </body> </html>