docs: capitaliser les patterns valides du 16 mars

This commit is contained in:
MaksTinyWorkshop
2026-03-16 15:36:17 +01:00
parent 019a6d2787
commit 0fe41269e8
4 changed files with 413 additions and 7 deletions

View File

@@ -8,7 +8,7 @@ Ce fichier contient **uniquement** des patterns back-end :
Objectif : éviter de réinventer la roue et réduire le temps de debug.
Dernière mise à jour : 12-03-2026
Dernière mise à jour : 16-03-2026
---
@@ -32,6 +32,11 @@ Dernière mise à jour : 12-03-2026
- [Restauration dachats Stripe en 3 étapes](#pattern-restauration-achats-stripe)
- [Mapping explicite de `P2002` Prisma sur update de champ unique](#pattern-prisma-p2002-update-unique)
- [Autorisation interne minimale sans RBAC complet](#pattern-autorisation-interne-minimale)
- [Anti-énumération sur endpoints auth liés à un email](#pattern-anti-enumeration-auth-email)
- [Token à usage unique — génération, hash et invalidation atomique](#pattern-token-usage-unique)
- [Guardrails multi-tenant — 403 vs 404 selon la sémantique](#pattern-guardrails-multi-tenant-403-404)
- [Repository tenant-aware — `tenantId` obligatoire dans la signature](#pattern-repository-tenant-aware)
- [Défense en profondeur — inclure `tenantId` dans les updates](#pattern-tenantid-dans-updates)
---
@@ -747,3 +752,176 @@ handlePackWebhookEvent(event): PackWebhookResult | null
- On préfère 5 patterns solides à 50 “bons conseils”.
- Un pattern = une idée actionnable + son cadre dutilisation.
---
<a id="pattern-anti-enumeration-auth-email"></a>
## Pattern : Anti-énumération sur endpoints auth liés à un email
- Objectif : empêcher quun endpoint auth révèle si un compte existe, nexiste pas ou nest pas éligible.
- Contexte : reset de mot de passe, invitation, vérification de compte, login ou tout flux qui part dun email utilisateur.
- Quand lutiliser : dès quune requête auth touche un identifiant de type email.
- Quand léviter : jamais sur une surface exposée.
- Avantage :
- réduit la fuite dinformation sur les comptes existants
- homogénéise les réponses côté client
- se combine bien avec les garde-fous anti-abus
- Limites / vigilance :
- ne protège pas seul contre le brute-force, à combiner avec du rate-limiting
- les logs internes doivent conserver la vraie cause sans lexposer au client
- Validé le : 16-03-2026
- Contexte technique : Node.js / auth applicative / API HTTP
### Implémentation (exemple minimal)
```txt
- retourner la même réponse HTTP 200 quun compte existe ou non
- ne jamais distinguer "email inconnu", "email connu" ou "compte OAuth-only" dans la réponse
- journaliser la cause réelle côté serveur
- ajouter un rate-limiting basé sur email + IP
```
### Checklist
- Réponse client uniforme pour les cas compte connu/inconnu/non éligible
- Aucune fuite dexistence dans le message ou le code derreur
- Rate-limiting présent sur les endpoints exposés
- Logs internes exploitables
---
<a id="pattern-token-usage-unique"></a>
## Pattern : Token à usage unique — génération, hash et invalidation atomique
- Objectif : standardiser la création et la consommation de tokens sensibles sans stocker de secret brut en base.
- Contexte : invitation, reset de mot de passe, vérification demail, lien magique ou tout token one-shot.
- Quand lutiliser : pour tout token à usage unique transmis à lutilisateur.
- Quand léviter : sessions longues ou secrets devant être relus en clair côté serveur.
- Avantage :
- réduit limpact dune fuite de base
- garde des tokens URL-safe
- favorise une consommation atomique et réutilisable
- Limites / vigilance :
- la consommation doit rester atomique
- la politique dexpiration doit être explicite
- Validé le : 16-03-2026
- Contexte technique : Node.js `crypto` / Prisma / email ou URL signée
### Implémentation (exemple minimal)
```txt
- générer le token avec `crypto.randomBytes(32).toString("base64url")`
- stocker uniquement le hash SHA-256 du token en base
- transmettre le token brut uniquement via URL ou email
- recalculer le hash côté serveur lors de la consommation
- invalider le token dans une transaction atomique après usage
```
### Checklist
- Token brut jamais persisté en base
- Hash recalculé côté serveur pour la vérification
- Expiration explicite
- Invalidation atomique après consommation
---
<a id="pattern-guardrails-multi-tenant-403-404"></a>
## Pattern : Guardrails multi-tenant — 403 vs 404 selon la sémantique
- Objectif : éviter les fuites dinformation inter-tenant tout en gardant une sémantique derreur claire.
- Contexte : API multi-tenant avec ressources métier isolées et surfaces internes ou opérateur.
- Quand lutiliser : dès quune vérification dappartenance tenant peut soit refuser explicitement laccès, soit masquer lexistence dune ressource.
- Quand léviter : contexte mono-tenant ou endpoints purement internes sans enjeu de fuite.
- Avantage :
- clarifie la convention de sécurité
- évite les réponses incohérentes selon les modules
- facilite les tests disolation tenant
- Limites / vigilance :
- la convention doit être documentée et appliquée partout
- un mauvais choix entre 403 et 404 peut révéler une information sensible
- Validé le : 16-03-2026
- Contexte technique : API multi-tenant / HTTP / services métier
### Implémentation (exemple minimal)
```txt
- `assertTenantMatch(actor, expectedTenantId)` -> 403 quand la ressource est connue mais laccès refusé
- `assertResourceBelongsToTenant(actor, resourceTenantId)` -> 404 quand il faut masquer lexistence dune ressource dun autre tenant
- documenter la convention dans le module
- couvrir les deux sémantiques par des tests dédiés
```
### Checklist
- Convention 403 vs 404 documentée
- Helpers distincts selon la sémantique métier
- Aucune fuite dexistence cross-tenant sur les ressources métier
- Tests dédiés sur les deux comportements
---
<a id="pattern-repository-tenant-aware"></a>
## Pattern : Repository tenant-aware — `tenantId` obligatoire dans la signature
- Objectif : rendre impossible par construction une query non scopée sur un domaine multi-tenant.
- Contexte : repositories ou services daccès aux données sur ressources tenant-scoped.
- Quand lutiliser : dès quun domaine métier est massivement filtré par tenant.
- Quand léviter : domaines réellement globaux ou méthodes volontairement cross-tenant.
- Avantage :
- force le scoping dès la signature TypeScript
- réduit les oublis de filtre tenant dans les call sites
- rend les exceptions cross-tenant visibles
- Limites / vigilance :
- les exceptions cross-tenant doivent être rares et documentées explicitement
- ne dispense pas dun second garde-fou dans les mutations sensibles
- Validé le : 16-03-2026
- Contexte technique : TypeScript / Prisma / architecture repository
### Implémentation (exemple minimal)
```txt
- chaque méthode métier tenant-scoped prend `tenantId` en paramètre obligatoire
- les méthodes réellement cross-tenant sont nommées et documentées comme exception
- les call sites Prisma directs sur ces domaines sont interdits ou supprimés
```
### Checklist
- `tenantId` obligatoire sur les méthodes tenant-scoped
- Exceptions cross-tenant documentées
- Appels directs concurrents à Prisma supprimés
- Tests sur scoping tenant au niveau repository
---
<a id="pattern-tenantid-dans-updates"></a>
## Pattern : Défense en profondeur — inclure `tenantId` dans les updates
- Objectif : éviter une mutation cross-tenant même si un identifiant a été mal résolu en amont.
- Contexte : `update` ou `updateMany` sur une ressource tenant-scoped.
- Quand lutiliser : dès quune mutation dépend dun `id` reçu ou résolu dans un flux multi-tenant.
- Quand léviter : ressources globales non liées à un tenant.
- Avantage :
- ajoute une seconde barrière côté base
- réduit limpact dun call site mal scopé
- rend la mutation plus sûre sans complexité forte
- Limites / vigilance :
- ne remplace pas le scoping en lecture ni la vérification dautorisation
- suppose que `tenantId` soit disponible au moment de la mutation
- Validé le : 16-03-2026
- Contexte technique : Prisma / multi-tenant / mutations métier
### Implémentation (exemple minimal)
```txt
- préférer `where: { id, tenantId }` à `where: { id }` sur les updates tenant-scoped
- appliquer la même règle sur `updateMany` et opérations de révocation
- conserver les vérifications métier amont, mais ne pas leur déléguer toute la sécurité
```
### Checklist
- `tenantId` présent dans les clauses `where` des updates sensibles
- Pas de mutation tenant-scoped basée sur `id` seul
- Revue explicite des exceptions documentées