datakeen-session-react 1.1.190 → 1.1.192

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/dist/cjs/components/DatakeenSession.js +7 -1
  2. package/dist/cjs/components/DatakeenSession.js.map +1 -1
  3. package/dist/cjs/components/document-collection/DocumentCollection.js +42 -29
  4. package/dist/cjs/components/document-collection/DocumentCollection.js.map +1 -1
  5. package/dist/cjs/components/session/EndFlow.js +3 -2
  6. package/dist/cjs/components/session/EndFlow.js.map +1 -1
  7. package/dist/cjs/components/session/MobileRedirect.js +4 -0
  8. package/dist/cjs/components/session/MobileRedirect.js.map +1 -1
  9. package/dist/cjs/components/session/PdfGeneration.js +25 -19
  10. package/dist/cjs/components/session/PdfGeneration.js.map +1 -1
  11. package/dist/cjs/components/session/StartSession.js +16 -5
  12. package/dist/cjs/components/session/StartSession.js.map +1 -1
  13. package/dist/cjs/components/session/UserInputForm/CustomFormFields.js +7 -14
  14. package/dist/cjs/components/session/UserInputForm/CustomFormFields.js.map +1 -1
  15. package/dist/cjs/components/session/UserInputForm.js +2 -2
  16. package/dist/cjs/components/session/UserInputForm.js.map +1 -1
  17. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js +12 -14
  18. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  19. package/dist/cjs/components/template/ExternalVerificationNodeHandler.js +67 -4
  20. package/dist/cjs/components/template/ExternalVerificationNodeHandler.js.map +1 -1
  21. package/dist/cjs/hooks/useSession.js +3 -3
  22. package/dist/cjs/hooks/useSession.js.map +1 -1
  23. package/dist/cjs/hooks/useUserInputForm.js +13 -9
  24. package/dist/cjs/hooks/useUserInputForm.js.map +1 -1
  25. package/dist/cjs/i18n/en.json.js +4 -1
  26. package/dist/cjs/i18n/en.json.js.map +1 -1
  27. package/dist/cjs/i18n/fr.json.js +4 -1
  28. package/dist/cjs/i18n/fr.json.js.map +1 -1
  29. package/dist/cjs/services/api.js +5 -0
  30. package/dist/cjs/services/api.js.map +1 -1
  31. package/dist/cjs/services/auditTrailService.js +19 -9
  32. package/dist/cjs/services/auditTrailService.js.map +1 -1
  33. package/dist/cjs/services/integrationService.js +2 -0
  34. package/dist/cjs/services/integrationService.js.map +1 -1
  35. package/dist/cjs/services/sessionCredentials.js +24 -0
  36. package/dist/cjs/services/sessionCredentials.js.map +1 -0
  37. package/dist/cjs/types/session.js.map +1 -1
  38. package/dist/cjs/utils/customFieldIds.js +52 -0
  39. package/dist/cjs/utils/customFieldIds.js.map +1 -0
  40. package/dist/cjs/utils/jdiCodes.js +3 -1
  41. package/dist/cjs/utils/jdiCodes.js.map +1 -1
  42. package/dist/cjs/utils/navigation.js +21 -0
  43. package/dist/cjs/utils/navigation.js.map +1 -0
  44. package/dist/esm/components/DatakeenSession.js +8 -2
  45. package/dist/esm/components/DatakeenSession.js.map +1 -1
  46. package/dist/esm/components/document-collection/DocumentCollection.js +43 -30
  47. package/dist/esm/components/document-collection/DocumentCollection.js.map +1 -1
  48. package/dist/esm/components/session/EndFlow.js +3 -2
  49. package/dist/esm/components/session/EndFlow.js.map +1 -1
  50. package/dist/esm/components/session/MobileRedirect.js +4 -0
  51. package/dist/esm/components/session/MobileRedirect.js.map +1 -1
  52. package/dist/esm/components/session/PdfGeneration.js +25 -19
  53. package/dist/esm/components/session/PdfGeneration.js.map +1 -1
  54. package/dist/esm/components/session/StartSession.js +16 -5
  55. package/dist/esm/components/session/StartSession.js.map +1 -1
  56. package/dist/esm/components/session/UserInputForm/CustomFormFields.js +7 -14
  57. package/dist/esm/components/session/UserInputForm/CustomFormFields.js.map +1 -1
  58. package/dist/esm/components/session/UserInputForm.js +2 -2
  59. package/dist/esm/components/session/UserInputForm.js.map +1 -1
  60. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js +12 -14
  61. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  62. package/dist/esm/components/template/ExternalVerificationNodeHandler.js +67 -4
  63. package/dist/esm/components/template/ExternalVerificationNodeHandler.js.map +1 -1
  64. package/dist/esm/hooks/useSession.js +3 -3
  65. package/dist/esm/hooks/useSession.js.map +1 -1
  66. package/dist/esm/hooks/useUserInputForm.js +13 -9
  67. package/dist/esm/hooks/useUserInputForm.js.map +1 -1
  68. package/dist/esm/i18n/en.json.js +4 -1
  69. package/dist/esm/i18n/en.json.js.map +1 -1
  70. package/dist/esm/i18n/fr.json.js +4 -1
  71. package/dist/esm/i18n/fr.json.js.map +1 -1
  72. package/dist/esm/services/api.js +5 -0
  73. package/dist/esm/services/api.js.map +1 -1
  74. package/dist/esm/services/auditTrailService.js +19 -9
  75. package/dist/esm/services/auditTrailService.js.map +1 -1
  76. package/dist/esm/services/integrationService.js +2 -0
  77. package/dist/esm/services/integrationService.js.map +1 -1
  78. package/dist/esm/services/sessionCredentials.js +20 -0
  79. package/dist/esm/services/sessionCredentials.js.map +1 -0
  80. package/dist/esm/types/session.js.map +1 -1
  81. package/dist/esm/utils/customFieldIds.js +50 -0
  82. package/dist/esm/utils/customFieldIds.js.map +1 -0
  83. package/dist/esm/utils/jdiCodes.js +3 -1
  84. package/dist/esm/utils/jdiCodes.js.map +1 -1
  85. package/dist/esm/utils/navigation.js +19 -0
  86. package/dist/esm/utils/navigation.js.map +1 -0
  87. package/dist/types/components/DatakeenSession.d.ts +1 -1
  88. package/dist/types/hooks/useSession.d.ts +1 -1
  89. package/dist/types/types/session.d.ts +3 -0
  90. package/docs/SESSION_TOKEN_MIGRATION.md +52 -0
  91. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"auditTrailService.js","sources":["../../../../src/services/auditTrailService.ts"],"sourcesContent":["/**\n * Audit Trail Service\n *\n * Service for interacting with the Datakeen Audit Trail API.\n * Handles creating and retrieving audit trail entries.\n */\n\nimport { apiService } from \"./api\";\nimport { fetchSessionById } from \"./sessionService\";\n\n/**\n * Event types for audit trail entries.\n * These must match the backend AuditTrailEventType enum.\n */\nexport enum AuditTrailEventType {\n STATUS_MODIFIED = \"STATUS_MODIFIED\",\n INFORMATION_MODIFIED = \"INFORMATION_MODIFIED\",\n AI_CONTROLED = \"AI_CONTROLED\",\n SESSION_STARTED = \"SESSION_STARTED\",\n SESSION_ENDED = \"SESSION_ENDED\",\n SESSION_ABANDONED = \"SESSION_ABANDONED\",\n DOCUMENT_UPLOADED = \"DOCUMENT_UPLOADED\",\n SELFIE_CAPTURED = \"SELFIE_CAPTURED\",\n FORM_SENDED_LINK = \"FORM_SENDED_LINK\",\n SIGNATURE_DOCUMENT_OPENED = \"SIGNATURE_DOCUMENT_OPENED\",\n DOCUMENT_SIGNED = \"DOCUMENT_SIGNED\",\n FORM_VALIDATED = \"FORM_VALIDATED\",\n DOCUMENT_TYPE_SELECTED = \"DOCUMENT_TYPE_SELECTED\",\n CAPTURE_MODE_SELECTED = \"CAPTURE_MODE_SELECTED\",\n PHOTO_CAPTURED = \"PHOTO_CAPTURED\",\n PHOTOS_VALIDATED = \"PHOTOS_VALIDATED\",\n DOCUMENT_LOADED = \"DOCUMENT_LOADED\",\n DOCUMENTS_VALIDATED = \"DOCUMENTS_VALIDATED\",\n VERIFICATION_COMPLETED = \"VERIFICATION_COMPLETED\",\n}\n\n/**\n * Interface for audit trail entry creation request data\n */\nexport interface CreateAuditTrailRequest {\n eventType: AuditTrailEventType;\n analysisId: string;\n documentsName?: Record<string, any>;\n userInputs?: Record<string, any>;\n metadata?: Record<string, any>;\n clientInfoId?: string;\n userId?: string;\n}\n\n/**\n * Interface for audit trail entry response data\n */\nexport interface AuditTrailEntry {\n id: string;\n eventType: AuditTrailEventType;\n documentsName?: Record<string, any>;\n userInputs?: Record<string, any>;\n analysisId: string;\n clientInfoId?: string;\n userId?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Creates an audit trail entry and associates it with an analysis\n *\n * @param auditTrailData - The audit trail data to create\n * @returns The created audit trail entry\n */\nexport const createAuditTrailEntry = async (\n auditTrailData: CreateAuditTrailRequest\n): Promise<AuditTrailEntry> => {\n try {\n const payload = {\n ...auditTrailData,\n toSession: true,\n };\n const response = await apiService.post(\n \"/session/audit-trail\",\n payload\n );\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Fetches all audit trail entries for a specific analysis\n *\n * @param analysisId - The ID of the analysis\n * @returns Array of audit trail entries\n */\nexport const getAuditTrailsByAnalysisId = async (\n analysisId: string\n): Promise<AuditTrailEntry[]> => {\n try {\n const response = await apiService.get(\n `/session/audit-trail/analysis/${analysisId}`\n );\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Fetches all audit trail entries for a specific session\n *\n * @param sessionId - The ID of the session\n * @returns Array of audit trail entries\n */\nexport const getAuditTrailsBySessionId = async (\n sessionId: string\n): Promise<AuditTrailEntry[]> => {\n try {\n const response = await apiService.get(\n `/session/audit-trail/session/${sessionId}`\n );\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Creates an audit trail entry when a session is started\n *\n * @param analysisId - The ID of the analysis associated with the session\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSessionStarted = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SESSION_STARTED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a session is ended\n *\n * @param analysisId - The ID of the analysis associated with the session\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSessionEnded = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SESSION_ENDED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a document is uploaded\n *\n * @param analysisId - The ID of the analysis\n * @param documentName - The name or details of the document\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logDocumentUploaded = async (\n analysisId: string,\n documentName: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_UPLOADED,\n analysisId,\n documentsName: documentName,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a selfie is captured\n *\n * @param analysisId - The ID of the analysis\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSelfieCaptured = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SELFIE_CAPTURED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when user information is modified\n *\n * @param analysisId - The ID of the analysis\n * @param userInputs - The user inputs that were modified\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logInformationModified = async (\n analysisId: string,\n userInputs: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.INFORMATION_MODIFIED,\n analysisId,\n userInputs,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a session status is modified\n *\n * @param analysisId - The ID of the analysis\n * @param status - The new status value\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logStatusModified = async (\n analysisId: string,\n status: any,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.STATUS_MODIFIED,\n analysisId,\n userInputs: { status },\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when an AI control is performed\n *\n * @param analysisId - The ID of the analysis\n * @param aiResults - The results of the AI control\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logAiControlled = async (\n analysisId: string,\n aiResults: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.AI_CONTROLED,\n analysisId,\n userInputs: aiResults,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a form link is sent\n *\n * @param analysisId - The ID of the analysis\n * @param recipientInfo - Information about the link recipient\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logFormSendedLink = async (\n analysisId: string,\n recipientInfo: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.FORM_SENDED_LINK,\n analysisId,\n userInputs: recipientInfo,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a signature document is opened\n *\n * @param analysisId - The ID of the analysis\n * @param documentInfo - Information about the document being signed\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSignatureDocumentOpened = async (\n analysisId: string,\n documentInfo?: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SIGNATURE_DOCUMENT_OPENED,\n analysisId,\n userInputs: documentInfo || {},\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a document is signed\n *\n * @param analysisId - The ID of the analysis\n * @param signatureInfo - Information about the signature\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logDocumentSigned = async (\n analysisId: string,\n signatureInfo?: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_SIGNED,\n analysisId,\n userInputs: signatureInfo || {},\n clientInfoId,\n });\n};\n\n// ─── APP3-1763 — Nouveaux events de parcours ─────────────────────────────────\n// Convention : sessionId est passé dans le champ analysisId (backend route via toSession:true).\n// Tous les appels sont fire-and-forget — les callers ne doivent PAS await ces fonctions.\n\nexport const logFormValidated = (\n sessionId: string,\n userInputs?: Record<string, any>,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.FORM_VALIDATED,\n analysisId: sessionId,\n userInputs: userInputs || {},\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentTypeSelected = (\n sessionId: string,\n documentType: string,\n documentLabel?: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_TYPE_SELECTED,\n analysisId: sessionId,\n metadata: { documentType, documentLabel: documentLabel ?? documentType },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logCaptureModeSelected = (\n sessionId: string,\n captureMode: \"picture\" | \"upload\",\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.CAPTURE_MODE_SELECTED,\n analysisId: sessionId,\n metadata: { captureMode },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logPhotoCaptured = (\n sessionId: string,\n side: \"recto\" | \"verso\",\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.PHOTO_CAPTURED,\n analysisId: sessionId,\n metadata: { side },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logPhotosValidated = (\n sessionId: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.PHOTOS_VALIDATED,\n analysisId: sessionId,\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentLoaded = (\n sessionId: string,\n side: \"recto\" | \"verso\",\n documentType?: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_LOADED,\n analysisId: sessionId,\n metadata: { side, ...(documentType ? { documentType } : {}) },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentsValidated = (\n sessionId: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENTS_VALIDATED,\n analysisId: sessionId,\n clientInfoId,\n }).catch(() => {});\n};\n"],"names":["AuditTrailEventType","__awaiter","apiService"],"mappings":"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"}
