datakeen-session-react 1.1.183 → 1.1.185

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 (41) hide show
  1. package/dist/cjs/components/DatakeenSession.js +3 -1
  2. package/dist/cjs/components/DatakeenSession.js.map +1 -1
  3. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoRecorder.js +6 -1
  4. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoRecorder.js.map +1 -1
  5. package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js +15 -3
  6. package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
  7. package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js +10 -2
  8. package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
  9. package/dist/cjs/components/session/Selfie.js +8 -2
  10. package/dist/cjs/components/session/Selfie.js.map +1 -1
  11. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js +1 -1
  12. package/dist/cjs/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  13. package/dist/cjs/i18n/en.json.js +13 -1
  14. package/dist/cjs/i18n/en.json.js.map +1 -1
  15. package/dist/cjs/i18n/fr.json.js +13 -1
  16. package/dist/cjs/i18n/fr.json.js.map +1 -1
  17. package/dist/cjs/services/analysis.js +3 -1
  18. package/dist/cjs/services/analysis.js.map +1 -1
  19. package/dist/cjs/services/sessionService.js +11 -0
  20. package/dist/cjs/services/sessionService.js.map +1 -1
  21. package/dist/esm/components/DatakeenSession.js +3 -1
  22. package/dist/esm/components/DatakeenSession.js.map +1 -1
  23. package/dist/esm/components/document-video/document-video-flow/DocumentVideoRecorder.js +6 -1
  24. package/dist/esm/components/document-video/document-video-flow/DocumentVideoRecorder.js.map +1 -1
  25. package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js +15 -3
  26. package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
  27. package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js +10 -2
  28. package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
  29. package/dist/esm/components/session/Selfie.js +8 -2
  30. package/dist/esm/components/session/Selfie.js.map +1 -1
  31. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js +1 -1
  32. package/dist/esm/components/signature-electronic/SignedDocumentPreview.js.map +1 -1
  33. package/dist/esm/i18n/en.json.js +13 -2
  34. package/dist/esm/i18n/en.json.js.map +1 -1
  35. package/dist/esm/i18n/fr.json.js +13 -2
  36. package/dist/esm/i18n/fr.json.js.map +1 -1
  37. package/dist/esm/services/analysis.js +3 -1
  38. package/dist/esm/services/analysis.js.map +1 -1
  39. package/dist/esm/services/sessionService.js +11 -1
  40. package/dist/esm/services/sessionService.js.map +1 -1
  41. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"sessionService.js","sources":["../../../../src/services/sessionService.ts"],"sourcesContent":["/**\n * Session Service\n *\n * Service for interacting with the Datakeen Session API.\n * Handles fetching session data by ID.\n */\n\nimport type {\n ClientInfo,\n SessionData,\n SessionTemplate,\n SessionTemplateNode,\n} from \"../types/session\";\nimport { apiService } from \"./api\";\nimport { logStatusModified } from \"./auditTrailService\";\nimport { clearSessionMemory } from \"./sessionMemoryStore\";\n\n/**\n * Fetches session data by ID from the Datakeen backend\n *\n * @param sessionId - The unique identifier of the session\n * @returns The session data\n */\nexport const fetchSessionById = async (\n sessionId: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.get(`/session/sdk/${sessionId}`);\n return response.data;\n } catch (error) {\n console.error(\"Error fetching session data:\", error);\n throw error;\n }\n};\n\n/** Sends client information (IP, device, browser, OS) to the backend for a specific session\n *\n * @param sessionId - The unique identifier of the session\n * @param clientInfo - The client information to send\n */\nexport const sendClientInfo = async (\n sessionId: string,\n clientInfo: ClientInfo,\n): Promise<void> => {\n try {\n await apiService.post(`/session/sdk/${sessionId}/client-info`, clientInfo);\n } catch (error) {\n console.error(\"Error sending client info:\", error);\n throw error;\n }\n};\n\n/**\n * Determines if the session template has a specific type of node\n *\n * @param template - The session template\n * @param nodeType - The type of node to check for\n * @returns true if the template has a node of the specified type, false otherwise\n */\nexport const hasNodeType = (\n template: SessionTemplate,\n nodeType: string,\n): boolean => {\n return template.nodes.some((node) => node.type === nodeType);\n};\n\n/**\n * Determines if the session template has a node with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to check for\n * @returns true if the template has a node with the specified requiredDocumentType, false otherwise\n */\nexport const hasDocumentTypeNode = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): boolean => {\n return template.nodes.some(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Gets all nodes of a specific type\n *\n * @param template - The session template\n * @param nodeType - The type of node to get\n * @returns Array of nodes matching the type\n */\nexport const getNodesByType = (\n template: SessionTemplate,\n nodeType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter((node) => node.type === nodeType);\n};\n\n/**\n * Gets all nodes with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to get\n * @returns Array of nodes matching the requiredDocumentType\n */\nexport const getNodesByDocumentType = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Get document options for a specific document type\n *\n * @param template - The session template\n * @param requiredDocumentType - The document type to get options for\n * @returns Array of document options (empty if none found)\n */\nexport const getDocumentOptions = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): string[] => {\n const node = template.nodes.find(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n return node?.selectedOptions || [];\n};\n\n/**\n * Determines if the session template has a selfie step\n *\n * @param template - The session template\n * @returns true if the template has a selfie step, false otherwise\n */\nexport const hasSelfieCaptureStep = (template: SessionTemplate): boolean => {\n return hasNodeType(template, \"selfie-capture\");\n};\n\n/**\n * Determines if the session template has an ID document step\n *\n * @param template - The session template\n * @returns true if the template has an ID document step, false otherwise\n */\nexport const hasDocumentStep = (template: SessionTemplate): boolean => {\n // Check if there's any document-selection node with requiredDocumentType \"id-card\"\n // or if none specified, just check for document-selection nodes\n const hasIDCard = hasDocumentTypeNode(template, \"id-card\");\n return hasIDCard || hasNodeType(template, \"document-selection\");\n};\n\n/**\n * Determines if the session template has a JDD (proof of address) step\n *\n * @param template - The session template\n * @returns true if the template has a JDD step, false otherwise\n */\nexport const hasJDDStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"jdd\");\n};\n\n/**\n * Determines if the session template has a proof of funds step\n *\n * @param template - The session template\n * @returns true if the template has a proof of funds step, false otherwise\n */\nexport const hasProofOfFundsStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"income-proof\");\n};\n\n/**\n * Determines if the session template has a document collection step\n *\n * @param template - The session template\n * @returns true if the template has a document collection step, false otherwise\n */\nexport const hasDocumentCollectionStep = (\n template: SessionTemplate,\n): boolean => {\n return hasNodeType(template, \"document-collection\");\n};\n\n/**\n * Gets all node types in the template\n *\n * @param template - The session template\n * @returns Array of node types in the template\n */\nexport const getNodeTypes = (template: SessionTemplate): string[] => {\n return Array.from(new Set(template.nodes.map((node) => node.type)));\n};\n\n/**\n * Gets all document types required in the template\n *\n * @param template - The session template\n * @returns Array of document types required in the template\n */\nexport const getRequiredDocumentTypes = (\n template: SessionTemplate,\n): string[] => {\n return Array.from(\n new Set(\n template.nodes\n .filter((node) => node.requiredDocumentType)\n .map((node) => node.requiredDocumentType!),\n ),\n );\n};\n\n/**\n * Converts template document type to internal document type\n * This helps standardize document types between the template and the application\n *\n * @param templateDocType - The document type as defined in the template\n * @returns The internal document type used by the application\n */\nexport const convertTemplateDocTypeToInternal = (\n templateDocType: string,\n): string => {\n if (!templateDocType) return \"\";\n\n // Mapping between template document types and internal document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n \"income-proof\": \"income-proof\", // Using consistent naming\n };\n\n return typeMap[templateDocType] || templateDocType;\n};\n\n/**\n * Converts internal document type to template document type\n *\n * @param internalDocType - The document type used internally by the application\n * @returns The document type as expected in the template\n */\nexport const convertInternalDocTypeToTemplate = (\n internalDocType: string,\n): string => {\n if (!internalDocType) return \"\";\n\n // Mapping between internal document types and template document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n funds: \"income-proof\", // Map funds to income-proof for backwards compatibility\n \"income-proof\": \"income-proof\",\n };\n\n return typeMap[internalDocType] || internalDocType;\n};\n\n/**\n * Updates session data with user input information\n *\n * @param sessionId - The unique identifier of the session\n * @param userInput - The user input data (firstName, lastName, birthDate)\n * @returns The updated session data\n */\nexport const updateSessionUserInput = async (\n sessionId: string,\n userInput: {\n firstName?: string;\n lastName?: string;\n birthDate?: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n userInput,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session data:\", error);\n throw error;\n }\n};\n\n/**\n * Records the NFC fallback reason when the user declares they cannot use the\n * contactless scan, and marks the NFC scan as skipped server-side.\n *\n * @param sessionId - The unique identifier of the session\n * @param payload - The selected reason (technical key), its human-readable label,\n * and an optional free-text comment.\n */\nexport const skipNfcWithReason = async (\n sessionId: string,\n payload: { reason: string; label: string; comment?: string },\n): Promise<void> => {\n await apiService.post(`/session/sdk/${sessionId}/nfc-skip`, payload);\n};\n\n/**\n * Resets a terminal NFC failure before the user starts again with another\n * document. The backend keeps completed scans immutable and treats this call\n * as a no-op when the status is not terminal.\n */\nexport const resetNfcScan = async (sessionId: string): Promise<void> => {\n await apiService.post(`/session/sdk/${sessionId}/nfc-reset`);\n};\n\n/**\n * Updates session data with contact information\n *\n * @param sessionId - The unique identifier of the session\n * @param contactInfo - The contact information data (email, phoneNumber)\n * @returns The updated session data\n */\nexport const updateSessionContactInfo = async (\n sessionId: string,\n contactInfo: {\n email: string;\n phoneNumber: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n contactInfo,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating contact information:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session status\n *\n * @param sessionId - The unique identifier of the session\n * @param status - The new status for the session\n * @param reachedEndNodeId - Id of the end node actually reached (when status is \"ended\"),\n * so the backend can force the correct final status with multiple end nodes.\n * @returns The updated session data\n */\nexport const updateSessionStatus = async (\n sessionId: string,\n status: string,\n reachedEndNodeId?: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n status,\n ...(reachedEndNodeId ? { reachedEndNodeId } : {}),\n });\n\n // Log status modification in audit trail\n if (response.data && response.data.analysisId) {\n try {\n await logStatusModified(\n sessionId,\n status,\n response.data.clientInfoId || undefined,\n );\n } catch (err) {\n console.error(\"Failed to log status modification in audit trail:\", err);\n // Non-blocking error - continue session\n }\n }\n\n return response.data;\n } catch (error) {\n console.error(\"Error updating session status:\", error);\n throw error;\n }\n};\n\n/**\n * Updates the current step in the session\n *\n * @param sessionId - The unique identifier of the session\n * @param currentStep - The current step index in the workflow\n * @returns The updated session data\n */\nexport const updateSessionCurrentStep = async (\n sessionId: string,\n currentStep: number,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n currentStep,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session current step:\", error);\n throw error;\n }\n};\n\n/**\n * Gets the journey steps from the template in order\n *\n * @param template - The session template\n * @returns Array of ordered steps\n */\nexport const getOrderedJourneySteps = (\n template: SessionTemplate,\n): SessionTemplateNode[] => {\n // Filter out only start nodes, keep end nodes for proper journey completion, then sort by order.\n // Tiebreaker on id keeps the ordering deterministic when several nodes share the same `order`\n // (e.g. parallel branches of a condition), independently of their position in template.nodes.\n return template.nodes\n .filter((node) => node.type !== \"start\")\n .sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));\n};\n\nconst normalizeHandle = (value?: string): string => {\n return (value || \"\").trim().toLowerCase();\n};\n\n/**\n * Finds the outgoing edge to follow from a node.\n *\n * Resolution order:\n * 1. Exact handle match via sourceHandle/conditionValue.\n * 2. For condition:false loops, fallback to targetHandle=right.\n * 3. First outgoing edge as final fallback.\n */\nexport const findOutgoingEdge = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): SessionTemplate[\"edges\"][number] | null => {\n const outgoingEdges = (template.edges || []).filter(\n (edge) => edge.source === currentNodeId,\n );\n\n if (outgoingEdges.length === 0) {\n return null;\n }\n\n if (!handle) {\n return outgoingEdges[0];\n }\n\n const normalizedHandle = normalizeHandle(handle);\n const edgeByHandle = outgoingEdges.find((edge) => {\n return (\n normalizeHandle(edge.sourceHandle) === normalizedHandle ||\n normalizeHandle(edge.conditionValue) === normalizedHandle\n );\n });\n\n if (edgeByHandle) {\n return edgeByHandle;\n }\n\n const currentNode = template.nodes.find((node) => node.id === currentNodeId);\n if (currentNode?.type === \"condition\" && normalizedHandle === \"false\") {\n const rightHandleLoopEdge = outgoingEdges.find(\n (edge) => normalizeHandle(edge.targetHandle) === \"right\",\n );\n if (rightHandleLoopEdge) {\n return rightHandleLoopEdge;\n }\n }\n\n return outgoingEdges[0];\n};\n\n/**\n * Gets the next step index by following the graph edge from the current node\n *\n * @param currentNodeId - The ID of the current node\n * @param template - The session template\n * @returns The next step index (1-based) or null if no edge found\n */\nexport const getNextStepIndex = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): number | null => {\n const orderedNodes = getOrderedJourneySteps(template);\n const edge = findOutgoingEdge(currentNodeId, template, handle);\n\n if (!edge) {\n console.debug(\n `[sessionService] No outgoing edge found for node ${currentNodeId}${handle ? ` with handle ${handle}` : \"\"}`,\n );\n return null;\n }\n\n const targetId = edge.target;\n const targetIndex = orderedNodes.findIndex((n) => n.id === targetId);\n\n if (targetIndex === -1) {\n console.debug(\n `[sessionService] Target node ${targetId} not found in ordered steps`,\n );\n return null;\n }\n\n // steps are 1-indexed in the SDK (0 is StartSession)\n return 1 + targetIndex;\n};\n\n/**\n * Reconstructs the navigation history by following the graph from step 0\n * up to (and including) targetStep. Returns [0, ...stepIndices].\n * If the graph path cannot reach targetStep, falls back to [0, targetStep].\n */\nexport const reconstructHistoryToStep = (\n targetStep: number,\n template: SessionTemplate,\n): number[] => {\n if (targetStep <= 0) return [0];\n\n const orderedNodes = getOrderedJourneySteps(template);\n const history: number[] = [0];\n let currentStep = 1; // first node is step 1\n\n // Follow the default (first) edge from each node in sequence\n for (let safetyLimit = 0; safetyLimit < orderedNodes.length + 1; safetyLimit++) {\n if (currentStep === targetStep) {\n history.push(currentStep);\n break;\n }\n if (currentStep > targetStep) break;\n\n const nodeIndex = currentStep - 1;\n const currentNode = orderedNodes[nodeIndex];\n if (!currentNode) break;\n\n history.push(currentStep);\n\n const nextStep = getNextStepIndex(currentNode.id, template);\n if (nextStep === null) break;\n currentStep = nextStep;\n }\n\n // Fallback: if we couldn't reach targetStep via graph, use simple seed\n if (history[history.length - 1] !== targetStep) {\n return [0, targetStep];\n }\n\n return history;\n};\n\n/**\n * Maps a template node type to a step component type\n *\n * @param node - The session template node\n * @returns The step component type\n */\nexport const getStepComponentType = (node: SessionTemplateNode): string => {\n // Map from template node types to component types\n const typeMap: Record<string, string> = {\n \"document-selection\": \"document\",\n \"document-collection\": \"document-collection\",\n \"selfie-capture\": \"selfie\",\n \"contact-info\": \"contact-info\",\n \"user-input\": \"user-input\",\n \"otp-verification\": \"otp\",\n };\n\n // First check the node type\n if (node.type in typeMap) {\n return typeMap[node.type];\n }\n\n // Then check the requiredDocumentType\n if (node.requiredDocumentType) {\n return node.requiredDocumentType;\n }\n\n // Default fallback\n return node.type;\n};\n\n/**\n * Checks if a session has expired\n *\n * @param session - The session data to check\n * @returns true if the session has expired, false otherwise\n */\nexport const isSessionExpired = (session: SessionData): boolean => {\n if (!session.expireTime) {\n return false;\n }\n\n const currentTime = Date.now();\n return currentTime > session.expireTime;\n};\n\n/**\n * Stores document options in localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @param options - The options to store\n */\nexport const storeDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n options: string[],\n): void => {\n if (!sessionId || !documentTypeId || !options || options.length === 0) {\n console.warn(\"Missing data for storeDocumentOptions:\", {\n sessionId,\n documentTypeId,\n options,\n });\n return;\n }\n\n // Create a consistent key format based on document type\n let storageKey = \"\";\n\n switch (documentTypeId) {\n case \"jdd\":\n storageKey = `jddOptions_${sessionId}`;\n break;\n case \"income-proof\":\n storageKey = `fundsOptions_${sessionId}`;\n break;\n case \"id-card\":\n storageKey = `idOptions_${sessionId}`;\n break;\n case \"document-collection\":\n storageKey = `documentCollectionOptions_${sessionId}`;\n break;\n default:\n storageKey = `${documentTypeId}Options_${sessionId}`;\n }\n\n localStorage.setItem(storageKey, JSON.stringify(options));\n};\n\n/**\n * Retrieves document options from localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @returns Array of options or default options if none found\n */\nexport const retrieveDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n): string[] => {\n if (!sessionId || !documentTypeId) {\n console.warn(\"Missing data for retrieveDocumentOptions:\", {\n sessionId,\n documentTypeId,\n });\n return [];\n }\n\n // Create consistent key formats to check\n const possibleKeys = [\n `${documentTypeId}Options_${sessionId}`,\n documentTypeId === \"jdd\" ? `jddOptions_${sessionId}` : \"\",\n documentTypeId === \"income-proof\" ? `fundsOptions_${sessionId}` : \"\",\n documentTypeId === \"id-card\" ? `idOptions_${sessionId}` : \"\",\n documentTypeId === \"document-collection\"\n ? `documentCollectionOptions_${sessionId}`\n : \"\",\n ].filter(Boolean);\n\n // Try each possible key\n for (const key of possibleKeys) {\n const savedOptions = localStorage.getItem(key);\n if (savedOptions) {\n try {\n const parsedOptions = JSON.parse(savedOptions);\n\n return parsedOptions;\n } catch (e) {\n console.error(\n `Error parsing options for ${documentTypeId} with key ${key}:`,\n e,\n );\n }\n }\n }\n\n // Return default options if none found\n console.warn(`No options found for ${documentTypeId}, using defaults`);\n if (documentTypeId === \"jdd\") {\n return [\n \"Facture d'électricité (< 3 mois)\",\n \"Facture de gaz (< 3 mois)\",\n \"Facture d'eau (< 3 mois)\",\n \"Quittance de loyer (< 3 mois)\",\n \"Facture téléphone/internet (< 3 mois)\",\n \"Attestation d'assurance habitation (< 3 mois)\",\n ];\n } else if (documentTypeId === \"income-proof\") {\n return [\n \"Bulletin de salaire\",\n \"Avis d'imposition\",\n \"Relevé de compte bancaire\",\n \"Attestation de revenus\",\n \"Contrat de travail\",\n ];\n } else if (documentTypeId === \"id-card\") {\n return [\"Carte nationale d'identité\", \"Passeport\", \"Permis de conduire\"];\n } else if (documentTypeId === \"document-collection\") {\n return [\"Document administratif\", \"Justificatif\", \"Attestation\"];\n }\n\n return [];\n};\n\nconst clearStorageBySessionId = (sessionId: string): void => {\n const scopedKeys = [\n `userInput_${sessionId}`,\n `contactInfo_${sessionId}`,\n `sessionData_${sessionId}`,\n ];\n\n scopedKeys.forEach((key) => {\n localStorage.removeItem(key);\n sessionStorage.removeItem(key);\n });\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n sessionStorage.removeItem(key);\n }\n }\n\n if (localStorage.getItem(\"sessionId\") === sessionId) {\n localStorage.removeItem(\"sessionId\");\n }\n if (sessionStorage.getItem(\"sessionId\") === sessionId) {\n sessionStorage.removeItem(\"sessionId\");\n }\n};\n\n/**\n * Clears all client-side session traces (memory + browser storage)\n * for a given session. This is intentionally aggressive for security.\n */\nexport const clearSessionSensitiveData = (sessionId?: string): void => {\n clearSessionMemory(sessionId);\n\n if (sessionId) {\n clearStorageBySessionId(sessionId);\n return;\n }\n\n localStorage.removeItem(\"sessionId\");\n sessionStorage.removeItem(\"sessionId\");\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n sessionStorage.removeItem(key);\n }\n }\n};\n\n/**\n * Returns the pre-fill data for a given run index from a `userInput` object\n * that contains a `_list` array.\n *\n * Convention: when the integrator wants to pre-fill different data per run\n * (e.g. multiple persons in a loop), they pass `userInput: { _list: [...] }`\n * at session creation. Each element in `_list` corresponds to a run (0-indexed).\n *\n * @param userInput - The session's userInput object\n * @param runIndex - The current run index (0 = first pass, 1 = second pass, …)\n * @returns The pre-fill data for that run, or null if not defined\n */\nexport const getRunPrefillData = (\n userInput: Record<string, unknown>,\n runIndex: number,\n): Record<string, unknown> | null => {\n const list = userInput?._list;\n if (!Array.isArray(list)) return null;\n return (list[runIndex] as Record<string, unknown>) ?? null;\n};\n"],"names":["__awaiter","apiService","__assign","logStatusModified","clearSessionMemory"],"mappings":"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"}
