datakeen-session-react 1.1.195-dev.5 → 1.1.195-dev.7

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 (68) hide show
  1. package/dist/cjs/components/document-collection/DocumentError.js +5 -1
  2. package/dist/cjs/components/document-collection/DocumentError.js.map +1 -1
  3. package/dist/cjs/components/document-collection/DocumentProcessing.js +13 -11
  4. package/dist/cjs/components/document-collection/DocumentProcessing.js.map +1 -1
  5. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js +9 -5
  6. package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
  7. package/dist/cjs/components/jdi/JDIError.js +5 -1
  8. package/dist/cjs/components/jdi/JDIError.js.map +1 -1
  9. package/dist/cjs/components/jdi/JDIProcessing.js +15 -14
  10. package/dist/cjs/components/jdi/JDIProcessing.js.map +1 -1
  11. package/dist/cjs/components/selfie/Video.js +2 -2
  12. package/dist/cjs/components/selfie/Video.js.map +1 -1
  13. package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js +2 -2
  14. package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
  15. package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
  16. package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
  17. package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js +123 -13
  18. package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
  19. package/dist/cjs/components/session/Selfie.js +1 -1
  20. package/dist/cjs/components/session/Selfie.js.map +1 -1
  21. package/dist/cjs/i18n/en.json.js +3 -1
  22. package/dist/cjs/i18n/en.json.js.map +1 -1
  23. package/dist/cjs/i18n/es.json.js +3 -1
  24. package/dist/cjs/i18n/es.json.js.map +1 -1
  25. package/dist/cjs/i18n/fr.json.js +3 -1
  26. package/dist/cjs/i18n/fr.json.js.map +1 -1
  27. package/dist/cjs/services/analysis.js +40 -26
  28. package/dist/cjs/services/analysis.js.map +1 -1
  29. package/dist/cjs/services/iadService.js +30 -0
  30. package/dist/cjs/services/iadService.js.map +1 -0
  31. package/dist/cjs/types/session.js.map +1 -1
  32. package/dist/cjs/utils/analysisErrors.js +33 -12
  33. package/dist/cjs/utils/analysisErrors.js.map +1 -1
  34. package/dist/esm/components/document-collection/DocumentError.js +5 -1
  35. package/dist/esm/components/document-collection/DocumentError.js.map +1 -1
  36. package/dist/esm/components/document-collection/DocumentProcessing.js +14 -12
  37. package/dist/esm/components/document-collection/DocumentProcessing.js.map +1 -1
  38. package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js +9 -5
  39. package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
  40. package/dist/esm/components/jdi/JDIError.js +5 -1
  41. package/dist/esm/components/jdi/JDIError.js.map +1 -1
  42. package/dist/esm/components/jdi/JDIProcessing.js +16 -15
  43. package/dist/esm/components/jdi/JDIProcessing.js.map +1 -1
  44. package/dist/esm/components/selfie/Video.js +2 -2
  45. package/dist/esm/components/selfie/Video.js.map +1 -1
  46. package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js +2 -2
  47. package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
  48. package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
  49. package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
  50. package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js +124 -14
  51. package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
  52. package/dist/esm/components/session/Selfie.js +1 -1
  53. package/dist/esm/components/session/Selfie.js.map +1 -1
  54. package/dist/esm/i18n/en.json.js +3 -1
  55. package/dist/esm/i18n/en.json.js.map +1 -1
  56. package/dist/esm/i18n/es.json.js +3 -1
  57. package/dist/esm/i18n/es.json.js.map +1 -1
  58. package/dist/esm/i18n/fr.json.js +3 -1
  59. package/dist/esm/i18n/fr.json.js.map +1 -1
  60. package/dist/esm/services/analysis.js +40 -26
  61. package/dist/esm/services/analysis.js.map +1 -1
  62. package/dist/esm/services/iadService.js +28 -0
  63. package/dist/esm/services/iadService.js.map +1 -0
  64. package/dist/esm/types/session.js.map +1 -1
  65. package/dist/esm/utils/analysisErrors.js +30 -12
  66. package/dist/esm/utils/analysisErrors.js.map +1 -1
  67. package/docs/POLLING_SYSTEM.md +4 -0
  68. package/package.json +1 -1
@@ -16,21 +16,118 @@ var useLiveFrameCapture = require('../hooks/useLiveFrameCapture.js');
16
16
  var useI18n = require('../../../hooks/useI18n.js');
17
17
  var useIsMobile = require('../../../hooks/useIsMobile.js');
18
18
  var unisseyStrings = require('../utils/unisseyStrings.js');
19
+ var iadService = require('../../../services/iadService.js');
19
20
 
