<!DOCTYPE html>
<html>
<head>
<title>Loading...</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="robots" content="noindex">
<meta insert_dynamic_content_here>
<script>
/* global XMLHttpRequest */
(function(a) {
var r;
/* Some browsers fail localStorage access due to corruption, preventing Cockpit login */ try {
r = window.localStorage;
window.localStorage.removeItem("url-root");
} catch (e) {
r = window.sessionStorage;
a.warn(String(e));
}
var s;
var l = window.environment || {};
var u = l.OAuth || null;
if (u) {
if (!u.TokenParam) u.TokenParam = "access_token";
if (!u.ErrorParam) u.ErrorParam = "error_description";
}
var t = /\$\{([^}]+)\}|\$([a-zA-Z0-9_]+)/g;
function c(e /* ... */) {
var o = Array.prototype.slice.call(arguments, 1);
return e.replace(t, function(e, t, n) {
return o[t || n] || "";
});
}
function n(e) {
if (window.cockpit_po) {
var t = window.cockpit_po[e];
if (t && t[1]) return t[1];
}
return e;
}
function i() {
if (!document.querySelectorAll) return;
var e = document.querySelectorAll("[translate]");
for (var t = 0; t < e.length; t++) e[t].textContent = n(e[t].textContent);
}
var d = n;
var f, p, w, v;
var o = /[?&]?([^=]+)=([^&]*)/g;
var g = null;
function y(e) {
e = e.split("+").join(" ");
var t = {};
var n;
for (;;) {
n = o.exec(e);
if (!n) break;
t[decodeURIComponent(n[1])] = decodeURIComponent(n[2]);
}
return t;
}
if (!a) a = function() {};
function m(e) {
return document.getElementById(e);
}
function h(e) {
if (window.console) a.warn("fatal:", e);
m("login-again").style.display = "none";
m("login-wait-validating").style.display = "none";
if (g) {
m("login-again").href = g;
m("login-again").style.display = "block";
}
m("login").style.display = "none";
m("login-details").style.display = "none";
m("login-fatal").style.display = "block";
var t = m("login-fatal-message");
t.textContent = "";
t.appendChild(document.createTextNode(e));
}
function b(e, t) {
var n;
var o = m(e);
if (o && window.getComputedStyle) n = window.getComputedStyle(o, ":before");
if (!n) return;
var i;
var r = n.content;
if (r && r != "none" && r != "normal") {
i = r.length;
if ((r[0] === '"' || r[0] === "'") && i > 2 && r[i - 1] === r[0]) r = r.substr(1, i - 2);
o.innerHTML = r || t;
} else {
o.removeAttribute("class");
}
}
function k() {
function o(e) {
if (window.console) a.warn(c(d("This web browser is too old to run Cockpit (missing $0)"), e));
m("login").style.display = "none";
m("login-details").style.display = "none";
m("unsupported-browser").style.display = "block";
document.body.className += " brand-unsupported-browser";
}
function e(t, e) {
var n;
try {
n = e[t];
} catch (e) {
h(c(d("The web browser configuration prevents Cockpit from running (inaccessible $0)"), t));
throw e;
}
if (n === undefined) {
o();
return false;
}
return true;
}
function t() {
/*
* Be certain to use parenthesis when checking CSS strings
* as Edge is oddly particular.
*
* Instead of "display: inline", use:
* "(display: inline)"
* or
* "display", "inline"
*/
var e = [].join.call(arguments, ": ");
if (!window.CSS.supports.apply(this, arguments)) {
h(c(d("The web browser configuration prevents Cockpit from running (inaccessible $0)"), e));
o(e);
return false;
}
return true;
}
return ("MozWebSocket" in window || e("WebSocket", window)) && e("XMLHttpRequest", window) && e("sessionStorage", window) && e("JSON", window) && e("defineProperty", Object) && e("console", window) && e("pushState", window.history) && e("textContent", document) && e("CSS", window) && e("supports", window.CSS) && t("display", "flex") && t("display", "grid");
}
function x(e) {
return e.replace(/^\s+|\s+$/g, "");
}
/* Sets values for application, url_root and login_path */ function S(e) {
var t = document.createElement("a");
var n = document.baseURI;
var o;
/* Some IEs don't support baseURI */ if (!n) {
o = document.getElementsByTagName("base");
if (o.length > 0) n = o[0].href; else n = "/";
}
e = e || "/";
t.href = n;
if (t.pathname != "/") {
s = t.pathname.replace(/^\/+|\/+$/g, "");
r.setItem("url-root", s);
if (s && e.indexOf("/" + s) === 0) e = e.replace("/" + s, "") || "/";
}
if (e.indexOf("/=") === 0) {
l.hostname = e.substring(2);
e = "/cockpit+" + e.split("/")[1];
} else if (e.indexOf("/cockpit/") !== 0 && e.indexOf("/cockpit+") !== 0) {
e = "/cockpit";
}
p = e.split("/")[1];
f = "/" + p + "/login";
if (s) f = "/" + s + f;
v = p;
w = f;
}
function T(e, t) {
// On keypress, only accept spacebar (enter acts as a click)
if (e && e.type === "keypress" && e.key !== " ") return;
// Stop the <a>'s click handler, otherwise it causes a page reload
if (e && e.type === "click") e.preventDefault();
if (t === undefined) t = m("server-group").style.display === "none";
m("option-group").setAttribute("data-state", t);
if (t) {
m("server-group").style.display = "block";
m("option-caret").setAttribute("class", "caret caret-down");
m("option-caret").setAttribute("className", "caret caret-down");
} else {
m("server-group").style.display = "none";
m("option-caret").setAttribute("class", "caret caret-right");
m("option-caret").setAttribute("className", "caret caret-right");
}
}
function e() {
window.onload = null;
i();
S(window.location.pathname);
/* Determine if we are nested or not, and switch styles */ if (window.location.pathname.indexOf("/" + s + "/cockpit/") === 0 || window.location.pathname.indexOf("/" + s + "/cockpit+") === 0) document.documentElement.setAttribute("class", "inline");
// Setup title
var e = l.page.title;
if (!e || p.indexOf("cockpit+=") === 0) e = l.hostname;
document.title = e;
if (p.indexOf("cockpit+=") === 0) {
m("brand").style.display = "none";
m("badge").style.visibility = "hidden";
} else {
b("badge", "");
b("brand", "Cockpit");
}
if (!k()) return;
m("show-other-login-options").addEventListener("click", T);
m("show-other-login-options").addEventListener("keypress", T);
m("server-clear").addEventListener("click", function() {
var e = m("server-field");
e.value = "";
e.focus();
});
/* Setup the user's last choice about the authorized button */ var t = r.getItem("authorized-default") || "";
if (t.indexOf("password") !== -1) m("authorized-input").checked = true;
var n = l["os-release"];
if (n) r.setItem("os-release", JSON.stringify(n));
var o = window.sessionStorage.getItem("logout-intent") == "explicit";
if (o) window.sessionStorage.removeItem("logout-intent");
/* Try automatic/kerberos authentication? */ if (u) {
m("login-details").style.display = "none";
m("login").style.display = "none";
if (o) {
O();
m("login-again").textContent = d("Login Again");
h(d("Logout Successful"));
} else {
I();
}
} else if (o) {
z();
} else {
C();
}
}
function C() {
var e = new XMLHttpRequest();
e.open("GET", f, true);
e.onreadystatechange = function() {
if (e.readyState == 4) {
if (e.status == 200) {
j(JSON.parse(e.responseText));
} else if (e.status == 401) {
z();
} else if (e.statusText) {
h(decodeURIComponent(e.statusText));
} else if (e.status === 0) {
z();
} else {
h(c(d("$0 error"), e.status));
}
}
};
e.send();
}
function O() {
var e = window.location.href.split("#", 2);
g = u.URL;
if (u.URL.indexOf("?") > -1) g += "&"; else g += "?";
g += "redirect_uri=" + encodeURIComponent(e[0]);
}
function I() {
var e = document.createElement("a");
if (!u.URL) return h(d("Cockpit authentication is configured incorrectly."));
var t = y(window.location.search);
if (!window.location.search && window.location.hash) t = y(window.location.hash.slice(1));
/* Not all providers allow hashes in redirect urls */ var n, o, i;
O();
if (t[u.TokenParam]) {
if (window.sessionStorage.getItem("login-wanted")) {
e.href = window.sessionStorage.getItem("login-wanted");
S(e.pathname);
}
n = t[u.TokenParam];
m("login-wait-validating").style.display = "block";
i = new XMLHttpRequest();
i.open("GET", f, true);
i.setRequestHeader("Authorization", "Bearer " + n);
i.onreadystatechange = function() {
if (i.readyState == 4) {
if (i.status == 200) {
j(JSON.parse(i.responseText));
} else {
o = $(i.getResponseHeader("WWW-Authenticate"), i.responseText);
if (o) P(o); else h(decodeURIComponent(i.statusText));
}
}
};
i.send();
} else if (t[u.ErrorParam]) {
h(t[u.ErrorParam]);
} else {
/* Store url we originally wanted in case we
* had to strip a hash or query params
*/
window.sessionStorage.setItem("login-wanted", window.location.href);
window.location = g;
}
}
function E() {
m("error-group").style.display = "none";
m("login-error-message").textContent = "";
}
function L(e, t) {
E();
if (e) {
/* OAuth failures are always fatal */
if (u) {
h(e);
} else {
N(t);
m("login-error-message").textContent = e;
m("error-group").style.display = "block";
}
}
}
function A(e) {
var t = m("server-field").value;
if (!t) {
L(e, false);
} else {
E();
m("login-error-message").textContent = e;
m("error-group").style.display = "block";
T(null, true);
N();
}
}
function R(e) {
var t = m("login-note");
if (e) {
t.style.display = "block";
t.textContent = e;
} else {
t.innerHTML = " ";
}
}
function H() {
return l.page.require_host && v.indexOf("cockpit+=") === -1;
}
function U() {
L(null);
var e;
var t = x(m("login-user-input").value);
if (t === "") {
L(d("User name cannot be empty"));
} else if (H() && m("server-field").value === "") {
L(d("Please specify the host to connect to"));
} else {
e = m("server-field").value;
if (e) {
p = "cockpit+=" + e;
f = w.replace("/" + v + "/", "/" + p + "/");
} else {
p = v;
f = w;
}
m("server-name").textContent = e || l.hostname;
m("login-button").removeEventListener("click", U);
/* When checked we tell the server to keep authentication */ var n = m("authorized-input").checked ? "password" : "";
var o = m("login-password-input").value;
r.setItem("authorized-default", n);
var i = {
Authorization: "Basic " + window.btoa(q(t + ":" + o)),
"X-Authorize": n
};
// allow unknown remote hosts with interactive logins with "Connect to:"
if (e) i["X-SSH-Connect-Unknown-Hosts"] = "yes";
J("GET", i, false);
}
}
function N(e) {
var t = l.page.connect;
var n = m("option-group").getAttribute("data-state");
m("login-wait-validating").style.display = "none";
m("login").style.visibility = "visible";
m("login").style.display = "block";
m("user-group").style.display = e ? "none" : "block";
m("password-group").style.display = e ? "none" : "block";
m("conversation-group").style.display = e ? "block" : "none";
m("login-button-text").textContent = d("Log In");
m("login-password-input").value = "";
if (H()) {
m("option-group").style.display = "none";
n = true;
} else {
m("option-group").style.display = !t || e ? "none" : "block";
}
if (!t || e) {
m("server-group").style.display = "none";
} else {
m("server-group").style.display = n ? "block" : "none";
}
m("login-button").removeAttribute("disabled");
if (!e) m("login-button").addEventListener("click", U);
}
function z() {
/* Show the login screen */
m("server-name").textContent = document.title;
R(d("Log in with your server user account."));
m("login-user-input").addEventListener("keydown", function(e) {
L(null);
if (e.which == 13) m("login-password-input").focus();
}, false);
var e = function(e) {
L(null);
if (e.which == 13) U();
};
m("login-password-input").addEventListener("keydown", e);
m("authorized-input").addEventListener("keydown", e);
N();
m("login-user-input").focus();
}
function P(e) {
var t = e.echo ? "text" : "password";
m("conversation-prompt").textContent = e.prompt;
var n = m("conversation-message");
var o = e.error || e.message;
if (o) {
n.textContent = o;
n.style.display = "block";
} else {
n.style.display = "none";
}
var i = m("conversation-input");
i.value = "";
if (e["default"]) i.value = e["default"];
i.setAttribute("type", t);
i.focus();
L("");
function r() {
m("conversation-input").removeEventListener("keydown", s);
m("login-button").removeEventListener("click", r);
L(null, true);
W(e.id, m("conversation-input").value);
}
function s(e) {
L(null, true);
if (e.which == 13) {
r();
}
}
m("conversation-input").addEventListener("keydown", s);
m("login-button").addEventListener("click", r);
N(true);
}
function q(e) {
return window.unescape(encodeURIComponent(e));
}
function $(e, t) {
var n;
var o;
var i;
var r;
if (!e) return null;
n = e.split(" ");
if (n[0].toLowerCase() !== "x-conversation" && n.length != 3) return null;
r = n[1];
try {
o = window.atob(n[2]);
} catch (e) {
if (window.console) a.error("Invalid prompt data", e);
return null;
}
try {
i = JSON.parse(t);
} catch (e) {
if (window.console) a.log("Got invalid JSON response for prompt data", e);
i = {};
}
i.id = r;
i.prompt = o;
return i;
}
function J(e, t, n) {
m("login-button").setAttribute("disabled", "true");
var o = new XMLHttpRequest();
o.open("GET", f, true);
var i;
var r;
var s;
for (s in t) o.setRequestHeader(s, t[s]);
o.onreadystatechange = function() {
if (o.readyState != 4) {
return;
} else if (o.status == 200) {
var e = JSON.parse(o.responseText);
j(e);
} else if (o.status == 401) {
r = o.getResponseHeader("WWW-Authenticate");
if (r && r.toLowerCase().indexOf("x-conversation") === 0) {
i = $(r, o.responseText);
if (i) P(i); else h(d("Internal Error: Invalid challenge header"));
} else {
if (window.console) a.log(o.statusText);
if (o.statusText.indexOf("authentication-not-supported") > -1) {
var t = x(m("login-user-input").value);
h(c(d("The server refused to authenticate '$0' using password authentication, and no other supported authentication methods are available."), t));
} else if (o.statusText.indexOf("terminated") > -1) {
L(d("Authentication Failed: Server closed connection"));
} else if (o.statusText.indexOf("no-host") > -1) {
A(d("Unable to connect to that address"));
} else if (o.statusText.indexOf("unknown-hostkey") > -1) {
A(d("Refusing to connect. Hostkey is unknown"));
} else if (o.statusText.indexOf("unknown-host") > -1) {
A(d("Refusing to connect. Host is unknown"));
} else if (o.statusText.indexOf("invalid-hostkey") > -1) {
A(d("Refusing to connect. Hostkey does not match"));
} else if (n) {
L(d("Authentication failed"));
} else {
L(d("Wrong user name or password"));
}
}
} else if (o.status == 403) {
L(decodeURIComponent(o.statusText) || d("Permission denied"));
} else if (o.statusText) {
h(decodeURIComponent(o.statusText));
} else {
h(c(d("$0 error"), o.status));
}
m("login-button").removeAttribute("disabled");
};
o.send();
}
function W(e, t) {
var n = {
Authorization: "X-Conversation " + e + " " + window.btoa(q(t))
};
J("GET", n, true);
}
function M(e) {
// Force a reload if not triggered below
// because only the hash part of the url
// changed
var t = window.setTimeout(function() {
t = null;
window.location.reload(true);
}, 100);
if (e && e != window.location.href) window.location = e;
// cancel forced reload if we are reloading
window.onbeforeunload = function() {
if (t) window.clearTimeout(t);
t = null;
};
}
function X(n) {
var e = "/" + p + "/@localhost/";
if (s) e = "/" + s + e;
var o = e + "shell/index.html";
var i = new XMLHttpRequest();
i.open("GET", e + "manifests.json", true);
i.onreadystatechange = function() {
if (i.readyState == 4) {
if (i.status == 200) {
var e = JSON.parse(i.responseText);
var t = e ? e["base1"] : {};
if (!t["version"] || t["version"] < "119.x") {
M(o);
} else M(n);
} else {
M(o);
}
}
};
i.send();
}
function G(e, t, n) {
var o = 0;
while (o < e.length) {
var i = e.key(o);
if (n && i.indexOf("cockpit") !== 0) e.removeItem(i); else if (i.indexOf(t) === 0) e.removeItem(i); else o++;
}
}
function _(e) {
/* Clear anything not prefixed with
* different application from sessionStorage
*/
G(window.sessionStorage, p, true);
/* Clear anything prefixed with our application
* and login-data, but not other non-application values.
*/ r.removeItem("login-data");
G(r, p, false);
var t;
if (e && e["login-data"]) {
t = JSON.stringify(e["login-data"]);
/* login-data is tied to the auth cookie, since
* cookies are available after the page
* session ends login-data should be too.
*/ r.setItem(p + "login-data", t);
/* Backwards compatbility for packages that aren't application prefixed */ r.setItem("login-data", t);
}
/* URL Root is set by cockpit ws and shouldn't be prefixed
* by application
*/ if (s) r.setItem("url-root", s);
}
function j(e) {
var t = window.sessionStorage.getItem("login-wanted");
var n = m("server-field").value;
if (n && p != v) {
t = "/=" + n;
if (s) t = "/" + s + t;
}
/* clean up sessionStorage. clear anything that isn't prefixed
* with an application and anything prefixed with our application.
*/ G(window.sessionStorage, p, false);
_(e);
/* Make sure that the base1 version is new enough to handle
* urls that reference machines.
*/ if (p.indexOf("cockpit+=") === 0) {
X(t);
} else {
M(t);
}
}
window.onload = e;
})(window.console);
//# sourceMappingURL=login.min.js.map </script>
<style>
#option-group,.btn,.cross,button{cursor:pointer}
.btn,label{font-weight:600}
.btn,img{vertical-align:middle}
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;font-size:62.5%;-webkit-tap-highlight-color:transparent}
body{margin:0;font-family:"Open Sans",Helvetica,Arial,sans-serif;font-size:12px;line-height:1.66666667;background-color:#fff}
a{background:0 0;color:#0099d3;text-decoration:none}
.btn,.btn:active{background-image:none}
a:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
a:active,a:hover{outline:0}
a:focus,a:hover{color:#00618a;text-decoration:underline}
img{border:0}
button,input,select,textarea{font-family:inherit;margin:0;font-size:inherit;line-height:inherit}
button,input{line-height:normal}
.btn,.form-control{line-height:1.66666667}
button,select{text-transform:none}
button{-webkit-appearance:button;overflow:visible}
button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}
*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}
p{margin:0 0 10px}
.container{margin-right:auto;margin-left:auto;padding-left:20px;padding-right:20px}
.form-group,.row{margin-right:-20px}
.container:after,.container:before,.row:after,.row:before{content:" ";display:table}
.container:after,.row:after{clear:both}
@media (min-width:768px){.container{width:760px}
}
@media (min-width:992px){.container{width:980px}
}
@media (min-width:1200px){.container{width:1180px}
}
.row{margin-left:-20px}
.col-lg-5,.col-lg-7,.col-md-10,.col-md-2,.col-md-6,.col-sm-1,.col-sm-10,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-5,.col-sm-6,.col-sm-7,.col-xs-12{position:relative;min-height:1px;padding-left:20px;padding-right:20px}
.col-xs-12{float:left;width:100%}
@media (min-width:768px){.col-sm-1,.col-sm-10,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-5,.col-sm-6,.col-sm-7{float:left}
.col-sm-12{width:100%}
.col-sm-10{width:83.33333333333334%}
.col-sm-7{width:58.333333333333336%}
.col-sm-6{width:50%}
.col-sm-5{width:41.66666666666667%}
.col-sm-3{width:25%}
.col-sm-2{width:16.666666666666664%}
.col-sm-1{width:8.333333333333332%}
.col-sm-offset-2{margin-left:16.666666666666664%}
.control-label{text-align:right}
}
@media (min-width:992px){.col-md-10,.col-md-2,.col-md-6{float:left}
.col-md-10{width:83.33333333333334%}
.col-md-6{width:50%}
.col-md-2{width:16.666666666666664%}
}
@media (min-width:1200px){.col-lg-5,.col-lg-7{float:left}
.col-lg-7{width:58.333333333333336%}
.col-lg-5{width:41.66666666666667%}
}
label{display:inline-block;margin-bottom:5px}
.form-control{height:26px;color:#333}
.form-control[type=text],.form-control[type=password]{display:block;width:100%;padding:2px 6px;font-size:12px;background-color:#fff;background-image:none;border:1px solid #bababa;border-radius:1px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}
.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}
.form-control:-moz-placeholder{color:#999;font-style:italic}
.form-control::-moz-placeholder{color:#999;font-style:italic;opacity:1}
.form-control:-ms-input-placeholder{color:#999;font-style:italic}
.form-control::-webkit-input-placeholder{color:#999;font-style:italic}
.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}
.control-label{margin-top:0;margin-bottom:0;padding-top:3px}
.form-group{margin-left:-20px}
.form-group:after{clear:both;margin-bottom:15px}
.form-group:after,.form-group:before{content:" ";display:table}
.btn{display:inline-block;margin-bottom:0;text-align:center;border:1px solid transparent;white-space:nowrap;padding:2px 6px;font-size:12px;border-radius:1px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;-o-user-select:none;user-select:none;-webkit-box-shadow:0 2px 3px rgba(0,0,0,.1);box-shadow:0 2px 3px rgba(0,0,0,.1)}
.btn:focus{outline:dotted thin;outline:-webkit-focus-ring-color auto 5px;outline-offset:-2px}
.btn:focus,.btn:hover{color:#4d5258;text-decoration:none}
.alert-danger,.btn-primary,.login-pf .container .help-block,body{color:#fff}
.btn:active{outline:0;-webkit-box-shadow:inset 0 2px 8px rgba(0,0,0,.2);box-shadow:inset 0 2px 8px rgba(0,0,0,.2)}
.btn-lg{padding:6px 10px;font-size:14px;line-height:1.33;border-radius:1px}
@-ms-viewport{width:device-width}
.btn-primary{background-color:#189ad1;background-image:-webkit-linear-gradient(top,#1cace8 0,#1998cc 100%);background-image:linear-gradient(to bottom,#1cace8 0,#1998cc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff1cace8', endColorstr='#ff1998cc', GradientType=0);border-color:#267da1}
.btn-primary:active,.btn-primary:focus,.btn-primary:hover{background-color:#189ad1;background-image:none;border-color:#267da1;color:#fff}
.btn-primary:active{background-image:none}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:400;src:url(cockpit/static/fonts/OpenSans-Regular-webfont.woff) format('woff')}
@font-face{font-family:'Open Sans';font-style:normal;font-weight:700;src:url(cockpit/static/fonts/OpenSans-Bold-webfont.woff) format('woff')}
.form-control:hover{border-color:#7BB2DD}
.login-pf{height:100%}
.login-pf #brand{position:relative;top:-70px}
.login-pf #brand img{display:block;margin:0 auto;max-width:100%}
@media (min-width:768px){.login-pf #brand img{margin:0;text-align:left}
}
.login-pf #badge{display:block;margin:20px auto 70px;position:relative;text-align:center}
.login-pf .container{background-color:#181818;background-color:rgba(255,255,255,.055);clear:right;padding-bottom:40px;padding-top:20px;width:auto}
@media (min-width:768px){.login-pf #badge{float:right;margin-right:64px;margin-top:50px}
.login-pf .container{bottom:13%;padding-left:80px;position:absolute;width:100%}
}
.login-pf .container .details p:first-child{border-top:1px solid #474747;padding-top:25px;margin-top:25px}
@media (min-width:768px){.login-pf .container .login-area{border-right:1px solid #474747}
.login-pf .container .details{padding-left:40px}
.login-pf .container .details p:first-child{border-top:0;padding-top:0;margin-top:0}
}
.login-pf .container .details p{margin-bottom:2px}
.login-pf .container .control-label{font-size:13px;font-weight:400;text-align:left}
.login-pf .container .form-group:last-child,.login-pf .container .form-group:last-child .help-block:last-child{margin-bottom:0}
@-webkit-keyframes rotation{from{-webkit-transform:rotate(0)}
to{-webkit-transform:rotate(359deg)}
}
@keyframes rotation{from{transform:rotate(0)}
to{transform:rotate(359deg)}
}
.spinner{-webkit-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-bottom:4px solid rgba(0,0,0,.25);border-left:4px solid rgba(0,0,0,.25);border-right:4px solid rgba(0,0,0,.25);border-radius:100%;border-top:4px solid rgba(0,0,0,.75);height:24px;margin:4px 0 0;position:relative;width:24px}
.alert{padding:7px 11px;margin-bottom:20px;border:2px solid transparent;border-radius:1px}
.alert-danger{background:0 0;border-color:#c00;font-weight:700}
#option-group{margin-left:-20px;margin-right:-20px}
#option-group a{color:inherit}
#server-group:before{clear:both;margin-top:5px}
.login-fatal{font-size:130%}
.unsupported-browser ul{color:#aaa;display:inline-block;margin:0 auto;text-align:left}
.unsupported-browser a{color:#fff;font-weight:700;text-decoration:underline}
.cross,.inline .container .help-block{color:#000}
.login-browser-recommendations{margin-top:6rem}
@media screen and (max-width:480px){.unsupported-browser .container>.row>.col-sm-12{position:static}
}
@media screen and (min-width:481px){.brand-unsupported-browser #brand{margin-left:-40px;position:absolute;text-align:center;width:100%}
.unsupported-browser{font-size:140%;margin-left:-30px;text-align:center}
.unsupported-browser-heading{font-size:3rem;left:50%;margin:0 0 0 -32rem;position:absolute;text-align:center;top:-16rem;width:64rem}
.login-browser-recommendations h3{font-weight:400;margin-top:0}
}
.caret,.server-box{position:relative}
#login-wait-validating div{float:left}
.conversation-prompt{white-space:normal;word-wrap:break-word}
.control-label{white-space:nowrap;font-size:13px}
.spinner{border-color:rgba(255,255,255,.75) rgba(255,255,255,.25) rgba(255,255,255,.25)}
.inline #badge,.inline #brand,.inline #login-details{display:none}
.inline body{background:0 0!important;color:#000}
@media (min-width:768px){.login-button-container{float:right}
}
.caret{display:inline-block;top:4px}
.caret-down{transform:rotate(90deg);-moz-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform-origin:8px 8px;-moz-transform-origin:8px 8px;-webkit-transform-origin:8px 8px}
.cross{position:absolute;right:25px;top:2px;font-weight:700;font-size:14px;opacity:.7}
#option-group:hover svg,.cross:hover{opacity:1}
#option-group div{margin-left:-3px;margin-top:3px;margin-bottom:10px}
#option-group svg{opacity:.7}
#authorized-input{width:13px;height:13px;padding:0;vertical-align:bottom;margin:8px 5px 3px 0}
#login-button{padding:7px}
#login-button .spinner{display:none}
#login-button[disabled]{padding:0;background-color:#333;background-image:none;border-color:#555}
#login-button[disabled] .spinner{display:inline-block}
#login-button[disabled] #login-button-text,.hide-before:before{display:none}
@media (max-width:480px){.login-pf{display:flex;flex-direction:column-reverse;height:auto;position:relative}
.row{display:flex;flex-direction:column}
.login-pf .container{width:100%}
.login-pf #badge{max-width:33vw;margin:3rem auto;height:8rem;padding:0;background-position:50% 100%}
.container>.row>.col-sm-12{order:1;position:absolute;bottom:0;left:0;width:100%;text-align:center}
.login-pf #brand{position:static;font-size:inherit;background-position:50% 50%}
.details{text-align:center}
}
#server-name { display: none;}
/*# sourceMappingURL=login.min.css.map */ </style>
<link href="cockpit/static/branding.css" type="text/css" rel="stylesheet">
</head>
<body class="login-pf">
<span id="badge">
</span>
<div class="container">
<div class="row">
<div class="col-sm-12">
<div id="brand" class="hide-before">
</div><!--/#brand-->
</div><!--/.col-*-->
<div id="login" class="col-sm-7 col-md-6 col-lg-5 login-area" style="visibility: hidden;">
<div role="form">
<div id="error-group" class="alert alert-danger" hidden>
<span id="login-error-message"></span>
</div>
<div id="conversation-group" class="form-group" hidden>
<div class="col-sm-12 col-md-12">
<div id="conversation-message"></div>
<label id="conversation-prompt" for="conversation-input"></label>
</div>
<div class="col-sm-12 col-md-12">
<input type="password" class="form-control" id="conversation-input">
</div>
</div>
<div id="user-group" class="form-group">
<label for="login-user-input" class="col-sm-2 col-md-2 control-label" translate>User name</label>
<div class="col-sm-10 col-md-10">
<input type="text" class="form-control" id="login-user-input" autocorrect="off" autocapitalize="none" autofocus>
</div>
</div>
<div id="password-group" class="form-group">
<label for="login-password-input" class="col-sm-2 col-md-2 control-label" translate>Password</label>
<div class="col-sm-10 col-md-10">
<input type="password" class="form-control" id="login-password-input">
</div>
<div class="col-sm-2 col-md-2"></div>
<div class="col-sm-10 col-md-10">
<input type="checkbox" class="form-control" id="authorized-input" checked>
<label for="authorized-input" class="control-label" translate>Reuse my password for privileged tasks</label>
</div>
</div>
<div id="option-group">
<div class="col-sm-5 col-md-5">
<i id="option-caret" class="caret caret-right" aria-hidden="true">
<svg height="16" width="16" viewBox="0 0 16 16">
<polygon fill="#ffffff" points="4,0 4,14 12,7">
</polygon>
</svg>
</i>
<a href="#" id="show-other-login-options" translate>Other Options</a>
</div>
</div>
<div id="server-group" class="form-group" hidden>
<label title="Log in to another system. Leave blank to log in to the local system." for="server-field" class="col-sm-2 col-md-2 control-label" translate>Connect to</label>
<div class="col-sm-10 col-md-10 server-box">
<input type="text" class="form-control" id="server-field">
<span class="cross" id="server-clear" aria-hidden="true">❌</span>
</div>
</div>
<div class="form-group">
<div class="col-md-3 col-sm-3 login-button-container">
<button class="btn btn-primary btn-lg col-xs-12" id="login-button">
<span class="spinner"></span>
<span id="login-button-text" translate>Log In</span>
</button>
</div>
</div>
</div>
</div><!--/.col-*-->
<div class="col-sm-5 col-md-6 col-lg-7 details" id="login-details">
<p>
<label class="control-label"><span translate></span><b id="server-name"></b></label>
</p>
<p id="login-note" class="login-note"></p>
</div><!--/.col-*-->
<div class="col-sm-5 col-md-6 col-lg-7" id="login-wait-validating" hidden>
<div class="col-sm-4">
<span class="help-block" translate>Validating authentication token</span>
</div>
<div class="col-sm-1">
<div class="spinner col-xs-15">
</div>
</div>
</div>
<div class="col-sm-12" id="login-fatal" hidden>
<span id="login-fatal-message"></span>
<a id="login-again" translate hidden>Try Again</a>
</div>
<div class="unsupported-browser col-sm-12" id="unsupported-browser" hidden>
<h2 classname="unsupported-browser-heading" translate>A modern browser is required for security, reliability, and performance.</h2>
<div class="login-browser-recommendations">
<div class="col-sm-6">
<h3 translate>Download a new browser for free</h3>
<ul>
<li><a href="https://firefox.com/">Mozilla Firefox</a> / Linux, Windows, macOS</li>
<li><a href="https://google.com/chrome">Google Chrome</a> / Linux, Windows, macOS</li>
</ul>
</div>
<div class="col-sm-6">
<h3 translate>Or use a bundled browser</h3>
<ul>
<li><a href="https://microsoftedge.com/">Microsoft Edge</a> / Windows 10+</li>
<li><a href="https://apple.com/safari/">Apple Safari</a> / macOS</li>
</ul>
</div>
</div>
</div>
</div><!--/.row-->
</div><!--/.container-->
<style>
#badge {display: none !important;}
.kod-loading {position: absolute;left: 0;right: 0;top: 0;bottom: 0;z-index: 999;background: #fff;display: flex;justify-content: center;align-items: center;}
.kod-loading img {width: 64px;}
.kod-page.login-pf .container {background: transparent;}
#login-button {border:1px solid #007cee;background:#1890ff;border-radius:3px;}
/* 登录框样式 */
body.login-pf {
padding: 0px;
margin: 0px;
color: #666;
display: flex;
height: 100vh;
justify-content: center;
align-items: center;
background: url(./cockpit/static/kod-login/11.jpg) no-repeat center center;
width: 100%;
background-size: cover;
}
.login-pf .container {
box-shadow: 0 20px 60px rgb(0 0 0 / 40%), 0 0 150px rgb(0 0 0 / 40%);
width: 430px;
max-width: 430px;
border-radius: 4px;
margin: auto;
position: absolute;
z-index: 100;
max-height: 95%;
left: 50%;
margin-left: -215px;
padding: 10px 15px 50px 15px;
animation-duration: 0.5s;
bottom: inherit;
color: #666;
border: 1px solid rgba(180,180,180,0.4);
background: rgba(255,255,255,0.8) !important;
display: none;
}
.login-pf .container>.row{
margin: 0px;
}
.login-pf #brand {
top: 0px !important;
height: 120px;
line-height: 120px;
text-align: center;
margin-bottom: 20px;
border-bottom: 1px solid #eee;
width: 100%;
background: none;
font-size: 18pt;
}
#login {
width: 100%;
border: none;
}
#login>[role=form] {
position: relative;
}
#login>[role=form] #option-group {
display: none !important;
}
#login>[role=form] #error-group {
position: absolute;
bottom: -50px;
margin-left: 66px;
border: none;
color: #f04134;
padding: 0px;
}
#login #user-group #login-user-input,
#login #password-group #login-password-input {
line-height: 25px;
border: 1px solid #bbb;
height: 30px;
padding: 0px;
padding-left: 10px;
border-radius: 3px;
width: 85%;
}
#login #password-group label[for='authorized-input'] {
font-size: 12px;
}
#login #password-group>div:last-child {
visibility: hidden;
}
#login-button {
font-size: 14px;
border-radius: 4px;
border: 1px solid #1890ff;
background-color: #1890ff;
box-shadow: inset 0 1px 0 hsl(0deg 0% 100% / 10%), 0 1px 1px rgb(0 0 0 / 10%);
text-shadow: 0 -1px 0 rgb(0 0 0 / 10%);
transition: all .16s;
height: 34.6px;
width: 85%;
outline: none;
}
#login-button:hover {
background: #007aea
}
#login-button:active {
box-shadow: 0 0 0 3px rgba(56,144,255,0.2)
}
#login-button[disabled] {
border-color: #1890ff;
background: #1890ff;
}
#login-details {
float: right;
padding-left: 20px;
}
</style>
<script type="text/javascript" charset="utf-8">
window.addEventListener('load', function(){
var getById = function(id) {
if (typeof id === "string" && !! id) {
return document.getElementById(id);
}
};
var getAccount = function(){
var query = window.location.search.substring(1).split('&');
var idx = query[0].indexOf('=');
var key = query[0].slice(0, idx);
var value = query[0].slice(idx + 1);
if (key != 'token' || !value) return false;
var token = decodeURI(atob(value));
var len = parseInt(token.charAt(0));
token = token.slice(1);
var code = decodeURI(atob(token));
var name = code.substring(len, len*2);
var password = code.substring(0, len) + '' + code.substring(len*2);
return {name: name, password: password};
}
var loginSubmit = function(){
hasSubmit = true;
getById('login-user-input').value = account.name;
getById('login-password-input').value = account.password;
getById('login-button').click();
}
var loginShow = function(){
document.querySelector('.login-pf .container').style.display = 'block';
}
// 0.页面图标
var headHTML = document.getElementsByTagName('head')[0].innerHTML;
headHTML += '<link head-type="kod" href="./cockpit/static/kod-login/icon.png" rel="icon" type="image/x-icon">';
document.getElementsByTagName('head')[0].innerHTML = headHTML;
// 替换title
getById('brand').innerHTML = '控制面板';
// 隐藏登录页logo
// getById('badge').style.display = 'none';
// 登录按钮
// getById('login-button').style = 'border:1px solid #007cee;background:#1890ff;border-radius:3px;';
document.getElementsByTagName('body')[0].classList.add('kod-page');
document.querySelector('.login-button-container').classList.add('col-sm-10','col-md-10');
getById('login-details').classList.remove('col-sm-5', 'col-md-6', 'col-lg-7');
getById('login-details').classList.add('col-sm-10','col-md-10','col-lg-10');
// 非跳转访问不作处理
if (!document.referrer) return loginShow();
// 1.追加loading
var pageLoading = document.createElement('div');
pageLoading.className = 'kod-loading';
pageLoading.innerHTML = '<img src="./cockpit/static/kod-login/loading-page.gif" />';
document.body.appendChild(pageLoading);
// 2.获取账号密码,登录跳转
var hasSubmit = false;
var account = getAccount();
if (!account) {
loginShow();
pageLoading.style.display = 'none';
}
// 监听登录结果,处理样式
window.addEventListener('ajaxReadyStateChange', function (e) {
e.detail.onload = function () {
if (e.detail.readyState == 4 && e.detail.status != 200) {
// 访问页面时会自动请求一次登录(是否存在不主动请求的情况?),401失败,失败后清空密码,此时再填充账号密码触发登录
var pathname = e.detail.responseURL.replace(location.origin, '');
if (pathname == '/cockpit/login' && account && !hasSubmit) {
return loginSubmit();
}
if (hasSubmit) {
hasSubmit = false;
getById('error-group').style.display = 'none';
getById('login-user-input').value = '';
loginShow();
pageLoading.style.display = 'none';
}
}
}
});
});
//监听ajax请求
(function () {
if ( typeof window.CustomEvent === "function" ) return false;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
(function () {
function ajaxEventTrigger(event) {
var ajaxEvent = new CustomEvent(event, { detail: this });
window.dispatchEvent(ajaxEvent);
}
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
})();
</script>
</body>
</html>