feat: Release version 3.1.4 - Mode terrain et génération PDF
✨ Nouvelles fonctionnalités: - Ajout du mode terrain pour utilisation mobile hors connexion - Génération automatique de reçus PDF avec template personnalisé - Révision complète du système de cartes avec amélioration des performances 🔧 Améliorations techniques: - Refactoring du module chat avec architecture simplifiée - Optimisation du système de sécurité NIST SP 800-63B - Amélioration de la gestion des secteurs géographiques - Support UTF-8 étendu pour les noms d'utilisateurs 📱 Application mobile: - Nouveau mode terrain dans user_field_mode_page - Interface utilisateur adaptative pour conditions difficiles - Synchronisation offline améliorée 🗺️ Cartographie: - Optimisation des performances MapBox - Meilleure gestion des tuiles hors ligne - Amélioration de l'affichage des secteurs 📄 Documentation: - Ajout guide Android (ANDROID-GUIDE.md) - Documentation sécurité API (API-SECURITY.md) - Guide module chat (CHAT_MODULE.md) 🐛 Corrections: - Résolution des erreurs 400 lors de la création d'utilisateurs - Correction de la validation des noms d'utilisateurs - Fix des problèmes de synchronisation chat 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
176
api/docs/FIX_USER_CREATION_400_ERRORS.md
Normal file
176
api/docs/FIX_USER_CREATION_400_ERRORS.md
Normal file
@@ -0,0 +1,176 @@
|
||||
# Correction des erreurs 400 lors de la création d'utilisateurs
|
||||
|
||||
## Problème identifié
|
||||
Un administrateur (fk_role=2) rencontrait des erreurs 400 répétées lors de tentatives de création de membre, menant à un bannissement par fail2ban :
|
||||
- 17:09:39 - POST /api/users HTTP/1.1 400 (Bad Request)
|
||||
- 17:10:44 - POST /api/users/check-username HTTP/1.1 400 (Bad Request)
|
||||
- 17:11:21 - POST /api/users HTTP/1.1 400 (Bad Request)
|
||||
|
||||
## Causes identifiées
|
||||
|
||||
### 1. Conflit de routage (CRITIQUE)
|
||||
**Problème:** La route `/api/users/check-username` était déclarée APRÈS la route générique `/api/users` dans Router.php, causant une mauvaise interprétation où "check-username" était traité comme un ID utilisateur.
|
||||
|
||||
**Solution:** Déplacer la déclaration de la route spécifique AVANT les routes avec paramètres.
|
||||
|
||||
### 2. Messages d'erreur non informatifs
|
||||
**Problème:** Les erreurs 400 retournaient des messages génériques sans détails sur le champ problématique.
|
||||
|
||||
**Solution:** Ajout de messages d'erreur détaillés incluant :
|
||||
- Le champ en erreur (`field`)
|
||||
- La valeur problématique (`value`)
|
||||
- Le format attendu (`format`)
|
||||
- La raison de l'erreur (`reason`)
|
||||
|
||||
### 3. Manque de logs de débogage
|
||||
**Problème:** Aucun log n'était généré pour tracer les erreurs de validation.
|
||||
|
||||
**Solution:** Ajout de logs détaillés à chaque point de validation.
|
||||
|
||||
## Modifications apportées
|
||||
|
||||
### 1. Router.php (ligne 36-44)
|
||||
```php
|
||||
// AVANT (incorrect)
|
||||
$this->post('users', ['UserController', 'createUser']);
|
||||
$this->post('users/check-username', ['UserController', 'checkUsername']);
|
||||
|
||||
// APRÈS (correct)
|
||||
$this->post('users/check-username', ['UserController', 'checkUsername']); // Route spécifique en premier
|
||||
$this->post('users', ['UserController', 'createUser']);
|
||||
```
|
||||
|
||||
### 2. UserController.php - Amélioration des validations
|
||||
|
||||
#### Validation de l'email
|
||||
```php
|
||||
// Réponse améliorée
|
||||
Response::json([
|
||||
'status' => 'error',
|
||||
'message' => 'Email requis',
|
||||
'field' => 'email' // Indique clairement le champ problématique
|
||||
], 400);
|
||||
```
|
||||
|
||||
#### Validation du username manuel
|
||||
```php
|
||||
// Réponse améliorée
|
||||
Response::json([
|
||||
'status' => 'error',
|
||||
'message' => 'Le nom d\'utilisateur est requis pour cette entité',
|
||||
'field' => 'username',
|
||||
'reason' => 'L\'entité requiert la saisie manuelle des identifiants'
|
||||
], 400);
|
||||
```
|
||||
|
||||
#### Format du username
|
||||
```php
|
||||
// Réponse améliorée
|
||||
Response::json([
|
||||
'status' => 'error',
|
||||
'message' => 'Format du nom d\'utilisateur invalide',
|
||||
'field' => 'username',
|
||||
'format' => '10-30 caractères, commence par une lettre, caractères autorisés: a-z, 0-9, ., -, _',
|
||||
'value' => $username // Montre la valeur soumise
|
||||
], 400);
|
||||
```
|
||||
|
||||
### 3. Ajout de logs détaillés
|
||||
|
||||
Chaque point de validation génère maintenant un log avec :
|
||||
- Le type d'erreur
|
||||
- L'utilisateur qui fait la requête
|
||||
- Les données reçues (sans données sensibles)
|
||||
- Le contexte de l'erreur
|
||||
|
||||
Exemple :
|
||||
```php
|
||||
LogService::log('Erreur création utilisateur : Format username invalide', [
|
||||
'level' => 'warning',
|
||||
'createdBy' => $currentUserId,
|
||||
'email' => $email,
|
||||
'username' => $username,
|
||||
'username_length' => strlen($username)
|
||||
]);
|
||||
```
|
||||
|
||||
## Cas d'erreur 400 possibles
|
||||
|
||||
### Pour /api/users (création)
|
||||
|
||||
1. **Email manquant ou vide**
|
||||
- Message: "Email requis"
|
||||
- Field: "email"
|
||||
|
||||
2. **Nom manquant ou vide**
|
||||
- Message: "Nom requis"
|
||||
- Field: "name"
|
||||
|
||||
3. **Format email invalide**
|
||||
- Message: "Format d'email invalide"
|
||||
- Field: "email"
|
||||
- Value: [email soumis]
|
||||
|
||||
4. **Username manuel requis mais manquant** (si chk_username_manuel=1)
|
||||
- Message: "Le nom d'utilisateur est requis pour cette entité"
|
||||
- Field: "username"
|
||||
- Reason: "L'entité requiert la saisie manuelle des identifiants"
|
||||
|
||||
5. **Format username invalide**
|
||||
- Message: "Format du nom d'utilisateur invalide"
|
||||
- Field: "username"
|
||||
- Format: "10-30 caractères, commence par une lettre..."
|
||||
- Value: [username soumis]
|
||||
|
||||
6. **Mot de passe manuel requis mais manquant** (si chk_mdp_manuel=1)
|
||||
- Message: "Le mot de passe est requis pour cette entité"
|
||||
- Field: "password"
|
||||
- Reason: "L'entité requiert la saisie manuelle des mots de passe"
|
||||
|
||||
### Pour /api/users/check-username
|
||||
|
||||
1. **Username manquant**
|
||||
- Message: "Username requis pour la vérification"
|
||||
- Field: "username"
|
||||
|
||||
2. **Format username invalide**
|
||||
- Message: "Format invalide"
|
||||
- Field: "username"
|
||||
- Format: "10-30 caractères, commence par une lettre..."
|
||||
- Value: [username soumis]
|
||||
|
||||
## Test de la solution
|
||||
|
||||
Un script de test a été créé : `/tests/test_user_creation.php`
|
||||
|
||||
Il teste tous les cas d'erreur possibles et vérifie que :
|
||||
1. Les codes HTTP sont corrects
|
||||
2. Les messages d'erreur sont informatifs
|
||||
3. Les champs en erreur sont identifiés
|
||||
|
||||
## Recommandations pour éviter le bannissement fail2ban
|
||||
|
||||
1. **Côté client (application Flutter)** :
|
||||
- Valider les données AVANT l'envoi
|
||||
- Afficher clairement les erreurs à l'utilisateur
|
||||
- Implémenter un délai entre les tentatives (rate limiting côté client)
|
||||
|
||||
2. **Côté API** :
|
||||
- Les messages d'erreur détaillés permettent maintenant de corriger rapidement les problèmes
|
||||
- Les logs permettent de diagnostiquer les problèmes récurrents
|
||||
|
||||
3. **Configuration fail2ban** :
|
||||
- Considérer d'augmenter le seuil pour les erreurs 400 (ex: 5 tentatives au lieu de 3)
|
||||
- Exclure certaines IP de confiance si nécessaire
|
||||
|
||||
## Suivi des logs
|
||||
|
||||
Les logs sont maintenant générés dans :
|
||||
- `/logs/geosector-[environment]-[date].log` : Logs généraux avec détails des erreurs
|
||||
|
||||
Format des logs :
|
||||
```
|
||||
timestamp;browser;os;client_type;level;metadata;message
|
||||
```
|
||||
|
||||
Les erreurs de validation sont loggées avec le niveau "warning" pour permettre un suivi sans être critiques.
|
||||
Reference in New Issue
Block a user