- Remplacement de DocuSeal par solution souveraine Odentas Sign - Système d'authentification OTP pour signataires (bcryptjs + JWT) - 8 routes API: send-otp, verify-otp, sign, pdf-url, positions, status, webhook, signers - Interface moderne avec canvas de signature et animations (framer-motion, confetti) - Système de templates pour auto-détection des positions de signature (CDDU, RG, avenants) - PDF viewer avec @react-pdf-viewer (compatible Next.js) - Stockage S3: source/, signatures/, evidence/, signed/, certs/ - Tables Supabase: sign_requests, signers, sign_positions, sign_events, sign_assets - Evidence bundle automatique (JSON metadata + timestamps) - Templates emails: OTP et completion - Scripts Lambda prêts: pades-sign (KMS seal) et tsaStamp (RFC3161) - Mode test détecté automatiquement (emails whitelist) - Tests complets avec PDF CDDU réel (2 signataires)
9.3 KiB
Guide de Test - Odentas Sign
Ce guide vous permet de tester Odentas Sign sans déclencher Odentas Seal, pour valider le workflow complet de signature électronique en environnement de développement.
🧪 Mode Test
Le système détecte automatiquement le mode test quand :
- La référence du contrat commence par
TEST- - Le PDF source est dans
source/test/ - Les emails contiennent
test@ou@example.com
En mode test :
- ✅ Création de la demande de signature
- ✅ Authentification OTP (code affiché dans les logs)
- ✅ Capture et upload de la signature
- ✅ Bundle de preuves (evidence)
- ❌ Scellage PAdES désactivé
- ❌ Horodatage TSA désactivé
- ❌ Archivage Object Lock désactivé
- ❌ Envoi d'emails désactivé
🚀 Étape 1 : Créer une demande de test
Option A : Via l'API de test (recommandé)
curl -X POST http://localhost:3000/api/odentas-sign/test/create-mock \
-H "Content-Type: application/json" \
-d '{
"title": "Contrat CDDU Test",
"signerName": "Marie Test",
"signerEmail": "marie.test@example.com"
}'
Réponse :
{
"success": true,
"test_mode": true,
"request": {
"id": "xxx",
"ref": "TEST-...",
"title": "Contrat CDDU Test",
"status": "pending"
},
"signers": [
{
"signerId": "yyy",
"role": "Employeur",
"name": "Jean Dupont (Test)",
"email": "employeur-test@example.com",
"signatureUrl": "http://localhost:3000/signer/xxx/yyy"
},
{
"signerId": "zzz",
"role": "Salarié",
"name": "Marie Test",
"email": "marie.test@example.com",
"signatureUrl": "http://localhost:3000/signer/xxx/zzz"
}
]
}
Option B : Via l'API normale avec un vrai contrat
Si vous avez déjà un PDF uploadé dans S3 :
curl -X POST http://localhost:3000/api/odentas-sign/requests/create \
-H "Content-Type: application/json" \
-d '{
"contractId": "votre-contract-id",
"contractRef": "TEST-2025-0001",
"pdfS3Key": "source/test/contrat-test.pdf",
"title": "Contrat de travail CDDU",
"signers": [
{
"role": "Employeur",
"name": "Votre Nom",
"email": "vous-test@example.com"
},
{
"role": "Salarié",
"name": "Salarié Test",
"email": "salarie-test@example.com"
}
],
"positions": [
{
"role": "Employeur",
"page": 1,
"x": 100,
"y": 650,
"w": 200,
"h": 60
},
{
"role": "Salarié",
"page": 1,
"x": 350,
"y": 650,
"w": 200,
"h": 60
}
]
}'
🔐 Étape 2 : Tester le flux de signature
2.1. Ouvrir l'URL de signature
Utilisez l'URL retournée dans signers[].signatureUrl.
Note : L'interface frontend n'existe pas encore, donc pour l'instant on teste uniquement les APIs.
2.2. Demander un code OTP
curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/send-otp
Réponse :
{
"success": true,
"test_mode": true,
"otp_code_in_logs": true,
"message": "Mode test : le code OTP est affiché dans les logs serveur",
"expires_at": "2025-10-27T15:30:00.000Z"
}
⚠️ Important : Le code OTP apparaît dans les logs serveur (terminal où Next.js tourne) :
[OTP] 🧪 MODE TEST détecté
[OTP] ========================================
[OTP] 🔐 CODE OTP POUR marie.test@example.com:
[OTP] ➡️ 123456
[OTP] ========================================
2.3. Vérifier le code OTP
curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/verify-otp \
-H "Content-Type: application/json" \
-d '{"otp": "123456"}'
Réponse :
{
"success": true,
"sessionToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"signer": {
"id": "xxx",
"name": "Marie Test",
"email": "marie.test@example.com",
"role": "Salarié"
},
"request": {
"id": "yyy",
"ref": "TEST-...",
"title": "Contrat CDDU Test"
}
}
Copiez le sessionToken pour l'étape suivante.
2.4. Enregistrer la signature
Créez une image de signature en base64 (pour tester, voici un petit carré rouge) :
# Image 100x50 pixels, carré rouge simple
SIGNATURE_B64="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAAyCAYAAACqNX6+AAAABmJLR0QA/wD/AP+gvaeTAAAAeklEQVR4nO3QMQEAAAjAMMC/52ECvlRA00ASAgECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQIECAAAECBAgQcNkFzQABOWLnlYwAAAAASUVORK5CYII="
curl -X POST http://localhost:3000/api/odentas-sign/signers/[SIGNER_ID]/sign \
-H "Content-Type: application/json" \
-H "Authorization: Bearer [SESSION_TOKEN]" \
-d "{
\"signatureImageBase64\": \"$SIGNATURE_B64\",
\"consentText\": \"Je consens à signer électroniquement ce document.\"
}"
Réponse :
{
"success": true,
"message": "Signature enregistrée avec succès",
"signed_at": "2025-10-27T15:25:00.000Z",
"all_signed": false,
"signer": {
"id": "xxx",
"name": "Marie Test",
"role": "Salarié"
}
}
2.5. Signer avec le deuxième signataire
Répétez les étapes 2.2 à 2.4 avec le deuxième signerId.
Quand le dernier signataire signe, "all_signed": true et le webhook de completion est déclenché.
📊 Étape 3 : Vérifier les résultats
3.1. Vérifier le statut de la demande
curl http://localhost:3000/api/odentas-sign/requests/[REQUEST_ID]
Réponse :
{
"success": true,
"request": {
"id": "xxx",
"ref": "TEST-...",
"status": "completed",
"progress": {
"total": 2,
"signed": 2,
"percentage": 100
}
},
"signers": [
{
"id": "yyy",
"role": "Employeur",
"signed_at": "2025-10-27T15:20:00.000Z",
"signature_image_s3": "signatures/xxx/yyy.png"
},
{
"id": "zzz",
"role": "Salarié",
"signed_at": "2025-10-27T15:25:00.000Z",
"signature_image_s3": "signatures/xxx/zzz.png"
}
]
}
3.2. Vérifier dans Supabase
Allez dans Supabase et vérifiez les tables :
sign_requests
SELECT * FROM sign_requests WHERE ref LIKE 'TEST-%' ORDER BY created_at DESC;
signers
SELECT * FROM signers WHERE request_id = '[REQUEST_ID]';
sign_events
SELECT * FROM sign_events WHERE request_id = '[REQUEST_ID]' ORDER BY ts ASC;
sign_assets
SELECT * FROM sign_assets WHERE request_id = '[REQUEST_ID]';
3.3. Vérifier dans S3
Le bucket odentas-sign doit contenir :
odentas-sign/
├── source/test/
│ └── TEST-xxx.pdf # PDF source de test
├── signatures/
│ └── [request_id]/
│ ├── [signer1_id].png # Signature employeur
│ └── [signer2_id].png # Signature salarié
└── evidence/
└── TEST-xxx.json # Bundle de preuves
📋 Logs attendus
Dans votre terminal Next.js, vous devriez voir :
[TEST] PDF de test créé: source/test/TEST-xxx.pdf
[CREATE REQUEST] Création demande: TEST-xxx
[OTP] 🧪 MODE TEST détecté
[OTP] 🔐 CODE OTP POUR employeur-test@example.com: 123456
[OTP] ✅ Mode test - Code affiché dans les logs
[SIGN] Enregistrement signature pour employeur-test@example.com...
[SIGN] ✅ Image uploadée: signatures/xxx/yyy.png
[SIGN] ✅ Signataire mis à jour
[SIGN] 🎉 Tous les signataires ont signé !
[WEBHOOK COMPLETION] 🧪 MODE TEST détecté - scellage PAdES désactivé
[WEBHOOK] 🧪 MODE TEST : Scellage PAdES/TSA/Archive SAUTE
[WEBHOOK COMPLETION] ✅ Traitement terminé pour TEST-xxx (MODE TEST)
🧹 Nettoyage après test
Pour nettoyer les données de test :
-- Supprimer les demandes de test (cascade sur signers, positions, events)
DELETE FROM sign_requests WHERE ref LIKE 'TEST-%';
-- Supprimer les assets de test
DELETE FROM sign_assets WHERE request_id IN (
SELECT id FROM sign_requests WHERE ref LIKE 'TEST-%'
);
Dans S3, supprimer manuellement :
source/test/signatures/[request_ids de test]/evidence/TEST-*.json
🎯 Checklist de validation
- Création de demande de test réussie
- Code OTP visible dans les logs
- Vérification OTP réussie avec session token
- Upload de la signature réussie
- Images de signature présentes dans S3
- Statut
completedaprès signature complète - Logs confirment le mode test (pas de scellage)
- Evidence bundle créé dans S3
- Tables Supabase cohérentes
- Événements d'audit enregistrés
⏭️ Prochaine étape
Une fois les APIs validées, vous pourrez :
- Créer l'interface frontend (
/app/signer/[requestId]/[signerId]/page.tsx) - Intégrer avec vos contrats existants
- Créer la Lambda d'orchestration pour le scellage
- Activer le mode production (sans TEST-)
🐛 Dépannage
Le code OTP n'apparaît pas dans les logs
- Vérifiez que l'email contient
test@ou@example.com - Ou que la ref commence par
TEST-
Erreur "Session invalide"
- Le JWT expire après 30 minutes
- Redemandez un OTP et re-vérifiez
Erreur S3
- Vérifiez que le bucket
odentas-signexiste - Vérifiez les credentials AWS dans
.env.local
Erreur Supabase
- Vérifiez que les tables existent (voir définitions dans README)
- Vérifiez les RLS policies
Dernière mise à jour : 27 octobre 2025