228 Zeilen
8.5 KiB
HTML
228 Zeilen
8.5 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Backup-Codes{% endblock %}
|
|
|
|
{% block extra_css %}
|
|
<style>
|
|
.success-icon {
|
|
font-size: 5rem;
|
|
animation: bounce 0.5s ease-in-out;
|
|
}
|
|
@keyframes bounce {
|
|
0%, 100% { transform: translateY(0); }
|
|
50% { transform: translateY(-20px); }
|
|
}
|
|
.backup-code {
|
|
font-family: 'Courier New', monospace;
|
|
font-size: 1.3rem;
|
|
font-weight: bold;
|
|
letter-spacing: 2px;
|
|
padding: 8px 15px;
|
|
background-color: #f8f9fa;
|
|
border: 2px dashed #dee2e6;
|
|
border-radius: 5px;
|
|
display: inline-block;
|
|
margin: 5px;
|
|
}
|
|
.backup-codes-container {
|
|
background-color: #fff;
|
|
border: 2px solid #dee2e6;
|
|
border-radius: 10px;
|
|
padding: 30px;
|
|
margin: 20px 0;
|
|
}
|
|
.action-buttons .btn {
|
|
margin: 5px;
|
|
}
|
|
@media print {
|
|
.no-print {
|
|
display: none !important;
|
|
}
|
|
.backup-codes-container {
|
|
border: 1px solid #000;
|
|
}
|
|
}
|
|
</style>
|
|
{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="container py-4">
|
|
<div class="row">
|
|
<div class="col-md-8 offset-md-2">
|
|
<!-- Success Message -->
|
|
<div class="text-center mb-4">
|
|
<div class="success-icon text-success">✅</div>
|
|
<h1 class="mt-3">2FA erfolgreich aktiviert!</h1>
|
|
<p class="lead text-muted">Ihre Zwei-Faktor-Authentifizierung ist jetzt aktiv.</p>
|
|
</div>
|
|
|
|
<!-- Backup Codes Card -->
|
|
<div class="card shadow">
|
|
<div class="card-header bg-warning text-dark">
|
|
<h4 class="mb-0">
|
|
<span style="font-size: 1.5rem; vertical-align: middle;">⚠️</span>
|
|
Wichtig: Ihre Backup-Codes
|
|
</h4>
|
|
</div>
|
|
<div class="card-body">
|
|
<div class="alert alert-info mb-4">
|
|
<strong>Was sind Backup-Codes?</strong><br>
|
|
Diese Codes ermöglichen Ihnen den Zugang zu Ihrem Account, falls Sie keinen Zugriff auf Ihre Authenticator-App haben.
|
|
<strong>Jeder Code kann nur einmal verwendet werden.</strong>
|
|
</div>
|
|
|
|
<!-- Backup Codes Display -->
|
|
<div class="backup-codes-container text-center">
|
|
<h5 class="mb-4">Ihre 8 Backup-Codes:</h5>
|
|
<div class="row justify-content-center">
|
|
{% for code in backup_codes %}
|
|
<div class="col-md-6 col-lg-4 mb-3">
|
|
<div class="backup-code">{{ code }}</div>
|
|
</div>
|
|
{% endfor %}
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Action Buttons -->
|
|
<div class="text-center action-buttons no-print">
|
|
<button type="button" class="btn btn-primary btn-lg" onclick="downloadCodes()">
|
|
💾 Als Datei speichern
|
|
</button>
|
|
<button type="button" class="btn btn-secondary btn-lg" onclick="printCodes()">
|
|
🖨️ Drucken
|
|
</button>
|
|
<button type="button" class="btn btn-info btn-lg" onclick="copyCodes()">
|
|
📋 Alle kopieren
|
|
</button>
|
|
</div>
|
|
|
|
<hr class="my-4">
|
|
|
|
<!-- Security Tips -->
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="alert alert-danger">
|
|
<h6>❌ Nicht empfohlen:</h6>
|
|
<ul class="mb-0 small">
|
|
<li>Im selben Passwort-Manager wie Ihr Passwort</li>
|
|
<li>Als Foto auf Ihrem Handy</li>
|
|
<li>In einer unverschlüsselten Datei</li>
|
|
<li>Per E-Mail an sich selbst</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="alert alert-success">
|
|
<h6>✅ Empfohlen:</h6>
|
|
<ul class="mb-0 small">
|
|
<li>Ausgedruckt in einem Safe</li>
|
|
<li>In einem separaten Passwort-Manager</li>
|
|
<li>Verschlüsselt auf einem USB-Stick</li>
|
|
<li>An einem sicheren Ort zu Hause</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Confirmation -->
|
|
<div class="text-center mt-4 no-print">
|
|
<div class="form-check mb-3">
|
|
<input class="form-check-input" type="checkbox" id="confirmSaved" onchange="checkConfirmation()">
|
|
<label class="form-check-label" for="confirmSaved">
|
|
Ich habe die Backup-Codes sicher gespeichert
|
|
</label>
|
|
</div>
|
|
<a href="{{ url_for('auth.profile') }}" class="btn btn-lg btn-success" id="continueBtn" style="display: none;">
|
|
✅ Weiter zum Profil
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const backupCodes = {{ backup_codes | tojson }};
|
|
|
|
function checkConfirmation() {
|
|
const checkbox = document.getElementById('confirmSaved');
|
|
const continueBtn = document.getElementById('continueBtn');
|
|
continueBtn.style.display = checkbox.checked ? 'inline-block' : 'none';
|
|
}
|
|
|
|
function downloadCodes() {
|
|
const content = `V2 Admin Panel - Backup Codes
|
|
=====================================
|
|
Generiert am: ${new Date().toLocaleString('de-DE')}
|
|
|
|
WICHTIG: Bewahren Sie diese Codes sicher auf!
|
|
Jeder Code kann nur einmal verwendet werden.
|
|
|
|
Ihre 8 Backup-Codes:
|
|
--------------------
|
|
${backupCodes.map((code, i) => `${i + 1}. ${code}`).join('\n')}
|
|
|
|
Sicherheitshinweise:
|
|
-------------------
|
|
✓ Bewahren Sie diese Codes getrennt von Ihrem Passwort auf
|
|
✓ Speichern Sie sie an einem sicheren physischen Ort
|
|
✓ Teilen Sie diese Codes niemals mit anderen
|
|
✓ Jeder Code funktioniert nur einmal
|
|
|
|
Bei Verlust Ihrer Authenticator-App:
|
|
------------------------------------
|
|
1. Gehen Sie zur Login-Seite
|
|
2. Geben Sie Benutzername und Passwort ein
|
|
3. Klicken Sie auf "Backup-Code verwenden"
|
|
4. Geben Sie einen dieser Codes ein
|
|
|
|
Nach Verwendung eines Codes sollten Sie neue Backup-Codes generieren.`;
|
|
|
|
const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
|
|
const url = window.URL.createObjectURL(blob);
|
|
const a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = `v2-backup-codes-${new Date().toISOString().split('T')[0]}.txt`;
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
window.URL.revokeObjectURL(url);
|
|
document.body.removeChild(a);
|
|
|
|
// Visual feedback
|
|
const btn = event.target;
|
|
const originalText = btn.innerHTML;
|
|
btn.innerHTML = '✅ Heruntergeladen!';
|
|
btn.classList.remove('btn-primary');
|
|
btn.classList.add('btn-success');
|
|
setTimeout(() => {
|
|
btn.innerHTML = originalText;
|
|
btn.classList.remove('btn-success');
|
|
btn.classList.add('btn-primary');
|
|
}, 2000);
|
|
}
|
|
|
|
function printCodes() {
|
|
window.print();
|
|
}
|
|
|
|
function copyCodes() {
|
|
const codesText = backupCodes.join('\n');
|
|
navigator.clipboard.writeText(codesText).then(function() {
|
|
// Visual feedback
|
|
const btn = event.target;
|
|
const originalText = btn.innerHTML;
|
|
btn.innerHTML = '✅ Kopiert!';
|
|
btn.classList.remove('btn-info');
|
|
btn.classList.add('btn-success');
|
|
setTimeout(() => {
|
|
btn.innerHTML = originalText;
|
|
btn.classList.remove('btn-success');
|
|
btn.classList.add('btn-info');
|
|
}, 2000);
|
|
}).catch(function(err) {
|
|
alert('Fehler beim Kopieren. Bitte manuell kopieren.');
|
|
});
|
|
}
|
|
</script>
|
|
{% endblock %} |