feat: Armarium v1.1.0 — dashboard, auth, 2FA, SMTP, settings, deploy
Dashboard: - ApexCharts bar chart (income vs fixed costs vs expenses) and donut chart - KPI cards: income, fixed costs, savings rate with configurable goal - Greeting with time-of-day and locale-aware date/time display Authentication & security: - Email-based login (no username), case-insensitive lookup - JWT access/refresh tokens with rotation and blacklist - TOTP 2FA with QR code, backup codes (copy + PDF export) - 2FA recovery via email code - Cloudflare Turnstile CAPTCHA on login and register Email flows: - Email verification on registration (24h token) - Password reset flow (15min token, anti-enumeration) - Brevo SMTP integration with HTML + plaintext email templates - Notification emails: 2FA recovery, password changed, email changed Settings page: - 2FA management (enable/disable, QR, backup codes) - Active sessions list with per-device revoke - Data export: ZIP with 6 PDFs via fpdf2 - Notification preferences (3 toggles) - Danger zone: account deletion with mandatory export + confirmation phrase UI & layout: - Sidebar with collapsible/flyout mode, Angular signal-based dropdowns - Dark mode (class-based), language switcher (DE/FR/IT/EN) - Mobile-responsive layout with touch-friendly targets - Roboto font via @fontsource (GDPR-compliant, no Google CDN) - Pure Tailwind CSS v3 Infrastructure: - Forgejo Actions CI/CD pipeline (auto-deploy on push to main) - Gunicorn + Nginx + PostgreSQL production setup - Rate limiting, HSTS, secure cookies, CSRF protection
This commit is contained in:
@@ -0,0 +1,34 @@
|
||||
{% extends "emails/base.html" %}
|
||||
|
||||
{% block subject %}Armarium – 2FA-Wiederherstellung{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">Hallo,</p>
|
||||
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">
|
||||
Du hast eine 2FA-Wiederherstellung für dein Armarium-Konto angefordert.
|
||||
Gib den folgenden Code auf der Anmeldeseite ein:
|
||||
</p>
|
||||
|
||||
<!-- Code Box -->
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:0 0 24px;">
|
||||
<tr>
|
||||
<td align="center" style="background-color:#f5f3ff;border:1px solid #ddd6fe;border-radius:8px;padding:20px;">
|
||||
<span style="font-size:28px;font-weight:700;letter-spacing:6px;color:#7c3aed;font-family:monospace;">{{ code }}</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 8px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Gültig für <strong>15 Minuten</strong> · Einmalig verwendbar
|
||||
</p>
|
||||
|
||||
<p style="margin:0 0 24px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere diese E-Mail.
|
||||
Dein Konto ist weiterhin sicher.
|
||||
</p>
|
||||
|
||||
<p style="margin:0;font-size:15px;color:#374151;line-height:1.6;">
|
||||
– Das Armarium-Team
|
||||
</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,18 @@
|
||||
Armarium – 2FA-Wiederherstellung
|
||||
|
||||
Hallo,
|
||||
|
||||
Du hast eine 2FA-Wiederherstellung für dein Armarium-Konto angefordert.
|
||||
|
||||
Dein Wiederherstellungscode lautet:
|
||||
|
||||
{{ code }}
|
||||
|
||||
Gib diesen Code auf der Anmeldeseite ein.
|
||||
Er ist 15 Minuten gültig und kann nur einmal verwendet werden.
|
||||
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere diese E-Mail.
|
||||
Dein Konto ist weiterhin sicher.
|
||||
|
||||
– Das Armarium-Team
|
||||
https://www.armarium.ch
|
||||
@@ -0,0 +1,46 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="de">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>{% block subject %}Armarium{% endblock %}</title>
|
||||
</head>
|
||||
<body style="margin:0;padding:0;background-color:#f3f4f6;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;">
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="background-color:#f3f4f6;padding:40px 16px;">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="max-width:600px;">
|
||||
|
||||
<!-- Header -->
|
||||
<tr>
|
||||
<td style="background-color:#7c3aed;border-radius:12px 12px 0 0;padding:28px 40px;">
|
||||
<span style="font-size:22px;font-weight:700;color:#ffffff;letter-spacing:-0.3px;">Armarium</span>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Body -->
|
||||
<tr>
|
||||
<td style="background-color:#ffffff;padding:36px 40px;">
|
||||
{% block body %}{% endblock %}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<!-- Footer -->
|
||||
<tr>
|
||||
<td style="background-color:#f9fafb;border-top:1px solid #e5e7eb;border-radius:0 0 12px 12px;padding:20px 40px;">
|
||||
<p style="margin:0;font-size:12px;color:#9ca3af;line-height:1.6;">
|
||||
Du erhältst diese E-Mail, weil du ein Konto bei
|
||||
<a href="https://www.armarium.ch" style="color:#7c3aed;text-decoration:none;">armarium.ch</a> hast.
|
||||
<br>Falls du diese E-Mail nicht erwartet hast, kannst du sie ignorieren.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,33 @@
|
||||
{% extends "emails/base.html" %}
|
||||
|
||||
{% block subject %}Armarium – Deine E-Mail-Adresse wurde geändert{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">Hallo,</p>
|
||||
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">
|
||||
Die E-Mail-Adresse deines Armarium-Kontos wurde geändert.
|
||||
</p>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:0 0 24px;">
|
||||
<tr>
|
||||
<td style="background-color:#f5f3ff;border-radius:8px;padding:16px 20px;">
|
||||
<p style="margin:0 0 6px;font-size:12px;font-weight:600;color:#6b7280;text-transform:uppercase;letter-spacing:0.05em;">Neue Adresse</p>
|
||||
<p style="margin:0;font-size:15px;color:#374151;font-weight:600;">{{ new_email }}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:0 0 24px;">
|
||||
<tr>
|
||||
<td style="background-color:#fef2f2;border-left:3px solid #ef4444;border-radius:0 6px 6px 0;padding:14px 18px;">
|
||||
<p style="margin:0;font-size:13px;color:#374151;line-height:1.6;">
|
||||
Falls du diese Änderung nicht selbst vorgenommen hast, kontaktiere uns umgehend unter
|
||||
<a href="mailto:support@armarium.ch" style="color:#7c3aed;text-decoration:none;">support@armarium.ch</a>.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0;font-size:15px;color:#374151;line-height:1.6;">– Das Armarium-Team</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,12 @@
|
||||
Armarium – Deine E-Mail-Adresse wurde geändert
|
||||
|
||||
Hallo,
|
||||
|
||||
Die E-Mail-Adresse deines Armarium-Kontos wurde geändert.
|
||||
|
||||
Neue Adresse: {{ new_email }}
|
||||
|
||||
Falls du diese Änderung nicht selbst vorgenommen hast, kontaktiere uns umgehend unter support@armarium.ch.
|
||||
|
||||
– Das Armarium-Team
|
||||
https://www.armarium.ch
|
||||
@@ -0,0 +1,24 @@
|
||||
{% extends "emails/base.html" %}
|
||||
|
||||
{% block subject %}Armarium – Dein Passwort wurde geändert{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">Hallo,</p>
|
||||
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">
|
||||
Dein Armarium-Passwort wurde erfolgreich geändert.
|
||||
</p>
|
||||
|
||||
<table role="presentation" width="100%" cellpadding="0" cellspacing="0" style="margin:0 0 24px;">
|
||||
<tr>
|
||||
<td style="background-color:#f5f3ff;border-left:3px solid #7c3aed;border-radius:0 6px 6px 0;padding:14px 18px;">
|
||||
<p style="margin:0;font-size:13px;color:#374151;line-height:1.6;">
|
||||
Falls du diese Änderung nicht selbst vorgenommen hast, kontaktiere uns umgehend unter
|
||||
<a href="mailto:support@armarium.ch" style="color:#7c3aed;text-decoration:none;">support@armarium.ch</a>.
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0;font-size:15px;color:#374151;line-height:1.6;">– Das Armarium-Team</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,10 @@
|
||||
Armarium – Dein Passwort wurde geändert
|
||||
|
||||
Hallo,
|
||||
|
||||
Dein Armarium-Passwort wurde erfolgreich geändert.
|
||||
|
||||
Falls du diese Änderung nicht selbst vorgenommen hast, kontaktiere uns umgehend unter support@armarium.ch.
|
||||
|
||||
– Das Armarium-Team
|
||||
https://www.armarium.ch
|
||||
@@ -0,0 +1,35 @@
|
||||
{% extends "emails/base.html" %}
|
||||
|
||||
{% block subject %}Armarium – Passwort zurücksetzen{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">Hallo,</p>
|
||||
|
||||
<p style="margin:0 0 24px;font-size:15px;color:#374151;line-height:1.6;">
|
||||
Du hast eine Anfrage zum Zurücksetzen deines Passworts gestellt.
|
||||
Klicke auf den Button, um ein neues Passwort zu wählen:
|
||||
</p>
|
||||
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:0 0 28px;">
|
||||
<tr>
|
||||
<td style="border-radius:8px;background-color:#7c3aed;">
|
||||
<a href="{{ link }}" target="_blank"
|
||||
style="display:inline-block;padding:14px 28px;font-size:15px;font-weight:600;color:#ffffff;text-decoration:none;border-radius:8px;">
|
||||
Neues Passwort setzen
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 8px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Gültig für <strong>15 Minuten</strong>. Falls der Button nicht funktioniert, kopiere diesen Link:
|
||||
</p>
|
||||
<p style="margin:0 0 24px;font-size:12px;color:#7c3aed;line-height:1.6;word-break:break-all;">{{ link }}</p>
|
||||
|
||||
<p style="margin:0 0 24px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere diese E-Mail.
|
||||
Dein Passwort bleibt unverändert.
|
||||
</p>
|
||||
|
||||
<p style="margin:0;font-size:15px;color:#374151;line-height:1.6;">– Das Armarium-Team</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,16 @@
|
||||
Armarium – Passwort zurücksetzen
|
||||
|
||||
Hallo,
|
||||
|
||||
Du hast eine Anfrage zum Zurücksetzen deines Passworts gestellt.
|
||||
|
||||
Link zum Zurücksetzen:
|
||||
{{ link }}
|
||||
|
||||
Gültig für 15 Minuten.
|
||||
|
||||
Falls du diese Anfrage nicht gestellt hast, ignoriere diese E-Mail.
|
||||
Dein Passwort bleibt unverändert.
|
||||
|
||||
– Das Armarium-Team
|
||||
https://www.armarium.ch
|
||||
@@ -0,0 +1,33 @@
|
||||
{% extends "emails/base.html" %}
|
||||
|
||||
{% block subject %}Armarium – E-Mail-Adresse bestätigen{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<p style="margin:0 0 20px;font-size:15px;color:#374151;line-height:1.6;">Hallo,</p>
|
||||
|
||||
<p style="margin:0 0 24px;font-size:15px;color:#374151;line-height:1.6;">
|
||||
Willkommen bei Armarium! Bitte bestätige deine E-Mail-Adresse, um dein Konto zu aktivieren.
|
||||
</p>
|
||||
|
||||
<table role="presentation" cellpadding="0" cellspacing="0" style="margin:0 0 28px;">
|
||||
<tr>
|
||||
<td style="border-radius:8px;background-color:#7c3aed;">
|
||||
<a href="{{ link }}" target="_blank"
|
||||
style="display:inline-block;padding:14px 28px;font-size:15px;font-weight:600;color:#ffffff;text-decoration:none;border-radius:8px;">
|
||||
E-Mail-Adresse bestätigen
|
||||
</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="margin:0 0 8px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Gültig für <strong>24 Stunden</strong>. Falls der Button nicht funktioniert, kopiere diesen Link:
|
||||
</p>
|
||||
<p style="margin:0 0 24px;font-size:12px;color:#7c3aed;line-height:1.6;word-break:break-all;">{{ link }}</p>
|
||||
|
||||
<p style="margin:0 0 24px;font-size:13px;color:#6b7280;line-height:1.6;">
|
||||
Falls du dieses Konto nicht erstellt hast, kannst du diese E-Mail ignorieren.
|
||||
</p>
|
||||
|
||||
<p style="margin:0;font-size:15px;color:#374151;line-height:1.6;">– Das Armarium-Team</p>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,15 @@
|
||||
Armarium – E-Mail-Adresse bestätigen
|
||||
|
||||
Hallo,
|
||||
|
||||
Willkommen bei Armarium! Bitte bestätige deine E-Mail-Adresse, um dein Konto zu aktivieren.
|
||||
|
||||
Link zur Bestätigung:
|
||||
{{ link }}
|
||||
|
||||
Gültig für 24 Stunden.
|
||||
|
||||
Falls du dieses Konto nicht erstellt hast, kannst du diese E-Mail ignorieren.
|
||||
|
||||
– Das Armarium-Team
|
||||
https://www.armarium.ch
|
||||
Reference in New Issue
Block a user