0.2.0 (2026-04-16)¶
Security-focused release: multi-factor authentication, stronger password policy, platform hardening, and admin user management.
✨ Features¶
- Multi-Factor Authentication (MFA) with support for two simultaneous methods: email (via Resend) and TOTP app (Google Authenticator, Authy).
- Configurable default MFA method when both methods are active.
- "Try another method" option during login verification to switch between available MFA methods.
- Single-use recovery codes (8 codes in XXXXX-XXXXX format) as backup when primary MFA method is unavailable.
- Full MFA management from the profile Security section: enable, disable, change default method, regenerate recovery codes.
- Non-intrusive banner for users without active MFA, recommending activation after login.
- Differentiated session duration: 2 days without MFA, 5 days with MFA enabled.
- Stronger password policy: minimum 12 characters, at least one uppercase, lowercase, digit, and special character. Cannot match email.
- Real-time password strength indicator on registration, change, and reset password forms.
- Admin user management panel with paginated list, search, MFA status, subscription plan, and registration date.
- Admin option to disable MFA for any user (account recovery for locked-out users).
- User export to Excel (.xlsx) with MFA data, plan, and registration date.
- MFA emails with multi-language support (Spanish/English) based on user's selected language.
🔧 Internal¶
- Security headers middleware: X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy, Permissions-Policy, Cache-Control, Strict-Transport-Security (production).
- Login rate limiting: maximum 10 attempts per IP per minute.
- Account lockout: temporary 15-minute lockout after 5 consecutive failed attempts.
- New backend
mfa/module following SOLID pattern (interfaces, repository, services, schemas, routes). - Dependencies added:
pyotp,qrcode[pil],openpyxl.
⬆️ Upgrades¶
- Password policy updated from 8 to 12 minimum characters with special character requirement.