nordabiz/templates/auth/2fa_backup_codes.html
Maciej Pienczyn 0dba52e9c4 feat: Add security features - 2FA, audit log, alerting
Security enhancements:
- Two-Factor Authentication (TOTP) for all users
  - Enable/disable 2FA in settings
  - Backup codes for recovery
  - Login flow with 2FA verification
- Audit log for admin actions
  - Track all sensitive operations
  - IP address and user agent logging
- Security alerts system
  - Alert types: brute_force, honeypot_hit, account_locked, geo_blocked
  - Email notifications for high/critical alerts
  - Dashboard for alert management
- Admin security dashboard (/admin/security)
  - View/acknowledge/resolve alerts
  - Unlock locked accounts
  - 2FA status overview

New files:
- security_service.py: Security utilities
- templates/auth/verify_2fa.html
- templates/auth/2fa_settings.html
- templates/auth/2fa_setup.html
- templates/auth/2fa_backup_codes.html
- templates/admin/security_dashboard.html

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 21:23:27 +01:00

218 lines
5.7 KiB
HTML

{% extends "base.html" %}
{% block title %}Kody zapasowe 2FA - Norda Biznes Hub{% endblock %}
{% block container_class %}container-narrow{% endblock %}
{% block extra_css %}
<style>
.backup-container {
max-width: 600px;
margin: 0 auto;
padding: var(--spacing-2xl) 0;
}
.backup-card {
background-color: var(--surface);
padding: var(--spacing-2xl);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-lg);
}
.backup-header {
text-align: center;
margin-bottom: var(--spacing-xl);
}
.backup-header .icon {
font-size: 3rem;
margin-bottom: var(--spacing-md);
}
.backup-header h1 {
font-size: var(--font-size-2xl);
color: var(--text-primary);
margin-bottom: var(--spacing-sm);
}
.success-message {
background-color: #dcfce7;
color: #166534;
padding: var(--spacing-md);
border-radius: var(--radius);
text-align: center;
margin-bottom: var(--spacing-xl);
}
.warning-box {
background-color: #fef3c7;
border: 1px solid #fcd34d;
border-radius: var(--radius-lg);
padding: var(--spacing-lg);
margin-bottom: var(--spacing-xl);
}
.warning-box h3 {
color: #92400e;
font-size: var(--font-size-base);
margin-bottom: var(--spacing-sm);
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
.warning-box p {
color: #78350f;
font-size: var(--font-size-sm);
margin: 0;
}
.codes-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--spacing-md);
margin-bottom: var(--spacing-xl);
}
.code-item {
background-color: var(--background);
padding: var(--spacing-md);
border-radius: var(--radius);
font-family: monospace;
font-size: var(--font-size-lg);
text-align: center;
letter-spacing: 0.1em;
border: 1px solid var(--border);
}
.actions {
display: flex;
gap: var(--spacing-md);
justify-content: center;
flex-wrap: wrap;
}
.btn {
padding: var(--spacing-md) var(--spacing-xl);
border: none;
border-radius: var(--radius);
font-size: var(--font-size-base);
font-weight: 600;
cursor: pointer;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
}
.btn-primary {
background-color: var(--primary);
color: white;
}
.btn-secondary {
background-color: var(--background);
color: var(--text-primary);
border: 1px solid var(--border);
}
.btn:hover {
opacity: 0.9;
}
.instructions {
background-color: var(--background);
border-radius: var(--radius-lg);
padding: var(--spacing-lg);
margin-top: var(--spacing-xl);
}
.instructions h3 {
font-size: var(--font-size-base);
color: var(--text-primary);
margin-bottom: var(--spacing-md);
}
.instructions ul {
margin: 0;
padding-left: var(--spacing-lg);
color: var(--text-secondary);
font-size: var(--font-size-sm);
}
.instructions li {
margin-bottom: var(--spacing-xs);
}
@media print {
.backup-card {
box-shadow: none;
}
.actions, .instructions {
display: none;
}
}
</style>
{% endblock %}
{% block content %}
<div class="backup-container">
<div class="backup-card">
<div class="backup-header">
<div class="icon"></div>
<h1>2FA zostało włączone!</h1>
</div>
<div class="success-message">
Uwierzytelnianie dwuskładnikowe jest teraz aktywne dla Twojego konta.
</div>
<div class="warning-box">
<h3>⚠️ Zapisz te kody w bezpiecznym miejscu!</h3>
<p>
Kody zapasowe pozwolą Ci zalogować się, jeśli stracisz dostęp do aplikacji uwierzytelniającej.
Każdy kod można użyć tylko raz. Po zamknięciu tej strony nie będziesz mógł ich ponownie zobaczyć.
</p>
</div>
<div class="codes-grid">
{% for code in backup_codes %}
<div class="code-item">{{ code }}</div>
{% endfor %}
</div>
<div class="actions">
<button class="btn btn-secondary" onclick="window.print();">
🖨️ Drukuj
</button>
<button class="btn btn-secondary" onclick="copyAllCodes();">
📋 Kopiuj wszystkie
</button>
<a href="{{ url_for('settings_2fa') }}" class="btn btn-primary">
Kontynuuj →
</a>
</div>
<div class="instructions">
<h3>Jak używać kodów zapasowych:</h3>
<ul>
<li>Podczas logowania wybierz "Użyj kodu zapasowego"</li>
<li>Wprowadź jeden z powyższych kodów</li>
<li>Każdy kod działa tylko raz - po użyciu jest nieaktywny</li>
<li>Gdy zostanie Ci mało kodów, wygeneruj nowe w ustawieniach</li>
</ul>
</div>
</div>
</div>
<script>
function copyAllCodes() {
const codes = [{% for code in backup_codes %}'{{ code }}'{% if not loop.last %}, {% endif %}{% endfor %}];
const text = 'NordaBiznes - Kody zapasowe 2FA\n\n' + codes.join('\n');
navigator.clipboard.writeText(text).then(() => {
alert('Kody zostały skopiowane do schowka!');
});
}
</script>
{% endblock %}