137 lines
6.2 KiB
HTML
137 lines
6.2 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta content="width=device-width, initial-scale=1.0" name="viewport">
|
|
<title langtag="title-login"></title>
|
|
<!-- Mainly scripts -->
|
|
<!-- Latest compiled and minified CSS -->
|
|
<link href="{{.web_base_url}}/static/css/fontawesome.min.css" rel="stylesheet">
|
|
<link href="{{.web_base_url}}/static/css/solid.min.css" rel="stylesheet">
|
|
<link href="{{.web_base_url}}/static/css/bootstrap.min.css" rel="stylesheet">
|
|
<link href="{{.web_base_url}}/static/css/style.css?v={{.version}}" rel="stylesheet">
|
|
<!-- Latest compiled and minified JavaScript -->
|
|
<script src="{{.web_base_url}}/static/js/jquery-3.7.1.min.js"></script>
|
|
<script src="{{.web_base_url}}/static/js/bootstrap.min.js"></script>
|
|
<script src="{{.web_base_url}}/static/js/jsencrypt.min.js"></script>
|
|
<!-- Latest compiled and minified Locales -->
|
|
<script src="{{.web_base_url}}/static/js/language.js?v={{.version}}" type="text/javascript"></script>
|
|
</head>
|
|
|
|
<body class="login-page">
|
|
<nav class="navbar navbar-static-top navbar-right navbar-login">
|
|
<div class="ml-auto d-flex align-items-center" style="gap: 0.5rem;">
|
|
<button id="theme-toggle" class="btn btn-outline-secondary" onclick="toggleTheme()">
|
|
<i class="fa fa-moon"></i>
|
|
</button>
|
|
<span class="btn-group dropdown">
|
|
<button id="languagemenu" class="btn btn-outline-primary dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
|
|
<i class="fa fa-globe-asia fa-lg"></i>
|
|
<span></span>
|
|
</button>
|
|
<ul class="dropdown-menu"></ul>
|
|
</span>
|
|
</div>
|
|
</nav>
|
|
|
|
<div class="login-card">
|
|
<div class="login-header">
|
|
<img src="{{.web_base_url}}/static/img/nps.svg?v={{.version}}" alt="Logo" style="width: 32px; height: 32px; margin-right: 20px !important;">
|
|
<div class="navbar-brand" style="font-weight: lighter; font-size: 2.0rem !important"><h1 langtag="title-login"></h1></div>
|
|
</div>
|
|
<div class="login-body">
|
|
<form class="m-t" onsubmit="return false;">
|
|
<div class="form-group position-relative">
|
|
<i class="fas fa-user-circle input-icon"></i>
|
|
<input class="form-control" langtag="word-username" name="username" placeholder="username" required="" type="text">
|
|
</div>
|
|
<div class="form-group position-relative">
|
|
<i class="fas fa-key input-icon"></i>
|
|
<input class="form-control" langtag="word-password" name="password" placeholder="password" required="" type="password">
|
|
</div>
|
|
{{if eq true .captcha_open}}
|
|
<div class="form-group captcha-group position-relative">
|
|
<div class="flex-fill">
|
|
<i class="fas fa-shield-alt input-icon"></i>
|
|
<input class="form-control" langtag="word-captcha" name="captcha" placeholder="captcha" required="">
|
|
</div>
|
|
<div class="captcha-container">
|
|
{{create_captcha}}
|
|
</div>
|
|
</div>
|
|
{{end}}
|
|
<button class="btn btn-primary block full-width m-b" langtag="word-login" onclick="if (this.form.reportValidity()) login()" type="submit"></button>
|
|
{{if eq true .register_allow}}
|
|
<p class="text-muted text-center">
|
|
<small langtag="info-noaccount"></small>
|
|
<small><a href="{{.web_base_url}}/login/register" langtag="word-register"></a></small>
|
|
</p>
|
|
{{end}}
|
|
</form>
|
|
</div>
|
|
<div class="footer">
|
|
<div class="float-right">
|
|
<span langtag="word-readmore"></span>
|
|
<strong><a href="https://github.com/djylb/nps" langtag="word-go"></a></strong>
|
|
</div>
|
|
<div><strong langtag="word-copyright"></strong> <span langtag="application"></span> © 2018-{{.year}}</div>
|
|
</div>
|
|
|
|
<script type="text/javascript">
|
|
window.nps = {
|
|
web_base_url: "{{.web_base_url}}",
|
|
version: "{{.version}}",
|
|
publicKey: `{{.public_key}}`,
|
|
loginNonce: "{{.login_nonce}}"
|
|
};
|
|
function encryptWithRSA(plain) {
|
|
const crypt = new JSEncrypt();
|
|
crypt.setPublicKey(window.nps.publicKey);
|
|
return crypt.encrypt(plain);
|
|
}
|
|
function login() {
|
|
const data = {};
|
|
$("form").serializeArray().forEach(item => {
|
|
data[item.name] = item.value;
|
|
});
|
|
const ts = Date.now();
|
|
const payload = JSON.stringify({
|
|
n: window.nps.loginNonce,
|
|
t: ts,
|
|
p: data.password
|
|
});
|
|
data.password = encryptWithRSA(payload);
|
|
$.ajax({
|
|
type: "POST",
|
|
url: window.nps.web_base_url + "/login/verify",
|
|
data: data,
|
|
success: function (res) {
|
|
if (res.status) {
|
|
showMsg(langreply(res.msg), 'success', 1000, function() {
|
|
window.location.href = window.nps.web_base_url + "/index/index";
|
|
});
|
|
} else {
|
|
showMsg(langreply(res.msg), 'error', 3000, function() {
|
|
if (res.nonce) {
|
|
window.nps.loginNonce = res.nonce;
|
|
}
|
|
if (res.cert) {
|
|
window.nps.publicKey = res.cert;
|
|
}
|
|
{{if eq true .captcha_open}}
|
|
var $img = $('.captcha-img');
|
|
if ($img.length) {
|
|
$img.trigger('click');
|
|
}
|
|
$('input[name="captcha"]').val('');
|
|
{{end}}
|
|
});
|
|
}
|
|
}
|
|
});
|
|
return false;
|
|
}
|
|
</script>
|
|
</body>
|
|
</html>
|