Envoie les emails via un relais SMTP configurable plutôt qu'en direct-to-MX

Ajoute le bloc "smtp" (host, port, identifiants, TLS) dans config.json,
plus fiable et plus simple à opérer qu'une livraison directe au MX du
destinataire. data/config.json n'est plus versionné (secrets), remplacé
par data/config.example.json.
This commit is contained in:
Antoine
2026-07-17 21:46:52 +02:00
parent 1d9380736e
commit e6a523f76f
10 changed files with 297 additions and 64 deletions

View File

@ -11,22 +11,46 @@
<div class="login-error">{{ error }}</div>
{% endif %}
{% if step == "email" %}
<form method="post" action="/login" class="login-form">
<label class="login-label" for="username">Identifiant</label>
<label class="login-label" for="email">Adresse email</label>
<input
id="username"
id="email"
class="login-input"
type="text"
name="username"
autocomplete="username"
type="email"
name="email"
value="{{ email }}"
autocomplete="email"
autofocus
placeholder="prenom.nom"
pattern="[a-zA-Z0-9_\-]{1,32}"
placeholder="prenom.nom@domaine.fr"
required
>
<p class="login-hint">Lettres, chiffres, tirets — 1 à 32 caractères.</p>
<button class="login-btn" type="submit">Entrer</button>
<button class="login-btn" type="submit">Continuer</button>
</form>
{% elif step == "password" %}
<form method="post" action="/login/password" class="login-form">
<input type="hidden" name="email" value="{{ email }}">
<label class="login-label">{{ email }}</label>
<input
id="password"
class="login-input"
type="password"
name="password"
autocomplete="current-password"
autofocus
placeholder="Mot de passe"
required
>
<button class="login-btn" type="submit">Se connecter</button>
</form>
{% elif step == "sent" %}
<p class="login-hint">
Un email a été envoyé à <b>{{ email }}</b> avec un lien pour définir ton mot de passe.
Le lien est valable 24h.
</p>
{% endif %}
</div>
</div>

View File

@ -0,0 +1,49 @@
{% extends "base.html" %}
{% block content %}
<div class="login-wrap">
<div class="login-card">
<div class="login-header">
<span class="login-eyebrow">Décompte Horaire</span>
<h1 class="login-title">Définir ton mot de passe</h1>
</div>
{% if error %}
<div class="login-error">{{ error }}</div>
{% endif %}
{% if valid %}
<form method="post" action="/set-password/{{ token }}" class="login-form">
<label class="login-label" for="password">Nouveau mot de passe</label>
<input
id="password"
class="login-input"
type="password"
name="password"
autocomplete="new-password"
autofocus
placeholder="8 caractères minimum"
minlength="8"
required
>
<label class="login-label" for="password2">Confirmation</label>
<input
id="password2"
class="login-input"
type="password"
name="password2"
autocomplete="new-password"
placeholder="Retape le même mot de passe"
minlength="8"
required
>
<button class="login-btn" type="submit">Valider</button>
</form>
{% else %}
<p class="login-hint">
Ce lien est invalide ou a expiré. Retourne sur la
<a href="/login">page de connexion</a> pour en redemander un.
</p>
{% endif %}
</div>
</div>
{% endblock %}