Sécurité
TimePick embarque plusieurs protections activées par défaut, sans configuration à faire côté opérateur : limitation de débit sur les endpoints sensibles, réponses anti-énumération, garde-fou sur le dernier administrateur, codes de secours à usage unique. Cette fiche décrit ce qui est protégé et ce qu'il n'y a pas besoin de régler — elle ne couvre ni le déroulé pas-à-pas de la connexion de secours (voir Usage — Connexion de secours), ni le durcissement de l'infrastructure (HTTPS, pare-feu VPS — voir Déploiement Coolify / VPS).
Rien à activer
Ces protections font partie du code serveur : elles s'appliquent dès le premier démarrage, sur toute instance (locale, Docker, Coolify), sans variable d'environnement ni réglage dans l'écran Paramètres.
Limitation de débit (rate limiting)
Certains endpoints sensibles sont limités en nombre de requêtes, indépendamment de toute configuration :
| Endpoint | Fenêtre | Quota |
|---|---|---|
POST /api/auth/emergency-login (connexion de secours) | 15 minutes | 5 requêtes par adresse IP |
POST /api/auth/resend-invitation (renvoi d'invitation) | 60 secondes | 1 requête par identité (email + événement) |
POST /api/admin/recovery-codes/generate (régénération des codes de secours) | 24 heures | 1 régénération par administrateur |
POST /api/uploads/email-image (upload d'image dans l'éditeur d'emails) | 1 minute | 30 requêtes |
PUT/POST /api/setup/smtp (configuration SMTP pendant l'assistant /setup) | 1 minute | 10 requêtes |
POST /api/setup/smtp/test (test SMTP pendant l'assistant /setup) | 1 minute | 5 requêtes |
| Actions admin destructrices génériques (suppression, etc.) | 1 minute | 10 requêtes par administrateur |
| Envoi d'un email de test (Paramètres → Serveur d'email) | 1 minute | 5 requêtes par administrateur |
Les limites par adresse IP protègent contre un attaquant externe ; celles par administrateur ou par identité protègent contre un abus depuis un compte ou un jeton compromis. Aucune de ces valeurs n'est modifiable depuis l'interface — un besoin de quota différent (déploiement multi-tenant, forte volumétrie) implique une modification du code serveur.
Au-delà du quota, le serveur répond 429 avec un code d'erreur RATE_LIMITED. Ces limites sont fixes dans le code serveur ; elles ne s'ajustent pas depuis l'interface.
Connexion de secours : double protection
La connexion de secours (/emergency-login) cumule la limite par IP ci-dessus avec un verrou par compte : au-delà de 10 tentatives de code invalide en 1 heure pour un même administrateur, les tentatives suivantes échouent silencieusement (même réponse que pour un code invalide, pour ne pas révéler que le compte est verrouillé). Le détail de ce flux est décrit dans la fiche d'usage dédiée.
Chaque tentative de connexion de secours (réussie, code invalide, compte verrouillé, email inconnu, code expiré) est journalisée en base dans la table recovery_audit_log (adresse IP, user-agent, résultat, horodatage). Ce journal n'est pas exposé dans l'interface d'administration ; il sert de trace forensique en cas d'incident et se consulte directement en base par un mainteneur.
Anti-énumération des emails
Pour empêcher qu'un tiers déduise, en observant les réponses de l'API, quelles adresses email sont enregistrées dans l'instance, POST /api/auth/login (demande de lien de connexion) renvoie systématiquement le même message, que l'email corresponde ou non à un compte :
{ "data": { "message": "Si cet email est enregistré, vous recevrez un lien de connexion." } }Le comportement est identique en réponse HTTP (200) et en contenu, qu'un email ait effectivement été envoyé ou non — un observateur externe ne peut donc pas distinguer un email inscrit d'un email absent en regardant uniquement la réponse de l'API. La connexion de secours applique le même principe : un email admin inconnu ou un code invalide renvoient tous deux la même erreur générique INVALID_CREDENTIALS, sans distinction, et le serveur exécute systématiquement le même nombre d'opérations de hachage (bcrypt) pour égaliser le temps de réponse.
Durées de vie des liens et des sessions
La sécurité des flux de connexion repose aussi sur des durées de vie limitées, configurables sans redémarrage depuis l'écran Paramètres (onglet Authentification) :
- Lien de connexion administrateur : 24 heures par défaut.
- Lien de connexion membre : 7 jours par défaut (délai plus long car ces invitations concernent des créneaux planifiés à l'avance).
- Session active (après connexion) : 2 heures par défaut.
Ces valeurs sont détaillées dans Paramètres in-app ; elles ne relèvent pas de cette fiche mais complètent le dispositif : un lien ou une session volés perdent leur validité passé ce délai.
Protection du dernier administrateur
TimePick empêche de se retrouver sans aucun administrateur :
- Suppression bloquée — supprimer le dernier compte administrateur échoue avec une erreur
409(« Impossible de supprimer le dernier administrateur »). - Rétrogradation bloquée — changer le rôle du dernier administrateur vers « membre » échoue de la même façon (« Impossible de rétrograder le dernier administrateur »).
- Auto-suppression interdite — un administrateur ne peut pas supprimer son propre compte, quel que soit le nombre d'administrateurs restants (« Vous ne pouvez pas supprimer votre propre compte »).
Avec deux administrateurs ou plus, un administrateur peut rétrograder son propre compte (auto-démotion) après confirmation ; l'opération entraîne alors une déconnexion immédiate. Ces garde-fous s'appliquent uniquement au rôle administrateur : ils n'empêchent pas de désactiver ou reconfigurer d'autres aspects du compte, et ne remplacent pas une vraie politique de continuité (garder au moins deux administrateurs actifs en pratique, pas seulement un seul protégé par le système).
Codes de secours
Les codes de secours permettent à un administrateur de se reconnecter sans accès à sa messagerie (SMTP en panne, compte email inaccessible…). Points à retenir côté exploitation :
- Générés par lot de 8 codes, affichés une seule fois à l'écran au moment de la génération — TimePick ne les stocke que sous forme hachée (bcrypt) en base et ne peut donc plus les réafficher ensuite.
- Jamais envoyés par email : les récupérer implique d'être connecté à l'interface d'administration au moment de la génération.
- À noter et conserver hors ligne (gestionnaire de mots de passe, coffre-fort) immédiatement après génération.
- Régénérer une nouvelle série invalide immédiatement l'ancienne (limité à une régénération par 24 heures, voir tableau ci-dessus).
À conserver avant d'en avoir besoin
Un administrateur sans codes de secours valides et sans accès à sa messagerie n'a aucun moyen de reconnexion via l'application. Générer les codes dès la première connexion, avant qu'un incident SMTP ne survienne.
Le déroulé complet (génération, utilisation, expiration) est décrit dans Usage — Connexion de secours.
Rappels transverses
- Assistant de configuration initiale (
/setup) — accessible uniquement tant qu'aucun administrateur n'existe en base ; se referme automatiquement dès le premier admin créé. Détails dans Configuration initiale. - Secrets d'environnement —
JWT_SECRET(signature des sessions) etENCRYPTION_KEY(chiffrement du mot de passe SMTP en base) sont obligatoires au démarrage et doivent être générés spécifiquement pour l'instance, jamais recopiés d'un exemple. Voir Variables d'environnement. - HTTPS en production — TimePick ne termine pas lui-même le TLS ; le chiffrement du trafic est à la charge du reverse proxy / de la plateforme d'hébergement. Voir Déploiement Coolify / VPS.