20
21
  var SelfieRecorder = function (_a) {
21
22
  var _b;
22
- var handleSelfie = _a.handleSelfie, _c = _a.onBeginCapture, onBeginCapture = _c === void 0 ? function () { } : _c, btnBg = _a.btnBg, btnText = _a.btnText;
23
+ var handleSelfie = _a.handleSelfie, _c = _a.onBeginCapture, onBeginCapture = _c === void 0 ? function () { } : _c, sessionId = _a.sessionId, iad = _a.iad, btnBg = _a.btnBg, btnText = _a.btnText;
23
24
  var t = useI18n.useI18n().t;
24
25
  var isMobile = useIsMobile.default(768);
25
26
  var recorderRef = React.useRef(null);
26
27
  var _d = React.useState(false), disableButton = _d[0], setDisableButton = _d[1];
27
28
  var _e = React.useState(false), recorderReady = _e[0], setRecorderReady = _e[1];
28
29
  var _f = React.useState("idle"), recordingState = _f[0], setRecordingState = _f[1];
30
+ var _g = React.useState(), iadConfig = _g[0], setIadConfig = _g[1];
31
+ var _h = React.useState((iad === null || iad === void 0 ? void 0 : iad.enabled) !== true), iadPreparationDone = _h[0], setIadPreparationDone = _h[1];
32
+ var _j = React.useState(), captureError = _j[0], setCaptureError = _j[1];
33
+ /**
34
+ * Préparation IAD déjà demandée pour une session, avec son résultat.
35
+ * `preparation` reste indéfini tant que la requête n'a pas abouti.
36
+ */
37
+ var preparedSessionRef = React.useRef();
29
38
  var recordingStateRef = React.useRef("idle");
30
39
  var lastRecorderStatusRef = React.useRef();
31
40
  var capturedThumbnailRef = React.useRef(null);
32
- var _g = useLiveFrameCapture.useLiveFrameCapture(), captureFrame = _g.captureFrame, cleanup = _g.cleanup;
41
+ var _k = useLiveFrameCapture.useLiveFrameCapture(), captureFrame = _k.captureFrame, cleanup = _k.cleanup;
33
42
  useVideoRecorderStyles.default(btnBg, btnText);
43
+ React.useEffect(function () {
44
+ var cancelled = false;
45
+ if ((iad === null || iad === void 0 ? void 0 : iad.enabled) !== true || !sessionId) {
46
+ setIadConfig(undefined);
47
+ setIadPreparationDone(true);
48
+ return function () {
49
+ cancelled = true;
50
+ };
51
+ }
52
+ /**
53
+ * La donnée de préparation est à USAGE UNIQUE : une seconde requête invalide
54
+ * la première et provoque des suspicions d'injection systématiques (doc
55
+ * Unissey, « False rejections possible root causes »). On ne prépare donc
56
+ * qu'une fois par session — ce garde neutralise aussi le double montage du
57
+ * StrictMode en développement.
58
+ */
59
+ /**
60
+ * La préparation est mémorisée par session : on ne redemande pas de donnée
61
+ * (usage unique côté Unissey), mais on réapplique le résultat déjà obtenu.
62
+ *
63
+ * C'est indispensable avec le double montage du StrictMode : au premier
64
+ * montage la requête part puis le démontage annule l'application du
65
+ * résultat ; sans réapplication ici, `iadPreparationDone` resterait
66
+ * définitivement `false` et le recorder ne serait jamais monté.
67
+ */
68
+ var cached = preparedSessionRef.current;
69
+ if ((cached === null || cached === void 0 ? void 0 : cached.sessionId) === sessionId) {
70
+ if (cached.preparation)
71
+ setIadConfig(cached.preparation);
72
+ setIadPreparationDone(true);
73
+ return function () {
74
+ cancelled = true;
75
+ };
76
+ }
77
+ var entry = { sessionId: sessionId };
78
+ preparedSessionRef.current = entry;
79
+ setIadConfig(undefined);
80
+ setIadPreparationDone(false);
81
+ void iadService.prepareIadCapture(sessionId)
82
+ .then(function (preparation) {
83
+ var config = {
84
+ mode: preparation.mode,
85
+ data: preparation.data,
86
+ };
87
+ // Mémorisé même si ce montage est annulé : le montage suivant le
88
+ // réappliquera sans consommer une nouvelle donnée.
89
+ entry.preparation = config;
90
+ if (!cancelled)
91
+ setIadConfig(config);
92
+ })
93
+ .catch(function (error) {
94
+ // Seul le message est loggué : l'objet d'erreur Axios embarque la
95
+ // requête (en-têtes d'authentification, URL avec identifiant de session).
96
+ console.warn("[IAD prepare failed]", error instanceof Error ? error.message : "unknown error");
97
+ // Fail open for capture: the backend will keep the IAD verdict
98
+ // inconclusive if a trustworthy signal cannot be produced.
99
+ // Aucune donnée n'a été consommée : on libère le garde pour permettre
100
+ // une nouvelle tentative au prochain montage.
101
+ if (preparedSessionRef.current === entry) {
102
+ preparedSessionRef.current = undefined;
103
+ }
104
+ })
105
+ .finally(function () {
106
+ // Volontairement sans garde `cancelled` : le drapeau doit passer à
107
+ // `true` même si ce montage est annulé, sinon le recorder reste bloqué.
108
+ setIadPreparationDone(true);
109
+ });
110
+ return function () {
111
+ cancelled = true;
112
+ };
113
+ }, [iad === null || iad === void 0 ? void 0 : iad.enabled, sessionId]);
114
+ /**
115
+ * La prop `config` doit être STABLE entre les rendus.
116
+ *
117
+ * `VideoRecorder` est un web-component Lit : un nouvel objet à chaque rendu
118
+ * est vu comme une prop modifiée, ce qui réinitialise le recorder — il
119
+ * recharge alors ses modules WASM et redemande une préparation IAD, en
120
+ * boucle. Sans ce mémo, l'écran de capture ne devient jamais prêt.
121
+ */
122
+ /**
123
+ * L'IAD est-elle attendue pour cette capture ET techniquement obtenable ?
124
+ *
125
+ * Sert à retarder le montage du recorder jusqu'à ce que `iadConfig` soit
126
+ * prête. Repasse à `false` si la préparation a échoué (`preparedSessionRef`
127
+ * libéré par le `catch`) : la capture démarre alors sans IAD plutôt que de
128
+ * rester bloquée — le backend produira un verdict `inconclusive`.
129
+ */
130
+ var recorderConfig = React.useMemo(function () { return (iadConfig ? { iadConfig: iadConfig } : undefined); }, [iadConfig]);
34
131
  var updateRecordingState = React.useCallback(function (state) {
35
132
  recordingStateRef.current = state;
36
133
  setRecordingState(state);
@@ -55,14 +152,6 @@ var SelfieRecorder = function (_a) {
55
152
  React.useEffect(function () {
56
153
  document.body.classList.add("recording-selfie");
57
154
  var cleanupObserver = videoElementStyles.setupVideoElementsObserver();
58
- // Les traducteurs automatiques (Safari iOS notamment) réécrivent le DOM et
59
- // détruisent les marqueurs de template Lit du web component Unissey : la capture
60
- // ne redémarre alors plus jamais. React sérialise `translate` en propriété DOM sur
61
- // un custom element (d'où un translate="yes" parasite), il faut poser l'attribut
62
- // impérativement.
63
- document
64
- .querySelectorAll("uni-video-recorder")
65
- .forEach(function (el) { return el.setAttribute("translate", "no"); });
66
155
  // iOS-specific fix: Add required attributes to video elements after mount
67
156
  if (selfieCaptureUtils.isIOS()) {
68
157
  var addIOSVideoAttributes = function () {
@@ -111,10 +200,24 @@ var SelfieRecorder = function (_a) {
111
200
  cleanup();
112
201
  };
113
202
  }, [cleanup]);
203
+ // Les traducteurs automatiques (Safari iOS notamment) réécrivent le DOM et
204
+ // détruisent les marqueurs de template Lit du web component Unissey : la capture
205
+ // ne redémarre alors plus jamais. React sérialise `translate` en propriété DOM sur
206
+ // un custom element (d'où un translate="yes" parasite), il faut poser l'attribut
207
+ // impérativement. Le recorder n'étant monté qu'une fois la préparation IAD
208
+ // terminée, l'attribut est posé à ce moment-là (et non au montage du composant).
209
+ React.useEffect(function () {
210
+ if (!iadPreparationDone)
211
+ return;
212
+ document
213
+ .querySelectorAll("uni-video-recorder")
214
+ .forEach(function (el) { return el.setAttribute("translate", "no"); });
215
+ }, [iadPreparationDone]);
114
216
  var recordStarting = function () {
115
217
  if (!recorderReady || recordingState !== "idle")
116
218
  return;
117
219
  onBeginCapture();
220
+ setCaptureError(undefined);
118
221
  updateRecordingState("preparing");
119
222
  setDisableButton(true);
120
223
  var triggerCapture = function () { return tslib_es6.__awaiter(void 0, void 0, void 0, function () {
@@ -171,10 +274,14 @@ var SelfieRecorder = function (_a) {
171
274
  return function () { return clearInterval(interval); };
172
275
  }, [resetCaptureControlsFromPolling]);
173
276
  var handleRecorderReady = function () {
277
+ setCaptureError(undefined);
174
278
  setRecorderReady(true);
175
279
  resetCaptureControls();
176
280
  };
177
281
  var handleRecordInterrupted = function () {
282
+ var _a;
283
+ var recorderError = (_a = recorderRef.current) === null || _a === void 0 ? void 0 : _a.error;
284
+ setCaptureError(recorderError || t("unissey.forbiddenActionMessages.default"));
178
285
  resetCaptureControls();
179
286
  };
180
287
  var handleRecordCompleted = function (e) {
@@ -217,11 +324,14 @@ var SelfieRecorder = function (_a) {
217
324
  _b.zIndex = isMobile ? 50 : "auto",
218
325
  _b.height = "100%",
219
326
  _b.width = "100%",
220
- _b), children: [jsxRuntime.jsxs("div", { className: "p-4 text-center bg-white shrink-0", children: [jsxRuntime.jsx(Title.default, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsxRuntime.jsx(Subtitle.default, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsxRuntime.jsx("div", { className: "video-container flex-1 relative overflow-hidden", children: jsxRuntime.jsx(sdkReact.VideoRecorder, tslib_es6.__assign({ ref: recorderRef, preset: sdkReact.AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: (typeof window !== 'undefined' && window.__E2E_DISABLE_FACE_CHECKER__) ? 'disabled' : 'enabled', disableDebugMode: true, onRecorderReady: handleRecorderReady, onRecordInterrupted: handleRecordInterrupted, onRecordCompleted: handleRecordCompleted, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius notranslate w-full h-full" }, (selfieCaptureUtils.isIOS() && {
327
+ _b), children: [jsxRuntime.jsxs("div", { className: "p-4 text-center bg-white shrink-0", children: [jsxRuntime.jsx(Title.default, { className: "text-lg md:text-xl mb-1", children: t("selfie.recorder.title") }), jsxRuntime.jsx(Subtitle.default, { className: "text-xs text-gray-600 md:text-sm", children: t("selfie.recorder.subtitle") })] }), jsxRuntime.jsx("div", { className: "video-container flex-1 relative overflow-hidden", children: iadPreparationDone && (jsxRuntime.jsx(sdkReact.VideoRecorder, tslib_es6.__assign({ ref: recorderRef, preset: sdkReact.AcquisitionPreset.SELFIE_OPTIMIZED, hideCaptureBtn: true, faceChecker: typeof window !== "undefined" &&
328
+ window.__E2E_DISABLE_FACE_CHECKER__
329
+ ? "disabled"
330
+ : "enabled", disableDebugMode: true }, (recorderConfig ? { config: recorderConfig } : {}), { onRecorderReady: handleRecorderReady, onRecordInterrupted: handleRecordInterrupted, onRecordCompleted: handleRecordCompleted, style: { width: "100%", height: "100%" }, className: "video-recorder-no-radius notranslate w-full h-full" }, (selfieCaptureUtils.isIOS() && {
221
331
  "data-playsinline": "true",
222
332
  "data-autoplay": "true",
223
- "data-muted": "true"
224
- }), { strings: unisseyStrings.getUnisseyStrings(t) })) }), jsxRuntime.jsx("div", { className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative", style: { zIndex: 9999 }, children: jsxRuntime.jsxs("div", { className: "max-w-md mx-auto", children: [jsxRuntime.jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxRuntime.jsxs(Button.default, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, style: { backgroundColor: btnBg !== null && btnBg !== void 0 ? btnBg : "#11E5C5", color: btnText !== null && btnText !== void 0 ? btnText : "#3C3C40" }, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxRuntime.jsxs("span", { className: "flex items-center justify-center", children: [jsxRuntime.jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxRuntime.jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
333
+ "data-muted": "true",
334
+ }), { strings: unisseyStrings.getUnisseyStrings(t) }))) }), captureError && (jsxRuntime.jsx("div", { role: "alert", className: "shrink-0 bg-red-50 px-4 py-2 text-center text-sm text-red-700", children: captureError })), jsxRuntime.jsx("div", { className: "shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative", style: { zIndex: 9999 }, children: jsxRuntime.jsxs("div", { className: "max-w-md mx-auto", children: [jsxRuntime.jsx("div", { className: "text-center text-xs text-gray-400 mt-3", children: t("selfie.recorder.note") }), jsxRuntime.jsxs(Button.default, { onClick: recordStarting, className: "w-full py-3 md:py-4 relative selfie-button", disabled: disableButton || !recorderReady, style: { backgroundColor: btnBg !== null && btnBg !== void 0 ? btnBg : "#11E5C5", color: btnText !== null && btnText !== void 0 ? btnText : "#3C3C40" }, children: [recordingState === "idle" && t("selfie.recorder.start"), recordingState === "preparing" && t("selfie.recorder.preparing"), recordingState === "recording" && (jsxRuntime.jsxs("span", { className: "flex items-center justify-center", children: [jsxRuntime.jsx("span", { className: "mr-2", children: t("selfie.recorder.recording_label") }), jsxRuntime.jsxs("span", { className: "flex space-x-1 loading-dots", children: [jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" }), jsxRuntime.jsx("span", { className: "h-1 w-1 bg-white rounded-full" })] })] })), recordingState === "processing" && t("selfie.recorder.processing")] })] }) })] }));
225
335
  };
226
336
 
227
337
  exports.default = SelfieRecorder;
@@ -1 +1 @@
1
- {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import {\n useCallback,\n useRef,\n useState,\n useEffect,\n type ElementRef,\n} 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 \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport useIsMobile from \"../../../hooks/useIsMobile\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\n\ntype RecordingState = \"idle\" | \"preparing\" | \"recording\" | \"processing\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n isCapturing?: boolean;\n btnBg?: string;\n btnText?: string;\n}\n\ntype VideoRecorderElement = ElementRef<typeof VideoRecorder>;\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n btnBg,\n btnText,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const isMobile = useIsMobile(768);\n const recorderRef = useRef<VideoRecorderElement | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<RecordingState>(\"idle\");\n const recordingStateRef = useRef<RecordingState>(\"idle\");\n const lastRecorderStatusRef = useRef<string | undefined>();\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles(btnBg, btnText);\n\n const updateRecordingState = useCallback((state: RecordingState) => {\n recordingStateRef.current = state;\n setRecordingState(state);\n }, []);\n\n const resetCaptureControls = useCallback(() => {\n capturedThumbnailRef.current = null;\n updateRecordingState(\"idle\");\n setDisableButton(false);\n }, [updateRecordingState]);\n\n // Réinitialisation déclenchée par le polling de statut Unissey.\n // Pendant une capture en cours (preparing/recording/processing), les transitions\n // internes du cycle d'enregistrement (starting → running → ready) ne doivent PAS\n // réactiver le bouton. Seule une perte réelle de la caméra (passage par\n // \"no-session\") justifie un reset pendant la capture (scénario retry caméra).\n const resetCaptureControlsFromPolling = useCallback(\n (previousStatus: string | undefined) => {\n if (\n recordingStateRef.current !== \"idle\" &&\n previousStatus !== \"no-session\"\n ) {\n return;\n }\n resetCaptureControls();\n },\n [resetCaptureControls]\n );\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\n const cleanupObserver = setupVideoElementsObserver();\n\n // Les traducteurs automatiques (Safari iOS notamment) réécrivent le DOM et\n // détruisent les marqueurs de template Lit du web component Unissey : la capture\n // ne redémarre alors plus jamais. React sérialise `translate` en propriété DOM sur\n // un custom element (d'où un translate=\"yes\" parasite), il faut poser l'attribut\n // impérativement.\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.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-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n updateRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n updateRecordingState(\"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(\"SelfieRecorder: failed to capture frame\", error);\n updateRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n useEffect(() => {\n const interval = setInterval(() => {\n const status = recorderRef.current?.sdkJsStatus;\n const isReady = status === \"ready\" || status === \"running\";\n setRecorderReady((prev) => (prev !== isReady ? isReady : prev));\n\n const previousStatus = lastRecorderStatusRef.current;\n const wasReady = previousStatus === \"ready\" || previousStatus === \"running\";\n if (status !== previousStatus) {\n lastRecorderStatusRef.current = status;\n if (isReady && previousStatus !== undefined && !wasReady) {\n resetCaptureControlsFromPolling(previousStatus);\n }\n }\n }, 500);\n return () => clearInterval(interval);\n }, [resetCaptureControlsFromPolling]);\n\n const handleRecorderReady = () => {\n setRecorderReady(true);\n resetCaptureControls();\n };\n\n const handleRecordInterrupted = () => {\n resetCaptureControls();\n };\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(\"🍎 iOS detected - checking video elements for proper attributes\");\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 updateRecordingState(\"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 }\n });\n\n updateRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div\n className=\"selfie selfie-recorder-root notranslate flex flex-col\"\n translate=\"no\"\n style={{\n [\"--dk-btn-bg\" as string]: btnBg ?? \"#11E5C5\",\n [\"--dk-btn-text\" as string]: btnText ?? \"#3C3C40\",\n position: isMobile ? \"fixed\" : \"relative\",\n inset: isMobile ? 0 : \"auto\",\n zIndex: isMobile ? 50 : \"auto\",\n height: \"100%\",\n width: \"100%\",\n }}\n >\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n <VideoRecorder\n ref={recorderRef}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker={(typeof window !== 'undefined' && window.__E2E_DISABLE_FACE_CHECKER__) ? 'disabled' : 'enabled'}\n disableDebugMode\n onRecorderReady={handleRecorderReady}\n onRecordInterrupted={handleRecordInterrupted}\n onRecordCompleted={handleRecordCompleted}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius notranslate w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\"\n })}\n strings={getUnisseyStrings(t)}\n />\n </div>\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n style={{ backgroundColor: btnBg ?? \"#11E5C5\", color: btnText ?? \"#3C3C40\" }}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</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\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["useI18n","useIsMobile","useRef","useState","useLiveFrameCapture","useVideoRecorderStyles","useCallback","useEffect","setupVideoElementsObserver","isIOS","__awaiter","waitForVideoFrame","delay","getRecorderVideoElement","_jsxs","_jsx","Title","Subtitle","VideoRecorder","AcquisitionPreset","getUnisseyStrings","Button"],"mappings":"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"}
1
+ {"version":3,"file":"SelfieRecorder.js","sources":["../../../../../../src/components/selfie/selfie-flow/SelfieRecorder.tsx"],"sourcesContent":["import {\n useCallback,\n useMemo,\n useRef,\n useState,\n useEffect,\n type ElementRef,\n} from \"react\";\nimport {\n AcquisitionPreset,\n VideoRecorder,\n type IadConfig,\n} from \"@unissey-web/sdk-react\";\nimport Button from \"../../ui/Button\";\nimport Title from \"../../ui/Title\";\nimport Subtitle from \"../../ui/Subtitle\";\nimport useVideoRecorderStyles from \"../hooks/useVideoRecorderStyles\";\nimport { setupVideoElementsObserver } from \"../utils/videoElementStyles\";\nimport { delay, isIOS, waitForVideoFrame, getRecorderVideoElement } from \"../utils/selfieCaptureUtils\";\nimport { useLiveFrameCapture } from \"../hooks/useLiveFrameCapture\";\nimport { useI18n } from \"../../../hooks/useI18n\";\nimport useIsMobile from \"../../../hooks/useIsMobile\";\nimport { getUnisseyStrings } from \"../utils/unisseyStrings\";\nimport { prepareIadCapture } from \"../../../services/iadService\";\n\ntype RecordingState = \"idle\" | \"preparing\" | \"recording\" | \"processing\";\n\ninterface SelfieRecorderProps {\n handleSelfie: (e: Event) => void;\n onBeginCapture?: () => void;\n sessionId?: string;\n iad?: { enabled: boolean; level?: \"basic\" | \"reinforced\" };\n isCapturing?: boolean;\n btnBg?: string;\n btnText?: string;\n}\n\ntype VideoRecorderElement = ElementRef<typeof VideoRecorder>;\ntype VideoRecorderWithError = VideoRecorderElement & { error?: string };\n\n/** Préparation IAD mémorisée pour une session (donnée à usage unique). */\ntype PreparedIadSession = {\n sessionId: string;\n preparation?: IadConfig;\n};\n\nconst SelfieRecorder = ({\n handleSelfie,\n onBeginCapture = () => { },\n sessionId,\n iad,\n btnBg,\n btnText,\n}: SelfieRecorderProps) => {\n const { t } = useI18n();\n const isMobile = useIsMobile(768);\n const recorderRef = useRef<VideoRecorderElement | null>(null);\n const [disableButton, setDisableButton] = useState(false);\n const [recorderReady, setRecorderReady] = useState(false);\n const [recordingState, setRecordingState] = useState<RecordingState>(\"idle\");\n const [iadConfig, setIadConfig] = useState<IadConfig>();\n const [iadPreparationDone, setIadPreparationDone] = useState(\n iad?.enabled !== true,\n );\n const [captureError, setCaptureError] = useState<string>();\n /**\n * Préparation IAD déjà demandée pour une session, avec son résultat.\n * `preparation` reste indéfini tant que la requête n'a pas abouti.\n */\n const preparedSessionRef = useRef<PreparedIadSession>();\n const recordingStateRef = useRef<RecordingState>(\"idle\");\n const lastRecorderStatusRef = useRef<string | undefined>();\n const capturedThumbnailRef = useRef<string | null>(null);\n const { captureFrame, cleanup } = useLiveFrameCapture();\n\n useVideoRecorderStyles(btnBg, btnText);\n\n useEffect(() => {\n let cancelled = false;\n\n if (iad?.enabled !== true || !sessionId) {\n setIadConfig(undefined);\n setIadPreparationDone(true);\n return () => {\n cancelled = true;\n };\n }\n\n /**\n * La donnée de préparation est à USAGE UNIQUE : une seconde requête invalide\n * la première et provoque des suspicions d'injection systématiques (doc\n * Unissey, « False rejections possible root causes »). On ne prépare donc\n * qu'une fois par session — ce garde neutralise aussi le double montage du\n * StrictMode en développement.\n */\n /**\n * La préparation est mémorisée par session : on ne redemande pas de donnée\n * (usage unique côté Unissey), mais on réapplique le résultat déjà obtenu.\n *\n * C'est indispensable avec le double montage du StrictMode : au premier\n * montage la requête part puis le démontage annule l'application du\n * résultat ; sans réapplication ici, `iadPreparationDone` resterait\n * définitivement `false` et le recorder ne serait jamais monté.\n */\n const cached = preparedSessionRef.current;\n if (cached?.sessionId === sessionId) {\n if (cached.preparation) setIadConfig(cached.preparation);\n setIadPreparationDone(true);\n return () => {\n cancelled = true;\n };\n }\n\n const entry: PreparedIadSession = { sessionId };\n preparedSessionRef.current = entry;\n\n setIadConfig(undefined);\n setIadPreparationDone(false);\n void prepareIadCapture(sessionId)\n .then((preparation) => {\n const config: IadConfig = {\n mode: preparation.mode,\n data: preparation.data,\n };\n // Mémorisé même si ce montage est annulé : le montage suivant le\n // réappliquera sans consommer une nouvelle donnée.\n entry.preparation = config;\n if (!cancelled) setIadConfig(config);\n })\n .catch((error: unknown) => {\n // Seul le message est loggué : l'objet d'erreur Axios embarque la\n // requête (en-têtes d'authentification, URL avec identifiant de session).\n console.warn(\n \"[IAD prepare failed]\",\n error instanceof Error ? error.message : \"unknown error\",\n );\n // Fail open for capture: the backend will keep the IAD verdict\n // inconclusive if a trustworthy signal cannot be produced.\n // Aucune donnée n'a été consommée : on libère le garde pour permettre\n // une nouvelle tentative au prochain montage.\n if (preparedSessionRef.current === entry) {\n preparedSessionRef.current = undefined;\n }\n })\n .finally(() => {\n // Volontairement sans garde `cancelled` : le drapeau doit passer à\n // `true` même si ce montage est annulé, sinon le recorder reste bloqué.\n setIadPreparationDone(true);\n });\n\n return () => {\n cancelled = true;\n };\n }, [iad?.enabled, sessionId]);\n\n /**\n * La prop `config` doit être STABLE entre les rendus.\n *\n * `VideoRecorder` est un web-component Lit : un nouvel objet à chaque rendu\n * est vu comme une prop modifiée, ce qui réinitialise le recorder — il\n * recharge alors ses modules WASM et redemande une préparation IAD, en\n * boucle. Sans ce mémo, l'écran de capture ne devient jamais prêt.\n */\n /**\n * L'IAD est-elle attendue pour cette capture ET techniquement obtenable ?\n *\n * Sert à retarder le montage du recorder jusqu'à ce que `iadConfig` soit\n * prête. Repasse à `false` si la préparation a échoué (`preparedSessionRef`\n * libéré par le `catch`) : la capture démarre alors sans IAD plutôt que de\n * rester bloquée — le backend produira un verdict `inconclusive`.\n */\n const recorderConfig = useMemo(\n () => (iadConfig ? { iadConfig } : undefined),\n [iadConfig],\n );\n\n const updateRecordingState = useCallback((state: RecordingState) => {\n recordingStateRef.current = state;\n setRecordingState(state);\n }, []);\n\n const resetCaptureControls = useCallback(() => {\n capturedThumbnailRef.current = null;\n updateRecordingState(\"idle\");\n setDisableButton(false);\n }, [updateRecordingState]);\n\n // Réinitialisation déclenchée par le polling de statut Unissey.\n // Pendant une capture en cours (preparing/recording/processing), les transitions\n // internes du cycle d'enregistrement (starting → running → ready) ne doivent PAS\n // réactiver le bouton. Seule une perte réelle de la caméra (passage par\n // \"no-session\") justifie un reset pendant la capture (scénario retry caméra).\n const resetCaptureControlsFromPolling = useCallback(\n (previousStatus: string | undefined) => {\n if (\n recordingStateRef.current !== \"idle\" &&\n previousStatus !== \"no-session\"\n ) {\n return;\n }\n resetCaptureControls();\n },\n [resetCaptureControls]\n );\n\n useEffect(() => {\n document.body.classList.add(\"recording-selfie\");\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.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-selfie\");\n cleanupObserver();\n cleanup();\n clearTimeout(iosTimeout);\n clearInterval(iosInterval);\n };\n }\n\n return () => {\n document.body.classList.remove(\"recording-selfie\");\n cleanupObserver();\n cleanup();\n };\n }, [cleanup]);\n\n // Les traducteurs automatiques (Safari iOS notamment) réécrivent le DOM et\n // détruisent les marqueurs de template Lit du web component Unissey : la capture\n // ne redémarre alors plus jamais. React sérialise `translate` en propriété DOM sur\n // un custom element (d'où un translate=\"yes\" parasite), il faut poser l'attribut\n // impérativement. Le recorder n'étant monté qu'une fois la préparation IAD\n // terminée, l'attribut est posé à ce moment-là (et non au montage du composant).\n useEffect(() => {\n if (!iadPreparationDone) return;\n document\n .querySelectorAll(\"uni-video-recorder\")\n .forEach((el) => el.setAttribute(\"translate\", \"no\"));\n }, [iadPreparationDone]);\n\n const recordStarting = () => {\n if (!recorderReady || recordingState !== \"idle\") return;\n onBeginCapture();\n setCaptureError(undefined);\n updateRecordingState(\"preparing\");\n setDisableButton(true);\n\n const triggerCapture = async () => {\n try {\n await waitForVideoFrame(recorderRef.current);\n await delay(200);\n updateRecordingState(\"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(\"SelfieRecorder: failed to capture frame\", error);\n updateRecordingState(\"idle\");\n setDisableButton(false);\n }\n };\n\n void triggerCapture();\n };\n\n useEffect(() => {\n const interval = setInterval(() => {\n const status = recorderRef.current?.sdkJsStatus;\n const isReady = status === \"ready\" || status === \"running\";\n setRecorderReady((prev) => (prev !== isReady ? isReady : prev));\n\n const previousStatus = lastRecorderStatusRef.current;\n const wasReady = previousStatus === \"ready\" || previousStatus === \"running\";\n if (status !== previousStatus) {\n lastRecorderStatusRef.current = status;\n if (isReady && previousStatus !== undefined && !wasReady) {\n resetCaptureControlsFromPolling(previousStatus);\n }\n }\n }, 500);\n return () => clearInterval(interval);\n }, [resetCaptureControlsFromPolling]);\n\n const handleRecorderReady = () => {\n setCaptureError(undefined);\n setRecorderReady(true);\n resetCaptureControls();\n };\n\n const handleRecordInterrupted = () => {\n const recorderError = (recorderRef.current as VideoRecorderWithError | null)?.error;\n setCaptureError(\n recorderError || t(\"unissey.forbiddenActionMessages.default\"),\n );\n resetCaptureControls();\n };\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(\"🍎 iOS detected - checking video elements for proper attributes\");\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 updateRecordingState(\"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 }\n });\n\n updateRecordingState(\"processing\");\n handleSelfie(enhancedEvent);\n };\n\n return (\n <div\n className=\"selfie selfie-recorder-root notranslate flex flex-col\"\n translate=\"no\"\n style={{\n [\"--dk-btn-bg\" as string]: btnBg ?? \"#11E5C5\",\n [\"--dk-btn-text\" as string]: btnText ?? \"#3C3C40\",\n position: isMobile ? \"fixed\" : \"relative\",\n inset: isMobile ? 0 : \"auto\",\n zIndex: isMobile ? 50 : \"auto\",\n height: \"100%\",\n width: \"100%\",\n }}\n >\n <div className=\"p-4 text-center bg-white shrink-0\">\n <Title className=\"text-lg md:text-xl mb-1\">{t(\"selfie.recorder.title\")}</Title>\n <Subtitle className=\"text-xs text-gray-600 md:text-sm\">{t(\"selfie.recorder.subtitle\")}</Subtitle>\n </div>\n\n <div className=\"video-container flex-1 relative overflow-hidden\">\n {/* Le recorder ne doit monter QU'UNE FOIS la config IAD disponible.\n Unissey réinitialise sa session interne dès que la prop `config`\n change (`updated()` → `callInitSession()`). Monter sans config puis\n l'injecter créerait une première session SANS IAD — donc sans\n `selfie-metadata` — avant de la recréer. On attend donc que la\n préparation soit terminée ET, quand l'IAD est active, que sa config\n soit prête. */}\n {iadPreparationDone && (\n <VideoRecorder\n ref={recorderRef}\n preset={AcquisitionPreset.SELFIE_OPTIMIZED}\n hideCaptureBtn\n faceChecker={\n typeof window !== \"undefined\" &&\n window.__E2E_DISABLE_FACE_CHECKER__\n ? \"disabled\"\n : \"enabled\"\n }\n disableDebugMode\n {...(recorderConfig ? { config: recorderConfig } : {})}\n onRecorderReady={handleRecorderReady}\n onRecordInterrupted={handleRecordInterrupted}\n onRecordCompleted={handleRecordCompleted}\n style={{ width: \"100%\", height: \"100%\" }}\n className=\"video-recorder-no-radius notranslate w-full h-full\"\n {...(isIOS() && {\n \"data-playsinline\": \"true\",\n \"data-autoplay\": \"true\",\n \"data-muted\": \"true\",\n })}\n strings={getUnisseyStrings(t)}\n />\n )}\n </div>\n\n {captureError && (\n <div role=\"alert\" className=\"shrink-0 bg-red-50 px-4 py-2 text-center text-sm text-red-700\">\n {captureError}\n </div>\n )}\n\n <div className=\"shrink-0 bg-white border-t border-gray-200 p-4 md:p-6 relative\" style={{ zIndex: 9999 }}>\n <div className=\"max-w-md mx-auto\">\n <div className=\"text-center text-xs text-gray-400 mt-3\">\n {t(\"selfie.recorder.note\")}\n </div>\n\n <Button\n onClick={recordStarting}\n className=\"w-full py-3 md:py-4 relative selfie-button\"\n disabled={disableButton || !recorderReady}\n style={{ backgroundColor: btnBg ?? \"#11E5C5\", color: btnText ?? \"#3C3C40\" }}\n >\n {recordingState === \"idle\" && t(\"selfie.recorder.start\")}\n {recordingState === \"preparing\" && t(\"selfie.recorder.preparing\")}\n {recordingState === \"recording\" && (\n <span className=\"flex items-center justify-center\">\n <span className=\"mr-2\">{t(\"selfie.recorder.recording_label\")}</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\" && t(\"selfie.recorder.processing\")}\n </Button>\n </div>\n </div>\n </div>\n );\n};\n\nexport default SelfieRecorder;\n"],"names":["useI18n","useIsMobile","useRef","useState","useLiveFrameCapture","useVideoRecorderStyles","useEffect","prepareIadCapture","useMemo","useCallback","setupVideoElementsObserver","isIOS","__awaiter","waitForVideoFrame","delay","getRecorderVideoElement","_jsxs","_jsx","Title","Subtitle","VideoRecorder","__assign","AcquisitionPreset","getUnisseyStrings","Button"],"mappings":"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"}
@@ -49,7 +49,7 @@ var Selfie = function (_a) {
49
49
  var handleRetakeSelfie = function () {
50
50
  setInternalStep(0);
51
51
  };
52
- return (jsxRuntime.jsxs("div", { className: "h-full w-full transition-opacity duration-500 ".concat(isTransitioning ? "opacity-50" : "opacity-100"), children: [internalStep === 0 && (jsxRuntime.jsx(Video.default, { setSelfieData: setSelfieData, setStep: setInternalStep, btnBg: (_b = template.buttonBgColor) !== null && _b !== void 0 ? _b : "#11E5C5", btnText: (_c = template.buttonTextColor) !== null && _c !== void 0 ? _c : "#3C3C40" })), internalStep === 1 && selfieData && (jsxRuntime.jsx(SelfieConfirmation.default, { selfieData: selfieData, onConfirm: handleConfirmSelfie, onRetake: handleRetakeSelfie, setSelfiePhoto: setSelfiePhoto })), internalStep === 2 && selfieData && (jsxRuntime.jsx(SelfieProcessing.default, { onProcessingComplete: selfieProcessed, selfieVideo: selfieData, selfiePhoto: selfiePhoto, onRetake: onRetake, nodeId: node.id, onContinueAnyway: node.allowContinueOnFailure === false
52
+ return (jsxRuntime.jsxs("div", { className: "h-full w-full transition-opacity duration-500 ".concat(isTransitioning ? "opacity-50" : "opacity-100"), children: [internalStep === 0 && (jsxRuntime.jsx(Video.default, { setSelfieData: setSelfieData, setStep: setInternalStep, sessionId: sessionId, iad: node.iad, btnBg: (_b = template.buttonBgColor) !== null && _b !== void 0 ? _b : "#11E5C5", btnText: (_c = template.buttonTextColor) !== null && _c !== void 0 ? _c : "#3C3C40" })), internalStep === 1 && selfieData && (jsxRuntime.jsx(SelfieConfirmation.default, { selfieData: selfieData, onConfirm: handleConfirmSelfie, onRetake: handleRetakeSelfie, setSelfiePhoto: setSelfiePhoto })), internalStep === 2 && selfieData && (jsxRuntime.jsx(SelfieProcessing.default, { onProcessingComplete: selfieProcessed, selfieVideo: selfieData, selfiePhoto: selfiePhoto, onRetake: onRetake, nodeId: node.id, onContinueAnyway: node.allowContinueOnFailure === false
53
53
  ? undefined
54
54
  : handleContinueAnyway }))] }));
55
55
  };
@@ -1 +1 @@
1
- {"version":3,"file":"Selfie.js","sources":["../../../../../src/components/session/Selfie.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n SessionTemplate,\n SessionTemplateNode,\n stepObject,\n} from \"../../types/session\";\nimport Video from \"../selfie/Video\";\nimport SelfieConfirmation from \"../selfie/SelfieConfirmation\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport SelfieProcessing from \"../selfie/selfie-flow/SelfieProcessing\";\nimport { reportSelfieFailure } from \"../../services/sessionService\";\n\n/**\n * Composant de gestion du flux selfie.\n * Gère les étapes internes de capture et confirmation du selfie.\n */\nconst Selfie = ({\n stepObject,\n sessionId,\n node,\n template,\n}: {\n stepObject: stepObject;\n sessionId: string;\n node: SessionTemplateNode;\n template: SessionTemplate;\n}) => {\n const [internalStep, setInternalStep] = useState(0);\n const [selfieData, setSelfieData] = useState<SelfieCaptureData | null>(null);\n const [selfiePhoto, setSelfiePhoto] = useState<string | null>(null);\n const [isTransitioning, setIsTransitioning] = useState(false);\n\n const handleConfirmSelfie = () => {\n // Ajouter une transition visuelle avant de passer à l'étape suivante\n setIsTransitioning(true);\n\n // Attendre un peu pour l'animation avant de passer à l'étape suivante\n setTimeout(() => {\n setInternalStep(2); // Passer à l'étape de traitement du selfie\n setIsTransitioning(false);\n }, 500);\n };\n\n const selfieProcessed = (processed: boolean) => {\n // Callback pour indiquer que le selfie a été traité\n if (processed) {\n stepObject.goToNextStepCommitted(node.id, template);\n }\n };\n\n const handleContinueAnyway = () => {\n void reportSelfieFailure(sessionId, {\n nodeId: node.id,\n reason: \"user_bypassed\",\n bypassed: true,\n }).catch(() => undefined);\n stepObject.goToNextStepCommitted(node.id, template);\n };\n\n const onRetake = () => {\n setInternalStep(0);\n };\n\n const handleRetakeSelfie = () => {\n setInternalStep(0);\n };\n\n return (\n <div\n className={`h-full w-full transition-opacity duration-500 ${isTransitioning ? \"opacity-50\" : \"opacity-100\"\n }`}\n >\n {internalStep === 0 && (\n <Video\n setSelfieData={setSelfieData}\n setStep={setInternalStep}\n btnBg={template.buttonBgColor ?? \"#11E5C5\"}\n btnText={template.buttonTextColor ?? \"#3C3C40\"}\n />\n )}\n {internalStep === 1 && selfieData && (\n <SelfieConfirmation\n selfieData={selfieData}\n onConfirm={handleConfirmSelfie}\n onRetake={handleRetakeSelfie}\n setSelfiePhoto={setSelfiePhoto}\n />\n )}\n {internalStep === 2 && selfieData && (\n <SelfieProcessing\n onProcessingComplete={selfieProcessed}\n selfieVideo={selfieData}\n selfiePhoto={selfiePhoto}\n onRetake={onRetake}\n nodeId={node.id}\n onContinueAnyway={\n node.allowContinueOnFailure === false\n ? undefined\n : handleContinueAnyway\n }\n />\n )}\n </div>\n );\n};\n\nexport default Selfie;\n"],"names":["useState","reportSelfieFailure","_jsxs","_jsx","Video","SelfieConfirmation","SelfieProcessing"],"mappings":"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"}
1
+ {"version":3,"file":"Selfie.js","sources":["../../../../../src/components/session/Selfie.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport {\n SessionTemplate,\n SessionTemplateNode,\n stepObject,\n} from \"../../types/session\";\nimport Video from \"../selfie/Video\";\nimport SelfieConfirmation from \"../selfie/SelfieConfirmation\";\nimport type { SelfieCaptureData } from \"../../types/selfie\";\nimport SelfieProcessing from \"../selfie/selfie-flow/SelfieProcessing\";\nimport { reportSelfieFailure } from \"../../services/sessionService\";\n\n/**\n * Composant de gestion du flux selfie.\n * Gère les étapes internes de capture et confirmation du selfie.\n */\nconst Selfie = ({\n stepObject,\n sessionId,\n node,\n template,\n}: {\n stepObject: stepObject;\n sessionId: string;\n node: SessionTemplateNode;\n template: SessionTemplate;\n}) => {\n const [internalStep, setInternalStep] = useState(0);\n const [selfieData, setSelfieData] = useState<SelfieCaptureData | null>(null);\n const [selfiePhoto, setSelfiePhoto] = useState<string | null>(null);\n const [isTransitioning, setIsTransitioning] = useState(false);\n\n const handleConfirmSelfie = () => {\n // Ajouter une transition visuelle avant de passer à l'étape suivante\n setIsTransitioning(true);\n\n // Attendre un peu pour l'animation avant de passer à l'étape suivante\n setTimeout(() => {\n setInternalStep(2); // Passer à l'étape de traitement du selfie\n setIsTransitioning(false);\n }, 500);\n };\n\n const selfieProcessed = (processed: boolean) => {\n // Callback pour indiquer que le selfie a été traité\n if (processed) {\n stepObject.goToNextStepCommitted(node.id, template);\n }\n };\n\n const handleContinueAnyway = () => {\n void reportSelfieFailure(sessionId, {\n nodeId: node.id,\n reason: \"user_bypassed\",\n bypassed: true,\n }).catch(() => undefined);\n stepObject.goToNextStepCommitted(node.id, template);\n };\n\n const onRetake = () => {\n setInternalStep(0);\n };\n\n const handleRetakeSelfie = () => {\n setInternalStep(0);\n };\n\n return (\n <div\n className={`h-full w-full transition-opacity duration-500 ${isTransitioning ? \"opacity-50\" : \"opacity-100\"\n }`}\n >\n {internalStep === 0 && (\n <Video\n setSelfieData={setSelfieData}\n setStep={setInternalStep}\n sessionId={sessionId}\n iad={node.iad}\n btnBg={template.buttonBgColor ?? \"#11E5C5\"}\n btnText={template.buttonTextColor ?? \"#3C3C40\"}\n />\n )}\n {internalStep === 1 && selfieData && (\n <SelfieConfirmation\n selfieData={selfieData}\n onConfirm={handleConfirmSelfie}\n onRetake={handleRetakeSelfie}\n setSelfiePhoto={setSelfiePhoto}\n />\n )}\n {internalStep === 2 && selfieData && (\n <SelfieProcessing\n onProcessingComplete={selfieProcessed}\n selfieVideo={selfieData}\n selfiePhoto={selfiePhoto}\n onRetake={onRetake}\n nodeId={node.id}\n onContinueAnyway={\n node.allowContinueOnFailure === false\n ? undefined\n : handleContinueAnyway\n }\n />\n )}\n </div>\n );\n};\n\nexport default Selfie;\n"],"names":["useState","reportSelfieFailure","_jsxs","_jsx","Video","SelfieConfirmation","SelfieProcessing"],"mappings":"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"}
@@ -133,7 +133,8 @@ var user_guidance = {
133
133
  "2.2": "The photo is not clear. Avoid any blur or reflection",
134
134
  "2.4": "The photo is not clear. Avoid any blur or reflection",
135
135
  "2.6": "The document submitted is not the expected one",
136
- QUOTA_EXCEEDED: "Your organisation has reached its verification quota. Please try again later or contact the organisation that sent you this link."
136
+ QUOTA_EXCEEDED: "Your organisation has reached its verification quota. Please try again later or contact the organisation that sent you this link.",
137
+ INSUFFICIENT_CREDITS: "The organisation that sent you this link has run out of verification credits. Please contact them to complete your verification."
137
138
  };
138
139
  var validation_points = {
139
140
  "1.0": {
@@ -271,6 +272,7 @@ var errors = {
271
272
  verification_failed_subtitle_no_retry: "We could not validate your {{documentType}}. Please check the points below.",
272
273
  problems_detected: "Problems Detected",
273
274
  improvement_tips: "Improvement Tips",
275
+ service_refusal_title: "Verification temporarily unavailable",
274
276
  image_quality_insufficient: "• Image quality: Insufficient",
275
277
  readability_problematic: "• Information readability: Problematic",
276
278
  authenticity_not_verified: "• Authenticity: Not verified",
@@ -1 +1 @@
1
- {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"en.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -133,7 +133,8 @@ var user_guidance = {
133
133
  "2.2": "La foto no es clara. Evita desenfoques y reflejos",
134
134
  "2.4": "La foto no es clara. Evita desenfoques y reflejos",
135
135
  "2.6": "El documento enviado no es el esperado",
136
- QUOTA_EXCEEDED: "Su organización ha alcanzado su cuota de verificaciones. Inténtelo de nuevo más tarde o póngase en contacto con la organización que le envió este enlace."
136
+ QUOTA_EXCEEDED: "Su organización ha alcanzado su cuota de verificaciones. Inténtelo de nuevo más tarde o póngase en contacto con la organización que le envió este enlace.",
137
+ INSUFFICIENT_CREDITS: "La organización que le envió este enlace no tiene más créditos de verificación. Póngase en contacto con ella para completar su trámite."
137
138
  };
138
139
  var validation_points = {
139
140
  "1.0": {
@@ -271,6 +272,7 @@ var errors = {
271
272
  verification_failed_subtitle_no_retry: "No hemos podido validar tu {{documentType}}. Revisa los puntos siguientes.",
272
273
  problems_detected: "Problemas detectados",
273
274
  improvement_tips: "Consejos de mejora",
275
+ service_refusal_title: "Verificación temporalmente no disponible",
274
276
  image_quality_insufficient: "• Calidad de imagen: insuficiente",
275
277
  readability_problematic: "• Legibilidad de la información: problemática",
276
278
  authenticity_not_verified: "• Autenticidad: no verificada",
@@ -1 +1 @@
1
- {"version":3,"file":"es.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"es.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -133,7 +133,8 @@ var user_guidance = {
133
133
  "2.2": "La photo n'est pas nette. Évitez tout flou ou reflet",
134
134
  "2.4": "La photo n'est pas nette. Évitez tout flou ou reflet",
135
135
  "2.6": "Le document déposé n'est pas celui attendu",
136
- QUOTA_EXCEEDED: "Le quota de vérifications de votre organisation est atteint. Veuillez réessayer plus tard ou contacter l'organisation qui vous a envoyé ce lien."
136
+ QUOTA_EXCEEDED: "Le quota de vérifications de votre organisation est atteint. Veuillez réessayer plus tard ou contacter l'organisation qui vous a envoyé ce lien.",
137
+ INSUFFICIENT_CREDITS: "L'organisation qui vous a envoyé ce lien n'a plus de crédits de vérification. Veuillez la contacter pour finaliser votre démarche."
137
138
  };
138
139
  var validation_points = {
139
140
  "1.0": {
@@ -271,6 +272,7 @@ var errors = {
271
272
  verification_failed_subtitle_no_retry: "Nous n'avons pas pu valider votre {{documentType}}. Veuillez vérifier les points ci-dessous.",
272
273
  problems_detected: "Problèmes détectés",
273
274
  improvement_tips: "Conseils d'amélioration",
275
+ service_refusal_title: "Vérification momentanément impossible",
274
276
  image_quality_insufficient: "• Qualité des images : Insuffisante",
275
277
  readability_problematic: "• Lisibilité des informations : Problématique",
276
278
  authenticity_not_verified: "• Authenticité : Non vérifiée",
@@ -1 +1 @@
1
- {"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"fr.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -275,28 +275,30 @@ function analyzeFiles(sessionId_1, nodeId_1, files_1, documentTypeId_1) {
275
275
  }
276
276
  function analyzeSelfie(sessionId, selfieFile, selfiePhoto, nodeId) {
277
277
  return tslib_es6.__awaiter(this, void 0, void 0, function () {
278
- var formData, response, unisseyResponse, unisseyData, faceComparison, isHighConfidence, isMatch, isGenuine, analysisResponse, err_1, errorMessage, error_3;
279
- var _a, _b, _c, _d;
280
- return tslib_es6.__generator(this, function (_e) {
281
- switch (_e.label) {
278
+ var formData, response, unisseyResponse, unisseyData, faceComparison, faceComparisonDisabled, isHighConfidence, isMatch, isGenuine, analysisResponse, err_1, errorMessage, error_3;
279
+ var _a, _b, _c, _d, _e;
280
+ return tslib_es6.__generator(this, function (_f) {
281
+ switch (_f.label) {
282
282
  case 0:
283
283
  console.log("🤳 Starting selfie analysis for session:", sessionId);
284
284
  console.log("� File size:", selfieFile.media.size, "bytes");
285
285
  formData = new FormData();
286
286
  formData.append("file", selfieFile.media, "selfie.mp4");
287
287
  formData.append("photo", selfiePhoto);
288
+ if ((_a = selfieFile.metadata) === null || _a === void 0 ? void 0 : _a.trim()) {
289
+ formData.append("selfie-metadata", selfieFile.metadata);
290
+ }
288
291
  if (nodeId)
289
292
  formData.append("nodeId", nodeId);
290
- _e.label = 1;
293
+ _f.label = 1;
291
294
  case 1:
292
- _e.trys.push([1, 13, , 14]);
295
+ _f.trys.push([1, 13, , 14]);
293
296
  console.log("🚀 Sending selfie to UNISSEY API...");
294
297
  return [4 /*yield*/, api.apiService.post("/session/unissey/".concat(sessionId, "/analyze"), formData, {
295
298
  timeout: SELFIE_ANALYSIS_TIMEOUT,
296
299
  })];
297
300
  case 2:
298
- response = _e.sent();
299
- console.log("✅ Analysis response:", response);
301
+ response = _f.sent();
300
302
  if (!(response.success && response.data)) return [3 /*break*/, 12];
301
303
  console.log("🎉 Unissey analysis completed - checking results...");
302
304
  unisseyResponse = response.data;
@@ -305,40 +307,52 @@ function analyzeSelfie(sessionId, selfieFile, selfiePhoto, nodeId) {
305
307
  unisseyResponse.message === "ok"))) return [3 /*break*/, 11];
306
308
  console.log("✅ Unissey returned success status");
307
309
  unisseyData = unisseyResponse.data;
308
- faceComparison = (_a = unisseyData.details) === null || _a === void 0 ? void 0 : _a.face_comparison;
310
+ faceComparison = (_b = unisseyData.details) === null || _b === void 0 ? void 0 : _b.face_comparison;
311
+ faceComparisonDisabled = unisseyData.face_comparison_disabled === true;
309
312
  isHighConfidence = (faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.confidence_level) === "high";
310
- isMatch = unisseyData.is_match && (faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.result) === "match";
311
- isGenuine = isHighConfidence && isMatch;
312
- _e.label = 3;
313
+ isMatch = !faceComparisonDisabled &&
314
+ unisseyData.is_match && (faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.result) === "match";
315
+ isGenuine = faceComparisonDisabled
316
+ ? unisseyData.is_genuine !== false
317
+ : isHighConfidence && isMatch;
318
+ _f.label = 3;
313
319
  case 3:
314
- _e.trys.push([3, 9, , 10]);
320
+ _f.trys.push([3, 9, , 10]);
315
321
  return [4 /*yield*/, api.apiService.get("/session/sdk/".concat(sessionId))];
316
322
  case 4:
317
- analysisResponse = _e.sent();
323
+ analysisResponse = _f.sent();
318
324
  if (!(analysisResponse.data && analysisResponse.data.analysisId)) return [3 /*break*/, 8];
319
325
  return [4 /*yield*/, auditTrailService.logSelfieCaptured(sessionId, analysisResponse.data.clientInfoId || undefined)];
320
326
  case 5:
321
- _e.sent();
327
+ _f.sent();
322
328
  // Log AI control with selfie analysis results
323
329
  return [4 /*yield*/, auditTrailService.logAiControlled(sessionId, {
324
330
  selfieAnalysisResult: isGenuine ? "genuine" : "not_genuine",
325
- isMatch: isMatch ? "match" : "no_match",
331
+ isMatch: faceComparisonDisabled
332
+ ? "not_performed"
333
+ : isMatch
334
+ ? "match"
335
+ : "no_match",
326
336
  confidenceLevel: (faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.confidence_level) || "unknown",
327
337
  }, analysisResponse.data.clientInfoId || undefined)];
328
338
  case 6:
329
339
  // Log AI control with selfie analysis results
330
- _e.sent();
340
+ _f.sent();
331
341
  return [4 /*yield*/, auditTrailService.logStatusModified(sessionId, {
332
342
  selfieAnalysisResult: isGenuine ? "genuine" : "not_genuine",
333
- isMatch: isMatch ? "match" : "no_match",
343
+ isMatch: faceComparisonDisabled
344
+ ? "not_performed"
345
+ : isMatch
346
+ ? "match"
347
+ : "no_match",
334
348
  confidenceLevel: (faceComparison === null || faceComparison === void 0 ? void 0 : faceComparison.confidence_level) || "unknown",
335
349
  }, analysisResponse.data.clientInfoId || undefined)];
336
350
  case 7:
337
- _e.sent();
338
- _e.label = 8;
351
+ _f.sent();
352
+ _f.label = 8;
339
353
  case 8: return [3 /*break*/, 10];
340
354
  case 9:
341
- err_1 = _e.sent();
355
+ err_1 = _f.sent();
342
356
  console.error("Failed to log selfie capture in audit trail:", err_1);
343
357
  return [3 /*break*/, 10];
344
358
  case 10:
@@ -351,14 +365,14 @@ function analyzeSelfie(sessionId, selfieFile, selfiePhoto, nodeId) {
351
365
  console.error("❌ Unissey returned error status:", unisseyResponse.status, unisseyResponse.message);
352
366
  throw new Error("Unissey analysis failed: ".concat(unisseyResponse.message || "Unknown Unissey error"));
353
367
  case 12:
354
- errorMessage = ((_b = response.data) === null || _b === void 0 ? void 0 : _b.message) || response.data || "Unknown error";
368
+ errorMessage = ((_c = response.data) === null || _c === void 0 ? void 0 : _c.message) || response.data || "Unknown error";
355
369
  console.error("❌ API call failed:", errorMessage);
356
370
  throw new Error("Face comparison analysis failed: ".concat(errorMessage));
357
371
  case 13:
358
- error_3 = _e.sent();
372
+ error_3 = _f.sent();
359
373
  console.error("💥 Analysis error:", error_3);
360
374
  // Améliorer le message d'erreur pour l'UI
361
- if ((_d = (_c = error_3.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.message) {
375
+ if ((_e = (_d = error_3.response) === null || _d === void 0 ? void 0 : _d.data) === null || _e === void 0 ? void 0 : _e.message) {
362
376
  throw new Error("Analysis failed: ".concat(error_3.response.data.message));
363
377
  }
364
378
  else if (error_3.message) {
@@ -372,7 +386,7 @@ function analyzeSelfie(sessionId, selfieFile, selfiePhoto, nodeId) {
372
386
  });
373
387
  });
374
388
  }
375
- function uploadConvertedIdCardImage(sessionId, file) {
389
+ function uploadConvertedIdCardImage(sessionId, file, nodeId) {
376
390
  return tslib_es6.__awaiter(this, void 0, void 0, function () {
377
391
  var renamedFile, formData, response, error_4;
378
392
  return tslib_es6.__generator(this, function (_a) {
@@ -390,7 +404,7 @@ function uploadConvertedIdCardImage(sessionId, file) {
390
404
  case 1:
391
405
  _a.trys.push([1, 3, , 4]);
392
406
  console.log("\uD83D\uDE80 Uploading converted ID card image for session: ".concat(sessionId));
393
- return [4 /*yield*/, api.apiService.post("/session/sdk/".concat(sessionId, "/converted_id_card.png"), formData, {
407
+ return [4 /*yield*/, api.apiService.post("/session/sdk/".concat(sessionId, "/converted_id_card.png").concat(nodeId ? "?nodeId=".concat(encodeURIComponent(nodeId)) : ''), formData, {
394
408
  timeout: UPLOAD_TIMEOUT,
395
409
  })];
396
410
  case 2: