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.
- package/dist/cjs/components/document-collection/DocumentError.js +5 -1
- package/dist/cjs/components/document-collection/DocumentError.js.map +1 -1
- package/dist/cjs/components/document-collection/DocumentProcessing.js +13 -11
- package/dist/cjs/components/document-collection/DocumentProcessing.js.map +1 -1
- package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js +9 -5
- package/dist/cjs/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
- package/dist/cjs/components/jdi/JDIError.js +5 -1
- package/dist/cjs/components/jdi/JDIError.js.map +1 -1
- package/dist/cjs/components/jdi/JDIProcessing.js +15 -14
- package/dist/cjs/components/jdi/JDIProcessing.js.map +1 -1
- package/dist/cjs/components/selfie/Video.js +2 -2
- package/dist/cjs/components/selfie/Video.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js +2 -2
- package/dist/cjs/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
- package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js +123 -13
- package/dist/cjs/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/cjs/components/session/Selfie.js +1 -1
- package/dist/cjs/components/session/Selfie.js.map +1 -1
- package/dist/cjs/i18n/en.json.js +3 -1
- package/dist/cjs/i18n/en.json.js.map +1 -1
- package/dist/cjs/i18n/es.json.js +3 -1
- package/dist/cjs/i18n/es.json.js.map +1 -1
- package/dist/cjs/i18n/fr.json.js +3 -1
- package/dist/cjs/i18n/fr.json.js.map +1 -1
- package/dist/cjs/services/analysis.js +40 -26
- package/dist/cjs/services/analysis.js.map +1 -1
- package/dist/cjs/services/iadService.js +30 -0
- package/dist/cjs/services/iadService.js.map +1 -0
- package/dist/cjs/types/session.js.map +1 -1
- package/dist/cjs/utils/analysisErrors.js +33 -12
- package/dist/cjs/utils/analysisErrors.js.map +1 -1
- package/dist/esm/components/document-collection/DocumentError.js +5 -1
- package/dist/esm/components/document-collection/DocumentError.js.map +1 -1
- package/dist/esm/components/document-collection/DocumentProcessing.js +14 -12
- package/dist/esm/components/document-collection/DocumentProcessing.js.map +1 -1
- package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js +9 -5
- package/dist/esm/components/document-video/document-video-flow/DocumentVideoProcessing.js.map +1 -1
- package/dist/esm/components/jdi/JDIError.js +5 -1
- package/dist/esm/components/jdi/JDIError.js.map +1 -1
- package/dist/esm/components/jdi/JDIProcessing.js +16 -15
- package/dist/esm/components/jdi/JDIProcessing.js.map +1 -1
- package/dist/esm/components/selfie/Video.js +2 -2
- package/dist/esm/components/selfie/Video.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js +2 -2
- package/dist/esm/components/selfie/selfie-flow/SelfieFlow.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js +5 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieProcessing.js.map +1 -1
- package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js +124 -14
- package/dist/esm/components/selfie/selfie-flow/SelfieRecorder.js.map +1 -1
- package/dist/esm/components/session/Selfie.js +1 -1
- package/dist/esm/components/session/Selfie.js.map +1 -1
- package/dist/esm/i18n/en.json.js +3 -1
- package/dist/esm/i18n/en.json.js.map +1 -1
- package/dist/esm/i18n/es.json.js +3 -1
- package/dist/esm/i18n/es.json.js.map +1 -1
- package/dist/esm/i18n/fr.json.js +3 -1
- package/dist/esm/i18n/fr.json.js.map +1 -1
- package/dist/esm/services/analysis.js +40 -26
- package/dist/esm/services/analysis.js.map +1 -1
- package/dist/esm/services/iadService.js +28 -0
- package/dist/esm/services/iadService.js.map +1 -0
- package/dist/esm/types/session.js.map +1 -1
- package/dist/esm/utils/analysisErrors.js +30 -12
- package/dist/esm/utils/analysisErrors.js.map +1 -1
- package/docs/POLLING_SYSTEM.md +4 -0
- 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
|
|
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:
|
|
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":";;;;;;;;;;;AAYA;;;AAGG;AACH,IAAM,MAAM,GAAG,UAAC,EAUf,EAAA;;QATC,UAAU,GAAA,EAAA,CAAA,UAAA,EACV,SAAS,GAAA,EAAA,CAAA,SAAA,EACT,IAAI,GAAA,EAAA,CAAA,IAAA,EACJ,QAAQ,GAAA,EAAA,CAAA,QAAA;IAOF,IAAA,EAAA,GAAkCA,cAAQ,CAAC,CAAC,CAAC,EAA5C,YAAY,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,eAAe,GAAA,EAAA,CAAA,CAAA,CAAe;IAC7C,IAAA,EAAA,GAA8BA,cAAQ,CAA2B,IAAI,CAAC,EAArE,UAAU,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,aAAa,GAAA,EAAA,CAAA,CAAA,CAA4C;IACtE,IAAA,EAAA,GAAgCA,cAAQ,CAAgB,IAAI,CAAC,EAA5D,WAAW,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,cAAc,GAAA,EAAA,CAAA,CAAA,CAAiC;IAC7D,IAAA,EAAA,GAAwCA,cAAQ,CAAC,KAAK,CAAC,EAAtD,eAAe,GAAA,EAAA,CAAA,CAAA,CAAA,EAAE,kBAAkB,GAAA,EAAA,CAAA,CAAA,CAAmB;AAE7D,IAAA,IAAM,mBAAmB,GAAG,YAAA;;QAE1B,kBAAkB,CAAC,IAAI,CAAC;;AAGxB,QAAA,UAAU,CAAC,YAAA;AACT,YAAA,eAAe,CAAC,CAAC,CAAC,CAAC;YACnB,kBAAkB,CAAC,KAAK,CAAC;QAC3B,CAAC,EAAE,GAAG,CAAC;AACT,IAAA,CAAC;IAED,IAAM,eAAe,GAAG,UAAC,SAAkB,EAAA;;QAEzC,IAAI,SAAS,EAAE;YACb,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC;QACrD;AACF,IAAA,CAAC;AAED,IAAA,IAAM,oBAAoB,GAAG,YAAA;QAC3B,KAAKC,kCAAmB,CAAC,SAAS,EAAE;YAClC,MAAM,EAAE,IAAI,CAAC,EAAE;AACf,YAAA,MAAM,EAAE,eAAe;AACvB,YAAA,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC,KAAK,CAAC,YAAA,EAAM,OAAA,SAAS,CAAA,CAAT,CAAS,CAAC;QACzB,UAAU,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC;AACrD,IAAA,CAAC;AAED,IAAA,IAAM,QAAQ,GAAG,YAAA;QACf,eAAe,CAAC,CAAC,CAAC;AACpB,IAAA,CAAC;AAED,IAAA,IAAM,kBAAkB,GAAG,YAAA;QACzB,eAAe,CAAC,CAAC,CAAC;AACpB,IAAA,CAAC;
|
|
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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"}
|
package/dist/cjs/i18n/en.json.js
CHANGED
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/cjs/i18n/es.json.js
CHANGED
|
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/dist/cjs/i18n/fr.json.js
CHANGED
|
@@ -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 (
|
|
281
|
-
switch (
|
|
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
|
-
|
|
293
|
+
_f.label = 1;
|
|
291
294
|
case 1:
|
|
292
|
-
|
|
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 =
|
|
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 = (
|
|
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 =
|
|
311
|
-
|
|
312
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
340
|
+
_f.sent();
|
|
331
341
|
return [4 /*yield*/, auditTrailService.logStatusModified(sessionId, {
|
|
332
342
|
selfieAnalysisResult: isGenuine ? "genuine" : "not_genuine",
|
|
333
|
-
isMatch:
|
|
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
|
-
|
|
338
|
-
|
|
351
|
+
_f.sent();
|
|
352
|
+
_f.label = 8;
|
|
339
353
|
case 8: return [3 /*break*/, 10];
|
|
340
354
|
case 9:
|
|
341
|
-
err_1 =
|
|
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 = ((
|
|
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 =
|
|
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 ((
|
|
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:
|