# 🔐 Sécurisation Signature Salarié - Vérification Date de Naissance ## 📋 Vue d'ensemble Un système de vérification par date de naissance a été ajouté à la page `/signature-salarie/` pour sécuriser l'accès aux documents de signature électronique. ### Fonctionnement Lorsqu'un salarié clique sur le lien de signature reçu par email : 1. 🔒 Un **modal de sécurité moderne** s'affiche automatiquement 2. 📅 Le salarié doit **saisir sa date de naissance** 3. ✅ Le système vérifie dans la base de données (table `salaries`) 4. 📝 Si la date correspond, le **formulaire DocuSeal s'affiche** 5. ❌ Sinon, un message d'erreur apparaît et le formulaire reste bloqué --- ## 🎨 Interface utilisateur ### Modal de vérification - **Design moderne** avec gradient bleu et animations fluides - **Header** avec icône Shield et titre explicite - **Input date** avec validation HTML5 - **Messages d'erreur** clairs et animés - **Footer informatif** sur la protection des données - **Bouton désactivé** jusqu'à saisie d'une date valide - **Loader animé** pendant la vérification ### Expérience utilisateur - 🎯 **Simple** : Un seul champ à remplir - 🚀 **Rapide** : Vérification en moins d'une seconde - 💬 **Pédagogique** : Messages d'aide après 2 tentatives échouées - 🎭 **Animations** : Entrées/sorties fluides pour une UX moderne - 📱 **Responsive** : Adapté mobile et desktop --- ## 🛠️ Architecture technique ### Fichiers créés #### 1. **API de vérification** ``` app/api/signature-salarie/verify-birthdate/route.ts ``` **Fonctionnalités :** - ✅ Authentification via `docuseal_id` - ✅ Recherche du contrat dans `cddu_contracts` - ✅ Récupération du salarié via `employee_id` - ✅ Vérification de la `date_naissance` dans table `salaries` - ✅ Comparaison des dates (format normalisé YYYY-MM-DD) - ✅ Gestion des cas edge (date manquante = acceptation) - ✅ Logs détaillés pour debug **Endpoint :** ``` POST /api/signature-salarie/verify-birthdate ``` **Body :** ```json { "docuseal_id": "abc123xyz", "birthdate": "1990-05-15" } ``` **Réponses :** ```json // Succès { "verified": true, "message": "Date de naissance vérifiée" } // Échec { "verified": false, "error": "Date de naissance incorrecte" } ``` #### 2. **Composant Modal** ``` app/signature-salarie/BirthdateVerificationModal.tsx ``` **Props :** ```typescript interface BirthdateVerificationModalProps { docuseal_id: string; onVerified: () => void; } ``` **Features :** - ✅ Input type="date" avec validation HTML5 - ✅ Limite date max = aujourd'hui - ✅ Gestion des états (loading, error, success) - ✅ Compteur de tentatives - ✅ Message d'aide après 2 échecs - ✅ Animations Tailwind (animate-in, fade-in, etc.) - ✅ Design avec gradient et icônes Lucide #### 3. **Intégration dans la page** ``` app/signature-salarie/SignatureSalarieContent.tsx ``` **Modifications :** - ✅ Import du composant `BirthdateVerificationModal` - ✅ Ajout de l'état `isVerified` (défaut: `false`) - ✅ Affichage conditionnel du modal (`!isVerified`) - ✅ Callback `onVerified` pour fermer le modal - ✅ Le formulaire DocuSeal ne se charge que si vérifié --- ## 🔍 Flux de données ``` 1. Utilisateur arrive sur /signature-salarie/?docuseal_id=xxx ↓ 2. Page charge avec modal affiché (isVerified = false) ↓ 3. Utilisateur saisit sa date de naissance ↓ 4. Click sur "Vérifier et accéder au document" ↓ 5. Appel API : POST /api/signature-salarie/verify-birthdate ↓ 6. API cherche le contrat via docuseal_id ↓ 7. API récupère le salarié via employee_id ↓ 8. API compare date saisie vs date_naissance en base ↓ 9a. Si match → { verified: true } ↓ Modal se ferme (isVerified = true) ↓ Formulaire DocuSeal s'affiche 9b. Si pas de match → { verified: false, error: "..." } ↓ Message d'erreur affiché ↓ Input réinitialisé ↓ Tentatives incrémentées ``` --- ## 🎯 Cas d'usage ### Scénario 1 : Date correcte ``` 1. Salarié reçoit email avec lien 2. Clique sur le lien 3. Modal s'affiche 4. Saisit sa vraie date de naissance : "15/05/1990" 5. Clique sur "Vérifier" 6. ✅ Modal se ferme 7. ✅ Formulaire DocuSeal apparaît 8. ✅ Peut signer son contrat ``` ### Scénario 2 : Date incorrecte (1ère tentative) ``` 1. Salarié saisit une mauvaise date : "01/01/2000" 2. Clique sur "Vérifier" 3. ❌ Erreur : "Date de naissance incorrecte" 4. Input se vide 5. Peut réessayer ``` ### Scénario 3 : Date incorrecte (3e tentative) ``` 1. Salarié échoue 2 fois 2. Échoue une 3e fois 3. ❌ Message : "Date de naissance incorrecte" 4. ℹ️ Message additionnel : "Besoin d'aide ? Contactez-nous à paie@odentas.fr" ``` ### Scénario 4 : Date manquante en base ``` 1. API détecte que date_naissance = null dans salaries 2. ⚠️ Log : "Date de naissance non renseignée" 3. ✅ Accepte quand même (pour ne pas bloquer) 4. ✅ Modal se ferme 5. ℹ️ À corriger dans la base pour la prochaine fois ``` --- ## 🔐 Sécurité ### Protection mise en place | Aspect | Détail | |--------|--------| | **Authentification** | Via `docuseal_id` (slug unique et secret) | | **Vérification** | Comparaison stricte des dates | | **Données sensibles** | Date de naissance jamais exposée au client | | **Service Role** | Accès base de données avec droits admin | | **Logs** | Toutes les tentatives sont loggées | | **Limite** | Pas de limite de tentatives (volontaire) | ### Points d'attention ⚠️ **Données manquantes** : Si un salarié n'a pas de `date_naissance` en base, il peut quand même accéder (pour éviter de bloquer des signatures légitimes). 💡 **Recommandation** : S'assurer que tous les salariés ont une date de naissance renseignée dans la table `salaries`. --- ## 📊 Base de données ### Tables utilisées #### `cddu_contracts` ```sql SELECT employee_id, salarie_email, docuseal_employee_slug FROM cddu_contracts WHERE docuseal_employee_slug = 'abc123'; ``` #### `salaries` ```sql SELECT id, prenom, nom, date_naissance FROM salaries WHERE id = ''; ``` ### Champ requis | Table | Colonne | Type | Requis | Remarques | |-------|---------|------|--------|-----------| | `cddu_contracts` | `docuseal_employee_slug` | `text` | ✅ | Slug DocuSeal unique | | `cddu_contracts` | `employee_id` | `uuid` | ✅ | FK vers salaries | | `salaries` | `date_naissance` | `date` | ⚠️ | Si null, accepte quand même | --- ## 🧪 Tests ### Test manuel 1. **Créer un contrat test** - Avec un salarié ayant une date de naissance connue 2. **Générer une signature DocuSeal** - Récupérer le `docuseal_employee_slug` 3. **Accéder à l'URL** ``` https://paie.odentas.fr/signature-salarie/?docuseal_id= ``` 4. **Tester différents scénarios** - ✅ Date correcte - ❌ Date incorrecte - 📅 Date future (bloquée par HTML5) - 🔄 Plusieurs tentatives ### Test API (cURL) ```bash curl -X POST https://paie.odentas.fr/api/signature-salarie/verify-birthdate \ -H "Content-Type: application/json" \ -d '{ "docuseal_id": "abc123xyz", "birthdate": "1990-05-15" }' ``` **Réponse attendue :** ```json { "verified": true, "message": "Date de naissance vérifiée" } ``` --- ## 📝 Logs ### Console API ``` === API Vérification Date de Naissance Salarié === 🔍 Vérification pour docuseal_id: abc123xyz 📄 Contrat trouvé: { employee_id: '...', salarie_email: '...' } 👤 Salarié trouvé: { prenom: 'Jean', nom: 'Dupont', date_naissance: '1990-05-15' } 📅 Comparaison dates: { db: '1990-05-15', input: '1990-05-15', match: true } ✅ Date de naissance vérifiée avec succès ``` ### Console Frontend ```javascript // En cas d'erreur console.error('Erreur lors de la vérification:', err); // L'état du composant change isVerifying: false → true → false error: null → "Date de naissance incorrecte" attempts: 0 → 1 → 2 → 3... ``` --- ## 🚀 Déploiement ### Prérequis - ✅ Colonne `docuseal_employee_slug` existe dans `cddu_contracts` - ✅ Colonne `date_naissance` existe dans `salaries` - ✅ Relation FK `employee_id` configurée ### Checklist - [x] API créée : `/api/signature-salarie/verify-birthdate/route.ts` - [x] Composant modal créé : `BirthdateVerificationModal.tsx` - [x] Intégration dans : `SignatureSalarieContent.tsx` - [ ] Tests manuels effectués - [ ] Vérifier que les salariés ont des dates de naissance - [ ] Déployer sur Vercel - [ ] Tester en production avec un vrai contrat ### Déploiement ```bash # Les fichiers sont déjà prêts # Il suffit de commit et push git add . git commit -m "feat: Ajout vérification date de naissance signature salarié" git push origin main # Vercel déploie automatiquement ``` --- ## 🎨 Design ### Couleurs utilisées - **Primary** : `from-blue-600 to-blue-700` (gradient) - **Hover** : `from-blue-700 to-blue-800` - **Background info** : `bg-blue-50` / `border-blue-200` - **Error** : `bg-red-50` / `text-red-900` - **Text** : `text-gray-700` / `text-gray-900` ### Icônes (Lucide) - 🛡️ `Shield` : Sécurité - 📅 `Calendar` : Date - ⚠️ `AlertCircle` : Erreur - ⏳ `Loader2` : Chargement (animate-spin) ### Animations - `animate-in fade-in duration-200` : Apparition modal - `animate-in zoom-in-95 duration-300` : Entrée carte - `animate-in slide-in-from-top-2 duration-200` : Message erreur - `animate-spin` : Loader --- ## 🔧 Maintenance ### Problèmes possibles | Problème | Cause | Solution | |----------|-------|----------| | Date toujours refusée | Format date incorrect | Vérifier format en base (YYYY-MM-DD) | | Salarié introuvable | `employee_id` incorrect | Vérifier la relation FK | | Slug invalide | `docuseal_employee_slug` null | Vérifier l'intégration DocuSeal | | Modal ne se ferme pas | Callback non appelé | Vérifier `onVerified()` | ### Amélioration future - [ ] Ajouter un captcha après X tentatives - [ ] Envoyer un email après 5 échecs - [ ] Logger les tentatives dans une table dédiée - [ ] Ajouter une vérification supplémentaire (email ou code SMS) - [ ] Mode "debug" pour bypasser en développement --- ## 📞 Support En cas de problème, le salarié voit : > Besoin d'aide ? Contactez-nous à [paie@odentas.fr](mailto:paie@odentas.fr) Le support peut : 1. Vérifier que la date de naissance est correcte en base 2. Vérifier les logs CloudWatch ou Vercel 3. Tester manuellement l'API avec cURL 4. Envoyer un nouveau lien si nécessaire --- *Fonctionnalité ajoutée le 15 octobre 2025* *Sécurisation des signatures électroniques - Odentas Espace Paie*