1
+ {"version":3,"file":"sessionService.js","sources":["../../../../src/services/sessionService.ts"],"sourcesContent":["/**\n * Session Service\n *\n * Service for interacting with the Datakeen Session API.\n * Handles fetching session data by ID.\n */\n\nimport type {\n ClientInfo,\n SessionData,\n SessionTemplate,\n SessionTemplateNode,\n} from \"../types/session\";\nimport { apiService } from \"./api\";\nimport { logStatusModified } from \"./auditTrailService\";\nimport { clearSessionMemory } from \"./sessionMemoryStore\";\n\n/**\n * Fetches session data by ID from the Datakeen backend\n *\n * @param sessionId - The unique identifier of the session\n * @returns The session data\n */\nexport const fetchSessionById = async (\n sessionId: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.get(`/session/sdk/${sessionId}`);\n return response.data;\n } catch (error) {\n console.error(\"Error fetching session data:\", error);\n throw error;\n }\n};\n\n/** Sends client information (IP, device, browser, OS) to the backend for a specific session\n *\n * @param sessionId - The unique identifier of the session\n * @param clientInfo - The client information to send\n */\nexport const sendClientInfo = async (\n sessionId: string,\n clientInfo: ClientInfo,\n): Promise<void> => {\n try {\n await apiService.post(`/session/sdk/${sessionId}/client-info`, clientInfo);\n } catch (error) {\n console.error(\"Error sending client info:\", error);\n throw error;\n }\n};\n\n/**\n * Determines if the session template has a specific type of node\n *\n * @param template - The session template\n * @param nodeType - The type of node to check for\n * @returns true if the template has a node of the specified type, false otherwise\n */\nexport const hasNodeType = (\n template: SessionTemplate,\n nodeType: string,\n): boolean => {\n return template.nodes.some((node) => node.type === nodeType);\n};\n\n/**\n * Determines if the session template has a node with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to check for\n * @returns true if the template has a node with the specified requiredDocumentType, false otherwise\n */\nexport const hasDocumentTypeNode = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): boolean => {\n return template.nodes.some(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Gets all nodes of a specific type\n *\n * @param template - The session template\n * @param nodeType - The type of node to get\n * @returns Array of nodes matching the type\n */\nexport const getNodesByType = (\n template: SessionTemplate,\n nodeType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter((node) => node.type === nodeType);\n};\n\n/**\n * Gets all nodes with a specific requiredDocumentType\n *\n * @param template - The session template\n * @param requiredDocumentType - The requiredDocumentType to get\n * @returns Array of nodes matching the requiredDocumentType\n */\nexport const getNodesByDocumentType = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): SessionTemplateNode[] => {\n return template.nodes.filter(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n};\n\n/**\n * Get document options for a specific document type\n *\n * @param template - The session template\n * @param requiredDocumentType - The document type to get options for\n * @returns Array of document options (empty if none found)\n */\nexport const getDocumentOptions = (\n template: SessionTemplate,\n requiredDocumentType: string,\n): string[] => {\n const node = template.nodes.find(\n (node) => node.requiredDocumentType === requiredDocumentType,\n );\n return node?.selectedOptions || [];\n};\n\n/**\n * Determines if the session template has a selfie step\n *\n * @param template - The session template\n * @returns true if the template has a selfie step, false otherwise\n */\nexport const hasSelfieCaptureStep = (template: SessionTemplate): boolean => {\n return hasNodeType(template, \"selfie-capture\");\n};\n\n/**\n * Determines if the session template has an ID document step\n *\n * @param template - The session template\n * @returns true if the template has an ID document step, false otherwise\n */\nexport const hasDocumentStep = (template: SessionTemplate): boolean => {\n // Check if there's any document-selection node with requiredDocumentType \"id-card\"\n // or if none specified, just check for document-selection nodes\n const hasIDCard = hasDocumentTypeNode(template, \"id-card\");\n return hasIDCard || hasNodeType(template, \"document-selection\");\n};\n\n/**\n * Determines if the session template has a JDD (proof of address) step\n *\n * @param template - The session template\n * @returns true if the template has a JDD step, false otherwise\n */\nexport const hasJDDStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"jdd\");\n};\n\n/**\n * Determines if the session template has a proof of funds step\n *\n * @param template - The session template\n * @returns true if the template has a proof of funds step, false otherwise\n */\nexport const hasProofOfFundsStep = (template: SessionTemplate): boolean => {\n return hasDocumentTypeNode(template, \"income-proof\");\n};\n\n/**\n * Determines if the session template has a document collection step\n *\n * @param template - The session template\n * @returns true if the template has a document collection step, false otherwise\n */\nexport const hasDocumentCollectionStep = (\n template: SessionTemplate,\n): boolean => {\n return hasNodeType(template, \"document-collection\");\n};\n\n/**\n * Gets all node types in the template\n *\n * @param template - The session template\n * @returns Array of node types in the template\n */\nexport const getNodeTypes = (template: SessionTemplate): string[] => {\n return Array.from(new Set(template.nodes.map((node) => node.type)));\n};\n\n/**\n * Gets all document types required in the template\n *\n * @param template - The session template\n * @returns Array of document types required in the template\n */\nexport const getRequiredDocumentTypes = (\n template: SessionTemplate,\n): string[] => {\n return Array.from(\n new Set(\n template.nodes\n .filter((node) => node.requiredDocumentType)\n .map((node) => node.requiredDocumentType!),\n ),\n );\n};\n\n/**\n * Converts template document type to internal document type\n * This helps standardize document types between the template and the application\n *\n * @param templateDocType - The document type as defined in the template\n * @returns The internal document type used by the application\n */\nexport const convertTemplateDocTypeToInternal = (\n templateDocType: string,\n): string => {\n if (!templateDocType) return \"\";\n\n // Mapping between template document types and internal document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n \"income-proof\": \"income-proof\", // Using consistent naming\n };\n\n return typeMap[templateDocType] || templateDocType;\n};\n\n/**\n * Converts internal document type to template document type\n *\n * @param internalDocType - The document type used internally by the application\n * @returns The document type as expected in the template\n */\nexport const convertInternalDocTypeToTemplate = (\n internalDocType: string,\n): string => {\n if (!internalDocType) return \"\";\n\n // Mapping between internal document types and template document types\n const typeMap: Record<string, string> = {\n \"id-card\": \"id-card\",\n jdd: \"jdd\",\n funds: \"income-proof\", // Map funds to income-proof for backwards compatibility\n \"income-proof\": \"income-proof\",\n };\n\n return typeMap[internalDocType] || internalDocType;\n};\n\n/**\n * Updates session data with user input information\n *\n * @param sessionId - The unique identifier of the session\n * @param userInput - The user input data (firstName, lastName, birthDate)\n * @returns The updated session data\n */\nexport const updateSessionUserInput = async (\n sessionId: string,\n userInput: {\n firstName?: string;\n lastName?: string;\n birthDate?: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n userInput,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session data:\", error);\n throw error;\n }\n};\n\n/**\n * Records the NFC fallback reason when the user declares they cannot use the\n * contactless scan, and marks the NFC scan as skipped server-side.\n *\n * @param sessionId - The unique identifier of the session\n * @param payload - The selected reason (technical key), its human-readable label,\n * and an optional free-text comment.\n */\nexport const skipNfcWithReason = async (\n sessionId: string,\n payload: { reason: string; label: string; comment?: string },\n): Promise<void> => {\n await apiService.post(`/session/sdk/${sessionId}/nfc-skip`, payload);\n};\n\nexport type SelfieFailureReason =\n | \"timeout\"\n | \"network_error\"\n | \"api_error\"\n | \"user_bypassed\";\n\nexport interface SelfieFailurePayload {\n nodeId: string;\n reason?: SelfieFailureReason;\n conformityCode?: string;\n bypassed?: boolean;\n}\n\nexport const reportSelfieFailure = async (\n sessionId: string,\n payload: SelfieFailurePayload,\n): Promise<void> => {\n await apiService.post(`/session/sdk/${sessionId}/selfie-failed`, payload);\n};\n\n/**\n * Resets a terminal NFC failure before the user starts again with another\n * document. The backend keeps completed scans immutable and treats this call\n * as a no-op when the status is not terminal.\n */\nexport const resetNfcScan = async (sessionId: string): Promise<void> => {\n await apiService.post(`/session/sdk/${sessionId}/nfc-reset`);\n};\n\n/**\n * Updates session data with contact information\n *\n * @param sessionId - The unique identifier of the session\n * @param contactInfo - The contact information data (email, phoneNumber)\n * @returns The updated session data\n */\nexport const updateSessionContactInfo = async (\n sessionId: string,\n contactInfo: {\n email: string;\n phoneNumber: string;\n [key: string]: unknown;\n },\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n contactInfo,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating contact information:\", error);\n throw error;\n }\n};\n\n/**\n * Updates session status\n *\n * @param sessionId - The unique identifier of the session\n * @param status - The new status for the session\n * @param reachedEndNodeId - Id of the end node actually reached (when status is \"ended\"),\n * so the backend can force the correct final status with multiple end nodes.\n * @returns The updated session data\n */\nexport const updateSessionStatus = async (\n sessionId: string,\n status: string,\n reachedEndNodeId?: string,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n status,\n ...(reachedEndNodeId ? { reachedEndNodeId } : {}),\n });\n\n // Log status modification in audit trail\n if (response.data && response.data.analysisId) {\n try {\n await logStatusModified(\n sessionId,\n status,\n response.data.clientInfoId || undefined,\n );\n } catch (err) {\n console.error(\"Failed to log status modification in audit trail:\", err);\n // Non-blocking error - continue session\n }\n }\n\n return response.data;\n } catch (error) {\n console.error(\"Error updating session status:\", error);\n throw error;\n }\n};\n\n/**\n * Updates the current step in the session\n *\n * @param sessionId - The unique identifier of the session\n * @param currentStep - The current step index in the workflow\n * @returns The updated session data\n */\nexport const updateSessionCurrentStep = async (\n sessionId: string,\n currentStep: number,\n): Promise<SessionData> => {\n try {\n const response = await apiService.patch(`/session/sdk/${sessionId}`, {\n currentStep,\n });\n return response.data;\n } catch (error) {\n console.error(\"Error updating session current step:\", error);\n throw error;\n }\n};\n\n/**\n * Gets the journey steps from the template in order\n *\n * @param template - The session template\n * @returns Array of ordered steps\n */\nexport const getOrderedJourneySteps = (\n template: SessionTemplate,\n): SessionTemplateNode[] => {\n // Filter out only start nodes, keep end nodes for proper journey completion, then sort by order.\n // Tiebreaker on id keeps the ordering deterministic when several nodes share the same `order`\n // (e.g. parallel branches of a condition), independently of their position in template.nodes.\n return template.nodes\n .filter((node) => node.type !== \"start\")\n .sort((a, b) => a.order - b.order || a.id.localeCompare(b.id));\n};\n\nconst normalizeHandle = (value?: string): string => {\n return (value || \"\").trim().toLowerCase();\n};\n\n/**\n * Finds the outgoing edge to follow from a node.\n *\n * Resolution order:\n * 1. Exact handle match via sourceHandle/conditionValue.\n * 2. For condition:false loops, fallback to targetHandle=right.\n * 3. First outgoing edge as final fallback.\n */\nexport const findOutgoingEdge = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): SessionTemplate[\"edges\"][number] | null => {\n const outgoingEdges = (template.edges || []).filter(\n (edge) => edge.source === currentNodeId,\n );\n\n if (outgoingEdges.length === 0) {\n return null;\n }\n\n if (!handle) {\n return outgoingEdges[0];\n }\n\n const normalizedHandle = normalizeHandle(handle);\n const edgeByHandle = outgoingEdges.find((edge) => {\n return (\n normalizeHandle(edge.sourceHandle) === normalizedHandle ||\n normalizeHandle(edge.conditionValue) === normalizedHandle\n );\n });\n\n if (edgeByHandle) {\n return edgeByHandle;\n }\n\n const currentNode = template.nodes.find((node) => node.id === currentNodeId);\n if (currentNode?.type === \"condition\" && normalizedHandle === \"false\") {\n const rightHandleLoopEdge = outgoingEdges.find(\n (edge) => normalizeHandle(edge.targetHandle) === \"right\",\n );\n if (rightHandleLoopEdge) {\n return rightHandleLoopEdge;\n }\n }\n\n return outgoingEdges[0];\n};\n\n/**\n * Gets the next step index by following the graph edge from the current node\n *\n * @param currentNodeId - The ID of the current node\n * @param template - The session template\n * @returns The next step index (1-based) or null if no edge found\n */\nexport const getNextStepIndex = (\n currentNodeId: string,\n template: SessionTemplate,\n handle?: string,\n): number | null => {\n const orderedNodes = getOrderedJourneySteps(template);\n const edge = findOutgoingEdge(currentNodeId, template, handle);\n\n if (!edge) {\n console.debug(\n `[sessionService] No outgoing edge found for node ${currentNodeId}${handle ? ` with handle ${handle}` : \"\"}`,\n );\n return null;\n }\n\n const targetId = edge.target;\n const targetIndex = orderedNodes.findIndex((n) => n.id === targetId);\n\n if (targetIndex === -1) {\n console.debug(\n `[sessionService] Target node ${targetId} not found in ordered steps`,\n );\n return null;\n }\n\n // steps are 1-indexed in the SDK (0 is StartSession)\n return 1 + targetIndex;\n};\n\n/**\n * Reconstructs the navigation history by following the graph from step 0\n * up to (and including) targetStep. Returns [0, ...stepIndices].\n * If the graph path cannot reach targetStep, falls back to [0, targetStep].\n */\nexport const reconstructHistoryToStep = (\n targetStep: number,\n template: SessionTemplate,\n): number[] => {\n if (targetStep <= 0) return [0];\n\n const orderedNodes = getOrderedJourneySteps(template);\n const history: number[] = [0];\n let currentStep = 1; // first node is step 1\n\n // Follow the default (first) edge from each node in sequence\n for (let safetyLimit = 0; safetyLimit < orderedNodes.length + 1; safetyLimit++) {\n if (currentStep === targetStep) {\n history.push(currentStep);\n break;\n }\n if (currentStep > targetStep) break;\n\n const nodeIndex = currentStep - 1;\n const currentNode = orderedNodes[nodeIndex];\n if (!currentNode) break;\n\n history.push(currentStep);\n\n const nextStep = getNextStepIndex(currentNode.id, template);\n if (nextStep === null) break;\n currentStep = nextStep;\n }\n\n // Fallback: if we couldn't reach targetStep via graph, use simple seed\n if (history[history.length - 1] !== targetStep) {\n return [0, targetStep];\n }\n\n return history;\n};\n\n/**\n * Maps a template node type to a step component type\n *\n * @param node - The session template node\n * @returns The step component type\n */\nexport const getStepComponentType = (node: SessionTemplateNode): string => {\n // Map from template node types to component types\n const typeMap: Record<string, string> = {\n \"document-selection\": \"document\",\n \"document-collection\": \"document-collection\",\n \"selfie-capture\": \"selfie\",\n \"contact-info\": \"contact-info\",\n \"user-input\": \"user-input\",\n \"otp-verification\": \"otp\",\n };\n\n // First check the node type\n if (node.type in typeMap) {\n return typeMap[node.type];\n }\n\n // Then check the requiredDocumentType\n if (node.requiredDocumentType) {\n return node.requiredDocumentType;\n }\n\n // Default fallback\n return node.type;\n};\n\n/**\n * Checks if a session has expired\n *\n * @param session - The session data to check\n * @returns true if the session has expired, false otherwise\n */\nexport const isSessionExpired = (session: SessionData): boolean => {\n if (!session.expireTime) {\n return false;\n }\n\n const currentTime = Date.now();\n return currentTime > session.expireTime;\n};\n\n/**\n * Stores document options in localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @param options - The options to store\n */\nexport const storeDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n options: string[],\n): void => {\n if (!sessionId || !documentTypeId || !options || options.length === 0) {\n console.warn(\"Missing data for storeDocumentOptions:\", {\n sessionId,\n documentTypeId,\n options,\n });\n return;\n }\n\n // Create a consistent key format based on document type\n let storageKey = \"\";\n\n switch (documentTypeId) {\n case \"jdd\":\n storageKey = `jddOptions_${sessionId}`;\n break;\n case \"income-proof\":\n storageKey = `fundsOptions_${sessionId}`;\n break;\n case \"id-card\":\n storageKey = `idOptions_${sessionId}`;\n break;\n case \"document-collection\":\n storageKey = `documentCollectionOptions_${sessionId}`;\n break;\n default:\n storageKey = `${documentTypeId}Options_${sessionId}`;\n }\n\n localStorage.setItem(storageKey, JSON.stringify(options));\n};\n\n/**\n * Retrieves document options from localStorage for a specific document type\n *\n * @param sessionId - The session ID\n * @param documentTypeId - The document type ID (e.g., 'jdd', 'income-proof')\n * @returns Array of options or default options if none found\n */\nexport const retrieveDocumentOptions = (\n sessionId: string,\n documentTypeId: string,\n): string[] => {\n if (!sessionId || !documentTypeId) {\n console.warn(\"Missing data for retrieveDocumentOptions:\", {\n sessionId,\n documentTypeId,\n });\n return [];\n }\n\n // Create consistent key formats to check\n const possibleKeys = [\n `${documentTypeId}Options_${sessionId}`,\n documentTypeId === \"jdd\" ? `jddOptions_${sessionId}` : \"\",\n documentTypeId === \"income-proof\" ? `fundsOptions_${sessionId}` : \"\",\n documentTypeId === \"id-card\" ? `idOptions_${sessionId}` : \"\",\n documentTypeId === \"document-collection\"\n ? `documentCollectionOptions_${sessionId}`\n : \"\",\n ].filter(Boolean);\n\n // Try each possible key\n for (const key of possibleKeys) {\n const savedOptions = localStorage.getItem(key);\n if (savedOptions) {\n try {\n const parsedOptions = JSON.parse(savedOptions);\n\n return parsedOptions;\n } catch (e) {\n console.error(\n `Error parsing options for ${documentTypeId} with key ${key}:`,\n e,\n );\n }\n }\n }\n\n // Return default options if none found\n console.warn(`No options found for ${documentTypeId}, using defaults`);\n if (documentTypeId === \"jdd\") {\n return [\n \"Facture d'électricité (< 3 mois)\",\n \"Facture de gaz (< 3 mois)\",\n \"Facture d'eau (< 3 mois)\",\n \"Quittance de loyer (< 3 mois)\",\n \"Facture téléphone/internet (< 3 mois)\",\n \"Attestation d'assurance habitation (< 3 mois)\",\n ];\n } else if (documentTypeId === \"income-proof\") {\n return [\n \"Bulletin de salaire\",\n \"Avis d'imposition\",\n \"Relevé de compte bancaire\",\n \"Attestation de revenus\",\n \"Contrat de travail\",\n ];\n } else if (documentTypeId === \"id-card\") {\n return [\"Carte nationale d'identité\", \"Passeport\", \"Permis de conduire\"];\n } else if (documentTypeId === \"document-collection\") {\n return [\"Document administratif\", \"Justificatif\", \"Attestation\"];\n }\n\n return [];\n};\n\nconst clearStorageBySessionId = (sessionId: string): void => {\n const scopedKeys = [\n `userInput_${sessionId}`,\n `contactInfo_${sessionId}`,\n `sessionData_${sessionId}`,\n ];\n\n scopedKeys.forEach((key) => {\n localStorage.removeItem(key);\n sessionStorage.removeItem(key);\n });\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (key.endsWith(`_${sessionId}`)) {\n sessionStorage.removeItem(key);\n }\n }\n\n if (localStorage.getItem(\"sessionId\") === sessionId) {\n localStorage.removeItem(\"sessionId\");\n }\n if (sessionStorage.getItem(\"sessionId\") === sessionId) {\n sessionStorage.removeItem(\"sessionId\");\n }\n};\n\n/**\n * Clears all client-side session traces (memory + browser storage)\n * for a given session. This is intentionally aggressive for security.\n */\nexport const clearSessionSensitiveData = (sessionId?: string): void => {\n clearSessionMemory(sessionId);\n\n if (sessionId) {\n clearStorageBySessionId(sessionId);\n return;\n }\n\n localStorage.removeItem(\"sessionId\");\n sessionStorage.removeItem(\"sessionId\");\n\n for (let i = localStorage.length - 1; i >= 0; i -= 1) {\n const key = localStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n localStorage.removeItem(key);\n }\n }\n\n for (let i = sessionStorage.length - 1; i >= 0; i -= 1) {\n const key = sessionStorage.key(i);\n if (!key) {\n continue;\n }\n if (\n key.startsWith(\"userInput_\") ||\n key.startsWith(\"contactInfo_\") ||\n key.includes(\"Options_\")\n ) {\n sessionStorage.removeItem(key);\n }\n }\n};\n\n/**\n * Returns the pre-fill data for a given run index from a `userInput` object\n * that contains a `_list` array.\n *\n * Convention: when the integrator wants to pre-fill different data per run\n * (e.g. multiple persons in a loop), they pass `userInput: { _list: [...] }`\n * at session creation. Each element in `_list` corresponds to a run (0-indexed).\n *\n * @param userInput - The session's userInput object\n * @param runIndex - The current run index (0 = first pass, 1 = second pass, …)\n * @returns The pre-fill data for that run, or null if not defined\n */\nexport const getRunPrefillData = (\n userInput: Record<string, unknown>,\n runIndex: number,\n): Record<string, unknown> | null => {\n const list = userInput?._list;\n if (!Array.isArray(list)) return null;\n return (list[runIndex] as Record<string, unknown>) ?? null;\n};\n"],"names":["__awaiter","apiService","__assign","logStatusModified","clearSessionMemory"],"mappings":"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"}
@@ -14,6 +14,7 @@ import { useStepNavigation } from '../hooks/useStepNavigation.js';
14
14
  import { useStepCSS } from '../hooks/useStepCSS.js';
