@model LoginViewModel
|
<!DOCTYPE html>
|
<html lang="zh-CN">
|
<head>
|
<meta charset="UTF-8" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<title>登录 - Board</title>
|
<link rel="stylesheet" href="@Model.BasePath/static/style.css" />
|
</head>
|
<body class="page-login">
|
<main class="card">
|
<h1>Board 门户</h1>
|
<p class="muted">请使用域账号登录</p>
|
<form id="loginForm" class="form" autocomplete="on">
|
<label>
|
<span>用户名</span>
|
<input type="text" name="username" required autofocus />
|
</label>
|
<label>
|
<span>密码</span>
|
<input type="password" name="password" required />
|
</label>
|
<p id="loginError" class="error" hidden></p>
|
<button type="submit" class="btn primary login-submit">登录</button>
|
</form>
|
<div class="login-winauth">
|
<button type="button" class="btn winauth" id="btnWinAuth">一键登录(Windows 集成)</button>
|
</div>
|
</main>
|
<script>
|
(function () {
|
const params = new URLSearchParams(location.search);
|
const basePath = "@Model.BasePath";
|
const next = params.get("next") || (basePath + "/");
|
const form = document.getElementById("loginForm");
|
const err = document.getElementById("loginError");
|
const negotiateErr = params.get("negotiate_error");
|
if (negotiateErr) {
|
err.textContent = negotiateErr;
|
err.hidden = false;
|
const clean = new URLSearchParams();
|
const n = params.get("next");
|
if (n) clean.set("next", n);
|
const qs = clean.toString();
|
history.replaceState({}, "", basePath + "/login" + (qs ? "?" + qs : ""));
|
}
|
form.addEventListener("submit", async (e) => {
|
e.preventDefault();
|
err.hidden = true;
|
const fd = new FormData(form);
|
const body = {
|
username: fd.get("username"),
|
password: fd.get("password"),
|
next: next.startsWith(basePath + "/") ? next : (basePath + "/"),
|
};
|
const res = await fetch(basePath + "/api/login", {
|
method: "POST",
|
headers: { "Content-Type": "application/json" },
|
credentials: "include",
|
body: JSON.stringify(body),
|
});
|
const data = await res.json().catch(() => ({}));
|
if (!res.ok || !data.ok) {
|
err.textContent = data.error || "登录失败";
|
err.hidden = false;
|
return;
|
}
|
location.href = data.redirect || (basePath + "/");
|
});
|
|
document.getElementById("btnWinAuth").addEventListener("click", () => {
|
err.hidden = true;
|
const nextSafe = next.startsWith(basePath + "/") ? next : (basePath + "/");
|
const q = new URLSearchParams({ next: nextSafe });
|
location.href = basePath + "/api/winauth/negotiate?" + q.toString();
|
});
|
})();
|
</script>
|
</body>
|
</html>
|
|