- User kann nach TOTP-Eingabe das Gerät für 1–30 Tage speichern - Cookie mfa_trust mit zufälligem Token, gespeichert in trusted_devices[] - Nächstes POST /login: Cookie prüfen → gültiges Token → MFA überspringen - Abgelaufene Einträge werden beim Login automatisch bereinigt - Logout + MFA-Deaktivierung löschen Cookie + trusted_devices - mfa_verify.html: checkbox + days-select (1/3/7/14/30 Tage)
96 lines
3.9 KiB
HTML
96 lines
3.9 KiB
HTML
<!doctype html>
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>Sicherheitscode eingeben - CANCOM Signage</title>
|
|
<link rel="stylesheet"
|
|
href="https://unpkg.com/@tabler/core@1.0.0-beta20/dist/css/tabler.min.css">
|
|
<link rel="stylesheet"
|
|
href="https://cdn.jsdelivr.net/npm/@tabler/icons-webfont@latest/tabler-icons.min.css">
|
|
{% include "_styles.html" %}
|
|
<script>
|
|
(() => {
|
|
const stored = window.localStorage.getItem("signage-theme");
|
|
const theme = stored === "dark" || stored === "light" ? stored : "light";
|
|
document.documentElement.setAttribute("data-bs-theme", theme);
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div class="page">
|
|
|
|
{% include "_header.html" %}
|
|
|
|
<div class="page-wrapper d-flex align-items-center justify-content-center">
|
|
<div class="container-xl">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-5">
|
|
<div class="card card-md">
|
|
<div class="card-body">
|
|
<h2 class="text-center mb-2">Sicherheitscode</h2>
|
|
<p class="text-center text-muted mb-4">Gib den 6-stelligen Code aus deiner Authenticator-App ein.</p>
|
|
|
|
{% if error %}
|
|
<div class="alert alert-danger text-center" role="alert">{{ error }}</div>
|
|
{% endif %}
|
|
|
|
<form method="post">
|
|
<div class="mb-3">
|
|
<input type="text" name="code" class="form-control form-control-lg text-center"
|
|
placeholder="000000" inputmode="numeric" autocomplete="one-time-code"
|
|
maxlength="6" pattern="[0-9]{6}" required autofocus>
|
|
</div>
|
|
<button class="btn btn-primary w-100 mb-2" type="submit">Bestätigen</button>
|
|
<div class="form-check mb-2">
|
|
<input class="form-check-input" type="checkbox" id="remember" name="remember" value="7">
|
|
<label class="form-check-label" for="remember">
|
|
Gerät für
|
|
<select class="form-select form-select-sm d-inline-block w-auto" id="remember_days" onchange="document.getElementById('remember').value=this.value">
|
|
<option value="1">1 Tag</option>
|
|
<option value="3">3 Tage</option>
|
|
<option value="7" selected>7 Tage</option>
|
|
<option value="14">14 Tage</option>
|
|
<option value="30">30 Tage</option>
|
|
</select>
|
|
merken
|
|
</label>
|
|
</div>
|
|
<script>
|
|
(function() {
|
|
var cb = document.getElementById('remember');
|
|
var sel = document.getElementById('remember_days');
|
|
cb.addEventListener('change', function() {
|
|
if (this.checked) this.value = sel.value;
|
|
});
|
|
sel.addEventListener('change', function() {
|
|
if (cb.checked) cb.value = this.value;
|
|
});
|
|
})();
|
|
</script>
|
|
</form>
|
|
|
|
<p class="text-center text-muted mt-3 small">
|
|
<a href="#" onclick="document.getElementById('recovery-form').style.display='block';this.style.display='none';return false;">
|
|
Code verloren?
|
|
</a>
|
|
</p>
|
|
<form id="recovery-form" method="post" style="display:none;">
|
|
<input type="hidden" name="action" value="recovery">
|
|
<div class="mb-2">
|
|
<label class="form-label">Recovery-Code eingeben</label>
|
|
<input type="text" name="code" class="form-control" placeholder="ABCD-123">
|
|
</div>
|
|
<button class="btn btn-warning w-100" type="submit">Mit Recovery-Code anmelden</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% include "_footer.html" %}
|
|
</div>
|
|
</body>
|
|
</html> |