1
+ {"version":3,"file":"auditTrailService.js","sources":["../../../../src/services/auditTrailService.ts"],"sourcesContent":["/**\n * Audit Trail Service\n *\n * Service for interacting with the Datakeen Audit Trail API.\n * Handles creating and retrieving audit trail entries.\n */\n\nimport { getSessionCredential } from \"./sessionCredentials\";\nimport { apiService } from \"./api\";\nimport { fetchSessionById } from \"./sessionService\";\n\n/**\n * Event types for audit trail entries.\n * These must match the backend AuditTrailEventType enum.\n */\nexport enum AuditTrailEventType {\n STATUS_MODIFIED = \"STATUS_MODIFIED\",\n INFORMATION_MODIFIED = \"INFORMATION_MODIFIED\",\n AI_CONTROLED = \"AI_CONTROLED\",\n SESSION_STARTED = \"SESSION_STARTED\",\n SESSION_ENDED = \"SESSION_ENDED\",\n SESSION_ABANDONED = \"SESSION_ABANDONED\",\n DOCUMENT_UPLOADED = \"DOCUMENT_UPLOADED\",\n SELFIE_CAPTURED = \"SELFIE_CAPTURED\",\n FORM_SENDED_LINK = \"FORM_SENDED_LINK\",\n SIGNATURE_DOCUMENT_OPENED = \"SIGNATURE_DOCUMENT_OPENED\",\n DOCUMENT_SIGNED = \"DOCUMENT_SIGNED\",\n FORM_VALIDATED = \"FORM_VALIDATED\",\n DOCUMENT_TYPE_SELECTED = \"DOCUMENT_TYPE_SELECTED\",\n CAPTURE_MODE_SELECTED = \"CAPTURE_MODE_SELECTED\",\n PHOTO_CAPTURED = \"PHOTO_CAPTURED\",\n PHOTOS_VALIDATED = \"PHOTOS_VALIDATED\",\n DOCUMENT_LOADED = \"DOCUMENT_LOADED\",\n DOCUMENTS_VALIDATED = \"DOCUMENTS_VALIDATED\",\n VERIFICATION_COMPLETED = \"VERIFICATION_COMPLETED\",\n}\n\n/**\n * Interface for audit trail entry creation request data\n */\nexport interface CreateAuditTrailRequest {\n eventType: AuditTrailEventType;\n analysisId: string;\n documentsName?: Record<string, any>;\n userInputs?: Record<string, any>;\n metadata?: Record<string, any>;\n clientInfoId?: string;\n userId?: string;\n}\n\n/**\n * Interface for audit trail entry response data\n */\nexport interface AuditTrailEntry {\n id: string;\n eventType: AuditTrailEventType;\n documentsName?: Record<string, any>;\n userInputs?: Record<string, any>;\n analysisId: string;\n clientInfoId?: string;\n userId?: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Creates an audit trail entry and associates it with an analysis\n *\n * @param auditTrailData - The audit trail data to create\n * @returns The created audit trail entry\n */\nexport const createAuditTrailEntry = async (\n auditTrailData: CreateAuditTrailRequest\n): Promise<AuditTrailEntry> => {\n try {\n const payload = {\n ...auditTrailData,\n toSession: true,\n };\n const token = getSessionCredential(auditTrailData.analysisId);\n const response = token\n ? await apiService.post(\"/session/audit-trail\", payload, { headers: { \"X-Session-Token\": token } })\n : await apiService.post(\"/session/audit-trail\", payload);\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Fetches all audit trail entries for a specific analysis\n *\n * @param analysisId - The ID of the analysis\n * @returns Array of audit trail entries\n */\nexport const getAuditTrailsByAnalysisId = async (\n analysisId: string\n): Promise<AuditTrailEntry[]> => {\n try {\n const response = await apiService.get(\n `/session/audit-trail/analysis/${analysisId}`\n );\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Fetches all audit trail entries for a specific session\n *\n * @param sessionId - The ID of the session\n * @returns Array of audit trail entries\n */\nexport const getAuditTrailsBySessionId = async (\n sessionId: string\n): Promise<AuditTrailEntry[]> => {\n try {\n const response = await apiService.get(\n `/session/audit-trail/session/${sessionId}`\n );\n return response.data;\n } catch (error) {\n throw error;\n }\n};\n\n/**\n * Creates an audit trail entry when a session is started\n *\n * @param analysisId - The ID of the analysis associated with the session\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSessionStarted = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SESSION_STARTED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a session is ended\n *\n * @param analysisId - The ID of the analysis associated with the session\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSessionEnded = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SESSION_ENDED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a document is uploaded\n *\n * @param analysisId - The ID of the analysis\n * @param documentName - The name or details of the document\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logDocumentUploaded = async (\n analysisId: string,\n documentName: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_UPLOADED,\n analysisId,\n documentsName: documentName,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a selfie is captured\n *\n * @param analysisId - The ID of the analysis\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSelfieCaptured = async (\n analysisId: string,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SELFIE_CAPTURED,\n analysisId,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when user information is modified\n *\n * @param analysisId - The ID of the analysis\n * @param userInputs - The user inputs that were modified\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logInformationModified = async (\n analysisId: string,\n userInputs: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.INFORMATION_MODIFIED,\n analysisId,\n userInputs,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a session status is modified\n *\n * @param analysisId - The ID of the analysis\n * @param status - The new status value\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logStatusModified = async (\n analysisId: string,\n status: any,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.STATUS_MODIFIED,\n analysisId,\n userInputs: { status },\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when an AI control is performed\n *\n * @param analysisId - The ID of the analysis\n * @param aiResults - The results of the AI control\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logAiControlled = async (\n analysisId: string,\n aiResults: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.AI_CONTROLED,\n analysisId,\n userInputs: aiResults,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a form link is sent\n *\n * @param analysisId - The ID of the analysis\n * @param recipientInfo - Information about the link recipient\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logFormSendedLink = async (\n analysisId: string,\n recipientInfo: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.FORM_SENDED_LINK,\n analysisId,\n userInputs: recipientInfo,\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a signature document is opened\n *\n * @param analysisId - The ID of the analysis\n * @param documentInfo - Information about the document being signed\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logSignatureDocumentOpened = async (\n analysisId: string,\n documentInfo?: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.SIGNATURE_DOCUMENT_OPENED,\n analysisId,\n userInputs: documentInfo || {},\n clientInfoId,\n });\n};\n\n/**\n * Creates an audit trail entry when a document is signed\n *\n * @param analysisId - The ID of the analysis\n * @param signatureInfo - Information about the signature\n * @param clientInfoId - Optional client info ID\n * @returns The created audit trail entry\n */\nexport const logDocumentSigned = async (\n analysisId: string,\n signatureInfo?: Record<string, any>,\n clientInfoId?: string\n): Promise<AuditTrailEntry> => {\n return createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_SIGNED,\n analysisId,\n userInputs: signatureInfo || {},\n clientInfoId,\n });\n};\n\n// ─── APP3-1763 — Nouveaux events de parcours ─────────────────────────────────\n// Convention : sessionId est passé dans le champ analysisId (backend route via toSession:true).\n// Tous les appels sont fire-and-forget — les callers ne doivent PAS await ces fonctions.\n\nexport const logFormValidated = (\n sessionId: string,\n userInputs?: Record<string, any>,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.FORM_VALIDATED,\n analysisId: sessionId,\n userInputs: userInputs || {},\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentTypeSelected = (\n sessionId: string,\n documentType: string,\n documentLabel?: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_TYPE_SELECTED,\n analysisId: sessionId,\n metadata: { documentType, documentLabel: documentLabel ?? documentType },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logCaptureModeSelected = (\n sessionId: string,\n captureMode: \"picture\" | \"upload\",\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.CAPTURE_MODE_SELECTED,\n analysisId: sessionId,\n metadata: { captureMode },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logPhotoCaptured = (\n sessionId: string,\n side: \"recto\" | \"verso\",\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.PHOTO_CAPTURED,\n analysisId: sessionId,\n metadata: { side },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logPhotosValidated = (\n sessionId: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.PHOTOS_VALIDATED,\n analysisId: sessionId,\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentLoaded = (\n sessionId: string,\n side: \"recto\" | \"verso\",\n documentType?: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENT_LOADED,\n analysisId: sessionId,\n metadata: { side, ...(documentType ? { documentType } : {}) },\n clientInfoId,\n }).catch(() => {});\n};\n\nexport const logDocumentsValidated = (\n sessionId: string,\n clientInfoId?: string\n): void => {\n createAuditTrailEntry({\n eventType: AuditTrailEventType.DOCUMENTS_VALIDATED,\n analysisId: sessionId,\n clientInfoId,\n }).catch(() => {});\n};\n"],"names":["AuditTrailEventType","__awaiter","getSessionCredential","apiService"],"mappings":"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"}
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
4
+ var sessionCredentials = require('./sessionCredentials.js');
4
5
  var api = require('./api.js');
