@hexar/biometric-identity-sdk-react-native 1.0.9 → 1.0.10
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/components/BiometricIdentityFlow.d.ts.map +1 -1
- package/dist/components/BiometricIdentityFlow.js +16 -1
- package/dist/components/VideoRecorder.d.ts.map +1 -1
- package/dist/components/VideoRecorder.js +33 -27
- package/dist/hooks/useBiometricSDK.d.ts.map +1 -1
- package/dist/hooks/useBiometricSDK.js +27 -4
- package/package.json +1 -1
- package/src/components/BiometricIdentityFlow.tsx +17 -1
- package/src/components/VideoRecorder.tsx +33 -36
- package/src/hooks/useBiometricSDK.ts +30 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BiometricIdentityFlow.d.ts","sourceRoot":"","sources":["../../src/components/BiometricIdentityFlow.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAOL,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,cAAc,EAKd,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AAU5C,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,
|
|
1
|
+
{"version":3,"file":"BiometricIdentityFlow.d.ts","sourceRoot":"","sources":["../../src/components/BiometricIdentityFlow.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAA2C,MAAM,OAAO,CAAC;AAChE,OAAO,EAOL,SAAS,EACV,MAAM,cAAc,CAAC;AACtB,OAAO,EACL,gBAAgB,EAChB,WAAW,EACX,cAAc,EAKd,iBAAiB,EAClB,MAAM,oCAAoC,CAAC;AAU5C,MAAM,WAAW,0BAA0B;IACzC,oBAAoB,EAAE,CAAC,MAAM,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACzD,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IACzC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC5C,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE;QACP,SAAS,CAAC,EAAE,SAAS,CAAC;QACtB,OAAO,CAAC,EAAE,SAAS,CAAC;KACrB,CAAC;CACH;AAED,eAAO,MAAM,qBAAqB,EAAE,KAAK,CAAC,EAAE,CAAC,0BAA0B,CAiUtE,CAAC;AAiOF,eAAe,qBAAqB,CAAC"}
|
|
@@ -109,17 +109,28 @@ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language,
|
|
|
109
109
|
* Handle capture completion
|
|
110
110
|
*/
|
|
111
111
|
const handleCaptureComplete = (0, react_1.useCallback)(async (data) => {
|
|
112
|
+
console.log('handleCaptureComplete called, cameraMode:', cameraMode);
|
|
112
113
|
setShowCamera(false);
|
|
113
114
|
try {
|
|
114
115
|
if (cameraMode === 'front') {
|
|
116
|
+
console.log('Uploading front ID');
|
|
115
117
|
await uploadFrontID(data);
|
|
118
|
+
console.log('Front ID uploaded successfully');
|
|
116
119
|
}
|
|
117
120
|
else if (cameraMode === 'back') {
|
|
121
|
+
console.log('Uploading back ID');
|
|
118
122
|
await uploadBackID(data);
|
|
123
|
+
console.log('Back ID uploaded successfully');
|
|
119
124
|
}
|
|
120
125
|
else if (cameraMode === 'video') {
|
|
126
|
+
console.log('Processing video recording result');
|
|
121
127
|
// Handle video recording result
|
|
122
128
|
const videoResult = data;
|
|
129
|
+
console.log('Storing video recording:', {
|
|
130
|
+
frames: videoResult.frames.length,
|
|
131
|
+
duration: videoResult.duration,
|
|
132
|
+
challengesCompleted: videoResult.challengesCompleted.length
|
|
133
|
+
});
|
|
123
134
|
await storeVideoRecording({
|
|
124
135
|
frames: videoResult.frames,
|
|
125
136
|
duration: videoResult.duration,
|
|
@@ -128,8 +139,10 @@ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language,
|
|
|
128
139
|
challengesCompleted: videoResult.challengesCompleted,
|
|
129
140
|
sessionId: videoResult.sessionId,
|
|
130
141
|
});
|
|
142
|
+
console.log('Video recording stored, starting validation...');
|
|
131
143
|
// Automatically start validation after video
|
|
132
|
-
await validateIdentity();
|
|
144
|
+
const result = await validateIdentity();
|
|
145
|
+
console.log('Validation complete, result:', result);
|
|
133
146
|
}
|
|
134
147
|
}
|
|
135
148
|
catch (error) {
|
|
@@ -172,10 +185,12 @@ const BiometricIdentityFlow = ({ onValidationComplete, onError, theme, language,
|
|
|
172
185
|
}
|
|
173
186
|
// Show validation progress
|
|
174
187
|
if (state.currentStep === biometric_identity_sdk_core_1.SDKStep.VALIDATING) {
|
|
188
|
+
console.log('Rendering ValidationProgress, progress:', state.progress);
|
|
175
189
|
return (react_1.default.createElement(ValidationProgress_1.ValidationProgress, { progress: state.progress, theme: theme, language: language }));
|
|
176
190
|
}
|
|
177
191
|
// Show result
|
|
178
192
|
if (state.currentStep === biometric_identity_sdk_core_1.SDKStep.RESULT && state.validationResult) {
|
|
193
|
+
console.log('Rendering ResultScreen, result:', state.validationResult);
|
|
179
194
|
return (react_1.default.createElement(ResultScreen_1.ResultScreen, { result: state.validationResult, theme: theme, language: language, onClose: () => onValidationComplete(state.validationResult) }));
|
|
180
195
|
}
|
|
181
196
|
// Show error
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAGlI,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,
|
|
1
|
+
{"version":3,"file":"VideoRecorder.d.ts","sourceRoot":"","sources":["../../src/components/VideoRecorder.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAmD,MAAM,OAAO,CAAC;AAaxE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,iBAAiB,EAA2B,MAAM,oCAAoC,CAAC;AAGlI,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE,WAAW,CAAC;IACpB,QAAQ,CAAC,EAAE,iBAAiB,CAAC;IAC7B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sCAAsC;IACtC,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACrC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,UAAU,EAAE,CAAC,SAAS,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACtD,iCAAiC;IACjC,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,gDAAgD;IAChD,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CACtD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA+CD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CA8vBtD,CAAC;AA4OF,eAAe,aAAa,CAAC"}
|
|
@@ -274,16 +274,16 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
274
274
|
react_native_1.Alert.alert('Recording Error', 'Failed to record video. Please try again.', [{ text: 'OK', onPress: onCancel }]);
|
|
275
275
|
}, [onCancel]);
|
|
276
276
|
const handleVideoComplete = (0, react_1.useCallback)(async (video) => {
|
|
277
|
-
|
|
277
|
+
console.log('handleVideoComplete called with video:', video?.path);
|
|
278
278
|
if (!isRecordingRef.current && phase !== 'processing') {
|
|
279
|
-
|
|
279
|
+
console.log('Video already processed, ignoring duplicate callback');
|
|
280
280
|
return;
|
|
281
281
|
}
|
|
282
282
|
try {
|
|
283
283
|
setPhase('processing');
|
|
284
284
|
setOverallProgress(100);
|
|
285
285
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
286
|
-
|
|
286
|
+
console.log('Video Processing - Duration:', (actualDuration / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's, Frames:', frames.length);
|
|
287
287
|
if (actualDuration < minDurationMs) {
|
|
288
288
|
setPhase('recording');
|
|
289
289
|
setOverallProgress(0);
|
|
@@ -295,15 +295,15 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
295
295
|
try {
|
|
296
296
|
const RNFS = require('react-native-fs');
|
|
297
297
|
videoBase64 = await RNFS.readFile(video.path, 'base64');
|
|
298
|
-
|
|
298
|
+
console.log('Video file read successfully, size:', videoBase64.length, 'bytes');
|
|
299
299
|
}
|
|
300
300
|
catch (fsError) {
|
|
301
|
-
|
|
301
|
+
console.warn('Could not read video file, using captured frames:', fsError);
|
|
302
302
|
}
|
|
303
303
|
}
|
|
304
304
|
const finalFrames = frames.length > 0 ? frames : (videoBase64 ? [videoBase64] : []);
|
|
305
305
|
if (finalFrames.length === 0) {
|
|
306
|
-
|
|
306
|
+
console.error('No frames available, cannot complete');
|
|
307
307
|
setPhase('recording');
|
|
308
308
|
handleRecordingError(new Error('No video frames captured'));
|
|
309
309
|
return;
|
|
@@ -316,12 +316,18 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
316
316
|
challengesCompleted: completedChallenges,
|
|
317
317
|
sessionId,
|
|
318
318
|
};
|
|
319
|
-
|
|
319
|
+
console.log('Video recording completed successfully:', {
|
|
320
|
+
duration: (actualDuration / 1000).toFixed(1) + 's',
|
|
321
|
+
frames: result.frames.length,
|
|
322
|
+
challenges: `${completedChallenges.length}/${challenges.length}`,
|
|
323
|
+
instructionsFollowed: result.instructionsFollowed,
|
|
324
|
+
quality: result.qualityScore.toFixed(0) + '%'
|
|
325
|
+
});
|
|
320
326
|
isRecordingRef.current = false;
|
|
321
327
|
onComplete(result);
|
|
322
328
|
}
|
|
323
329
|
catch (error) {
|
|
324
|
-
|
|
330
|
+
console.error('Error processing video:', error);
|
|
325
331
|
setPhase('recording');
|
|
326
332
|
setOverallProgress(0);
|
|
327
333
|
handleRecordingError(error);
|
|
@@ -329,7 +335,7 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
329
335
|
}, [frames, completedChallenges, challenges, sessionId, onComplete, resetAndRetry, handleRecordingError, strings, minDurationMs, phase]);
|
|
330
336
|
const startFrameCapture = (0, react_1.useCallback)(() => {
|
|
331
337
|
if (cameraRef.current && device) {
|
|
332
|
-
|
|
338
|
+
console.log('Starting frame capture mode');
|
|
333
339
|
frameCaptureInterval.current = setInterval(async () => {
|
|
334
340
|
try {
|
|
335
341
|
const photo = await cameraRef.current?.takePhoto({
|
|
@@ -357,32 +363,32 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
357
363
|
}
|
|
358
364
|
}
|
|
359
365
|
catch (error) {
|
|
360
|
-
|
|
366
|
+
console.warn('Frame capture error:', error);
|
|
361
367
|
}
|
|
362
368
|
}, 100);
|
|
363
369
|
}
|
|
364
370
|
}, [device]);
|
|
365
371
|
const stopRecording = (0, react_1.useCallback)(async () => {
|
|
366
|
-
|
|
372
|
+
console.log('Stopping recording...');
|
|
367
373
|
if (frameCaptureInterval.current) {
|
|
368
374
|
clearInterval(frameCaptureInterval.current);
|
|
369
375
|
frameCaptureInterval.current = null;
|
|
370
376
|
}
|
|
371
377
|
if (videoRecordingRef.current) {
|
|
372
378
|
try {
|
|
373
|
-
|
|
379
|
+
console.log('Stopping video recording');
|
|
374
380
|
const recording = videoRecordingRef.current;
|
|
375
381
|
videoRecordingRef.current = null;
|
|
376
382
|
isRecordingRef.current = false;
|
|
377
383
|
await recording.stop();
|
|
378
|
-
|
|
384
|
+
console.log('Video recording stopped - waiting for onRecordingFinished callback');
|
|
379
385
|
}
|
|
380
386
|
catch (error) {
|
|
381
|
-
|
|
387
|
+
console.error('Error stopping video recording:', error);
|
|
382
388
|
isRecordingRef.current = false;
|
|
383
389
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
384
390
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
385
|
-
|
|
391
|
+
console.log('Video stopped with error, using captured frames');
|
|
386
392
|
const result = {
|
|
387
393
|
frames,
|
|
388
394
|
duration: actualDuration,
|
|
@@ -401,14 +407,14 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
401
407
|
}, [frames, completedChallenges, challenges, sessionId, onComplete, minDurationMs]);
|
|
402
408
|
const runChallenge = (0, react_1.useCallback)((index) => {
|
|
403
409
|
if (index >= challenges.length) {
|
|
404
|
-
|
|
410
|
+
console.log('All challenges completed, stopping recording');
|
|
405
411
|
setOverallProgress(100);
|
|
406
412
|
if (isRecordingRef.current) {
|
|
407
413
|
const elapsed = Date.now() - recordingStartTime.current;
|
|
408
|
-
|
|
414
|
+
console.log('Checking duration - Elapsed:', (elapsed / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's');
|
|
409
415
|
if (elapsed < minDurationMs) {
|
|
410
416
|
const remaining = minDurationMs - elapsed;
|
|
411
|
-
|
|
417
|
+
console.log('Waiting additional', (remaining / 1000).toFixed(1), 's to meet minimum duration');
|
|
412
418
|
setTimeout(() => {
|
|
413
419
|
if (isRecordingRef.current) {
|
|
414
420
|
stopRecording();
|
|
@@ -421,7 +427,7 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
421
427
|
else {
|
|
422
428
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
423
429
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
424
|
-
|
|
430
|
+
console.log('Recording already stopped, completing with frames');
|
|
425
431
|
const result = {
|
|
426
432
|
frames,
|
|
427
433
|
duration: actualDuration,
|
|
@@ -477,37 +483,37 @@ const VideoRecorder = ({ theme, language, duration, instructions, challenges: pr
|
|
|
477
483
|
setPhase('recording');
|
|
478
484
|
recordingStartTime.current = Date.now();
|
|
479
485
|
isRecordingRef.current = true;
|
|
480
|
-
|
|
486
|
+
console.log('Starting video recording, total duration:', (totalDuration / 1000).toFixed(1), 's');
|
|
481
487
|
if (cameraRef.current && device) {
|
|
482
488
|
try {
|
|
483
489
|
videoRecordingRef.current = await cameraRef.current.startRecording({
|
|
484
490
|
flash: 'off',
|
|
485
491
|
onRecordingFinished: (video) => {
|
|
486
|
-
|
|
492
|
+
console.log('Video recording finished callback called, path:', video?.path || 'N/A');
|
|
487
493
|
handleVideoComplete(video);
|
|
488
494
|
},
|
|
489
495
|
onRecordingError: (error) => {
|
|
490
|
-
|
|
496
|
+
console.error('Recording error:', error);
|
|
491
497
|
handleRecordingError(error);
|
|
492
498
|
},
|
|
493
499
|
});
|
|
494
|
-
|
|
500
|
+
console.log('Video recording started successfully');
|
|
495
501
|
}
|
|
496
502
|
catch (error) {
|
|
497
|
-
|
|
503
|
+
console.warn('Video recording not available, falling back to frame capture:', error);
|
|
498
504
|
startFrameCapture();
|
|
499
505
|
}
|
|
500
506
|
}
|
|
501
507
|
else {
|
|
502
|
-
|
|
508
|
+
console.log('Camera not available, using frame capture');
|
|
503
509
|
startFrameCapture();
|
|
504
510
|
}
|
|
505
511
|
runChallenge(0);
|
|
506
512
|
const timeoutId = setTimeout(() => {
|
|
507
|
-
|
|
513
|
+
console.log('Recording timeout reached, stopping recording');
|
|
508
514
|
if (isRecordingRef.current) {
|
|
509
515
|
stopRecording().catch(err => {
|
|
510
|
-
|
|
516
|
+
console.error('Error stopping recording on timeout:', err);
|
|
511
517
|
});
|
|
512
518
|
}
|
|
513
519
|
}, totalDuration);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useBiometricSDK.d.ts","sourceRoot":"","sources":["../../src/hooks/useBiometricSDK.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACZ,MAAM,oCAAoC,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,oBAAoB,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,mBAAmB,EAAE,CAAC,SAAS,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7E,gBAAgB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,CAAC,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,eAAO,MAAM,eAAe,QAAO,
|
|
1
|
+
{"version":3,"file":"useBiometricSDK.d.ts","sourceRoot":"","sources":["../../src/hooks/useBiometricSDK.ts"],"names":[],"mappings":"AACA,OAAO,EACL,oBAAoB,EACpB,QAAQ,EACR,WAAW,EACZ,MAAM,oCAAoC,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,GAAG,EAAE,oBAAoB,CAAC;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,mBAAmB,EAAE,CAAC,SAAS,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/D,eAAe,EAAE,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,KAAK,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;IAC7E,gBAAgB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC;IACrC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,WAAW,EAAE,CAAC,SAAS,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED,eAAO,MAAM,eAAe,QAAO,qBA+NlC,CAAC;AAEF,eAAe,eAAe,CAAC"}
|
|
@@ -137,11 +137,34 @@ const useBiometricSDK = () => {
|
|
|
137
137
|
* Validate identity with all collected data
|
|
138
138
|
*/
|
|
139
139
|
const validateIdentity = (0, react_1.useCallback)(async () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
140
|
+
console.log('validateIdentity called, current state:', sdk.getState().currentStep);
|
|
141
|
+
// Update state immediately to show validation screen
|
|
142
|
+
setState(sdk.getState());
|
|
143
|
+
// Poll state during validation to catch intermediate updates
|
|
144
|
+
const pollInterval = setInterval(() => {
|
|
145
|
+
if (isMounted.current) {
|
|
146
|
+
const currentState = sdk.getState();
|
|
147
|
+
setState(currentState);
|
|
148
|
+
console.log('State polled - step:', currentState.currentStep, 'progress:', currentState.progress);
|
|
149
|
+
}
|
|
150
|
+
}, 200);
|
|
151
|
+
try {
|
|
152
|
+
const result = await sdk.validateIdentity();
|
|
153
|
+
clearInterval(pollInterval);
|
|
154
|
+
if (isMounted.current) {
|
|
155
|
+
const finalState = sdk.getState();
|
|
156
|
+
setState(finalState);
|
|
157
|
+
console.log('Validation complete, final state:', finalState.currentStep, 'result:', result);
|
|
158
|
+
}
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
catch (error) {
|
|
162
|
+
clearInterval(pollInterval);
|
|
163
|
+
if (isMounted.current) {
|
|
164
|
+
setState(sdk.getState());
|
|
165
|
+
}
|
|
166
|
+
throw error;
|
|
143
167
|
}
|
|
144
|
-
return result;
|
|
145
168
|
}, [sdk]);
|
|
146
169
|
/**
|
|
147
170
|
* Reset SDK state
|
package/package.json
CHANGED
|
@@ -135,17 +135,29 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
|
|
|
135
135
|
* Handle capture completion
|
|
136
136
|
*/
|
|
137
137
|
const handleCaptureComplete = useCallback(async (data: any) => {
|
|
138
|
+
console.log('handleCaptureComplete called, cameraMode:', cameraMode);
|
|
138
139
|
setShowCamera(false);
|
|
139
140
|
|
|
140
141
|
try {
|
|
141
142
|
if (cameraMode === 'front') {
|
|
143
|
+
console.log('Uploading front ID');
|
|
142
144
|
await uploadFrontID(data);
|
|
145
|
+
console.log('Front ID uploaded successfully');
|
|
143
146
|
} else if (cameraMode === 'back') {
|
|
147
|
+
console.log('Uploading back ID');
|
|
144
148
|
await uploadBackID(data);
|
|
149
|
+
console.log('Back ID uploaded successfully');
|
|
145
150
|
} else if (cameraMode === 'video') {
|
|
151
|
+
console.log('Processing video recording result');
|
|
146
152
|
// Handle video recording result
|
|
147
153
|
const videoResult: VideoRecordingResult = data;
|
|
148
154
|
|
|
155
|
+
console.log('Storing video recording:', {
|
|
156
|
+
frames: videoResult.frames.length,
|
|
157
|
+
duration: videoResult.duration,
|
|
158
|
+
challengesCompleted: videoResult.challengesCompleted.length
|
|
159
|
+
});
|
|
160
|
+
|
|
149
161
|
await storeVideoRecording({
|
|
150
162
|
frames: videoResult.frames,
|
|
151
163
|
duration: videoResult.duration,
|
|
@@ -155,8 +167,10 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
|
|
|
155
167
|
sessionId: videoResult.sessionId,
|
|
156
168
|
});
|
|
157
169
|
|
|
170
|
+
console.log('Video recording stored, starting validation...');
|
|
158
171
|
// Automatically start validation after video
|
|
159
|
-
await validateIdentity();
|
|
172
|
+
const result = await validateIdentity();
|
|
173
|
+
console.log('Validation complete, result:', result);
|
|
160
174
|
}
|
|
161
175
|
} catch (error) {
|
|
162
176
|
console.error('Capture error:', error);
|
|
@@ -235,6 +249,7 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
|
|
|
235
249
|
|
|
236
250
|
// Show validation progress
|
|
237
251
|
if (state.currentStep === SDKStep.VALIDATING) {
|
|
252
|
+
console.log('Rendering ValidationProgress, progress:', state.progress);
|
|
238
253
|
return (
|
|
239
254
|
<ValidationProgress
|
|
240
255
|
progress={state.progress}
|
|
@@ -246,6 +261,7 @@ export const BiometricIdentityFlow: React.FC<BiometricIdentityFlowProps> = ({
|
|
|
246
261
|
|
|
247
262
|
// Show result
|
|
248
263
|
if (state.currentStep === SDKStep.RESULT && state.validationResult) {
|
|
264
|
+
console.log('Rendering ResultScreen, result:', state.validationResult);
|
|
249
265
|
return (
|
|
250
266
|
<ResultScreen
|
|
251
267
|
result={state.validationResult}
|
|
@@ -328,10 +328,10 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
328
328
|
}, [onCancel]);
|
|
329
329
|
|
|
330
330
|
const handleVideoComplete = useCallback(async (video: any) => {
|
|
331
|
-
|
|
331
|
+
console.log('handleVideoComplete called with video:', video?.path);
|
|
332
332
|
|
|
333
333
|
if (!isRecordingRef.current && phase !== 'processing') {
|
|
334
|
-
|
|
334
|
+
console.log('Video already processed, ignoring duplicate callback');
|
|
335
335
|
return;
|
|
336
336
|
}
|
|
337
337
|
|
|
@@ -340,10 +340,7 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
340
340
|
setOverallProgress(100);
|
|
341
341
|
|
|
342
342
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
343
|
-
|
|
344
|
-
'Video Processing',
|
|
345
|
-
`Duration: ${(actualDuration / 1000).toFixed(1)}s\nMin required: ${(minDurationMs / 1000).toFixed(1)}s\nFrames: ${frames.length}`
|
|
346
|
-
);
|
|
343
|
+
console.log('Video Processing - Duration:', (actualDuration / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's, Frames:', frames.length);
|
|
347
344
|
|
|
348
345
|
if (actualDuration < minDurationMs) {
|
|
349
346
|
setPhase('recording');
|
|
@@ -361,16 +358,16 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
361
358
|
try {
|
|
362
359
|
const RNFS = require('react-native-fs');
|
|
363
360
|
videoBase64 = await RNFS.readFile(video.path, 'base64');
|
|
364
|
-
|
|
361
|
+
console.log('Video file read successfully, size:', videoBase64.length, 'bytes');
|
|
365
362
|
} catch (fsError) {
|
|
366
|
-
|
|
363
|
+
console.warn('Could not read video file, using captured frames:', fsError);
|
|
367
364
|
}
|
|
368
365
|
}
|
|
369
366
|
|
|
370
367
|
const finalFrames = frames.length > 0 ? frames : (videoBase64 ? [videoBase64] : []);
|
|
371
368
|
|
|
372
369
|
if (finalFrames.length === 0) {
|
|
373
|
-
|
|
370
|
+
console.error('No frames available, cannot complete');
|
|
374
371
|
setPhase('recording');
|
|
375
372
|
handleRecordingError(new Error('No video frames captured'));
|
|
376
373
|
return;
|
|
@@ -385,15 +382,18 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
385
382
|
sessionId,
|
|
386
383
|
};
|
|
387
384
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
385
|
+
console.log('Video recording completed successfully:', {
|
|
386
|
+
duration: (actualDuration / 1000).toFixed(1) + 's',
|
|
387
|
+
frames: result.frames.length,
|
|
388
|
+
challenges: `${completedChallenges.length}/${challenges.length}`,
|
|
389
|
+
instructionsFollowed: result.instructionsFollowed,
|
|
390
|
+
quality: result.qualityScore.toFixed(0) + '%'
|
|
391
|
+
});
|
|
392
392
|
|
|
393
393
|
isRecordingRef.current = false;
|
|
394
394
|
onComplete(result);
|
|
395
395
|
} catch (error) {
|
|
396
|
-
|
|
396
|
+
console.error('Error processing video:', error);
|
|
397
397
|
setPhase('recording');
|
|
398
398
|
setOverallProgress(0);
|
|
399
399
|
handleRecordingError(error);
|
|
@@ -402,7 +402,7 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
402
402
|
|
|
403
403
|
const startFrameCapture = useCallback(() => {
|
|
404
404
|
if (cameraRef.current && device) {
|
|
405
|
-
|
|
405
|
+
console.log('Starting frame capture mode');
|
|
406
406
|
frameCaptureInterval.current = setInterval(async () => {
|
|
407
407
|
try {
|
|
408
408
|
const photo = await cameraRef.current?.takePhoto({
|
|
@@ -429,14 +429,14 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
429
429
|
}
|
|
430
430
|
}
|
|
431
431
|
} catch (error) {
|
|
432
|
-
|
|
432
|
+
console.warn('Frame capture error:', error);
|
|
433
433
|
}
|
|
434
434
|
}, 100);
|
|
435
435
|
}
|
|
436
436
|
}, [device]);
|
|
437
437
|
|
|
438
438
|
const stopRecording = useCallback(async () => {
|
|
439
|
-
|
|
439
|
+
console.log('Stopping recording...');
|
|
440
440
|
|
|
441
441
|
if (frameCaptureInterval.current) {
|
|
442
442
|
clearInterval(frameCaptureInterval.current);
|
|
@@ -445,20 +445,20 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
445
445
|
|
|
446
446
|
if (videoRecordingRef.current) {
|
|
447
447
|
try {
|
|
448
|
-
|
|
448
|
+
console.log('Stopping video recording');
|
|
449
449
|
const recording = videoRecordingRef.current;
|
|
450
450
|
videoRecordingRef.current = null;
|
|
451
451
|
isRecordingRef.current = false;
|
|
452
452
|
|
|
453
453
|
await recording.stop();
|
|
454
|
-
|
|
454
|
+
console.log('Video recording stopped - waiting for onRecordingFinished callback');
|
|
455
455
|
} catch (error) {
|
|
456
|
-
|
|
456
|
+
console.error('Error stopping video recording:', error);
|
|
457
457
|
isRecordingRef.current = false;
|
|
458
458
|
|
|
459
459
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
460
460
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
461
|
-
|
|
461
|
+
console.log('Video stopped with error, using captured frames');
|
|
462
462
|
const result: VideoRecordingResult = {
|
|
463
463
|
frames,
|
|
464
464
|
duration: actualDuration,
|
|
@@ -477,19 +477,16 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
477
477
|
|
|
478
478
|
const runChallenge = useCallback((index: number) => {
|
|
479
479
|
if (index >= challenges.length) {
|
|
480
|
-
|
|
480
|
+
console.log('All challenges completed, stopping recording');
|
|
481
481
|
setOverallProgress(100);
|
|
482
482
|
|
|
483
483
|
if (isRecordingRef.current) {
|
|
484
484
|
const elapsed = Date.now() - recordingStartTime.current;
|
|
485
|
-
|
|
486
|
-
'Checking Duration',
|
|
487
|
-
`Elapsed: ${(elapsed / 1000).toFixed(1)}s\nMin required: ${(minDurationMs / 1000).toFixed(1)}s`
|
|
488
|
-
);
|
|
485
|
+
console.log('Checking duration - Elapsed:', (elapsed / 1000).toFixed(1), 's, Min required:', (minDurationMs / 1000).toFixed(1), 's');
|
|
489
486
|
|
|
490
487
|
if (elapsed < minDurationMs) {
|
|
491
488
|
const remaining = minDurationMs - elapsed;
|
|
492
|
-
|
|
489
|
+
console.log('Waiting additional', (remaining / 1000).toFixed(1), 's to meet minimum duration');
|
|
493
490
|
setTimeout(() => {
|
|
494
491
|
if (isRecordingRef.current) {
|
|
495
492
|
stopRecording();
|
|
@@ -502,7 +499,7 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
502
499
|
} else {
|
|
503
500
|
const actualDuration = Date.now() - recordingStartTime.current;
|
|
504
501
|
if (actualDuration >= minDurationMs && frames.length > 0) {
|
|
505
|
-
|
|
502
|
+
console.log('Recording already stopped, completing with frames');
|
|
506
503
|
const result: VideoRecordingResult = {
|
|
507
504
|
frames,
|
|
508
505
|
duration: actualDuration,
|
|
@@ -569,38 +566,38 @@ export const VideoRecorder: React.FC<VideoRecorderProps> = ({
|
|
|
569
566
|
recordingStartTime.current = Date.now();
|
|
570
567
|
isRecordingRef.current = true;
|
|
571
568
|
|
|
572
|
-
|
|
569
|
+
console.log('Starting video recording, total duration:', (totalDuration / 1000).toFixed(1), 's');
|
|
573
570
|
|
|
574
571
|
if (cameraRef.current && device) {
|
|
575
572
|
try {
|
|
576
573
|
videoRecordingRef.current = await cameraRef.current.startRecording({
|
|
577
574
|
flash: 'off',
|
|
578
575
|
onRecordingFinished: (video: any) => {
|
|
579
|
-
|
|
576
|
+
console.log('Video recording finished callback called, path:', video?.path || 'N/A');
|
|
580
577
|
handleVideoComplete(video);
|
|
581
578
|
},
|
|
582
579
|
onRecordingError: (error: any) => {
|
|
583
|
-
|
|
580
|
+
console.error('Recording error:', error);
|
|
584
581
|
handleRecordingError(error);
|
|
585
582
|
},
|
|
586
583
|
});
|
|
587
|
-
|
|
584
|
+
console.log('Video recording started successfully');
|
|
588
585
|
} catch (error) {
|
|
589
|
-
|
|
586
|
+
console.warn('Video recording not available, falling back to frame capture:', error);
|
|
590
587
|
startFrameCapture();
|
|
591
588
|
}
|
|
592
589
|
} else {
|
|
593
|
-
|
|
590
|
+
console.log('Camera not available, using frame capture');
|
|
594
591
|
startFrameCapture();
|
|
595
592
|
}
|
|
596
593
|
|
|
597
594
|
runChallenge(0);
|
|
598
595
|
|
|
599
596
|
const timeoutId = setTimeout(() => {
|
|
600
|
-
|
|
597
|
+
console.log('Recording timeout reached, stopping recording');
|
|
601
598
|
if (isRecordingRef.current) {
|
|
602
599
|
stopRecording().catch(err => {
|
|
603
|
-
|
|
600
|
+
console.error('Error stopping recording on timeout:', err);
|
|
604
601
|
});
|
|
605
602
|
}
|
|
606
603
|
}, totalDuration);
|
|
@@ -192,11 +192,37 @@ export const useBiometricSDK = (): UseBiometricSDKResult => {
|
|
|
192
192
|
* Validate identity with all collected data
|
|
193
193
|
*/
|
|
194
194
|
const validateIdentity = useCallback(async () => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
195
|
+
console.log('validateIdentity called, current state:', sdk.getState().currentStep);
|
|
196
|
+
|
|
197
|
+
// Update state immediately to show validation screen
|
|
198
|
+
setState(sdk.getState());
|
|
199
|
+
|
|
200
|
+
// Poll state during validation to catch intermediate updates
|
|
201
|
+
const pollInterval = setInterval(() => {
|
|
202
|
+
if (isMounted.current) {
|
|
203
|
+
const currentState = sdk.getState();
|
|
204
|
+
setState(currentState);
|
|
205
|
+
console.log('State polled - step:', currentState.currentStep, 'progress:', currentState.progress);
|
|
206
|
+
}
|
|
207
|
+
}, 200);
|
|
208
|
+
|
|
209
|
+
try {
|
|
210
|
+
const result = await sdk.validateIdentity();
|
|
211
|
+
clearInterval(pollInterval);
|
|
212
|
+
|
|
213
|
+
if (isMounted.current) {
|
|
214
|
+
const finalState = sdk.getState();
|
|
215
|
+
setState(finalState);
|
|
216
|
+
console.log('Validation complete, final state:', finalState.currentStep, 'result:', result);
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
} catch (error) {
|
|
220
|
+
clearInterval(pollInterval);
|
|
221
|
+
if (isMounted.current) {
|
|
222
|
+
setState(sdk.getState());
|
|
223
|
+
}
|
|
224
|
+
throw error;
|
|
198
225
|
}
|
|
199
|
-
return result;
|
|
200
226
|
}, [sdk]);
|
|
201
227
|
|
|
202
228
|
/**
|