Ajoute la réinitialisation de mot de passe par email (SMTP)

Un lien "Mot de passe oublié ?" (login.html) mène à /forgot-password :
si l'adresse saisie correspond à un compte, un jeton à haute entropie
(secrets.token_urlsafe, valable 1h) est généré et envoyé par email via
smtplib (auth/send_email.py, aucune dépendance ajoutée) — configuré
uniquement par variables d'environnement (SMTP_HOST/PORT/USER/PASSWORD/
FROM, voir .env.example et docker-compose.prod.yml), n'importe quel
serveur SMTP existant convient (Mailcow compris).

Seul le hash SHA-256 du jeton est stocké (auth/password_reset.py, table
_password_reset_tokens) : un jeton envoyé par email reste inutilisable
même en cas de fuite de la base. Le même message générique s'affiche que
l'adresse corresponde à un compte ou non, pour ne jamais permettre à ce
formulaire de servir à deviner quelles adresses sont déjà inscrites. Un
échec d'envoi (SMTP non configuré) est journalisé côté serveur seulement,
jamais révélé à l'utilisateur.

/reset-password/<token> vérifie le jeton (non expiré, non déjà utilisé),
applique les mêmes règles de mot de passe fort qu'à l'inscription (même
schéma visuel), puis consomme le jeton et remet à zéro le compteur
anti-bruteforce du compte (auth/set_password.py) — une identité prouvée
par email est une voie de récupération légitime même pour un compte
verrouillé.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-08-28 20:50:49 +02:00
co-authored by Claude Sonnet 5
parent 9efe119936
commit d5a84413d1
15 changed files with 418 additions and 2 deletions
+10
View File
@@ -6,6 +6,16 @@ services:
- "${PORT:-5050}:5050"
volumes:
- forge_projects:/app/projects
environment:
# Réinitialisation de mot de passe par email (voir auth/send_email.py)
# — laissés vides ici tant qu'ils ne sont pas définis dans le .env du
# serveur : l'appli continue de fonctionner sans, l'envoi d'email
# échoue juste silencieusement côté utilisateur (logué côté serveur).
SMTP_HOST: ${SMTP_HOST:-}
SMTP_PORT: ${SMTP_PORT:-587}
SMTP_USER: ${SMTP_USER:-}
SMTP_PASSWORD: ${SMTP_PASSWORD:-}
SMTP_FROM: ${SMTP_FROM:-}
volumes:
forge_projects: