second commit
This commit is contained in:
85
static/js/login.js
Normal file
85
static/js/login.js
Normal file
@ -0,0 +1,85 @@
|
||||
(() => {
|
||||
"use strict";
|
||||
|
||||
const form = document.getElementById("login-form");
|
||||
const passwordFields = document.getElementById("password-fields");
|
||||
const totpFields = document.getElementById("totp-fields");
|
||||
const enrollBox = document.getElementById("enroll-box");
|
||||
const recoveryBox = document.getElementById("recovery-box");
|
||||
const errorBox = document.getElementById("error-box");
|
||||
const submitBtn = document.getElementById("submit-btn");
|
||||
|
||||
let pendingToken = null;
|
||||
let mode = "password"; // password -> totp | enroll_start -> enroll_confirm -> done
|
||||
|
||||
function showError(msg) {
|
||||
errorBox.textContent = msg;
|
||||
}
|
||||
|
||||
async function postJson(url, body) {
|
||||
const res = await fetch(url, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
credentials: "same-origin",
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
const data = await res.json().catch(() => ({}));
|
||||
if (!res.ok) {
|
||||
throw new Error(data.detail || "Unbekannter Fehler");
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
form.addEventListener("submit", async (ev) => {
|
||||
ev.preventDefault();
|
||||
showError("");
|
||||
|
||||
try {
|
||||
if (mode === "password") {
|
||||
const username = document.getElementById("username").value.trim();
|
||||
const password = document.getElementById("password").value;
|
||||
const result = await postJson("/auth/login", { username, password });
|
||||
pendingToken = result.pending_token;
|
||||
|
||||
passwordFields.style.display = "none";
|
||||
totpFields.style.display = "block";
|
||||
|
||||
if (!result.totp_enrolled) {
|
||||
mode = "enroll_start";
|
||||
const enroll = await postJson("/auth/totp/enroll/start", { pending_token: pendingToken });
|
||||
document.getElementById("qr-img").src = "data:image/png;base64," + enroll.qr_png_base64;
|
||||
enrollBox.style.display = "block";
|
||||
mode = "enroll_confirm";
|
||||
submitBtn.textContent = "TOTP bestaetigen & einrichten";
|
||||
} else {
|
||||
mode = "totp";
|
||||
submitBtn.textContent = "Code bestaetigen";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === "totp") {
|
||||
const code = document.getElementById("totp-code").value.trim();
|
||||
await postJson("/auth/login/totp", { pending_token: pendingToken, code });
|
||||
window.location.href = "/dashboard";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === "enroll_confirm") {
|
||||
const code = document.getElementById("totp-code").value.trim();
|
||||
const result = await postJson("/auth/totp/enroll/confirm", { pending_token: pendingToken, code });
|
||||
recoveryBox.style.display = "block";
|
||||
document.getElementById("recovery-codes").textContent = result.recovery_codes.join("\n");
|
||||
submitBtn.textContent = "Weiter zum Dashboard";
|
||||
mode = "done";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode === "done") {
|
||||
window.location.href = "/dashboard";
|
||||
}
|
||||
} catch (err) {
|
||||
showError(err.message);
|
||||
}
|
||||
});
|
||||
})();
|
||||
Reference in New Issue
Block a user