84 lines
2.7 KiB
JavaScript
84 lines
2.7 KiB
JavaScript
// login.js
|
|
document.addEventListener("DOMContentLoaded", () => {
|
|
const form = document.getElementById("login-form");
|
|
const errorBox = document.getElementById("error");
|
|
const usernameInput = document.getElementById("username");
|
|
const passwordInput = document.getElementById("password");
|
|
const twoFactorInput = document.getElementById("two-factor-code");
|
|
const twoFactorGroup = document.getElementById("two-factor-group");
|
|
const submitButton = document.getElementById("login-submit");
|
|
|
|
let pendingTwoFactorToken = null;
|
|
|
|
if (!form) return;
|
|
|
|
function showError(message) {
|
|
errorBox.textContent = message || "Login failed.";
|
|
errorBox.style.display = "block";
|
|
}
|
|
|
|
function storeTokens(data) {
|
|
localStorage.setItem("access_token", data.access_token);
|
|
localStorage.setItem("refresh_token", data.refresh_token);
|
|
}
|
|
|
|
function switchToTwoFactorMode(token) {
|
|
pendingTwoFactorToken = token;
|
|
usernameInput.disabled = true;
|
|
passwordInput.disabled = true;
|
|
twoFactorGroup.style.display = "block";
|
|
twoFactorInput.required = true;
|
|
twoFactorInput.focus();
|
|
submitButton.textContent = "Verify code";
|
|
}
|
|
|
|
form.addEventListener("submit", async (e) => {
|
|
e.preventDefault();
|
|
errorBox.style.display = "none";
|
|
submitButton.disabled = true;
|
|
|
|
try {
|
|
let response;
|
|
|
|
if (pendingTwoFactorToken) {
|
|
response = await fetch("/api/login/2fa", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
two_factor_token: pendingTwoFactorToken,
|
|
code: twoFactorInput.value.trim()
|
|
})
|
|
});
|
|
} else {
|
|
response = await fetch("/api/login", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
username: usernameInput.value,
|
|
password: passwordInput.value
|
|
})
|
|
});
|
|
}
|
|
|
|
if (!response.ok) {
|
|
const text = await response.text();
|
|
throw new Error(text);
|
|
}
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.requires_2fa) {
|
|
switchToTwoFactorMode(data.two_factor_token);
|
|
return;
|
|
}
|
|
|
|
storeTokens(data);
|
|
window.location.href = "/dashboard";
|
|
} catch (err) {
|
|
showError(err.message);
|
|
} finally {
|
|
submitButton.disabled = false;
|
|
}
|
|
});
|
|
});
|