15
15
  import { useTemplateLoader } from '../hooks/useTemplateLoader.js';
16
16
  import { useClientInfo } from '../hooks/useClientInfo.js';
17
+ import { useI18n } from '../hooks/useI18n.js';
17
18
  import { getOrderedJourneySteps } from '../services/sessionService.js';
18
19
  import NoSessionIdState from './states/NoSessionIdState.js';
19
20
  import LoadingState from './states/LoadingState.js';
@@ -45,6 +46,7 @@ var DatakeenSession = function (_a) {
45
46
  var sessionId = _a.sessionId, sessionConfig = _a.sessionConfig, apiBaseUrl = _a.apiBaseUrl;
46
47
  var isMobile = useIsMobile();
47
48
  var _p = useClientInfo(), clientInfo = _p.info, clientInfoLoaded = _p.isLoaded;
49
+ var currentLanguage = useI18n().currentLanguage;
48
50
  // Load base CSS and UI components CSS that are always needed
49
51
  useRouteCSS("ui-components");
50
52
  // Session data management
@@ -171,7 +173,7 @@ var DatakeenSession = function (_a) {
171
173
  (currentTemplateNode === null || currentTemplateNode === void 0 ? void 0 : currentTemplateNode.type) === "controle-jdi";
172
174
  var btnBg = (_g = (_f = session === null || session === void 0 ? void 0 : session.template) === null || _f === void 0 ? void 0 : _f.buttonBgColor) !== null && _g !== void 0 ? _g : "#11E5C5";
173
175
  var btnText = (_j = (_h = session === null || session === void 0 ? void 0 : session.template) === null || _h === void 0 ? void 0 : _h.buttonTextColor) !== null && _j !== void 0 ? _j : "#3C3C40";
174
- return (jsx(ConfigProvider, { apiBaseUrl: apiBaseUrl, children: jsx(DocumentProvider, { children: jsx("div", { className: "sdk-session flex-1 flex flex-col", style: __assign((_c = {}, _c["--dk-btn-bg"] = btnBg, _c["--dk-btn-text"] = btnText, _c), (isMobile
176
+ return (jsx(ConfigProvider, { apiBaseUrl: apiBaseUrl, children: jsx(DocumentProvider, { children: jsx("div", { className: "sdk-session notranslate flex-1 flex flex-col", lang: currentLanguage, translate: "no", style: __assign((_c = {}, _c["--dk-btn-bg"] = btnBg, _c["--dk-btn-text"] = btnText, _c), (isMobile
175
177
  ? (_d = {},
176
178
  _d["--dk-mobile-scroll-padding"] = mobileScrollPadding,
177
179
  _d) : undefined)), children: isMobile ? (jsxs("div", { className: "flex h-full w-full flex-col bg-white", style: mobileRootStyle, children: [jsx("div", { className: "flex flex-1 min-h-0 flex-col ".concat(isCaptureStep ? "" : "overflow-y-auto"), style: {
@@ -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 { 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\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 flex-1 flex flex-col\"\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 { 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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"}
@@ -25,6 +25,11 @@ var DocumentVideoRecorder = function (_a) {
25
25
  useEffect(function () {
26
26
  document.body.classList.add("recording-document-video");
27
27
  var cleanupObserver = setupVideoElementsObserver();
28
+ // Voir SelfieRecorder : un traducteur automatique détruit les marqueurs de template
29
+ // Lit du web component Unissey et bloque définitivement la capture.
30
+ document
31
+ .querySelectorAll("uni-video-recorder")
32
+ .forEach(function (el) { return el.setAttribute("translate", "no"); });
28
33
  // iOS-specific fix: Add required attributes to video elements after mount
29
34
  if (isIOS()) {
30
35
  var addIOSVideoAttributes = function () {
@@ -214,7 +219,7 @@ var DocumentVideoRecorder = function (_a) {
214
219
  documentType: documentType,
215
220
  side: side,
216
221
  defaultValue: "Analyse de votre ".concat(documentType, " (").concat(side, ")"),
217
- }) }), jsx(Subtitle, { className: "text-xs text-gray-600 md:text-sm", children: t("document_video.recorder.subtitle", "Gardez le document dans le cadre") })] }), jsx("div", { className: "video-container flex-grow relative flex items-center justify-center overflow-hidden", children: jsx(VideoRecorder, __assign({ ref: recorderRef, preset: AcquisitionPreset.DOC_VIDEO, hideCaptureBtn: true, faceChecker: "disabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius w-full h-full" }, (isIOS() && {
222
+ }) }), jsx(Subtitle, { className: "text-xs text-gray-600 md:text-sm", children: t("document_video.recorder.subtitle", "Gardez le document dans le cadre") })] }), jsx("div", { className: "video-container flex-grow relative flex items-center justify-center overflow-hidden", children: jsx(VideoRecorder, __assign({ ref: recorderRef, preset: AcquisitionPreset.DOC_VIDEO, hideCaptureBtn: true, faceChecker: "disabled", disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordCompleted: handleRecordCompleted, onRecord: recordStarting, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius notranslate w-full h-full" }, (isIOS() && {
218
223
  // iOS-specific attributes for fixing black screen
219
224
  "data-playsinline": "true",
220
225
  "data-autoplay": "true",
@@ -1 +1 @@
1
- {"version":3,"file":"DocumentVideoRecorder.js","sources":["../../../../../../src/components/document-video/document-video-flow/DocumentVideoRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../../selfie/hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../../selfie/utils/videoElementStyles\";\nimport {\n delay,\n isIOS,\n waitForVideoFrame,\n getRecorderVideoElement,\n} from \"../../selfie/utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../../selfie/hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../../selfie/utils/unisseyStrings\";\n\ninterface DocumentVideoRecorderProps {\n handleVideoCapture: (e: Event) => void;\n documentType: string;\n side: \"recto\" | \"verso\";\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst DocumentVideoRecorder = ({\n handleVideoCapture,\n documentType,\n side,\n onBeginCapture = () => {},\n isCapturing = false,\n}: DocumentVideoRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-document-video\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-document-video\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-document-video\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n // Activate torch (flash) on the environment camera for better hologram visibility\n useEffect(() => {\n if (!recorderReady) return;\n\n let videoTrack: MediaStreamTrack | null = null;\n\n const enableTorch = async () => {\n // Wait a short delay for the video element to be fully initialized\n await delay(500);\n\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (!videoElement) return;\n\n const stream = videoElement.srcObject as MediaStream | null;\n if (!stream) return;\n\n videoTrack = stream.getVideoTracks()[0] ?? null;\n if (!videoTrack) return;\n\n try {\n const capabilities = videoTrack.getCapabilities?.() as\n | Record<string, any>\n | undefined;\n if (!capabilities?.torch) {\n console.debug(\n \"[DocumentVideoRecorder] Torch not supported on this device\",\n );\n return;\n }\n\n await videoTrack.applyConstraints({\n advanced: [{ torch: true } as any],\n });\n console.debug(\"[DocumentVideoRecorder] Torch enabled\");\n } catch (error) {\n console.warn(\"[DocumentVideoRecorder] Failed to enable torch:\", error);\n }\n };\n\n enableTorch();\n\n return () => {\n // Turn off torch on cleanup\n if (videoTrack) {\n videoTrack\n .applyConstraints({\n advanced: [{ torch: false } as any],\n })\n .catch(() => {});\n }\n };\n }, [recorderReady]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"DocumentVideoRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\n \"🍎 iOS detected - checking video elements for proper attributes\",\n );\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\"),\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent(\"record-completed\", {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || \"\",\n thumbnail: capturedThumbnailRef.current || undefined,\n documentType: documentType,\n side,\n },\n });\n\n setRecordingState(\"processing\");\n handleVideoCapture(enhancedEvent);\n };\n\n return (\n <div className=\"selfie flex flex-col h-full w-full overflow-hidden\">\n <div className=\"p-4 text-center\">\n <Title className=\"text-lg md:text-xl mb-1\">\n {t(\"document_video.recorder.title\", {\n documentType,\n side,\n defaultValue: `Analyse de votre ${documentType} (${side})`,\n })}\n </Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">\n {t(\n \"document_video.recorder.subtitle\",\n \"Gardez le document dans le cadre\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"video-container flex-grow relative flex items-center justify-center overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.DOC_VIDEO}\n hideCaptureBtn\n faceChecker=\"disabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius w-full h-full\"\n {...(isIOS() && {\n // iOS-specific attributes for fixing black screen\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\",\n })}\n strings={getUnisseyStrings(t, \"document\")}\n />\n </div>\n\n <div className=\"sticky bottom-0 bg-white border-t border-gray-200 p-4 md:p-6\">\n <div className=\"max-w-md mx-auto\">\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" &&\n t(\"document_video.recorder.start\", \"Démarrer\")}\n {recordingState === \"preparing\" &&\n t(\"document_video.recorder.preparing\", \"Préparation\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">\n {t(\n \"document_video.recorder.recording\",\n \"Enregistrement en cours\",\n )}\n </span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" &&\n t(\"document_video.recorder.processing\", \"Traitement\")}\n </Button>\n\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\n \"document_video.recorder.note\",\n \"La vidéo sera enregistrée automatiquement\",\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default DocumentVideoRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
1
+ {"version":3,"file":"DocumentVideoRecorder.js","sources":["../../../../../../src/components/document-video/document-video-flow/DocumentVideoRecorder.tsx"],"sourcesContent":["import { useRef, useState, useEffect } from \"react\";\nimport { AcquisitionPreset, VideoRecorder } from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../../selfie/hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../../selfie/utils/videoElementStyles\";\nimport {\n delay,\n isIOS,\n waitForVideoFrame,\n getRecorderVideoElement,\n} from \"../../selfie/utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../../selfie/hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { getUnisseyStrings } from \"../../selfie/utils/unisseyStrings\";\n\ninterface DocumentVideoRecorderProps {\n handleVideoCapture: (e: Event) => void;\n documentType: string;\n side: \"recto\" | \"verso\";\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n}\n\ninterface VideoRecorderRef extends HTMLElement {\n capture: () => void;\n}\n\nconst DocumentVideoRecorder = ({\n handleVideoCapture,\n documentType,\n side,\n onBeginCapture = () => {},\n isCapturing = false,\n}: DocumentVideoRecorderProps) => {\n const { t } = useI18n();\n const recorderRef = useRef<VideoRecorderRef | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<\n \"idle\" | \"preparing\" | \"recording\" | \"processing\"\n >(\"idle\");\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles();\n\n useEffect(() => {\n document.body.classList.add(\"recording-document-video\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // Voir SelfieRecorder : un traducteur automatique détruit les marqueurs de template\n // Lit du web component Unissey et bloque définitivement la capture.\n document\n .querySelectorAll(\"uni-video-recorder\")\n .forEach((el) => el.setAttribute(\"translate\", \"no\"));\n\n // iOS-specific fix: Add required attributes to video elements after mount\n if (isIOS()) {\n const addIOSVideoAttributes = () => {\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder) => {\n // Try to access shadow DOM and video elements\n try {\n const shadowRoot = (recorder as any).shadowRoot;\n if (shadowRoot) {\n const videoElements = shadowRoot.querySelectorAll(\"video\");\n videoElements.forEach((video: HTMLVideoElement) => {\n video.setAttribute(\"playsinline\", \"true\");\n video.setAttribute(\"autoplay\", \"true\");\n video.setAttribute(\"muted\", \"true\");\n // Ensure video plays inline and autoplays\n video.playsInline = true;\n video.autoplay = true;\n video.muted = true;\n });\n }\n } catch (error) {\n console.log(\"Could not access shadow DOM:\", error);\n }\n\n // Also set attributes on the component itself\n recorder.setAttribute(\"playsinline\", \"true\");\n recorder.setAttribute(\"autoplay\", \"true\");\n recorder.setAttribute(\"muted\", \"true\");\n });\n };\n\n // Apply immediately and also after a delay to catch dynamically created elements\n addIOSVideoAttributes();\n const iosTimeout = setTimeout(addIOSVideoAttributes, 500);\n const iosInterval = setInterval(addIOSVideoAttributes, 1000);\n\n return () => {\n document.body.classList.remove(\"recording-document-video\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-document-video\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n // Activate torch (flash) on the environment camera for better hologram visibility\n useEffect(() => {\n if (!recorderReady) return;\n\n let videoTrack: MediaStreamTrack | null = null;\n\n const enableTorch = async () => {\n // Wait a short delay for the video element to be fully initialized\n await delay(500);\n\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (!videoElement) return;\n\n const stream = videoElement.srcObject as MediaStream | null;\n if (!stream) return;\n\n videoTrack = stream.getVideoTracks()[0] ?? null;\n if (!videoTrack) return;\n\n try {\n const capabilities = videoTrack.getCapabilities?.() as\n | Record<string, any>\n | undefined;\n if (!capabilities?.torch) {\n console.debug(\n \"[DocumentVideoRecorder] Torch not supported on this device\",\n );\n return;\n }\n\n await videoTrack.applyConstraints({\n advanced: [{ torch: true } as any],\n });\n console.debug(\"[DocumentVideoRecorder] Torch enabled\");\n } catch (error) {\n console.warn(\"[DocumentVideoRecorder] Failed to enable torch:\", error);\n }\n };\n\n enableTorch();\n\n return () => {\n // Turn off torch on cleanup\n if (videoTrack) {\n videoTrack\n .applyConstraints({\n advanced: [{ torch: false } as any],\n })\n .catch(() => {});\n }\n };\n }, [recorderReady]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n setRecordingState(\"recording\");\n\n // Capture a frame from the live video during recording (after a short delay)\n setTimeout(() => {\n const videoElement = getRecorderVideoElement(recorderRef.current);\n if (videoElement) {\n const thumbnail = captureFrame(videoElement);\n capturedThumbnailRef.current = thumbnail;\n }\n }, 1000); // Capture frame 1 second into recording\n\n recorderRef.current?.capture();\n } catch (error) {\n console.error(\"DocumentVideoRecorder: failed to capture frame\", error);\n setRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n const handleRecorderReady = () => setRecorderReady(true);\n\n const handleRecordCompleted = (e: Event) => {\n const customEvent = e as CustomEvent<{ media?: Blob; metadata?: string }>;\n if (!customEvent.detail?.media || customEvent.detail.media.size === 0) {\n console.error(\"❌ No valid media captured\");\n\n // iOS-specific debugging\n if (isIOS()) {\n console.log(\n \"🍎 iOS detected - checking video elements for proper attributes\",\n );\n const videoRecorders = document.querySelectorAll(\"uni-video-recorder\");\n videoRecorders.forEach((recorder, index) => {\n console.log(`VideoRecorder ${index}:`, {\n playsinline: recorder.getAttribute(\"playsinline\"),\n autoplay: recorder.getAttribute(\"autoplay\"),\n muted: recorder.getAttribute(\"muted\"),\n });\n });\n }\n\n setRecordingState(\"idle\");\n setDisableButton(false);\n return;\n }\n\n // Attach the captured thumbnail to the event\n const enhancedEvent = new CustomEvent(\"record-completed\", {\n detail: {\n media: customEvent.detail.media,\n metadata: customEvent.detail.metadata || \"\",\n thumbnail: capturedThumbnailRef.current || undefined,\n documentType: documentType,\n side,\n },\n });\n\n setRecordingState(\"processing\");\n handleVideoCapture(enhancedEvent);\n };\n\n return (\n <div className=\"selfie flex flex-col h-full w-full overflow-hidden\">\n <div className=\"p-4 text-center\">\n <Title className=\"text-lg md:text-xl mb-1\">\n {t(\"document_video.recorder.title\", {\n documentType,\n side,\n defaultValue: `Analyse de votre ${documentType} (${side})`,\n })}\n </Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">\n {t(\n \"document_video.recorder.subtitle\",\n \"Gardez le document dans le cadre\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"video-container flex-grow relative flex items-center justify-center overflow-hidden\">\n <VideoRecorder\n ref={recorderRef as any}\n preset={AcquisitionPreset.DOC_VIDEO}\n hideCaptureBtn\n faceChecker=\"disabled\"\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordCompleted={handleRecordCompleted}\n onRecord={recordStarting}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius notranslate w-full h-full\"\n {...(isIOS() && {\n // iOS-specific attributes for fixing black screen\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\",\n })}\n strings={getUnisseyStrings(t, \"document\")}\n />\n </div>\n\n <div className=\"sticky bottom-0 bg-white border-t border-gray-200 p-4 md:p-6\">\n <div className=\"max-w-md mx-auto\">\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n >\n {recordingState === \"idle\" &&\n t(\"document_video.recorder.start\", \"Démarrer\")}\n {recordingState === \"preparing\" &&\n t(\"document_video.recorder.preparing\", \"Préparation\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">\n {t(\n \"document_video.recorder.recording\",\n \"Enregistrement en cours\",\n )}\n </span>\n <span className=\"flex space-x-1 loading-dots\">\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n <span className=\"h-1 w-1 bg-white rounded-full\"></span>\n </span>\n </span>\n )}\n {recordingState === \"processing\" &&\n t(\"document_video.recorder.processing\", \"Traitement\")}\n </Button>\n\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\n \"document_video.recorder.note\",\n \"La vidéo sera enregistrée automatiquement\",\n )}\n </div>\n </div>\n </div>\n </div>\n );\n};\n\nexport default DocumentVideoRecorder;\n"],"names":["_jsxs","_jsx"],"mappings":"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"}
@@ -8,6 +8,7 @@ import { codeToStep } from '../../../services/utils.js';
8
8
  import { analyzeSelfie } from '../../../services/analysis.js';
9
9
  import { getActiveSessionId } from '../../../services/sessionMemoryStore.js';
10
10
  import ButtonDesktop from '../../ui/ButtonDesktop.js';
11
+ import { reportSelfieFailure } from '../../../services/sessionService.js';
11
12
 
12
13
  var processingSteps = [
13
14
  { key: "analysis" },
@@ -16,7 +17,7 @@ var processingSteps = [
16
17
  { key: "finalization" },
17
18
  ];
18
19
  var SelfieProcessing = function (_a) {
19
- var onProcessingComplete = _a.onProcessingComplete, selfieVideo = _a.selfieVideo, selfiePhoto = _a.selfiePhoto, onRetake = _a.onRetake, onContinueAnyway = _a.onContinueAnyway;
20
+ var onProcessingComplete = _a.onProcessingComplete, selfieVideo = _a.selfieVideo, selfiePhoto = _a.selfiePhoto, onRetake = _a.onRetake, onContinueAnyway = _a.onContinueAnyway, nodeId = _a.nodeId;
20
21
  var t = useI18n().t;
21
22
  var _b = useState(0), currentStep = _b[0], setCurrentStep = _b[1];
22
23
  var _c = useState(false), hasError = _c[0], setHasError = _c[1];
@@ -34,6 +35,13 @@ var SelfieProcessing = function (_a) {
34
35
  var timeoutId = setTimeout(function () {
35
36
  if (!isDone) {
36
37
  console.error("⏰ Selfie analysis timeout after 60 seconds");
38
+ var sessionId = getActiveSessionId();
39
+ if (sessionId) {
40
+ void reportSelfieFailure(sessionId, {
41
+ nodeId: nodeId,
42
+ reason: "timeout",
43
+ }).catch(function () { return undefined; });
44
+ }
37
45
  setHasError(true);
38
46
  setIsDone(true);
39
47
  onProcessingComplete(false);
@@ -59,7 +67,7 @@ var SelfieProcessing = function (_a) {
59
67
  case 1:
60
68
  _h.trys.push([1, 3, , 4]);
61
69
  return [4 /*yield*/, Promise.all([
62
- analyzeSelfie(sessionId, selfieVideo, selfiePhoto),
70
+ analyzeSelfie(sessionId, selfieVideo, selfiePhoto, nodeId),
63
71
  new Promise(function (resolve) { return setTimeout(resolve, 2000); }),
64
72
  ])];
65
73
  case 2:
@@ -106,6 +114,10 @@ var SelfieProcessing = function (_a) {
106
114
  case 3:
107
115
  error_1 = _h.sent();
108
116
  console.error("💥 Selfie analysis failed:", error_1);
117
+ void reportSelfieFailure(sessionId, {
118
+ nodeId: nodeId,
119
+ reason: "network_error",
120
+ }).catch(function () { return undefined; });
109
121
  clearTimeout(timeoutId);
110
122
  setHasError(true);
111
123
  setIsDone(true);
@@ -119,7 +131,7 @@ var SelfieProcessing = function (_a) {
119
131
  return function () {
120
132
  clearTimeout(timeoutId);
121
133
  };
122
- }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone]);
134
+ }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone, nodeId]);
123
135
  useEffect(function () {
124
136
  // While analysis is not finished, stay at step 0
125
137
  if (!isDone && !hasError) {
@@ -1 +1 @@
1
- {"version":3,"file":"SelfieProcessing.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieProcessing.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { codeToStep } from \"../../../services/utils\";\nimport type { SelfieCaptureData } from \"../../../types/selfie\";\nimport { analyzeSelfie } from \"../../../services/analysis\";\nimport { getActiveSessionId } from \"../../../services/sessionMemoryStore\";\nimport ButtonDesktop from \"../../ui/ButtonDesktop\";\n\ninterface SelfieProcessingProps {\n onProcessingComplete: (success: boolean) => void;\n selfieVideo: SelfieCaptureData | null;\n selfiePhoto: string | null;\n onRetake: () => void;\n onContinueAnyway?: () => void;\n}\n\nconst processingSteps = [\n { key: \"analysis\" },\n { key: \"face_detection\" },\n { key: \"liveness\" },\n { key: \"finalization\" },\n];\nconst SelfieProcessing = ({\n onProcessingComplete,\n selfieVideo,\n selfiePhoto,\n onRetake,\n onContinueAnyway,\n}: SelfieProcessingProps) => {\n const { t } = useI18n();\n const [currentStep, setCurrentStep] = useState(0);\n const [hasError, setHasError] = useState(false);\n const [isDone, setIsDone] = useState(false);\n const [conformityCode, setConformityCode] = useState<string | null>(null);\n\n const analysisStartedRef = useRef(false);\n useEffect(() => {\n // Prevent multiple analysis runs\n if (analysisStartedRef.current) return;\n if (!selfieVideo || !selfiePhoto) return;\n\n analysisStartedRef.current = true;\n\n // Timeout simple : 60 secondes pour tous\n const timeoutId = setTimeout(() => {\n if (!isDone) {\n console.error(\"⏰ Selfie analysis timeout after 60 seconds\");\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n }, 60000);\n\n const processFiles = async () => {\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n console.error(\"❌ No session ID found\");\n setHasError(true);\n onProcessingComplete(false);\n setIsDone(true);\n clearTimeout(timeoutId);\n return;\n }\n\n console.log(\"🚀 Starting selfie analysis...\");\n\n try {\n // Délai minimum simple : 2 secondes\n const [response] = await Promise.all([\n analyzeSelfie(sessionId, selfieVideo, selfiePhoto),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n\n console.log(\"✅ Analysis response:\", response);\n clearTimeout(timeoutId);\n\n // Handle Unissey response format\n let isSuccess = false;\n let conformityCodeToSet = \"4\"; // Default to error\n\n if (response && response.data) {\n // Check if analysis was successful based on real Unissey response structure\n const data = response.data;\n const details = data.details;\n const faceComparison = details?.face_comparison;\n\n // Success: face match with high confidence\n if (\n data.is_match &&\n faceComparison?.result === \"match\"\n // faceComparison?.confidence_level === \"high\" Pas assez explicit\n ) {\n isSuccess = true;\n conformityCodeToSet = \"1.0\"; // Success code\n } else if (details) {\n // Check specific failure reasons\n if (faceComparison?.result !== \"match\") {\n conformityCodeToSet = \"2.0\"; // Face comparison failed\n } else if (faceComparison?.confidence_level !== \"high\") {\n conformityCodeToSet = \"3.0\"; // Low confidence\n } else {\n conformityCodeToSet = \"4.0\"; // Generic error\n }\n }\n }\n\n console.log(\"📊 Selfie analysis result:\", {\n isSuccess,\n conformityCode: conformityCodeToSet,\n isMatch: response?.data?.is_match,\n confidenceLevel:\n response?.data?.details?.face_comparison?.confidence_level,\n comparisonResult: response?.data?.details?.face_comparison?.result,\n });\n\n setConformityCode(conformityCodeToSet);\n setIsDone(true);\n\n // Don't call onProcessingComplete here - let the animation effect handle it\n } catch (error) {\n console.error(\"💥 Selfie analysis failed:\", error);\n clearTimeout(timeoutId);\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n };\n\n processFiles();\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone]);\n\n useEffect(() => {\n // While analysis is not finished, stay at step 0\n if (!isDone && !hasError) {\n setCurrentStep(0);\n return;\n }\n // We want stepToStop to be the step in error (the one corresponding to conformityCode)\n let stepToStop = codeToStep(conformityCode || \"4\");\n // If codeToStep returns 0 (generic error), stop at the first step\n if (stepToStop === 0) stepToStop = 1;\n console.log(\"Step to stop (error):\", stepToStop);\n\n // When analysis is finished (success or error), start the animation\n const interval = setInterval(() => {\n setCurrentStep((prev) => {\n if (prev < stepToStop - 1) {\n return prev + 1;\n } else {\n clearInterval(interval);\n if (stepToStop < 4) setHasError(true);\n onProcessingComplete(stepToStop === 4);\n return prev; // Stop at the step in error\n }\n });\n }, 500); // Adjust the speed of the animation\n return () => clearInterval(interval);\n }, [onProcessingComplete, hasError, isDone, conformityCode]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n <div className=\"flex-1 px-4 py-6 pt-11 md:px-8 md:py-8\">\n <div className=\"w-full max-w-md mx-auto space-y-6\">\n <div className=\"text-center space-y-4\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {hasError\n ? t(\"selfie.processing.error_title\", \"Échec de l'analyse\")\n : t(\"selfie.processing.title\", \"Analyse en cours\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {hasError\n ? t(\n \"selfie.processing.error_subtitle\",\n \"Une erreur est survenue lors de l'analyse du selfie. Veuillez réessayer.\",\n )\n : t(\n \"selfie.processing.subtitle\",\n \"Nous analysons votre selfie. Cela peut prendre quelques instants.\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"w-full\">\n <div className=\"space-y-5\">\n {processingSteps.map(\n (step, index) =>\n step.key && (\n <div key={index} className=\"flex items-start\">\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {hasError && index === currentStep ? (\n // Step in error - red cross\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs font-bold\">\n ×\n </div>\n ) : index < currentStep ? (\n // Completed step - green check\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n ) : index === currentStep ? (\n // Current step - spinner\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Upcoming step - gray circle\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {t(`selfie.processing.steps.${step.key}.title`)}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(`selfie.processing.steps.${step.key}.subtitle`)}\n </p>\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n\n <div className=\"w-full\">\n <div className=\"bg-gray-200 rounded-full h-2\">\n <div\n className={\n hasError\n ? \"bg-red-500 h-2 rounded-full transition-all duration-500 ease-out\"\n : \"bg-[#11E5C5] h-2 rounded-full transition-all duration-500 ease-out\"\n }\n style={{\n width: `${\n ((currentStep + 1) / processingSteps.length) * 100\n }%`,\n }}\n ></div>\n </div>\n <p className=\"text-xs text-gray-500 mt-2 text-center\">\n {t(\"selfie.processing.step_of\", {\n current: currentStep + 1,\n total: processingSteps.length,\n })}\n </p>\n </div>\n\n {/* Footer with buttons */}\n {hasError && (\n <div className=\"sticky bottom-0 bg-white border-t border-gray-100 p-4 md:p-6\">\n <div className=\"w-full max-w-md mx-auto\">\n {/* Mobile layout - stacked buttons */}\n <div className=\"flex flex-col space-y-3 md:hidden\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n\n {/* Desktop layout - horizontal buttons */}\n <div className=\"hidden md:flex gap-3 justify-between items-center\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":";;;;;;;;;;;AAkBA,IAAM,eAAe,GAAG;IACtB,EAAE,GAAG,EAAE,UAAU,EAAE;IACnB,EAAE,GAAG,EAAE,gBAAgB,EAAE;IACzB,EAAE,GAAG,EAAE,UAAU,EAAE;IACnB,EAAE,GAAG,EAAE,cAAc,EAAE;CACxB;AACD,IAAM,gBAAgB,GAAG,UAAC,EAMF,EAAA;AALtB,IAAA,IAAA,oBAAoB,GAAA,EAAA,CAAA,oBAAA,EACpB,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,WAAW,GAAA,EAAA,CAAA,WAAA,EACX,QAAQ,GAAA,EAAA,CAAA,QAAA,EACR,gBAAgB,GAAA,EAAA,CAAA,gBAAA;AAER,IAAA,IAAA,CAAC,GAAK,OAAO,EAAE,EAAd;IACH,IAAA,EAAA,GAAgC,QAAQ,CAAC,CAAC,CAAC,EAA1C,WAAW,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,cAAc,GAAA,EAAA,CAAA,CAAA,CAAe;IAC3C,IAAA,EAAA,GAA0B,QAAQ,CAAC,KAAK,CAAC,EAAxC,QAAQ,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,WAAW,GAAA,EAAA,CAAA,CAAA,CAAmB;IACzC,IAAA,EAAA,GAAsB,QAAQ,CAAC,KAAK,CAAC,EAApC,MAAM,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,SAAS,GAAA,EAAA,CAAA,CAAA,CAAmB;IACrC,IAAA,EAAA,GAAsC,QAAQ,CAAgB,IAAI,CAAC,EAAlE,cAAc,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,iBAAiB,GAAA,EAAA,CAAA,CAAA,CAAiC;AAEzE,IAAA,IAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC;AACxC,IAAA,SAAS,CAAC,YAAA;;QAER,IAAI,kBAAkB,CAAC,OAAO;YAAE;AAChC,QAAA,IAAI,CAAC,WAAW,IAAI,CAAC,WAAW;YAAE;AAElC,QAAA,kBAAkB,CAAC,OAAO,GAAG,IAAI;;QAGjC,IAAM,SAAS,GAAG,UAAU,CAAC,YAAA;YAC3B,IAAI,CAAC,MAAM,EAAE;AACX,gBAAA,OAAO,CAAC,KAAK,CAAC,4CAA4C,CAAC;gBAC3D,WAAW,CAAC,IAAI,CAAC;gBACjB,SAAS,CAAC,IAAI,CAAC;gBACf,oBAAoB,CAAC,KAAK,CAAC;YAC7B;QACF,CAAC,EAAE,KAAK,CAAC;AAET,QAAA,IAAM,YAAY,GAAG,YAAA,EAAA,OAAA,SAAA,CAAA,MAAA,EAAA,MAAA,EAAA,MAAA,EAAA,YAAA;;;;;;wBACb,SAAS,GAAG,kBAAkB,EAAE;wBACtC,IAAI,CAAC,SAAS,EAAE;AACd,4BAAA,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC;4BACtC,WAAW,CAAC,IAAI,CAAC;4BACjB,oBAAoB,CAAC,KAAK,CAAC;4BAC3B,SAAS,CAAC,IAAI,CAAC;4BACf,YAAY,CAAC,SAAS,CAAC;4BACvB,OAAA,CAAA,CAAA,YAAA;wBACF;AAEA,wBAAA,OAAO,CAAC,GAAG,CAAC,gCAAgC,CAAC;;;;wBAIxB,OAAA,CAAA,CAAA,YAAM,OAAO,CAAC,GAAG,CAAC;AACnC,gCAAA,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC;AAClD,gCAAA,IAAI,OAAO,CAAC,UAAC,OAAO,IAAK,OAAA,UAAU,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA,CAAzB,CAAyB,CAAC;AACpD,6BAAA,CAAC,CAAA;;AAHK,wBAAA,QAAQ,GAAI,CAAA,EAAA,CAAA,IAAA,EAGjB,EAAA,CAAA,CAHa;AAKf,wBAAA,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,QAAQ,CAAC;wBAC7C,YAAY,CAAC,SAAS,CAAC;wBAGnB,SAAS,GAAG,KAAK;wBACjB,mBAAmB,GAAG,GAAG;AAE7B,wBAAA,IAAI,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE;AAEvB,4BAAA,IAAI,GAAG,QAAQ,CAAC,IAAI;AACpB,4BAAA,OAAO,GAAG,IAAI,CAAC,OAAO;4BACtB,cAAc,GAAG,OAAO,KAAA,IAAA,IAAP,OAAO,uBAAP,OAAO,CAAE,eAAe;;4BAG/C,IACE,IAAI,CAAC,QAAQ;gCACb,CAAA,cAAc,aAAd,cAAc,KAAA,MAAA,GAAA,MAAA,GAAd,cAAc,CAAE,MAAM,MAAK;;8BAE3B;gCACA,SAAS,GAAG,IAAI;AAChB,gCAAA,mBAAmB,GAAG,KAAK,CAAC;4BAC9B;iCAAO,IAAI,OAAO,EAAE;;gCAElB,IAAI,CAAA,cAAc,KAAA,IAAA,IAAd,cAAc,KAAA,MAAA,GAAA,MAAA,GAAd,cAAc,CAAE,MAAM,MAAK,OAAO,EAAE;AACtC,oCAAA,mBAAmB,GAAG,KAAK,CAAC;gCAC9B;qCAAO,IAAI,CAAA,cAAc,KAAA,IAAA,IAAd,cAAc,KAAA,MAAA,GAAA,MAAA,GAAd,cAAc,CAAE,gBAAgB,MAAK,MAAM,EAAE;AACtD,oCAAA,mBAAmB,GAAG,KAAK,CAAC;gCAC9B;qCAAO;AACL,oCAAA,mBAAmB,GAAG,KAAK,CAAC;gCAC9B;4BACF;wBACF;AAEA,wBAAA,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE;AACxC,4BAAA,SAAS,EAAA,SAAA;AACT,4BAAA,cAAc,EAAE,mBAAmB;4BACnC,OAAO,EAAE,CAAA,EAAA,GAAA,QAAQ,KAAA,IAAA,IAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,QAAQ;AACjC,4BAAA,eAAe,EACb,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAQ,aAAR,QAAQ,KAAA,MAAA,GAAA,MAAA,GAAR,QAAQ,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,eAAe,0CAAE,gBAAgB;AAC5D,4BAAA,gBAAgB,EAAE,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,QAAQ,aAAR,QAAQ,KAAA,MAAA,GAAA,MAAA,GAAR,QAAQ,CAAE,IAAI,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,OAAO,MAAA,IAAA,IAAA,EAAA,KAAA,MAAA,GAAA,MAAA,GAAA,EAAA,CAAE,eAAe,0CAAE,MAAM;AACnE,yBAAA,CAAC;wBAEF,iBAAiB,CAAC,mBAAmB,CAAC;wBACtC,SAAS,CAAC,IAAI,CAAC;;;;AAIf,wBAAA,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,OAAK,CAAC;wBAClD,YAAY,CAAC,SAAS,CAAC;wBACvB,WAAW,CAAC,IAAI,CAAC;wBACjB,SAAS,CAAC,IAAI,CAAC;wBACf,oBAAoB,CAAC,KAAK,CAAC;;;;;aAE9B;AAED,QAAA,YAAY,EAAE;QAEd,OAAO,YAAA;YACL,YAAY,CAAC,SAAS,CAAC;AACzB,QAAA,CAAC;IACH,CAAC,EAAE,CAAC,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AAE5D,IAAA,SAAS,CAAC,YAAA;;AAER,QAAA,IAAI,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE;YACxB,cAAc,CAAC,CAAC,CAAC;YACjB;QACF;;QAEA,IAAI,UAAU,GAAG,UAAU,CAAC,cAAc,IAAI,GAAG,CAAC;;QAElD,IAAI,UAAU,KAAK,CAAC;YAAE,UAAU,GAAG,CAAC;AACpC,QAAA,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,UAAU,CAAC;;QAGhD,IAAM,QAAQ,GAAG,WAAW,CAAC,YAAA;YAC3B,cAAc,CAAC,UAAC,IAAI,EAAA;AAClB,gBAAA,IAAI,IAAI,GAAG,UAAU,GAAG,CAAC,EAAE;oBACzB,OAAO,IAAI,GAAG,CAAC;gBACjB;qBAAO;oBACL,aAAa,CAAC,QAAQ,CAAC;oBACvB,IAAI,UAAU,GAAG,CAAC;wBAAE,WAAW,CAAC,IAAI,CAAC;AACrC,oBAAA,oBAAoB,CAAC,UAAU,KAAK,CAAC,CAAC;oBACtC,OAAO,IAAI,CAAC;gBACd;AACF,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC,EAAE,GAAG,CAAC,CAAC;QACR,OAAO,YAAA,EAAM,OAAA,aAAa,CAAC,QAAQ,CAAC,CAAA,CAAvB,CAAuB;IACtC,CAAC,EAAE,CAAC,oBAAoB,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,CAAC,CAAC;AAE5D,IAAA,QACEA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,6CAA6C,EAAA,QAAA,EAC1DA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,wCAAwC,EAAA,QAAA,EACrDC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mCAAmC,EAAA,QAAA,EAAA,CAChDA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uBAAuB,EAAA,QAAA,EAAA,CACpCD,GAAA,CAAC,KAAK,EAAA,EAAC,SAAS,EAAC,iCAAiC,EAAA,QAAA,EAC/C;AACC,sCAAE,CAAC,CAAC,+BAA+B,EAAE,oBAAoB;AACzD,sCAAE,CAAC,CAAC,yBAAyB,EAAE,kBAAkB,CAAC,EAAA,CAC9C,EACRA,GAAA,CAAC,QAAQ,EAAA,EAAC,SAAS,EAAC,uCAAuC,YACxD;AACC,sCAAE,CAAC,CACC,kCAAkC,EAClC,0EAA0E;sCAE5E,CAAC,CACC,4BAA4B,EAC5B,mEAAmE,CACpE,EAAA,CACI,CAAA,EAAA,CACP,EAENA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,QAAQ,EAAA,QAAA,EACrBA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,WAAW,EAAA,QAAA,EACvB,eAAe,CAAC,GAAG,CAClB,UAAC,IAAI,EAAE,KAAK,EAAA;gCACV,OAAA,IAAI,CAAC,GAAG,KACNC,IAAA,CAAA,KAAA,EAAA,EAAiB,SAAS,EAAC,kBAAkB,EAAA,QAAA,EAAA,CAC3CD,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yBAAyB,YACrC,QAAQ,IAAI,KAAK,KAAK,WAAW;;AAEhC,4CAAAA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,+FAA+F,EAAA,QAAA,EAAA,QAAA,EAAA,CAExG,IACJ,KAAK,GAAG,WAAW;;AAErB,4CAAAA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,uFAAuF,EAAA,QAAA,EAAA,QAAA,EAAA,CAEhG,IACJ,KAAK,KAAK,WAAW;;AAEvB,4CAAAA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,0HAA0H,GAAO;;4CAGhJA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,+CAA+C,EAAA,CAAO,CACtE,EAAA,CACG,EACNC,cAAK,SAAS,EAAC,gBAAgB,EAAA,QAAA,EAAA,CAC7BD,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAC,oCAAoC,YAC9C,CAAC,CAAC,kCAA2B,IAAI,CAAC,GAAG,EAAA,QAAA,CAAQ,CAAC,GAC7C,EACJA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAC,4BAA4B,YACtC,CAAC,CAAC,kCAA2B,IAAI,CAAC,GAAG,EAAA,WAAA,CAAW,CAAC,GAChD,CAAA,EAAA,CACA,CAAA,EAAA,EA3BE,KAAK,CA4BT,CACP;AA9BD,4BAAA,CA8BC,CACJ,EAAA,CACG,EAAA,CACF,EAENC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,QAAQ,EAAA,QAAA,EAAA,CACrBD,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,8BAA8B,YAC3CA,GAAA,CAAA,KAAA,EAAA,EACE,SAAS,EACP;AACE,0CAAE;AACF,0CAAE,oEAAoE,EAE1E,KAAK,EAAE;AACL,wCAAA,KAAK,EAAE,EAAA,CAAA,MAAA,CACL,CAAC,CAAC,WAAW,GAAG,CAAC,IAAI,eAAe,CAAC,MAAM,IAAI,GAAG,EAAA,GAAA,CACjD;qCACJ,EAAA,CACI,EAAA,CACH,EACNA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAC,wCAAwC,EAAA,QAAA,EAClD,CAAC,CAAC,2BAA2B,EAAE;oCAC9B,OAAO,EAAE,WAAW,GAAG,CAAC;oCACxB,KAAK,EAAE,eAAe,CAAC,MAAM;iCAC9B,CAAC,EAAA,CACA,CAAA,EAAA,CACA,EAGL,QAAQ,KACPA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,8DAA8D,EAAA,QAAA,EAC3EC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,yBAAyB,EAAA,QAAA,EAAA,CAEtCA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mCAAmC,EAAA,QAAA,EAAA,CAC/C,gBAAgB,KACfD,GAAA,CAAC,aAAa,EAAA,EAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAE,gBAAgB,EAAA,QAAA,EACjD,CAAC,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,EAAA,CACzC,CACjB,EACDA,GAAA,CAAC,aAAa,EAAA,EAAC,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,QAAQ,EAAA,QAAA,EAC7C,CAAC,CAAC,4BAA4B,EAAE,qBAAqB,CAAC,EAAA,CACzC,CAAA,EAAA,CACZ,EAGNC,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAC,mDAAmD,EAAA,QAAA,EAAA,CAC/D,gBAAgB,KACfD,GAAA,CAAC,aAAa,IAAC,IAAI,EAAC,MAAM,EAAC,OAAO,EAAE,gBAAgB,EAAA,QAAA,EACjD,CAAC,CAAC,wBAAwB,EAAE,yBAAyB,CAAC,GACzC,CACjB,EACDA,GAAA,CAAC,aAAa,EAAA,EAAC,IAAI,EAAC,UAAU,EAAC,OAAO,EAAE,QAAQ,EAAA,QAAA,EAC7C,CAAC,CAAC,4BAA4B,EAAE,qBAAqB,CAAC,EAAA,CACzC,CAAA,EAAA,CACZ,CAAA,EAAA,CACF,EAAA,CACF,CACP,CAAA,EAAA,CACG,EAAA,CACF,EAAA,CACF;AAEV;;;;"}
1
+ {"version":3,"file":"SelfieProcessing.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieProcessing.tsx"],"sourcesContent":["import { useState, useEffect, useRef } from \"react\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport { codeToStep } from \"../../../services/utils\";\nimport type { SelfieCaptureData } from \"../../../types/selfie\";\nimport { analyzeSelfie } from \"../../../services/analysis\";\nimport { getActiveSessionId } from \"../../../services/sessionMemoryStore\";\nimport ButtonDesktop from \"../../ui/ButtonDesktop\";\nimport { reportSelfieFailure } from \"../../../services/sessionService\";\n\ninterface SelfieProcessingProps {\n onProcessingComplete: (success: boolean) => void;\n selfieVideo: SelfieCaptureData | null;\n selfiePhoto: string | null;\n onRetake: () => void;\n onContinueAnyway?: () => void;\n nodeId: string;\n}\n\nconst processingSteps = [\n { key: \"analysis\" },\n { key: \"face_detection\" },\n { key: \"liveness\" },\n { key: \"finalization\" },\n];\nconst SelfieProcessing = ({\n onProcessingComplete,\n selfieVideo,\n selfiePhoto,\n onRetake,\n onContinueAnyway,\n nodeId,\n}: SelfieProcessingProps) => {\n const { t } = useI18n();\n const [currentStep, setCurrentStep] = useState(0);\n const [hasError, setHasError] = useState(false);\n const [isDone, setIsDone] = useState(false);\n const [conformityCode, setConformityCode] = useState<string | null>(null);\n\n const analysisStartedRef = useRef(false);\n useEffect(() => {\n // Prevent multiple analysis runs\n if (analysisStartedRef.current) return;\n if (!selfieVideo || !selfiePhoto) return;\n\n analysisStartedRef.current = true;\n\n // Timeout simple : 60 secondes pour tous\n const timeoutId = setTimeout(() => {\n if (!isDone) {\n console.error(\"⏰ Selfie analysis timeout after 60 seconds\");\n const sessionId = getActiveSessionId();\n if (sessionId) {\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"timeout\",\n }).catch(() => undefined);\n }\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n }, 60000);\n\n const processFiles = async () => {\n const sessionId = getActiveSessionId();\n if (!sessionId) {\n console.error(\"❌ No session ID found\");\n setHasError(true);\n onProcessingComplete(false);\n setIsDone(true);\n clearTimeout(timeoutId);\n return;\n }\n\n console.log(\"🚀 Starting selfie analysis...\");\n\n try {\n // Délai minimum simple : 2 secondes\n const [response] = await Promise.all([\n analyzeSelfie(sessionId, selfieVideo, selfiePhoto, nodeId),\n new Promise((resolve) => setTimeout(resolve, 2000)),\n ]);\n\n console.log(\"✅ Analysis response:\", response);\n clearTimeout(timeoutId);\n\n // Handle Unissey response format\n let isSuccess = false;\n let conformityCodeToSet = \"4\"; // Default to error\n\n if (response && response.data) {\n // Check if analysis was successful based on real Unissey response structure\n const data = response.data;\n const details = data.details;\n const faceComparison = details?.face_comparison;\n\n // Success: face match with high confidence\n if (\n data.is_match &&\n faceComparison?.result === \"match\"\n // faceComparison?.confidence_level === \"high\" Pas assez explicit\n ) {\n isSuccess = true;\n conformityCodeToSet = \"1.0\"; // Success code\n } else if (details) {\n // Check specific failure reasons\n if (faceComparison?.result !== \"match\") {\n conformityCodeToSet = \"2.0\"; // Face comparison failed\n } else if (faceComparison?.confidence_level !== \"high\") {\n conformityCodeToSet = \"3.0\"; // Low confidence\n } else {\n conformityCodeToSet = \"4.0\"; // Generic error\n }\n }\n }\n\n console.log(\"📊 Selfie analysis result:\", {\n isSuccess,\n conformityCode: conformityCodeToSet,\n isMatch: response?.data?.is_match,\n confidenceLevel:\n response?.data?.details?.face_comparison?.confidence_level,\n comparisonResult: response?.data?.details?.face_comparison?.result,\n });\n\n setConformityCode(conformityCodeToSet);\n setIsDone(true);\n\n // Don't call onProcessingComplete here - let the animation effect handle it\n } catch (error) {\n console.error(\"💥 Selfie analysis failed:\", error);\n void reportSelfieFailure(sessionId, {\n nodeId,\n reason: \"network_error\",\n }).catch(() => undefined);\n clearTimeout(timeoutId);\n setHasError(true);\n setIsDone(true);\n onProcessingComplete(false);\n }\n };\n\n processFiles();\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [onProcessingComplete, selfieVideo, selfiePhoto, isDone, nodeId]);\n\n useEffect(() => {\n // While analysis is not finished, stay at step 0\n if (!isDone && !hasError) {\n setCurrentStep(0);\n return;\n }\n // We want stepToStop to be the step in error (the one corresponding to conformityCode)\n let stepToStop = codeToStep(conformityCode || \"4\");\n // If codeToStep returns 0 (generic error), stop at the first step\n if (stepToStop === 0) stepToStop = 1;\n console.log(\"Step to stop (error):\", stepToStop);\n\n // When analysis is finished (success or error), start the animation\n const interval = setInterval(() => {\n setCurrentStep((prev) => {\n if (prev < stepToStop - 1) {\n return prev + 1;\n } else {\n clearInterval(interval);\n if (stepToStop < 4) setHasError(true);\n onProcessingComplete(stepToStop === 4);\n return prev; // Stop at the step in error\n }\n });\n }, 500); // Adjust the speed of the animation\n return () => clearInterval(interval);\n }, [onProcessingComplete, hasError, isDone, conformityCode]);\n\n return (\n <div className=\"flex flex-col justify-between h-full w-full\">\n <div className=\"flex-1 px-4 py-6 pt-11 md:px-8 md:py-8\">\n <div className=\"w-full max-w-md mx-auto space-y-6\">\n <div className=\"text-center space-y-4\">\n <Title className=\"text-xl md:text-2xl lg:text-3xl\">\n {hasError\n ? t(\"selfie.processing.error_title\", \"Échec de l'analyse\")\n : t(\"selfie.processing.title\", \"Analyse en cours\")}\n </Title>\n <Subtitle className=\"text-sm text-gray-600 leading-relaxed\">\n {hasError\n ? t(\n \"selfie.processing.error_subtitle\",\n \"Une erreur est survenue lors de l'analyse du selfie. Veuillez réessayer.\",\n )\n : t(\n \"selfie.processing.subtitle\",\n \"Nous analysons votre selfie. Cela peut prendre quelques instants.\",\n )}\n </Subtitle>\n </div>\n\n <div className=\"w-full\">\n <div className=\"space-y-5\">\n {processingSteps.map(\n (step, index) =>\n step.key && (\n <div key={index} className=\"flex items-start\">\n <div className=\"mr-4 mt-1 flex-shrink-0\">\n {hasError && index === currentStep ? (\n // Step in error - red cross\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-red-500 text-white text-xs font-bold\">\n ×\n </div>\n ) : index < currentStep ? (\n // Completed step - green check\n <div className=\"flex items-center justify-center w-6 h-6 rounded-full bg-[#11E5C5] text-white text-xs\">\n ✓\n </div>\n ) : index === currentStep ? (\n // Current step - spinner\n <div className=\"w-6 h-6 rounded-full border-2 border-t-[#11E5C5] border-r-[#11E5C5] border-b-[#11E5C5] border-l-transparent animate-spin\"></div>\n ) : (\n // Upcoming step - gray circle\n <div className=\"w-6 h-6 rounded-full border-2 border-gray-300\"></div>\n )}\n </div>\n <div className=\"flex-1 min-w-0\">\n <p className=\"font-medium text-[#3C3C40] text-sm\">\n {t(`selfie.processing.steps.${step.key}.title`)}\n </p>\n <p className=\"text-xs text-gray-500 mt-1\">\n {t(`selfie.processing.steps.${step.key}.subtitle`)}\n </p>\n </div>\n </div>\n ),\n )}\n </div>\n </div>\n\n <div className=\"w-full\">\n <div className=\"bg-gray-200 rounded-full h-2\">\n <div\n className={\n hasError\n ? \"bg-red-500 h-2 rounded-full transition-all duration-500 ease-out\"\n : \"bg-[#11E5C5] h-2 rounded-full transition-all duration-500 ease-out\"\n }\n style={{\n width: `${\n ((currentStep + 1) / processingSteps.length) * 100\n }%`,\n }}\n ></div>\n </div>\n <p className=\"text-xs text-gray-500 mt-2 text-center\">\n {t(\"selfie.processing.step_of\", {\n current: currentStep + 1,\n total: processingSteps.length,\n })}\n </p>\n </div>\n\n {/* Footer with buttons */}\n {hasError && (\n <div className=\"sticky bottom-0 bg-white border-t border-gray-100 p-4 md:p-6\">\n <div className=\"w-full max-w-md mx-auto\">\n {/* Mobile layout - stacked buttons */}\n <div className=\"flex flex-col space-y-3 md:hidden\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n\n {/* Desktop layout - horizontal buttons */}\n <div className=\"hidden md:flex gap-3 justify-between items-center\">\n {onContinueAnyway && (\n <ButtonDesktop type=\"back\" onClick={onContinueAnyway}>\n {t(\"errors.continue_anyway\", \"Poursuivre tout de même\")}\n </ButtonDesktop>\n )}\n <ButtonDesktop type=\"continue\" onClick={onRetake}>\n {t(\"selfie.confirmation.retake\", \"Reprendre le selfie\")}\n </ButtonDesktop>\n </div>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieProcessing;\n"],"names":["_jsx","_jsxs"],"mappings":"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"}