5
6
 
6
7
  /**
@@ -19,6 +20,7 @@ var getDocusealSigningToken = function (sessionId, templateId) { return tslib_es
19
20
  case 0:
20
21
  _a.trys.push([0, 2, , 3]);
21
22
  return [4 /*yield*/, api.apiService.get("/integrations/docuseal/signing-token", {
23
+ headers: { "X-Session-Token": sessionCredentials.getSessionCredential(sessionId) },
22
24
  params: { sessionId: sessionId, templateId: templateId },
23
25
  })];
24
26
  case 1:
@@ -1 +1 @@
1
- {"version":3,"file":"integrationService.js","sources":["../../../../src/services/integrationService.ts"],"sourcesContent":["import { apiService } from \"./api\";\n\n/**\n * Fetches a DocuSeal signing token for the electronic signature session.\n * The backend generates a JWT token — pre-filling happens client-side\n * via the DocusealForm component props, not server-side.\n *\n * @param sessionId - The current session identifier\n * @param templateId - The DocuSeal template identifier (external_id from node)\n * @returns Object containing the JWT token and DocuSeal host\n */\nexport const getDocusealSigningToken = async (\n sessionId: string,\n templateId: string,\n): Promise<{ token: string; host: string }> => {\n try {\n const response = await apiService.get(`/integrations/docuseal/signing-token`, {\n params: { sessionId, templateId },\n });\n return (response.data as any).data;\n } catch (error) {\n throw error;\n }\n};\n"],"names":["__awaiter","apiService"],"mappings":";;;;;AAEA;;;;;;;;AAQG;AACI,IAAM,uBAAuB,GAAG,UACnC,SAAiB,EACjB,UAAkB,EAAA,EAAA,OAAAA,mBAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,YAAA;;;;;;AAGG,gBAAA,OAAA,CAAA,CAAA,YAAMC,cAAU,CAAC,GAAG,CAAC,sCAAsC,EAAE;AAC1E,wBAAA,MAAM,EAAE,EAAE,SAAS,WAAA,EAAE,UAAU,YAAA,EAAE;AACpC,qBAAA,CAAC,CAAA;;AAFI,gBAAA,QAAQ,GAAG,EAAA,CAAA,IAAA,EAEf;AACF,gBAAA,OAAA,CAAA,CAAA,aAAQ,QAAQ,CAAC,IAAY,CAAC,IAAI,CAAA;;;AAElC,gBAAA,MAAM,OAAK;;;;;;;;"}
1
+ {"version":3,"file":"integrationService.js","sources":["../../../../src/services/integrationService.ts"],"sourcesContent":["import { getSessionCredential } from './sessionCredentials';\nimport { apiService } from \"./api\";\n\n/**\n * Fetches a DocuSeal signing token for the electronic signature session.\n * The backend generates a JWT token — pre-filling happens client-side\n * via the DocusealForm component props, not server-side.\n *\n * @param sessionId - The current session identifier\n * @param templateId - The DocuSeal template identifier (external_id from node)\n * @returns Object containing the JWT token and DocuSeal host\n */\nexport const getDocusealSigningToken = async (\n sessionId: string,\n templateId: string,\n): Promise<{ token: string; host: string }> => {\n try {\n const response = await apiService.get(`/integrations/docuseal/signing-token`, {\n headers: { \"X-Session-Token\": getSessionCredential(sessionId) },\n params: { sessionId, templateId },\n });\n return (response.data as any).data;\n } catch (error) {\n throw error;\n }\n};\n"],"names":["__awaiter","apiService","getSessionCredential"],"mappings":";;;;;;AAGA;;;;;;;;AAQG;AACI,IAAM,uBAAuB,GAAG,UACnC,SAAiB,EACjB,UAAkB,EAAA,EAAA,OAAAA,mBAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,YAAA;;;;;;AAGG,gBAAA,OAAA,CAAA,CAAA,YAAMC,cAAU,CAAC,GAAG,CAAC,sCAAsC,EAAE;wBAC1E,OAAO,EAAE,EAAE,iBAAiB,EAAEC,uCAAoB,CAAC,SAAS,CAAC,EAAE;AAC/D,wBAAA,MAAM,EAAE,EAAE,SAAS,WAAA,EAAE,UAAU,YAAA,EAAE;AACpC,qBAAA,CAAC,CAAA;;AAHI,gBAAA,QAAQ,GAAG,EAAA,CAAA,IAAA,EAGf;AACF,gBAAA,OAAA,CAAA,CAAA,aAAQ,QAAQ,CAAC,IAAY,CAAC,IAAI,CAAA;;;AAElC,gBAAA,MAAM,OAAK;;;;;;;;"}
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ /** Memory-only credentials, bound to a session and never sent to unrelated URLs. */
4
+ var credentials = new Map();
5
+ function setSessionCredential(sessionId, token) {
6
+ if (token)
7
+ credentials.set(sessionId, token);
8
+ else
9
+ credentials.delete(sessionId);
10
+ }
11
+ function getSessionCredential(sessionId) {
12
+ return credentials.get(sessionId);
13
+ }
14
+ function credentialForRequest(url) {
15
+ if (/^[a-z]+:/i.test(url) || url.startsWith('//'))
16
+ return undefined;
17
+ var match = url.match(/^\/?session\/sdk\/([^/?]+)/);
18
+ return match ? credentials.get(decodeURIComponent(match[1])) : undefined;
19
+ }
20
+
21
+ exports.credentialForRequest = credentialForRequest;
22
+ exports.getSessionCredential = getSessionCredential;
23
+ exports.setSessionCredential = setSessionCredential;
24
+ //# sourceMappingURL=sessionCredentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sessionCredentials.js","sources":["../../../../src/services/sessionCredentials.ts"],"sourcesContent":["/** Memory-only credentials, bound to a session and never sent to unrelated URLs. */\nconst credentials = new Map<string, string>();\nexport function setSessionCredential(sessionId: string, token?: string): void {\n if (token) credentials.set(sessionId, token);\n else credentials.delete(sessionId);\n}\nexport function getSessionCredential(sessionId: string): string | undefined {\n return credentials.get(sessionId);\n}\nexport function credentialForRequest(url: string): string | undefined {\n if (/^[a-z]+:/i.test(url) || url.startsWith('//')) return undefined;\n const match = url.match(/^\\/?session\\/sdk\\/([^/?]+)/);\n return match ? credentials.get(decodeURIComponent(match[1])) : undefined;\n}\n"],"names":[],"mappings":";;AAAA;AACA,IAAM,WAAW,GAAG,IAAI,GAAG,EAAkB;AACvC,SAAU,oBAAoB,CAAC,SAAiB,EAAE,KAAc,EAAA;AACpE,IAAA,IAAI,KAAK;AAAE,QAAA,WAAW,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAC;;AACvC,QAAA,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC;AACpC;AACM,SAAU,oBAAoB,CAAC,SAAiB,EAAA;AACpD,IAAA,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC;AACnC;AACM,SAAU,oBAAoB,CAAC,GAAW,EAAA;AAC9C,IAAA,IAAI,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC;AAAE,QAAA,OAAO,SAAS;IACnE,IAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,4BAA4B,CAAC;IACrD,OAAO,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;AAC1E;;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number, skipHistory?: boolean) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n /** Avance via le graphe et tronque l'historique au nœud d'arrivée. */\n goToNextStepCommitted: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n editableIfMissing?: boolean; // soft lock — éditable si la valeur API est absente\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n showLegacyCGU?: boolean; // default: true — rétrocompatibilité\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n cguLinkLabel?: string;\n privacyLinkLabel?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n nfcEnabled?: boolean;\n // \"nfcAndApi\" reste accepté pour rétrocompat (parcours legacy) ; à normaliser à la lecture.\n nfcMode?: \"nfcOnly\" | \"nfcOrPhoto\" | \"nfcAndApi\";\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\" | \"INPI_RBE\";\n /** INPI_RBE only. Opt-in: retry against the RNA (associations) when the RNE finds nothing. */\n rnaFallbackEnabled?: boolean;\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n /** Écran affiché après la signature. Valeurs vides : textes standard traduits. */\n signedScreenTitle?: string;\n signedScreenDescription?: string;\n signedScreenDownloadHint?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n\n /**\n * Paramétrable par nœud depuis le journey builder : autorise ou non le\n * bouton \"Poursuivre quand même\" en cas d'échec. S'applique aux nœuds\n * identity-control, document-collection, biometric-capture (selfie/video)\n * et external-verification. Absent/true = comportement actuel inchangé\n * (bouton proposé), false = masqué.\n *\n * Déprécié pour controle-jdi/identity-control quand une sortie \"false\" est\n * câblée : dans ce cas le routage automatique (blockingCodes +\n * maxResubmissionAction) prend le relais et ce bouton disparaît. Reste lu\n * tel quel pour les nœuds legacy sans sortie \"false\" (rétrocompat).\n */\n allowContinueOnFailure?: boolean;\n\n /**\n * Codes JDI exacts considérés comme bloquants pour ce nœud controle-jdi\n * (déclenchent la boucle de resoumission). Absent = DEFAULT_BLOCKING_CODES\n * (utils/jdiCodes.ts) — comportement legacy inchangé. Le code 8.0 est\n * toujours bloquant indépendamment de cette liste.\n */\n blockingCodes?: string[];\n\n /**\n * Action suivie quand les resoumissions sont épuisées sur un code bloquant\n * ET qu'une sortie \"false\" est câblée sur ce nœud controle-jdi (miroir de\n * conditionMaxRetryAction sur le nœud condition). Défaut \"end-journey\".\n */\n maxResubmissionAction?: \"end-journey\" | \"force-true\";\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n nfcStatus?: \"pending\" | \"opened\" | \"completed\" | \"skipped\" | \"failed\";\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n"],"names":[],"mappings":";;AAuEO,IAAM,2BAA2B,GAAsB;;;;"}
1
+ {"version":3,"file":"session.js","sources":["../../../../src/types/session.ts"],"sourcesContent":["import type React from \"react\";\n\nexport interface SessionConfig {\n sessionToken?: string;\n selfie?: boolean;\n requireMobile?: boolean;\n}\n\nexport interface DatakeenSessionProps {\n /** Session credential returned by server-side session creation. Required by secured backends. */\n sessionToken?: string;\n sessionId: string;\n sessionConfig?: SessionConfig;\n apiBaseUrl?: string; // Optional API base URL for dynamic environment configuration\n}\n\nexport interface UseSessionReturn {\n SessionComponent: React.ReactElement;\n}\n\nexport type stepObject = {\n setStep: (step: number, skipHistory?: boolean) => void;\n goBack: () => void;\n /** Retour arrière vers un nœud précis (ex: \"Corriger ma saisie\") :\n * tronque l'historique jusqu'à `targetStep` au lieu de l'empiler. */\n goBackToStep: (targetStep: number) => void;\n goToNextStep: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n /** Avance via le graphe et tronque l'historique au nœud d'arrivée. */\n goToNextStepCommitted: (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n ) => void;\n step: number;\n canGoBack: boolean;\n};\n\nexport interface ProcessingStep {\n title: string;\n subtitle: string;\n hasError?: boolean;\n}\n\nexport type ConditionTokenType = \"variable\" | \"control\" | \"operator\" | \"input\";\n\nexport interface ConditionToken {\n type: ConditionTokenType;\n value: string;\n label?: string;\n sourceNodeId?: string;\n}\n\n/**\n * Type for custom field value types\n */\nexport type CustomFieldValueType =\n | \"text\"\n | \"enum\"\n | \"number\"\n | \"boolean\"\n | \"date\"\n | \"email\"\n | \"address\"\n | \"list\";\n\n/**\n * Display formats supported for date fields (top-level and list columns).\n */\nexport type DateDisplayFormat = \"dd/mm/yyyy\" | \"mm/dd/yyyy\" | \"yyyy-mm-dd\";\n\nexport const DEFAULT_DATE_DISPLAY_FORMAT: DateDisplayFormat = \"dd/mm/yyyy\";\n\n/**\n * Column definition for a list-type custom field\n */\nexport interface ListColumn {\n label: string;\n type: \"text\" | \"enum\" | \"date\" | \"email\";\n options?: string[]; // required when type === 'enum'\n placeholder?: string; // text/email/date — shown to the end user\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n}\n\n/**\n * Interface for custom field definition\n */\nexport interface CustomField {\n id: string;\n label: string;\n placeholder?: string;\n description?: string;\n valueType: CustomFieldValueType;\n enumOptions?: string[];\n listColumns?: ListColumn[]; // for list type: column definitions\n minRows?: number; // for list type: minimum rows expected\n required?: boolean;\n regex?: string; // text — JS regex source (without slashes)\n regexErrorMessage?: string; // text — message displayed when regex fails\n dateFormat?: DateDisplayFormat; // date — display format expected\n lockedFromApi?: boolean;\n editableIfMissing?: boolean; // soft lock — éditable si la valeur API est absente\n userInputKey?: string;\n}\n\n/**\n * Interface for session template node\n */\nexport interface SessionTemplateNode {\n id: string;\n type: string;\n title: string;\n description: string;\n informationType?:\n | \"identity\"\n | \"identity-legal\"\n | \"contact\"\n | \"address\"\n | \"nationality\"\n | \"custom\";\n position: {\n x: number;\n y: number;\n };\n options: unknown[];\n selectedOptions: string[];\n requiredDocumentType?: string;\n isRequired: boolean;\n order: number;\n optionalFields?: string[];\n requiredFields?: string[];\n pageTitle?: string;\n pageDescription?: string;\n // Properties for document-collection node type\n allowedDocumentTypes?: Array<{\n id: string;\n name: string;\n /**\n * Optional side information coming from the template.\n * When provided and equals to two (\"two\", 2, \"double\", \"recto-verso\"),\n * consumers should allow uploading two sides (front/back).\n */\n side?: string | number;\n }>;\n allowedAddingMethods?: string[];\n introductionPage?: {\n title?: string;\n description?: string;\n };\n documentSelection?: {\n title?: string;\n description?: string;\n };\n // Start node specific properties\n welcomeTitle?: string;\n welcomeSubtitle?: string;\n welcomeDescription?: string;\n welcomeImage?: string;\n qrCodeTitle?: string;\n qrCodeDescription?: string;\n showLegacyCGU?: boolean; // default: true — rétrocompatibilité\n\n // Legal consent node specific properties\n consentDescription?: string;\n consentDescription2?: string;\n cguUrl?: string;\n privacyPolicyUrl?: string;\n cguLinkLabel?: string;\n privacyLinkLabel?: string;\n checkboxText?: string;\n // Identity control specific properties\n automaticPhotoCapture?: boolean;\n nfcEnabled?: boolean;\n // \"nfcAndApi\" reste accepté pour rétrocompat (parcours legacy) ; à normaliser à la lecture.\n nfcMode?: \"nfcOnly\" | \"nfcOrPhoto\" | \"nfcAndApi\";\n acceptedCountries?: AcceptedCountry[];\n // End node specific properties\n callbackURL?: string | null;\n // Résultat forcé par le nœud `end` (configuré dans le builder). Sert au SDK à\n // afficher la variante « erreur conservée » de l'écran de fin quand la branche\n // fausse d'une condition pointe directement vers un end non_compliant.\n expectedResult?: string;\n // Condition node specific properties\n conditionExpression?: string;\n conditionTokens?: ConditionToken[];\n conditionFalseErrorMessage?: string;\n conditionMaxRetries?: number;\n conditionMaxRetryAction?: \"end-journey\" | \"force-true\";\n // Undefined is treated as \"loop\" by the SDK for legacy templates.\n conditionFalseMode?: \"retry\" | \"loop\";\n\n // External verification specific properties\n targetApi?: \"INSEE\" | \"INPI_RBE\";\n /** INPI_RBE only. Opt-in: retry against the RNA (associations) when the RNE finds nothing. */\n rnaFallbackEnabled?: boolean;\n referenceNodeId?: string;\n referenceNodeType?:\n | \"information-input\"\n | \"document-collection\"\n | \"identity-control\";\n referenceField?: \"siren\" | \"siret\";\n referenceVariable?: string;\n // Custom form fields (for information-input with type 'custom')\n customFields?: CustomField[];\n\n // Electronic signature specific properties\n templateId?: string;\n external_id?: string;\n /** Écran affiché après la signature. Valeurs vides : textes standard traduits. */\n signedScreenTitle?: string;\n signedScreenDescription?: string;\n signedScreenDownloadHint?: string;\n fieldMappings?: Array<{\n sourceFieldId: string;\n label: string;\n docusealType: string;\n readonly: boolean;\n role?: string;\n sourceNodeId?: string;\n }>;\n /** If set, the generated PDF from this upstream pdf-generation node will be used as the document to sign */\n sourcePdfNodeId?: string;\n\n // PDF generation node specific properties\n // Note: htmlTemplate is intentionally NOT included — it is server-side only and never sent to the client\n pdfMode?: \"upload\" | \"html-template\";\n sourceNodeIds?: string[];\n\n // retry properties\n allowResubmission: boolean;\n maxResubmissionAttempts?: number;\n\n /**\n * Paramétrable par nœud depuis le journey builder : autorise ou non le\n * bouton \"Poursuivre quand même\" en cas d'échec. S'applique aux nœuds\n * identity-control, document-collection, biometric-capture (selfie/video)\n * et external-verification. Absent/true = comportement actuel inchangé\n * (bouton proposé), false = masqué.\n *\n * Déprécié pour controle-jdi/identity-control quand une sortie \"false\" est\n * câblée : dans ce cas le routage automatique (blockingCodes +\n * maxResubmissionAction) prend le relais et ce bouton disparaît. Reste lu\n * tel quel pour les nœuds legacy sans sortie \"false\" (rétrocompat).\n */\n allowContinueOnFailure?: boolean;\n\n /**\n * Codes JDI exacts considérés comme bloquants pour ce nœud controle-jdi\n * (déclenchent la boucle de resoumission). Absent = DEFAULT_BLOCKING_CODES\n * (utils/jdiCodes.ts) — comportement legacy inchangé. Le code 8.0 est\n * toujours bloquant indépendamment de cette liste.\n */\n blockingCodes?: string[];\n\n /**\n * Action suivie quand les resoumissions sont épuisées sur un code bloquant\n * ET qu'une sortie \"false\" est câblée sur ce nœud controle-jdi (miroir de\n * conditionMaxRetryAction sur le nœud condition). Défaut \"end-journey\".\n */\n maxResubmissionAction?: \"end-journey\" | \"force-true\";\n}\n\n/**\n * Interface for accepted countries\n */\nexport interface AcceptedCountry {\n code: string;\n documents: {\n passport: string[];\n idCard: string[];\n driverLicense: string[];\n residencePermit: string[];\n pinkDriverLicense: string[];\n };\n}\n\n/**\n * Interface for session template edge\n */\nexport interface SessionTemplateEdge {\n id: string;\n source: string;\n target: string;\n sourceHandle?: string;\n targetHandle?: string;\n conditionValue?: string;\n}\n\n/**\n * Interface for platform information\n */\nexport interface PlatformInfo {\n mobile: boolean;\n desktop: boolean;\n backoffice: boolean;\n}\n\n/**\n * Interface for session template\n */\n/** Clé du catalogue d'icônes des écrans de fin (mappée vers lucide-react au rendu). */\nexport type EndScreenIcon =\n | \"thanks\"\n | \"send\"\n | \"mail\"\n | \"check\"\n | \"clock\"\n | \"shield\"\n | \"user\"\n | \"info\";\n\nexport interface EndScreenItem {\n icon: EndScreenIcon;\n text: string;\n}\n\nexport interface EndScreenCase {\n title?: string;\n items: EndScreenItem[];\n}\n\n/** Textes de fin personnalisés (config globale du journey). Vide → fallback standard. */\nexport interface EndScreenConfig {\n compliant?: EndScreenCase;\n nonCompliant?: EndScreenCase;\n}\n\nexport interface SessionTemplate {\n id: string;\n name: string;\n description: string;\n version: string;\n languages: string[];\n nodes: SessionTemplateNode[];\n edges: SessionTemplateEdge[];\n groupId: string;\n userId: string | null;\n created_at: string;\n updated_at: string;\n platforms?: PlatformInfo;\n logo?: string;\n showQRCode?: boolean;\n buttonBgColor?: string;\n buttonTextColor?: string;\n endScreenConfig?: EndScreenConfig;\n}\n\n/**\n * Interface for session data\n */\nexport interface SessionData {\n id: string;\n userId: string | null;\n token: string;\n templateId: string;\n templateKey: string;\n expireTime: number;\n status: string;\n result: Record<string, unknown>;\n landingPage: unknown;\n withSelfie: boolean | null;\n groupId: string | null;\n userInput: Record<string, unknown>;\n contactInfo?: {\n email: string;\n phoneNumber: string;\n };\n callbackURL?: string | null;\n webhookURL: string;\n analysisTemplateId: string | null;\n userAgent: unknown[];\n mobile: boolean;\n analysisId: string | null;\n currentStep?: number;\n nfcStatus?: \"pending\" | \"opened\" | \"completed\" | \"skipped\" | \"failed\";\n createdAt: string;\n updatedAt: string;\n auditTrail: unknown[];\n user: unknown | null;\n analysis: unknown[];\n documents: unknown[];\n template: SessionTemplate;\n retryCounts?: Record<string, number>; // nodeId -> retry count\n}\n\nexport interface ClientInfo {\n ip?: string;\n location?: string;\n device: string;\n browser: string;\n os: string;\n}\n"],"names":[],"mappings":";;AA0EO,IAAM,2BAA2B,GAAsB;;;;"}
@@ -0,0 +1,52 @@
1
+ 'use strict';
2
+
3
+ var tslib_es6 = require('../node_modules/tslib/tslib.es6.js');
4
+
5
+ /** Séparateur du suffixe ajouté à un identifiant en collision. */
6
+ var DUPLICATE_SUFFIX = "__dup";
7
+ /**
8
+ * Garantit l'unicité des identifiants de champs d'un formulaire personnalisé.
9
+ *
10
+ * Tout l'état du formulaire est indexé par `field.id` (valeur saisie, erreur,
11
+ * erreurs de cellule). Deux champs partageant un identifiant partagent donc
12
+ * leur valeur : taper dans l'un remplit l'autre, et un seul des deux est
13
+ * finalement transmis.
14
+ *
15
+ * Le builder a longtemps dérivé l'identifiant de `Date.now()` seul, sans
16
+ * composante aléatoire : deux champs enregistrés dans la même milliseconde
17
+ * (double clic, ajout programmatique, import) se retrouvent avec le même.
18
+ * Les parcours déjà publiés portent ces doublons, que le SDK doit servir sans
19
+ * attendre une ré-édition côté backoffice.
20
+ *
21
+ * La première occurrence garde son identifiant — les conditions de parcours et
22
+ * les sessions existantes qui le référencent continuent de fonctionner. Seules
23
+ * les suivantes reçoivent un suffixe déterministe, donc stable d'un rendu à
24
+ * l'autre. La clé métier envoyée à l'API (`userInputKey` ou le label
25
+ * normalisé) n'est pas touchée.
26
+ */
27
+ function dedupeCustomFieldIds(fields) {
28
+ if (!fields || fields.length === 0)
29
+ return [];
30
+ var seen = new Set();
31
+ var hasDuplicate = false;
32
+ var deduped = fields.map(function (field, index) {
33
+ var id = field.id;
34
+ if (!seen.has(id)) {
35
+ seen.add(id);
36
+ return field;
37
+ }
38
+ hasDuplicate = true;
39
+ var candidate = "".concat(id).concat(DUPLICATE_SUFFIX).concat(index);
40
+ // Un parcours peut déjà contenir un identifiant homonyme du suffixe.
41
+ while (seen.has(candidate))
42
+ candidate = "".concat(candidate, "_");
43
+ seen.add(candidate);
44
+ return tslib_es6.__assign(tslib_es6.__assign({}, field), { id: candidate });
45
+ });
46
+ // Référence stable quand il n'y a rien à corriger : le cas normal ne doit pas
47
+ // invalider les mémos qui dépendent de la liste.
48
+ return hasDuplicate ? deduped : fields;
49
+ }
50
+
51
+ exports.dedupeCustomFieldIds = dedupeCustomFieldIds;
52
+ //# sourceMappingURL=customFieldIds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"customFieldIds.js","sources":["../../../../src/utils/customFieldIds.ts"],"sourcesContent":["import type { CustomField } from \"../types/session\";\n\n/** Séparateur du suffixe ajouté à un identifiant en collision. */\nconst DUPLICATE_SUFFIX = \"__dup\";\n\n/**\n * Garantit l'unicité des identifiants de champs d'un formulaire personnalisé.\n *\n * Tout l'état du formulaire est indexé par `field.id` (valeur saisie, erreur,\n * erreurs de cellule). Deux champs partageant un identifiant partagent donc\n * leur valeur : taper dans l'un remplit l'autre, et un seul des deux est\n * finalement transmis.\n *\n * Le builder a longtemps dérivé l'identifiant de `Date.now()` seul, sans\n * composante aléatoire : deux champs enregistrés dans la même milliseconde\n * (double clic, ajout programmatique, import) se retrouvent avec le même.\n * Les parcours déjà publiés portent ces doublons, que le SDK doit servir sans\n * attendre une ré-édition côté backoffice.\n *\n * La première occurrence garde son identifiant — les conditions de parcours et\n * les sessions existantes qui le référencent continuent de fonctionner. Seules\n * les suivantes reçoivent un suffixe déterministe, donc stable d'un rendu à\n * l'autre. La clé métier envoyée à l'API (`userInputKey` ou le label\n * normalisé) n'est pas touchée.\n */\nexport function dedupeCustomFieldIds(\n fields: CustomField[] | undefined,\n): CustomField[] {\n if (!fields || fields.length === 0) return [];\n\n const seen = new Set<string>();\n let hasDuplicate = false;\n\n const deduped = fields.map((field, index) => {\n const id = field.id;\n if (!seen.has(id)) {\n seen.add(id);\n return field;\n }\n\n hasDuplicate = true;\n let candidate = `${id}${DUPLICATE_SUFFIX}${index}`;\n // Un parcours peut déjà contenir un identifiant homonyme du suffixe.\n while (seen.has(candidate)) candidate = `${candidate}_`;\n seen.add(candidate);\n return { ...field, id: candidate };\n });\n\n // Référence stable quand il n'y a rien à corriger : le cas normal ne doit pas\n // invalider les mémos qui dépendent de la liste.\n return hasDuplicate ? deduped : fields;\n}\n"],"names":["__assign"],"mappings":";;;;AAEA;AACA,IAAM,gBAAgB,GAAG,OAAO;AAEhC;;;;;;;;;;;;;;;;;;;AAmBG;AACG,SAAU,oBAAoB,CAClC,MAAiC,EAAA;AAEjC,IAAA,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;AAAE,QAAA,OAAO,EAAE;AAE7C,IAAA,IAAM,IAAI,GAAG,IAAI,GAAG,EAAU;IAC9B,IAAI,YAAY,GAAG,KAAK;IAExB,IAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,UAAC,KAAK,EAAE,KAAK,EAAA;AACtC,QAAA,IAAM,EAAE,GAAG,KAAK,CAAC,EAAE;QACnB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;AACjB,YAAA,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AACZ,YAAA,OAAO,KAAK;QACd;QAEA,YAAY,GAAG,IAAI;QACnB,IAAI,SAAS,GAAG,EAAA,CAAA,MAAA,CAAG,EAAE,SAAG,gBAAgB,CAAA,CAAA,MAAA,CAAG,KAAK,CAAE;;AAElD,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AAAE,YAAA,SAAS,GAAG,EAAA,CAAA,MAAA,CAAG,SAAS,EAAA,GAAA,CAAG;AACvD,QAAA,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;AACnB,QAAA,OAAAA,kBAAA,CAAAA,kBAAA,CAAA,EAAA,EAAY,KAAK,CAAA,EAAA,EAAE,EAAE,EAAE,SAAS,EAAA,CAAA;AAClC,IAAA,CAAC,CAAC;;;IAIF,OAAO,YAAY,GAAG,OAAO,GAAG,MAAM;AACxC;;;;"}
@@ -13,6 +13,9 @@
13
13
  *
14
14
  * Miroir exact du catalogue frontend (app-frontend/src/utils/jdiCodes.ts) —
15
15
  * les deux listes doivent rester synchronisées.
16
+ *
17
+ * 2026-09-03 : 7.1 retiré (décision produit, cf. scripts/remediate-controle-jdi-blocking-codes.ts
18
+ * côté app-backend pour le nettoyage des configs `blockingCodes` déjà sauvegardées).
16
19
  */
17
20
  var DEFAULT_BLOCKING_CODES = [
18
21
  '2.0',
@@ -24,7 +27,6 @@ var DEFAULT_BLOCKING_CODES = [
24
27
  '2.6',
25
28
  '3.0',
26
29
  '7.0',
27
- '7.1',
28
30
  ];
29
31
  /**
30
32
  * Codes toujours bloquants, quelle que soit la configuration du nœud.
@@ -1 +1 @@
1
- {"version":3,"file":"jdiCodes.js","sources":["../../../../src/utils/jdiCodes.ts"],"sourcesContent":["/**\n * Codes JDI (Justificatif D'Identité) considérés comme \"bloquants\" pour le\n * nœud controle-jdi, c'est-à-dire déclenchant la boucle de resoumission\n * (écran d'erreur + éventuel réessai) plutôt qu'un passage silencieux.\n *\n * Historiquement cette liste était hardcodée en dur (inversée) dans\n * JDIProcessing.tsx / DocumentVideoProcessing.tsx / DocumentProcessing.tsx :\n * `isSuccess = [\"1.\", \"4.\", \"5.\", \"6.\", \"9.\"].some(prefix => code.startsWith(prefix))`.\n * Elle est désormais configurable par nœud via `node.blockingCodes`, avec\n * cette liste comme valeur par défaut pour préserver le comportement legacy.\n *\n * Miroir exact du catalogue frontend (app-frontend/src/utils/jdiCodes.ts) —\n * les deux listes doivent rester synchronisées.\n */\nexport const DEFAULT_BLOCKING_CODES: string[] = [\n '2.0',\n '2.1',\n '2.2',\n '2.3',\n '2.4',\n '2.5',\n '2.6',\n '3.0',\n '7.0',\n '7.1',\n];\n\n/**\n * Codes toujours bloquants, quelle que soit la configuration du nœud.\n * 8.0 (document trouvé dans la base de spécimens frauduleux) ne doit jamais\n * pouvoir être désactivé — cf. DocumentCheck.tsx `isRetryAllowed` historique\n * (`errorCode?.startsWith(\"8\")` bloque déjà totalement le retry).\n */\nexport const ALWAYS_BLOCKING_CODES: string[] = ['8.0'];\n\n/**\n * Détermine si un code JDI doit être traité comme bloquant pour un nœud\n * controle-jdi donné.\n *\n * - `configured` absent (nœud legacy, jamais reconfiguré) → applique\n * DEFAULT_BLOCKING_CODES (comportement inchangé).\n * - `configured` présent (même vide) → correspondance exacte uniquement\n * (pas de préfixe : \"4.0\" dans la liste ne bloque pas \"4.1\"/\"4.2\").\n * - Les codes de ALWAYS_BLOCKING_CODES bloquent toujours, indépendamment\n * de `configured`.\n */\nexport function isBlockingCode(code: string, configured?: string[]): boolean {\n if (ALWAYS_BLOCKING_CODES.includes(code)) {\n return true;\n }\n const list = configured ?? DEFAULT_BLOCKING_CODES;\n return list.includes(code);\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;AAaG;AACI,IAAM,sBAAsB,GAAa;IAC9C,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;;AAGP;;;;;AAKG;AACI,IAAM,qBAAqB,GAAa,CAAC,KAAK;AAErD;;;;;;;;;;AAUG;AACG,SAAU,cAAc,CAAC,IAAY,EAAE,UAAqB,EAAA;AAChE,IAAA,IAAI,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACxC,QAAA,OAAO,IAAI;IACb;IACA,IAAM,IAAI,GAAG,UAAU,KAAA,IAAA,IAAV,UAAU,KAAA,MAAA,GAAV,UAAU,GAAI,sBAAsB;AACjD,IAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC5B;;;;;;"}
1
+ {"version":3,"file":"jdiCodes.js","sources":["../../../../src/utils/jdiCodes.ts"],"sourcesContent":["/**\n * Codes JDI (Justificatif D'Identité) considérés comme \"bloquants\" pour le\n * nœud controle-jdi, c'est-à-dire déclenchant la boucle de resoumission\n * (écran d'erreur + éventuel réessai) plutôt qu'un passage silencieux.\n *\n * Historiquement cette liste était hardcodée en dur (inversée) dans\n * JDIProcessing.tsx / DocumentVideoProcessing.tsx / DocumentProcessing.tsx :\n * `isSuccess = [\"1.\", \"4.\", \"5.\", \"6.\", \"9.\"].some(prefix => code.startsWith(prefix))`.\n * Elle est désormais configurable par nœud via `node.blockingCodes`, avec\n * cette liste comme valeur par défaut pour préserver le comportement legacy.\n *\n * Miroir exact du catalogue frontend (app-frontend/src/utils/jdiCodes.ts) —\n * les deux listes doivent rester synchronisées.\n *\n * 2026-09-03 : 7.1 retiré (décision produit, cf. scripts/remediate-controle-jdi-blocking-codes.ts\n * côté app-backend pour le nettoyage des configs `blockingCodes` déjà sauvegardées).\n */\nexport const DEFAULT_BLOCKING_CODES: string[] = [\n '2.0',\n '2.1',\n '2.2',\n '2.3',\n '2.4',\n '2.5',\n '2.6',\n '3.0',\n '7.0',\n];\n\n/**\n * Codes toujours bloquants, quelle que soit la configuration du nœud.\n * 8.0 (document trouvé dans la base de spécimens frauduleux) ne doit jamais\n * pouvoir être désactivé — cf. DocumentCheck.tsx `isRetryAllowed` historique\n * (`errorCode?.startsWith(\"8\")` bloque déjà totalement le retry).\n */\nexport const ALWAYS_BLOCKING_CODES: string[] = ['8.0'];\n\n/**\n * Détermine si un code JDI doit être traité comme bloquant pour un nœud\n * controle-jdi donné.\n *\n * - `configured` absent (nœud legacy, jamais reconfiguré) → applique\n * DEFAULT_BLOCKING_CODES (comportement inchangé).\n * - `configured` présent (même vide) → correspondance exacte uniquement\n * (pas de préfixe : \"4.0\" dans la liste ne bloque pas \"4.1\"/\"4.2\").\n * - Les codes de ALWAYS_BLOCKING_CODES bloquent toujours, indépendamment\n * de `configured`.\n */\nexport function isBlockingCode(code: string, configured?: string[]): boolean {\n if (ALWAYS_BLOCKING_CODES.includes(code)) {\n return true;\n }\n const list = configured ?? DEFAULT_BLOCKING_CODES;\n return list.includes(code);\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;;;;;AAgBG;AACI,IAAM,sBAAsB,GAAa;IAC9C,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;IACL,KAAK;;AAGP;;;;;AAKG;AACI,IAAM,qBAAqB,GAAa,CAAC,KAAK;AAErD;;;;;;;;;;AAUG;AACG,SAAU,cAAc,CAAC,IAAY,EAAE,UAAqB,EAAA;AAChE,IAAA,IAAI,qBAAqB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;AACxC,QAAA,OAAO,IAAI;IACb;IACA,IAAM,IAAI,GAAG,UAAU,KAAA,IAAA,IAAV,UAAU,KAAA,MAAA,GAAV,UAAU,GAAI,sBAAsB;AACjD,IAAA,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;AAC5B;;;;;;"}
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Indirection minimale devant `window.location`.
5
+ *
6
+ * jsdom ≥ 22 déclare `window.location` non-configurable et `location.replace`
7
+ * non-inscriptible : `delete window.location` renvoie `false` et toute
8
+ * réassignation échoue en silence. Une redirection appelée directement sur
9
+ * `window.location` n'est donc plus observable en test — elle se contente
10
+ * d'émettre « Not implemented: navigation » dans la console jsdom, ce qui fait
11
+ * passer un test qui n'a en réalité rien vérifié.
12
+ *
13
+ * Ce module est interne : il n'est pas exporté par `src/index.ts` et ne fait
14
+ * pas partie du contrat public du paquet.
15
+ */
16
+ function replaceLocation(url) {
17
+ window.location.replace(url);
18
+ }
19
+
20
+ exports.replaceLocation = replaceLocation;
21
+ //# sourceMappingURL=navigation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigation.js","sources":["../../../../src/utils/navigation.ts"],"sourcesContent":["/**\n * Indirection minimale devant `window.location`.\n *\n * jsdom ≥ 22 déclare `window.location` non-configurable et `location.replace`\n * non-inscriptible : `delete window.location` renvoie `false` et toute\n * réassignation échoue en silence. Une redirection appelée directement sur\n * `window.location` n'est donc plus observable en test — elle se contente\n * d'émettre « Not implemented: navigation » dans la console jsdom, ce qui fait\n * passer un test qui n'a en réalité rien vérifié.\n *\n * Ce module est interne : il n'est pas exporté par `src/index.ts` et ne fait\n * pas partie du contrat public du paquet.\n */\nexport function replaceLocation(url: string): void {\n window.location.replace(url);\n}\n"],"names":[],"mappings":";;AAAA;;;;;;;;;;;;AAYG;AACG,SAAU,eAAe,CAAC,GAAW,EAAA;AACzC,IAAA,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC;AAC9B;;;;"}
@@ -1,6 +1,7 @@
1
1
  import { __assign } from '../node_modules/tslib/tslib.es6.js';
2
2
  import { jsx, jsxs } from 'react/jsx-runtime';
3
- import { useEffect, useRef, useState, useLayoutEffect, useMemo } from 'react';
3
+ import { setSessionCredential } from '../services/sessionCredentials.js';
4
+ import { useLayoutEffect, useEffect, useRef, useState, useMemo } from 'react';
4
5
  import Paper from './ui/Paper.js';
5
6
  import useIsMobile from '../hooks/useIsMobile.js';
6
7
  import PoweredBy from './ui/PoweredBy.js';
@@ -43,7 +44,12 @@ import SessionContent from './session/SessionContent.js';
43
44
  var DatakeenSession = function (_a) {
44
45
  var _b, _c, _d;
45
46
  var _e, _f, _g, _h, _j, _k, _l, _m, _o;
46
- var sessionId = _a.sessionId, sessionConfig = _a.sessionConfig, apiBaseUrl = _a.apiBaseUrl;
47
+ var sessionId = _a.sessionId, sessionToken = _a.sessionToken, sessionConfig = _a.sessionConfig, apiBaseUrl = _a.apiBaseUrl;
48
+ useLayoutEffect(function () {
49
+ var fragmentToken = typeof window !== 'undefined' ? new URLSearchParams(window.location.hash.slice(1)).get('sessionToken') : null;
50
+ setSessionCredential(sessionId, sessionToken || (sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.sessionToken) || fragmentToken || undefined);
51
+ return function () { return setSessionCredential(sessionId); };
52
+ }, [sessionId, sessionToken, sessionConfig === null || sessionConfig === void 0 ? void 0 : sessionConfig.sessionToken]);
47
53
  var isMobile = useIsMobile();
48
54
  var _p = useClientInfo(), clientInfo = _p.info, clientInfoLoaded = _p.isLoaded;
49
55
  var currentLanguage = useI18n().currentLanguage;
@@ -1 +1 @@
1
- {"version":3,"file":"DatakeenSession.js","sources":["../../../../src/components/DatakeenSession.tsx"],"sourcesContent":["import { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type { DatakeenSessionProps } from \"../types/session\";\nimport Paper from \"./ui/Paper\";\nimport useIsMobile from \"../hooks/useIsMobile\";\nimport PoweredBy from \"./ui/PoweredBy\";\nimport SessionExpired from \"./session/SessionExpired\";\nimport { useRouteCSS } from \"../hooks/useRouteCSS\";\nimport { DocumentProvider } from \"../context/DocumentContext\";\nimport { ConfigProvider } from \"../context/ConfigContext\";\nimport { setSessionStore } from \"../context/SessionContext\";\n\n// Hooks\nimport { useSessionData } from \"../hooks/useSessionData\";\nimport { useStepNavigation } from \"../hooks/useStepNavigation\";\nimport { useStepCSS } from \"../hooks/useStepCSS\";\nimport { useTemplateLoader } from \"../hooks/useTemplateLoader\";\nimport { useClientInfo } from \"../hooks/useClientInfo\";\nimport { useI18n } from \"../hooks/useI18n\";\nimport { getOrderedJourneySteps } from \"../services/sessionService\";\n\n// Components\nimport NoSessionIdState from \"./states/NoSessionIdState\";\nimport LoadingState from \"./states/LoadingState\";\nimport ErrorState from \"./states/ErrorState\";\nimport SessionContent from \"./session/SessionContent\";\n\n/**\n * DatakeenSession Component\n *\n * The main component of the Datakeen SDK that manages the multi-step verification flow.\n * This component handles the different steps of the session process, including:\n * - Initial welcome screen\n * - User information collection\n * - Country selection for JDI verification\n * - Mobile redirect when selfie is required\n *\n * The component maintains internal state for the current step and user input data,\n * progressing through the verification journey as the user completes each step.\n *\n * @param {DatakeenSessionProps} props - Component props\n * @param {string} props.sessionId - Unique identifier for the verification session\n * @param {SessionConfig} props.sessionConfig - Configuration for the session (e.g., selfie: true)\n * @param {string} props.apiBaseUrl - Optional API base URL for dynamic environment configuration\n * @returns {JSX.Element} A Paper-wrapped container with the appropriate step component based on current state\n */\nconst DatakeenSession = ({\n sessionId,\n sessionConfig,\n apiBaseUrl,\n}: DatakeenSessionProps) => {\n const isMobile = useIsMobile();\n const { info: clientInfo, isLoaded: clientInfoLoaded } = useClientInfo();\n const { currentLanguage } = useI18n();\n\n // Load base CSS and UI components CSS that are always needed\n useRouteCSS(\"ui-components\");\n\n // Session data management\n const {\n session,\n setSession,\n loading,\n setLoading,\n error,\n isExpired,\n userInput,\n setUserInput,\n contactInfo,\n setContactInfo,\n loadSession,\n handleRetrySession,\n } = useSessionData(sessionId, clientInfo, clientInfoLoaded);\n\n // Step navigation management\n const { step, stepObject, history } = useStepNavigation(\n sessionId,\n session?.status,\n session?.currentStep,\n session?.template,\n );\n\n // Load route-specific CSS based on current step\n useStepCSS(step, session);\n\n // Template loading logic\n useTemplateLoader(step, sessionId, session, loading, setSession, setLoading);\n\n // Load session data on component mount\n useEffect(() => {\n loadSession();\n }, [sessionId, sessionConfig]);\n\n // Update global session store whenever session data changes\n useEffect(() => {\n const sanitizedSessionForGlobalStore = session\n ? {\n ...session,\n token: \"\",\n userInput: {},\n contactInfo: undefined,\n }\n : null;\n\n setSessionStore({\n session: sanitizedSessionForGlobalStore,\n loading,\n error,\n isExpired,\n userInput: {},\n contactInfo: { email: \"\", phoneNumber: \"\" },\n });\n }, [session, loading, error, isExpired]);\n\n // Handle initial step setting when session loads.\n // Quand la session est déjà terminée (ex: rechargement), on positionne le step\n // sur le nœud `end`. On indexe sur getOrderedJourneySteps (start filtré + tri par\n // `order`) — MÊME référentiel que TemplateNodeRenderer — sinon l'index calculé\n // pointe sur un autre nœud que celui rendu (ex: external-verification, qui se\n // ré-exécute et part en boucle).\n // Idempotent : on ne re-navigue que si on n'est pas déjà sur le bon step, et on\n // resserre les dépendances pour ne pas se re-déclencher à chaque mutation de session\n // (userInput, retryCounts, polling…) — ce qui relançait la boucle.\n useEffect(() => {\n if (session?.status !== \"ended\" || !session.template) {\n return;\n }\n const orderedSteps = getOrderedJourneySteps(session.template);\n const endNodeIndex = orderedSteps.findIndex(\n (node) => node.type === \"end\",\n );\n const targetStep =\n endNodeIndex !== -1 ? 1 + endNodeIndex : 1 + orderedSteps.length;\n\n if (stepObject.step !== targetStep) {\n // skipHistory: repositionnement technique, pas une étape utilisateur\n // (évite aussi que goBack() ne ramène sur un nœud auto-exécutant).\n stepObject.setStep(targetStep, true);\n }\n // Dépendances volontairement resserrées à status + template.id (cf. commentaire\n // ci-dessus) : ne pas inclure `session`/`stepObject` qui relanceraient la boucle.\n }, [session?.status, session?.template?.id]);\n\n if (!sessionId) {\n return <NoSessionIdState />;\n }\n\n // PoweredBy de DatakeenSession : uniquement pour les états spéciaux (loading/error/expired)\n // Les pages normales utilisent MobilePageLayout qui gère son propre PoweredBy\n const showMobilePoweredBy = isMobile && (loading || !!error || isExpired);\n const showDesktopPoweredBy = !isMobile && !loading && !error && !isExpired;\n const poweredByRef = useRef<HTMLDivElement | null>(null);\n const [poweredByHeight, setPoweredByHeight] = useState(0);\n\n useLayoutEffect(() => {\n if (typeof window === \"undefined\" || !showMobilePoweredBy) {\n setPoweredByHeight(0);\n return;\n }\n\n const updateHeight = () => {\n if (poweredByRef.current) {\n setPoweredByHeight(poweredByRef.current.offsetHeight);\n }\n };\n\n updateHeight();\n window.addEventListener(\"resize\", updateHeight);\n\n return () => {\n window.removeEventListener(\"resize\", updateHeight);\n };\n }, [showMobilePoweredBy]);\n\n const mobileRootStyle: CSSProperties = {\n [\"--dk-mobile-footer-offset\" as any]: `${poweredByHeight}px`,\n };\n\n const renderSessionContent = () => {\n if (loading) {\n return <LoadingState />;\n }\n\n if (error) {\n return <ErrorState error={error} />;\n }\n\n if (isExpired) {\n return <SessionExpired onRetry={handleRetrySession} />;\n }\n\n return (\n <SessionContent\n step={step}\n loading={loading}\n session={session}\n sessionId={sessionId}\n stepObject={stepObject}\n stepHistory={history}\n userInput={userInput}\n setUserInput={setUserInput}\n contactInfo={contactInfo}\n setContactInfo={setContactInfo}\n />\n );\n };\n\n const mobileScrollPadding = showMobilePoweredBy\n ? `calc(${poweredByHeight}px + env(safe-area-inset-bottom, 0px))`\n : \"env(safe-area-inset-bottom, 0px)\";\n\n const currentTemplateNode = useMemo(() => {\n if (!session?.template || step < 1) {\n return null;\n }\n\n const templateIndex = Math.floor(step - 1);\n const orderedSteps = getOrderedJourneySteps(session.template);\n return orderedSteps[templateIndex] || null;\n }, [session?.template, step]);\n\n const shouldUseWideDesktopLayout =\n currentTemplateNode?.type === \"information-input\" &&\n currentTemplateNode.informationType === \"custom\" &&\n (currentTemplateNode.customFields || []).some(\n (field) => field.valueType === \"list\",\n );\n\n const [isRecordingSelfie, setIsRecordingSelfie] = useState(false);\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const update = () =>\n setIsRecordingSelfie(\n document.body.classList.contains(\"recording-selfie\"),\n );\n update();\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n return () => observer.disconnect();\n }, []);\n\n const isCaptureStep =\n currentTemplateNode?.type === \"biometric-capture\" ||\n currentTemplateNode?.type === \"selfie-capture\" ||\n currentTemplateNode?.type === \"document-collection\" || // Could be upload, but safer to allow full height\n currentTemplateNode?.type === \"controle-jdi\";\n\n const btnBg = session?.template?.buttonBgColor ?? \"#11E5C5\";\n const btnText = session?.template?.buttonTextColor ?? \"#3C3C40\";\n\n return (\n <ConfigProvider apiBaseUrl={apiBaseUrl}>\n <DocumentProvider>\n <div\n className=\"sdk-session notranslate flex-1 flex flex-col\"\n lang={currentLanguage}\n translate=\"no\"\n style={\n {\n [\"--dk-btn-bg\" as string]: btnBg,\n [\"--dk-btn-text\" as string]: btnText,\n ...(isMobile\n ? {\n [\"--dk-mobile-scroll-padding\" as string]:\n mobileScrollPadding,\n }\n : undefined),\n } as CSSProperties\n }\n >\n {isMobile ? (\n <div\n className=\"flex h-full w-full flex-col bg-white\"\n style={mobileRootStyle}\n >\n <div\n className={`flex flex-1 min-h-0 flex-col ${isCaptureStep ? \"\" : \"overflow-y-auto\"}`}\n style={{\n paddingBottom: isCaptureStep\n ? \"0\"\n : \"var(--dk-mobile-scroll-padding, env(safe-area-inset-bottom, 0px))\",\n }}\n >\n <div className=\"flex flex-1 flex-col min-h-0\">\n {renderSessionContent()}\n </div>\n </div>\n {showMobilePoweredBy && (\n <div\n className=\"bg-white px-4 pt-3 pb-4 sm:px-6 sm:pt-6 sm:pb-6\"\n style={{\n paddingBottom:\n \"calc(env(safe-area-inset-bottom, 0px) + 0.5rem)\",\n }}\n ref={poweredByRef}\n >\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-center w-full min-h-screen bg-gray-100 py-12\">\n <div className=\"flex flex-col items-center justify-center\">\n <Paper\n className={`dk-session-paper flex flex-col h-[800px] px-8 py-10 bg-white rounded-2xl shadow-xl z-10 ${isRecordingSelfie\n ? \"\"\n : shouldUseWideDesktopLayout\n ? \"w-[98vw] max-w-[1500px]\"\n : \"w-[600px]\"\n }`}\n style={\n isRecordingSelfie\n ? { width: \"min(66vw, 942px)\" }\n : undefined\n }\n >\n <div className=\"flex-1 w-full h-full overflow-y-auto\">\n {renderSessionContent()}\n </div>\n </Paper>\n {showDesktopPoweredBy && (\n <div className=\"pt-6 text-center\">\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </DocumentProvider>\n </ConfigProvider>\n );\n};\n\nexport default DatakeenSession;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
1
+ {"version":3,"file":"DatakeenSession.js","sources":["../../../../src/components/DatakeenSession.tsx"],"sourcesContent":["import { setSessionCredential } from '../services/sessionCredentials';\nimport { useEffect, useLayoutEffect, useMemo, useRef, useState } from \"react\";\nimport type { CSSProperties } from \"react\";\nimport type { DatakeenSessionProps } from \"../types/session\";\nimport Paper from \"./ui/Paper\";\nimport useIsMobile from \"../hooks/useIsMobile\";\nimport PoweredBy from \"./ui/PoweredBy\";\nimport SessionExpired from \"./session/SessionExpired\";\nimport { useRouteCSS } from \"../hooks/useRouteCSS\";\nimport { DocumentProvider } from \"../context/DocumentContext\";\nimport { ConfigProvider } from \"../context/ConfigContext\";\nimport { setSessionStore } from \"../context/SessionContext\";\n\n// Hooks\nimport { useSessionData } from \"../hooks/useSessionData\";\nimport { useStepNavigation } from \"../hooks/useStepNavigation\";\nimport { useStepCSS } from \"../hooks/useStepCSS\";\nimport { useTemplateLoader } from \"../hooks/useTemplateLoader\";\nimport { useClientInfo } from \"../hooks/useClientInfo\";\nimport { useI18n } from \"../hooks/useI18n\";\nimport { getOrderedJourneySteps } from \"../services/sessionService\";\n\n// Components\nimport NoSessionIdState from \"./states/NoSessionIdState\";\nimport LoadingState from \"./states/LoadingState\";\nimport ErrorState from \"./states/ErrorState\";\nimport SessionContent from \"./session/SessionContent\";\n\n/**\n * DatakeenSession Component\n *\n * The main component of the Datakeen SDK that manages the multi-step verification flow.\n * This component handles the different steps of the session process, including:\n * - Initial welcome screen\n * - User information collection\n * - Country selection for JDI verification\n * - Mobile redirect when selfie is required\n *\n * The component maintains internal state for the current step and user input data,\n * progressing through the verification journey as the user completes each step.\n *\n * @param {DatakeenSessionProps} props - Component props\n * @param {string} props.sessionId - Unique identifier for the verification session\n * @param {SessionConfig} props.sessionConfig - Configuration for the session (e.g., selfie: true)\n * @param {string} props.apiBaseUrl - Optional API base URL for dynamic environment configuration\n * @returns {JSX.Element} A Paper-wrapped container with the appropriate step component based on current state\n */\nconst DatakeenSession = ({\n sessionId,\n sessionToken,\n sessionConfig,\n apiBaseUrl,\n}: DatakeenSessionProps) => {\n useLayoutEffect(() => {\n const fragmentToken = typeof window !== 'undefined' ? new URLSearchParams(window.location.hash.slice(1)).get('sessionToken') : null;\n setSessionCredential(sessionId, sessionToken || sessionConfig?.sessionToken || fragmentToken || undefined);\n return () => setSessionCredential(sessionId);\n }, [sessionId, sessionToken, sessionConfig?.sessionToken]);\n const isMobile = useIsMobile();\n const { info: clientInfo, isLoaded: clientInfoLoaded } = useClientInfo();\n const { currentLanguage } = useI18n();\n\n // Load base CSS and UI components CSS that are always needed\n useRouteCSS(\"ui-components\");\n\n // Session data management\n const {\n session,\n setSession,\n loading,\n setLoading,\n error,\n isExpired,\n userInput,\n setUserInput,\n contactInfo,\n setContactInfo,\n loadSession,\n handleRetrySession,\n } = useSessionData(sessionId, clientInfo, clientInfoLoaded);\n\n // Step navigation management\n const { step, stepObject, history } = useStepNavigation(\n sessionId,\n session?.status,\n session?.currentStep,\n session?.template,\n );\n\n // Load route-specific CSS based on current step\n useStepCSS(step, session);\n\n // Template loading logic\n useTemplateLoader(step, sessionId, session, loading, setSession, setLoading);\n\n // Load session data on component mount\n useEffect(() => {\n loadSession();\n }, [sessionId, sessionConfig]);\n\n // Update global session store whenever session data changes\n useEffect(() => {\n const sanitizedSessionForGlobalStore = session\n ? {\n ...session,\n token: \"\",\n userInput: {},\n contactInfo: undefined,\n }\n : null;\n\n setSessionStore({\n session: sanitizedSessionForGlobalStore,\n loading,\n error,\n isExpired,\n userInput: {},\n contactInfo: { email: \"\", phoneNumber: \"\" },\n });\n }, [session, loading, error, isExpired]);\n\n // Handle initial step setting when session loads.\n // Quand la session est déjà terminée (ex: rechargement), on positionne le step\n // sur le nœud `end`. On indexe sur getOrderedJourneySteps (start filtré + tri par\n // `order`) — MÊME référentiel que TemplateNodeRenderer — sinon l'index calculé\n // pointe sur un autre nœud que celui rendu (ex: external-verification, qui se\n // ré-exécute et part en boucle).\n // Idempotent : on ne re-navigue que si on n'est pas déjà sur le bon step, et on\n // resserre les dépendances pour ne pas se re-déclencher à chaque mutation de session\n // (userInput, retryCounts, polling…) — ce qui relançait la boucle.\n useEffect(() => {\n if (session?.status !== \"ended\" || !session.template) {\n return;\n }\n const orderedSteps = getOrderedJourneySteps(session.template);\n const endNodeIndex = orderedSteps.findIndex(\n (node) => node.type === \"end\",\n );\n const targetStep =\n endNodeIndex !== -1 ? 1 + endNodeIndex : 1 + orderedSteps.length;\n\n if (stepObject.step !== targetStep) {\n // skipHistory: repositionnement technique, pas une étape utilisateur\n // (évite aussi que goBack() ne ramène sur un nœud auto-exécutant).\n stepObject.setStep(targetStep, true);\n }\n // Dépendances volontairement resserrées à status + template.id (cf. commentaire\n // ci-dessus) : ne pas inclure `session`/`stepObject` qui relanceraient la boucle.\n }, [session?.status, session?.template?.id]);\n\n if (!sessionId) {\n return <NoSessionIdState />;\n }\n\n // PoweredBy de DatakeenSession : uniquement pour les états spéciaux (loading/error/expired)\n // Les pages normales utilisent MobilePageLayout qui gère son propre PoweredBy\n const showMobilePoweredBy = isMobile && (loading || !!error || isExpired);\n const showDesktopPoweredBy = !isMobile && !loading && !error && !isExpired;\n const poweredByRef = useRef<HTMLDivElement | null>(null);\n const [poweredByHeight, setPoweredByHeight] = useState(0);\n\n useLayoutEffect(() => {\n if (typeof window === \"undefined\" || !showMobilePoweredBy) {\n setPoweredByHeight(0);\n return;\n }\n\n const updateHeight = () => {\n if (poweredByRef.current) {\n setPoweredByHeight(poweredByRef.current.offsetHeight);\n }\n };\n\n updateHeight();\n window.addEventListener(\"resize\", updateHeight);\n\n return () => {\n window.removeEventListener(\"resize\", updateHeight);\n };\n }, [showMobilePoweredBy]);\n\n const mobileRootStyle: CSSProperties = {\n [\"--dk-mobile-footer-offset\" as any]: `${poweredByHeight}px`,\n };\n\n const renderSessionContent = () => {\n if (loading) {\n return <LoadingState />;\n }\n\n if (error) {\n return <ErrorState error={error} />;\n }\n\n if (isExpired) {\n return <SessionExpired onRetry={handleRetrySession} />;\n }\n\n return (\n <SessionContent\n step={step}\n loading={loading}\n session={session}\n sessionId={sessionId}\n stepObject={stepObject}\n stepHistory={history}\n userInput={userInput}\n setUserInput={setUserInput}\n contactInfo={contactInfo}\n setContactInfo={setContactInfo}\n />\n );\n };\n\n const mobileScrollPadding = showMobilePoweredBy\n ? `calc(${poweredByHeight}px + env(safe-area-inset-bottom, 0px))`\n : \"env(safe-area-inset-bottom, 0px)\";\n\n const currentTemplateNode = useMemo(() => {\n if (!session?.template || step < 1) {\n return null;\n }\n\n const templateIndex = Math.floor(step - 1);\n const orderedSteps = getOrderedJourneySteps(session.template);\n return orderedSteps[templateIndex] || null;\n }, [session?.template, step]);\n\n const shouldUseWideDesktopLayout =\n currentTemplateNode?.type === \"information-input\" &&\n currentTemplateNode.informationType === \"custom\" &&\n (currentTemplateNode.customFields || []).some(\n (field) => field.valueType === \"list\",\n );\n\n const [isRecordingSelfie, setIsRecordingSelfie] = useState(false);\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n const update = () =>\n setIsRecordingSelfie(\n document.body.classList.contains(\"recording-selfie\"),\n );\n update();\n const observer = new MutationObserver(update);\n observer.observe(document.body, {\n attributes: true,\n attributeFilter: [\"class\"],\n });\n return () => observer.disconnect();\n }, []);\n\n const isCaptureStep =\n currentTemplateNode?.type === \"biometric-capture\" ||\n currentTemplateNode?.type === \"selfie-capture\" ||\n currentTemplateNode?.type === \"document-collection\" || // Could be upload, but safer to allow full height\n currentTemplateNode?.type === \"controle-jdi\";\n\n const btnBg = session?.template?.buttonBgColor ?? \"#11E5C5\";\n const btnText = session?.template?.buttonTextColor ?? \"#3C3C40\";\n\n return (\n <ConfigProvider apiBaseUrl={apiBaseUrl}>\n <DocumentProvider>\n <div\n className=\"sdk-session notranslate flex-1 flex flex-col\"\n lang={currentLanguage}\n translate=\"no\"\n style={\n {\n [\"--dk-btn-bg\" as string]: btnBg,\n [\"--dk-btn-text\" as string]: btnText,\n ...(isMobile\n ? {\n [\"--dk-mobile-scroll-padding\" as string]:\n mobileScrollPadding,\n }\n : undefined),\n } as CSSProperties\n }\n >\n {isMobile ? (\n <div\n className=\"flex h-full w-full flex-col bg-white\"\n style={mobileRootStyle}\n >\n <div\n className={`flex flex-1 min-h-0 flex-col ${isCaptureStep ? \"\" : \"overflow-y-auto\"}`}\n style={{\n paddingBottom: isCaptureStep\n ? \"0\"\n : \"var(--dk-mobile-scroll-padding, env(safe-area-inset-bottom, 0px))\",\n }}\n >\n <div className=\"flex flex-1 flex-col min-h-0\">\n {renderSessionContent()}\n </div>\n </div>\n {showMobilePoweredBy && (\n <div\n className=\"bg-white px-4 pt-3 pb-4 sm:px-6 sm:pt-6 sm:pb-6\"\n style={{\n paddingBottom:\n \"calc(env(safe-area-inset-bottom, 0px) + 0.5rem)\",\n }}\n ref={poweredByRef}\n >\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex items-center justify-center w-full min-h-screen bg-gray-100 py-12\">\n <div className=\"flex flex-col items-center justify-center\">\n <Paper\n className={`dk-session-paper flex flex-col h-[800px] px-8 py-10 bg-white rounded-2xl shadow-xl z-10 ${isRecordingSelfie\n ? \"\"\n : shouldUseWideDesktopLayout\n ? \"w-[98vw] max-w-[1500px]\"\n : \"w-[600px]\"\n }`}\n style={\n isRecordingSelfie\n ? { width: \"min(66vw, 942px)\" }\n : undefined\n }\n >\n <div className=\"flex-1 w-full h-full overflow-y-auto\">\n {renderSessionContent()}\n </div>\n </Paper>\n {showDesktopPoweredBy && (\n <div className=\"pt-6 text-center\">\n <PoweredBy\n logo={session?.template?.logo}\n text={session?.template?.logo ? \"par\" : undefined}\n />\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n </DocumentProvider>\n </ConfigProvider>\n );\n};\n\nexport default DatakeenSession;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { __assign, __awaiter, __generator } from '../../node_modules/tslib/tslib.es6.js';
1
+ import { __assign, __awaiter, __generator, __spreadArray } from '../../node_modules/tslib/tslib.es6.js';
2
2
  import { jsxs, jsx } from 'react/jsx-runtime';
3
3
  import { useState, useEffect } from 'react';
4
4
  import DocumentCollectionIntroduction from './DocumentCollectionIntroduction.js';
@@ -86,7 +86,10 @@ var DocumentCollection = function (_a) {
86
86
  var handleDocumentTypeSelect = function (docType, files) {
87
87
  setSelectedDocumentType(docType);
88
88
  if (files) {
89
- handleDocumentUpload(files);
89
+ // `docType` explicitement, pas l'état : `setSelectedDocumentType` ne prend
90
+ // effet qu'au rendu suivant, et la lecture depuis l'état renvoyait donc le
91
+ // type précédent — une pièce en collecte seule partait alors en analyse.
92
+ handleDocumentUpload(files, docType);
90
93
  return;
91
94
  }
92
95
  var isPictureAllowed = allowedAddingMethods.includes("picture");
@@ -145,16 +148,19 @@ var DocumentCollection = function (_a) {
145
148
  front: capturedImages.recto,
146
149
  back: capturedImages.verso || null,
147
150
  };
148
- setFileUploaded(files);
149
- setCurrentStep(4);
151
+ // Même aiguillage que pour un téléversement : ce chemin passait
152
+ // directement à l'analyse, donc une pièce en collecte seule capturée en
153
+ // photo déclenchait une analyse et affichait une erreur au candidat.
154
+ handleDocumentUpload(files);
150
155
  }
151
156
  };
152
- var handleDocumentUpload = function (files) {
157
+ var handleDocumentUpload = function (files, docTypeId) {
153
158
  setFileUploaded(files);
159
+ var effectiveDocType = docTypeId !== null && docTypeId !== void 0 ? docTypeId : selectedDocumentType;
154
160
  // Check if the selected document type is collectOnly — skip processing step
155
- var selectedDoc = allowedDocumentTypes.find(function (d) { return d.id === selectedDocumentType; });
161
+ var selectedDoc = allowedDocumentTypes.find(function (d) { return d.id === effectiveDocType; });
156
162
  if (selectedDoc === null || selectedDoc === void 0 ? void 0 : selectedDoc.collectOnly) {
157
- handleCollectOnlyUpload(files);
163
+ handleCollectOnlyUpload(files, effectiveDocType);
158
164
  return;
159
165
  }
160
166
  // Check if retry limit is reached before processing
@@ -197,30 +203,37 @@ var DocumentCollection = function (_a) {
197
203
  setCurrentStep(6);
198
204
  }
199
205
  };
200
- var handleCollectOnlyUpload = function (files) { return __awaiter(void 0, void 0, void 0, function () {
201
- var error_2;
202
- return __generator(this, function (_a) {
203
- switch (_a.label) {
204
- case 0:
205
- _a.trys.push([0, 2, , 3]);
206
- return [4 /*yield*/, analyzeFiles(sessionId, node.id, files, selectedDocumentType, {
207
- documentTypeKey: selectedDocumentType,
208
- collectOnly: true,
209
- enablePolling: false,
210
- })];
211
- case 1:
212
- _a.sent();
213
- handleProcessingComplete(true, retryCount, null);
214
- return [3 /*break*/, 3];
215
- case 2:
216
- error_2 = _a.sent();
217
- console.error("[DocumentCollection] collectOnly upload failed:", error_2);
218
- handleProcessingComplete(false, retryCount, null);
219
- return [3 /*break*/, 3];
220
- case 3: return [2 /*return*/];
221
- }
206
+ var handleCollectOnlyUpload = function (files_1) {
207
+ var args_1 = [];
208
+ for (var _i = 1; _i < arguments.length; _i++) {
209
+ args_1[_i - 1] = arguments[_i];
210
+ }
211
+ return __awaiter(void 0, __spreadArray([files_1], args_1, true), void 0, function (files, docTypeId) {
212
+ var error_2;
213
+ if (docTypeId === void 0) { docTypeId = selectedDocumentType; }
214
+ return __generator(this, function (_a) {
215
+ switch (_a.label) {
216
+ case 0:
217
+ _a.trys.push([0, 2, , 3]);
218
+ return [4 /*yield*/, analyzeFiles(sessionId, node.id, files, docTypeId, {
219
+ documentTypeKey: docTypeId,
220
+ collectOnly: true,
221
+ enablePolling: false,
222
+ })];
223
+ case 1:
224
+ _a.sent();
225
+ handleProcessingComplete(true, retryCount, null);
226
+ return [3 /*break*/, 3];
227
+ case 2:
228
+ error_2 = _a.sent();
229
+ console.error("[DocumentCollection] collectOnly upload failed:", error_2);
230
+ handleProcessingComplete(false, retryCount, null);
231
+ return [3 /*break*/, 3];
232
+ case 3: return [2 /*return*/];
233
+ }
234
+ });
222
235
  });
223
- }); };
236
+ };
224
237
  var handleRetryFromError = function () {
225
238
  setBlockContinue(false);
226
239
  setCurrentStep(1);