@aws-amplify/ui-react-liveness 3.0.13 → 3.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/dist/esm/components/FaceLivenessDetector/LivenessCheck/LivenessCameraModule.mjs +3 -10
  2. package/dist/esm/components/FaceLivenessDetector/service/machine/index.mjs +144 -158
  3. package/dist/esm/components/FaceLivenessDetector/service/utils/CustomWebSocketFetchHandler.mjs +3 -4
  4. package/dist/esm/components/FaceLivenessDetector/service/utils/liveness.mjs +62 -67
  5. package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +6 -5
  6. package/dist/esm/components/FaceLivenessDetector/service/utils/videoRecorder.mjs +1 -2
  7. package/dist/esm/components/FaceLivenessDetector/types/classNames.mjs +0 -5
  8. package/dist/esm/version.mjs +1 -1
  9. package/dist/index.js +218 -250
  10. package/dist/styles.css +1 -1
  11. package/dist/types/components/FaceLivenessDetector/hooks/useLivenessActor.d.ts +1 -1
  12. package/dist/types/components/FaceLivenessDetector/service/machine/index.d.ts +3 -4
  13. package/dist/types/components/FaceLivenessDetector/service/types/machine.d.ts +17 -18
  14. package/dist/types/components/FaceLivenessDetector/service/utils/liveness.d.ts +7 -9
  15. package/dist/types/components/FaceLivenessDetector/service/utils/streamProvider.d.ts +3 -10
  16. package/dist/types/components/FaceLivenessDetector/service/utils/videoRecorder.d.ts +1 -7
  17. package/dist/types/components/FaceLivenessDetector/shared/index.d.ts +0 -3
  18. package/dist/types/components/FaceLivenessDetector/types/classNames.d.ts +0 -5
  19. package/dist/types/version.d.ts +1 -1
  20. package/package.json +3 -3
  21. package/dist/types/components/FaceLivenessDetector/shared/GoodFitIllustration.d.ts +0 -7
  22. package/dist/types/components/FaceLivenessDetector/shared/StartScreenFigure.d.ts +0 -8
  23. package/dist/types/components/FaceLivenessDetector/shared/TooFarIllustration.d.ts +0 -7
@@ -79,22 +79,15 @@ const LivenessCameraModule = (props) => {
79
79
  const [mediaHeight, setMediaHeight] = useState(videoHeight);
80
80
  const [aspectRatio, setAspectRatio] = useState(() => videoWidth && videoHeight ? videoWidth / videoHeight : 0);
81
81
  React__default.useEffect(() => {
82
- if (canvasRef &&
83
- videoRef &&
84
- canvasRef.current &&
85
- videoRef.current &&
86
- videoStream &&
87
- isStartView) {
82
+ if (canvasRef?.current && videoRef?.current && videoStream && isStartView) {
88
83
  drawStaticOval(canvasRef.current, videoRef.current, videoStream);
89
84
  }
90
85
  }, [canvasRef, videoRef, videoStream, colorMode, isStartView]);
91
86
  React__default.useEffect(() => {
92
87
  const updateColorModeHandler = (e) => {
93
88
  if (e.matches &&
94
- canvasRef &&
95
- videoRef &&
96
- canvasRef.current &&
97
- videoRef.current &&
89
+ canvasRef?.current &&
90
+ videoRef?.current &&
98
91
  videoStream &&
99
92
  isStartView) {
100
93
  drawStaticOval(canvasRef.current, videoRef.current, videoStream);
@@ -1,3 +1,4 @@
1
+ import { nanoid } from 'nanoid';
1
2
  import { createMachine, assign, spawn, actions } from 'xstate';
2
3
  import { drawStaticOval, getBoundingBox, getColorsSequencesFromSessionInformation, isCameraDeviceVirtual, getFaceMatchState, isFaceDistanceBelowThreshold, estimateIllumination, getOvalDetailsFromSessionInformation, generateBboxFromLandmarks, drawLivenessOvalInCanvas, getOvalBoundingBox, getIntersectionOverUnion, getFaceMatchStateInLivenessOval, getStaticLivenessOvalDetails } from '../utils/liveness.mjs';
3
4
  import { FaceMatchState } from '../types/liveness.mjs';
@@ -5,16 +6,68 @@ import { LivenessErrorState } from '../types/error.mjs';
5
6
  import { BlazeFaceFaceDetection } from '../utils/blazefaceFaceDetection.mjs';
6
7
  import { LivenessStreamProvider } from '../utils/streamProvider.mjs';
7
8
  import { FreshnessColorDisplay } from '../utils/freshnessColorDisplay.mjs';
8
- import { nanoid } from 'nanoid';
9
9
  import { isServerSesssionInformationEvent, isDisconnectionEvent, isValidationExceptionEvent, isInternalServerExceptionEvent, isThrottlingExceptionEvent, isServiceQuotaExceededExceptionEvent, isInvalidSignatureRegionException } from '../utils/eventUtils.mjs';
10
10
  import { STATIC_VIDEO_CONSTRAINTS } from '../../utils/helpers.mjs';
11
11
  import { WS_CLOSURE_CODE } from '../utils/constants.mjs';
12
12
 
13
- /* eslint-disable */
14
- const MIN_FACE_MATCH_TIME = 1000;
13
+ const CAMERA_ID_KEY = 'AmplifyLivenessCameraId';
15
14
  const DEFAULT_FACE_FIT_TIMEOUT = 7000;
15
+ const MIN_FACE_MATCH_TIME = 1000;
16
16
  let responseStream;
17
- const CAMERA_ID_KEY = 'AmplifyLivenessCameraId';
17
+ const responseStreamActor = async (callback) => {
18
+ try {
19
+ const stream = await responseStream;
20
+ for await (const event of stream) {
21
+ if (isServerSesssionInformationEvent(event)) {
22
+ callback({
23
+ type: 'SET_SESSION_INFO',
24
+ data: {
25
+ sessionInfo: event.ServerSessionInformationEvent.SessionInformation,
26
+ },
27
+ });
28
+ }
29
+ else if (isDisconnectionEvent(event)) {
30
+ callback({ type: 'DISCONNECT_EVENT' });
31
+ }
32
+ else if (isValidationExceptionEvent(event)) {
33
+ callback({
34
+ type: 'SERVER_ERROR',
35
+ data: { error: { ...event.ValidationException } },
36
+ });
37
+ }
38
+ else if (isInternalServerExceptionEvent(event)) {
39
+ callback({
40
+ type: 'SERVER_ERROR',
41
+ data: { error: { ...event.InternalServerException } },
42
+ });
43
+ }
44
+ else if (isThrottlingExceptionEvent(event)) {
45
+ callback({
46
+ type: 'SERVER_ERROR',
47
+ data: { error: { ...event.ThrottlingException } },
48
+ });
49
+ }
50
+ else if (isServiceQuotaExceededExceptionEvent(event)) {
51
+ callback({
52
+ type: 'SERVER_ERROR',
53
+ data: { error: { ...event.ServiceQuotaExceededException } },
54
+ });
55
+ }
56
+ }
57
+ }
58
+ catch (error) {
59
+ let returnedError = error;
60
+ if (isInvalidSignatureRegionException(error)) {
61
+ returnedError = new Error('Invalid region in FaceLivenessDetector or credentials are scoped to the wrong region.');
62
+ }
63
+ if (returnedError instanceof Error) {
64
+ callback({
65
+ type: 'SERVER_ERROR',
66
+ data: { error: returnedError },
67
+ });
68
+ }
69
+ }
70
+ };
18
71
  function getLastSelectedCameraId() {
19
72
  return localStorage.getItem(CAMERA_ID_KEY);
20
73
  }
@@ -99,12 +152,12 @@ const livenessMachine = createMachine({
99
152
  },
100
153
  states: {
101
154
  cameraCheck: {
102
- entry: ['resetErrorState'],
155
+ entry: 'resetErrorState',
103
156
  invoke: {
104
157
  src: 'checkVirtualCameraAndGetStream',
105
158
  onDone: {
106
159
  target: 'waitForDOMAndCameraDetails',
107
- actions: ['updateVideoMediaStream'],
160
+ actions: 'updateVideoMediaStream',
108
161
  },
109
162
  onError: {
110
163
  target: 'permissionDenied',
@@ -137,7 +190,7 @@ const livenessMachine = createMachine({
137
190
  src: 'detectFace',
138
191
  onDone: {
139
192
  target: 'checkFaceDetectedBeforeStart',
140
- actions: ['updateFaceMatchBeforeStartDetails'],
193
+ actions: 'updateFaceMatchBeforeStartDetails',
141
194
  },
142
195
  },
143
196
  },
@@ -155,7 +208,7 @@ const livenessMachine = createMachine({
155
208
  src: 'detectFaceDistance',
156
209
  onDone: {
157
210
  target: 'checkFaceDistanceBeforeRecording',
158
- actions: ['updateFaceDistanceBeforeRecording'],
211
+ actions: 'updateFaceDistanceBeforeRecording',
159
212
  },
160
213
  },
161
214
  },
@@ -199,7 +252,7 @@ const livenessMachine = createMachine({
199
252
  initial: 'ovalDrawing',
200
253
  states: {
201
254
  ovalDrawing: {
202
- entry: ['sendTimeoutAfterOvalDrawingDelay'],
255
+ entry: 'sendTimeoutAfterOvalDrawingDelay',
203
256
  invoke: {
204
257
  src: 'detectInitialFaceAndDrawOval',
205
258
  onDone: {
@@ -229,13 +282,13 @@ const livenessMachine = createMachine({
229
282
  0: {
230
283
  target: 'ovalMatching',
231
284
  cond: 'hasRecordingStarted',
232
- actions: ['updateRecordingStartTimestampMs'],
285
+ actions: 'updateRecordingStartTimestampMs',
233
286
  },
234
287
  100: { target: 'checkRecordingStarted' },
235
288
  },
236
289
  },
237
290
  ovalMatching: {
238
- entry: ['cancelOvalDrawingTimeout'],
291
+ entry: 'cancelOvalDrawingTimeout',
239
292
  invoke: {
240
293
  src: 'detectFaceAndMatchOval',
241
294
  onDone: {
@@ -283,7 +336,7 @@ const livenessMachine = createMachine({
283
336
  },
284
337
  },
285
338
  success: {
286
- entry: ['stopRecording'],
339
+ entry: 'stopRecording',
287
340
  type: 'final',
288
341
  },
289
342
  },
@@ -336,13 +389,11 @@ const livenessMachine = createMachine({
336
389
  },
337
390
  permissionDenied: {
338
391
  entry: 'callUserPermissionDeniedCallback',
339
- on: {
340
- RETRY_CAMERA_CHECK: 'cameraCheck',
341
- },
392
+ on: { RETRY_CAMERA_CHECK: 'cameraCheck' },
342
393
  },
343
394
  mobileLandscapeWarning: {
344
395
  entry: 'callMobileLandscapeWarningCallback',
345
- always: [{ target: 'error' }],
396
+ always: { target: 'error' },
346
397
  },
347
398
  timeout: {
348
399
  entry: ['cleanUpResources', 'callUserTimeoutCallback', 'freezeStream'],
@@ -359,7 +410,7 @@ const livenessMachine = createMachine({
359
410
  },
360
411
  userCancel: {
361
412
  entry: ['cleanUpResources', 'callUserCancelCallback', 'resetContext'],
362
- always: [{ target: 'cameraCheck' }],
413
+ always: { target: 'cameraCheck' },
363
414
  },
364
415
  },
365
416
  }, {
@@ -368,16 +419,17 @@ const livenessMachine = createMachine({
368
419
  responseStreamActorRef: () => spawn(responseStreamActor),
369
420
  }),
370
421
  updateFailedAttempts: assign({
371
- failedAttempts: (context) => {
372
- return context.failedAttempts + 1;
373
- },
422
+ failedAttempts: (context) => context.failedAttempts + 1,
374
423
  }),
375
424
  updateVideoMediaStream: assign({
376
425
  videoAssociatedParams: (context, event) => ({
377
426
  ...context.videoAssociatedParams,
378
- videoMediaStream: event.data?.stream,
379
- selectedDeviceId: event.data?.selectedDeviceId,
380
- selectableDevices: event.data?.selectableDevices,
427
+ videoMediaStream: event.data
428
+ ?.stream,
429
+ selectedDeviceId: event.data
430
+ ?.selectedDeviceId,
431
+ selectableDevices: event.data
432
+ ?.selectableDevices,
381
433
  }),
382
434
  }),
383
435
  initializeFaceDetector: assign({
@@ -386,29 +438,23 @@ const livenessMachine = createMachine({
386
438
  const { faceModelUrl, binaryPath } = componentProps.config;
387
439
  const faceDetector = new BlazeFaceFaceDetection(binaryPath, faceModelUrl);
388
440
  faceDetector.triggerModelLoading();
389
- return {
390
- ...context.ovalAssociatedParams,
391
- faceDetector,
392
- };
441
+ return { ...context.ovalAssociatedParams, faceDetector };
393
442
  },
394
443
  }),
395
444
  updateLivenessStreamProvider: assign({
396
- livenessStreamProvider: (context, event) => {
397
- return event.data?.livenessStreamProvider;
398
- },
445
+ livenessStreamProvider: (context, event) => event.data?.livenessStreamProvider,
399
446
  }),
400
447
  setDOMAndCameraDetails: assign({
401
- videoAssociatedParams: (context, event) => {
402
- return {
403
- ...context.videoAssociatedParams,
404
- videoEl: event.data?.videoEl,
405
- canvasEl: event.data?.canvasEl,
406
- isMobile: event.data?.isMobile,
407
- };
408
- },
448
+ videoAssociatedParams: (context, event) => ({
449
+ ...context.videoAssociatedParams,
450
+ videoEl: event.data?.videoEl,
451
+ canvasEl: event.data?.canvasEl,
452
+ isMobile: event.data?.isMobile,
453
+ }),
409
454
  freshnessColorAssociatedParams: (context, event) => ({
410
455
  ...context.freshnessColorAssociatedParams,
411
- freshnessColorEl: event.data?.freshnessColorEl,
456
+ freshnessColorEl: event.data
457
+ ?.freshnessColorEl,
412
458
  }),
413
459
  }),
414
460
  updateDeviceAndStream: assign({
@@ -416,8 +462,10 @@ const livenessMachine = createMachine({
416
462
  setLastSelectedCameraId(event.data?.newDeviceId);
417
463
  return {
418
464
  ...context.videoAssociatedParams,
419
- selectedDeviceId: event.data?.newDeviceId,
420
- videoMediaStream: event.data?.newStream,
465
+ selectedDeviceId: event.data
466
+ ?.newDeviceId,
467
+ videoMediaStream: event.data
468
+ ?.newStream,
421
469
  };
422
470
  },
423
471
  }),
@@ -478,50 +526,49 @@ const livenessMachine = createMachine({
478
526
  'recording') {
479
527
  context.livenessStreamProvider.startRecordingLivenessVideo();
480
528
  }
481
- return {
482
- ...context.videoAssociatedParams,
483
- };
529
+ return { ...context.videoAssociatedParams };
484
530
  },
485
531
  }),
486
- stopRecording: (context) => { },
532
+ stopRecording: () => { },
487
533
  updateFaceMatchBeforeStartDetails: assign({
488
- faceMatchStateBeforeStart: (_, event) => {
489
- return event.data.faceMatchState;
490
- },
534
+ faceMatchStateBeforeStart: (_, event) => event.data.faceMatchState,
491
535
  }),
492
536
  updateFaceDistanceBeforeRecording: assign({
493
- isFaceFarEnoughBeforeRecording: (_, event) => {
494
- return event.data.isFaceFarEnoughBeforeRecording;
495
- },
537
+ isFaceFarEnoughBeforeRecording: (_, event) => !!event.data.isFaceFarEnoughBeforeRecording,
496
538
  }),
497
539
  updateFaceDistanceWhileLoading: assign({
498
- isFaceFarEnoughBeforeRecording: (_, event) => {
499
- return event.data.isFaceFarEnoughBeforeRecording;
500
- },
501
- errorState: (_, event) => {
502
- return event.data?.error;
503
- },
540
+ isFaceFarEnoughBeforeRecording: (_, event) => !!event.data.isFaceFarEnoughBeforeRecording,
541
+ errorState: (_, event) => event.data?.error,
504
542
  }),
505
543
  updateOvalAndFaceDetailsPostDraw: assign({
506
544
  ovalAssociatedParams: (context, event) => ({
507
545
  ...context.ovalAssociatedParams,
508
- initialFace: event.data.initialFace,
509
- ovalDetails: event.data.ovalDetails,
510
- scaleFactor: event.data.scaleFactor,
546
+ initialFace: event.data
547
+ .initialFace,
548
+ ovalDetails: event.data
549
+ .ovalDetails,
550
+ scaleFactor: event.data
551
+ .scaleFactor,
511
552
  }),
512
553
  faceMatchAssociatedParams: (context, event) => ({
513
554
  ...context.faceMatchAssociatedParams,
514
- faceMatchState: event.data.faceMatchState,
515
- illuminationState: event.data.illuminationState,
555
+ faceMatchState: event.data
556
+ .faceMatchState,
557
+ illuminationState: event.data
558
+ .illuminationState,
516
559
  }),
517
560
  }),
518
561
  updateFaceDetailsPostMatch: assign({
519
562
  faceMatchAssociatedParams: (context, event) => ({
520
563
  ...context.faceMatchAssociatedParams,
521
- faceMatchState: event.data.faceMatchState,
522
- faceMatchPercentage: event.data.faceMatchPercentage,
523
- illuminationState: event.data.illuminationState,
524
- currentDetectedFace: event.data.detectedFace,
564
+ faceMatchState: event.data
565
+ .faceMatchState,
566
+ faceMatchPercentage: event.data
567
+ .faceMatchPercentage,
568
+ illuminationState: event.data
569
+ .illuminationState,
570
+ currentDetectedFace: event.data
571
+ .detectedFace,
525
572
  }),
526
573
  }),
527
574
  updateEndFaceMatch: assign({
@@ -544,40 +591,30 @@ const livenessMachine = createMachine({
544
591
  };
545
592
  },
546
593
  }),
547
- resetErrorState: assign({
548
- errorState: (_) => undefined,
549
- }),
594
+ resetErrorState: assign({ errorState: (_) => undefined }),
550
595
  updateErrorStateForTimeout: assign({
551
- errorState: (_, event) => {
552
- return event.data?.errorState || LivenessErrorState.TIMEOUT;
553
- },
596
+ errorState: (_, event) => event.data?.errorState || LivenessErrorState.TIMEOUT,
554
597
  }),
555
598
  updateErrorStateForRuntime: assign({
556
- errorState: (_, event) => {
557
- return event.data?.errorState || LivenessErrorState.RUNTIME_ERROR;
558
- },
599
+ errorState: (_, event) => event.data?.errorState ||
600
+ LivenessErrorState.RUNTIME_ERROR,
559
601
  }),
560
602
  updateErrorStateForServer: assign({
561
603
  errorState: (_) => LivenessErrorState.SERVER_ERROR,
562
604
  }),
563
- clearErrorState: assign({
564
- errorState: (_) => undefined,
565
- }),
605
+ clearErrorState: assign({ errorState: (_) => undefined }),
566
606
  updateSessionInfo: assign({
567
- serverSessionInformation: (context, event) => {
607
+ serverSessionInformation: (_, event) => {
568
608
  return event.data.sessionInfo;
569
609
  },
570
610
  }),
571
- updateShouldDisconnect: assign({
572
- shouldDisconnect: (context) => {
573
- return true;
574
- },
575
- }),
611
+ updateShouldDisconnect: assign({ shouldDisconnect: () => true }),
576
612
  updateFreshnessDetails: assign({
577
613
  freshnessColorAssociatedParams: (context, event) => {
578
614
  return {
579
615
  ...context.freshnessColorAssociatedParams,
580
- freshnessColorsComplete: event.data.freshnessColorsComplete,
616
+ freshnessColorsComplete: event.data
617
+ .freshnessColorsComplete,
581
618
  };
582
619
  },
583
620
  }),
@@ -602,7 +639,7 @@ const livenessMachine = createMachine({
602
639
  delay: (context) => {
603
640
  return (context.serverSessionInformation?.Challenge
604
641
  ?.FaceMovementAndLightChallenge?.ChallengeConfig
605
- ?.OvalFitTimeout || DEFAULT_FACE_FIT_TIMEOUT);
642
+ ?.OvalFitTimeout ?? DEFAULT_FACE_FIT_TIMEOUT);
606
643
  },
607
644
  id: 'ovalMatchTimeout',
608
645
  }),
@@ -644,14 +681,12 @@ const livenessMachine = createMachine({
644
681
  },
645
682
  }),
646
683
  callMobileLandscapeWarningCallback: assign({
647
- errorState: (context) => {
648
- return LivenessErrorState.MOBILE_LANDSCAPE_ERROR;
649
- },
684
+ errorState: () => LivenessErrorState.MOBILE_LANDSCAPE_ERROR,
650
685
  }),
651
- callUserCancelCallback: async (context) => {
686
+ callUserCancelCallback: (context) => {
652
687
  context.componentProps.onUserCancel?.();
653
688
  },
654
- callUserTimeoutCallback: async (context) => {
689
+ callUserTimeoutCallback: (context) => {
655
690
  const error = new Error('Client Timeout');
656
691
  error.name = context.errorState;
657
692
  const livenessError = {
@@ -660,14 +695,14 @@ const livenessMachine = createMachine({
660
695
  };
661
696
  context.componentProps.onError?.(livenessError);
662
697
  },
663
- callErrorCallback: async (context, event) => {
698
+ callErrorCallback: (context, event) => {
664
699
  const livenessError = {
665
700
  state: context.errorState,
666
701
  error: event.data?.error || event.data,
667
702
  };
668
703
  context.componentProps.onError?.(livenessError);
669
704
  },
670
- cleanUpResources: async (context) => {
705
+ cleanUpResources: (context) => {
671
706
  const { freshnessColorEl } = context.freshnessColorAssociatedParams;
672
707
  if (freshnessColorEl) {
673
708
  freshnessColorEl.style.display = 'none';
@@ -686,9 +721,9 @@ const livenessMachine = createMachine({
686
721
  else if (context.errorState === undefined) {
687
722
  closureCode = WS_CLOSURE_CODE.USER_CANCEL;
688
723
  }
689
- await context.livenessStreamProvider?.endStreamWithCode(closureCode);
724
+ context.livenessStreamProvider?.endStreamWithCode(closureCode);
690
725
  },
691
- freezeStream: async (context) => {
726
+ freezeStream: (context) => {
692
727
  const { videoMediaStream, videoEl } = context.videoAssociatedParams;
693
728
  context.isRecordingStopped = true;
694
729
  videoEl?.pause();
@@ -696,7 +731,7 @@ const livenessMachine = createMachine({
696
731
  track.stop();
697
732
  });
698
733
  },
699
- pauseVideoStream: async (context) => {
734
+ pauseVideoStream: (context) => {
700
735
  const { videoEl } = context.videoAssociatedParams;
701
736
  context.isRecordingStopped = true;
702
737
  videoEl.pause();
@@ -752,7 +787,6 @@ const livenessMachine = createMachine({
752
787
  hasNotEnoughFaceDistanceBeforeRecording: (context) => {
753
788
  return !context.isFaceFarEnoughBeforeRecording;
754
789
  },
755
- hasLivenessCheckSucceeded: (_, __, meta) => meta.state.event.data.isLive,
756
790
  hasFreshnessColorShown: (context) => context.freshnessColorAssociatedParams.freshnessColorsComplete,
757
791
  hasServerSessionInfo: (context) => {
758
792
  return context.serverSessionInformation !== undefined;
@@ -805,14 +839,15 @@ const livenessMachine = createMachine({
805
839
  // If the initial stream is of real camera, use it otherwise use the first real camera
806
840
  const initialStreamDeviceId = tracksWithMoreThan15Fps[0].getSettings().deviceId;
807
841
  const isInitialStreamFromRealDevice = realVideoDevices.some((device) => device.deviceId === initialStreamDeviceId);
808
- let deviceId = initialStreamDeviceId;
842
+ const deviceId = isInitialStreamFromRealDevice
843
+ ? initialStreamDeviceId
844
+ : realVideoDevices[0].deviceId;
809
845
  let realVideoDeviceStream = initialStream;
810
846
  if (!isInitialStreamFromRealDevice) {
811
- deviceId = realVideoDevices[0].deviceId;
812
847
  realVideoDeviceStream = await navigator.mediaDevices.getUserMedia({
813
848
  video: {
814
849
  ...videoConstraints,
815
- deviceId: { exact: realVideoDevices[0].deviceId },
850
+ deviceId: { exact: deviceId },
816
851
  },
817
852
  audio: false,
818
853
  });
@@ -824,6 +859,7 @@ const livenessMachine = createMachine({
824
859
  selectableDevices: realVideoDevices,
825
860
  };
826
861
  },
862
+ // eslint-disable-next-line @typescript-eslint/require-await
827
863
  async openLivenessStreamConnection(context) {
828
864
  const { config } = context.componentProps;
829
865
  const { credentialProvider, endpointOverride } = config;
@@ -846,6 +882,7 @@ const livenessMachine = createMachine({
846
882
  await faceDetector.modelLoadingPromise;
847
883
  }
848
884
  catch (err) {
885
+ // eslint-disable-next-line no-console
849
886
  console.log({ err });
850
887
  }
851
888
  // detect face
@@ -885,10 +922,11 @@ const livenessMachine = createMachine({
885
922
  });
886
923
  const { isDistanceBelowThreshold: isFaceFarEnoughBeforeRecording, error, } = await isFaceDistanceBelowThreshold({
887
924
  faceDetector: faceDetector,
888
- videoEl: videoEl,
925
+ isMobile,
889
926
  ovalDetails,
927
+ videoEl: videoEl,
928
+ // if this is the second face distance check reduce the threshold
890
929
  reduceThreshold: faceDistanceCheckBeforeRecording,
891
- isMobile,
892
930
  });
893
931
  return { isFaceFarEnoughBeforeRecording, error };
894
932
  },
@@ -902,6 +940,7 @@ const livenessMachine = createMachine({
902
940
  await livenessStreamProvider.videoRecorder.recorderStarted;
903
941
  }
904
942
  catch (err) {
943
+ // eslint-disable-next-line no-console
905
944
  console.log({ err });
906
945
  }
907
946
  // detect face
@@ -917,6 +956,7 @@ const livenessMachine = createMachine({
917
956
  break;
918
957
  }
919
958
  case 1: {
959
+ //exactly one face detected;
920
960
  faceMatchState = FaceMatchState.FACE_IDENTIFIED;
921
961
  initialFace = detectedFaces[0];
922
962
  break;
@@ -1063,7 +1103,7 @@ const livenessMachine = createMachine({
1063
1103
  throw new Error('Video chunks not recorded successfully.');
1064
1104
  }
1065
1105
  livenessStreamProvider.sendClientInfo(livenessActionDocument);
1066
- await livenessStreamProvider.dispatchStopVideoEvent();
1106
+ livenessStreamProvider.dispatchStopVideoEvent();
1067
1107
  },
1068
1108
  async getLiveness(context) {
1069
1109
  const { onAnalysisComplete } = context.componentProps;
@@ -1072,59 +1112,5 @@ const livenessMachine = createMachine({
1072
1112
  },
1073
1113
  },
1074
1114
  });
1075
- const responseStreamActor = async (callback) => {
1076
- try {
1077
- const stream = await responseStream;
1078
- for await (const event of stream) {
1079
- if (isServerSesssionInformationEvent(event)) {
1080
- callback({
1081
- type: 'SET_SESSION_INFO',
1082
- data: {
1083
- sessionInfo: event.ServerSessionInformationEvent.SessionInformation,
1084
- },
1085
- });
1086
- }
1087
- else if (isDisconnectionEvent(event)) {
1088
- callback({ type: 'DISCONNECT_EVENT' });
1089
- }
1090
- else if (isValidationExceptionEvent(event)) {
1091
- callback({
1092
- type: 'SERVER_ERROR',
1093
- data: { error: { ...event.ValidationException } },
1094
- });
1095
- }
1096
- else if (isInternalServerExceptionEvent(event)) {
1097
- callback({
1098
- type: 'SERVER_ERROR',
1099
- data: { error: { ...event.InternalServerException } },
1100
- });
1101
- }
1102
- else if (isThrottlingExceptionEvent(event)) {
1103
- callback({
1104
- type: 'SERVER_ERROR',
1105
- data: { error: { ...event.ThrottlingException } },
1106
- });
1107
- }
1108
- else if (isServiceQuotaExceededExceptionEvent(event)) {
1109
- callback({
1110
- type: 'SERVER_ERROR',
1111
- data: { error: { ...event.ServiceQuotaExceededException } },
1112
- });
1113
- }
1114
- }
1115
- }
1116
- catch (error) {
1117
- let returnedError = error;
1118
- if (isInvalidSignatureRegionException(error)) {
1119
- returnedError = new Error('Invalid region in FaceLivenessDetector or credentials are scoped to the wrong region.');
1120
- }
1121
- if (returnedError instanceof Error) {
1122
- callback({
1123
- type: 'SERVER_ERROR',
1124
- data: { error: returnedError },
1125
- });
1126
- }
1127
- }
1128
- };
1129
1115
 
1130
- export { MIN_FACE_MATCH_TIME, livenessMachine };
1116
+ export { livenessMachine };
@@ -23,10 +23,10 @@ const getIterator = (stream) => {
23
23
  return stream;
24
24
  }
25
25
  if (isReadableStream(stream)) {
26
- //If stream is a ReadableStream, transfer the ReadableStream to async iterable.
26
+ // If stream is a ReadableStream, transfer the ReadableStream to async iterable.
27
27
  return readableStreamtoIterable(stream);
28
28
  }
29
- //For other types, just wrap them with an async iterable.
29
+ // For other types, just wrap them with an async iterable.
30
30
  return {
31
31
  [Symbol.asyncIterator]: async function* () {
32
32
  yield stream;
@@ -85,8 +85,7 @@ class CustomWebSocketFetchHandler {
85
85
  }
86
86
  this.sockets[url].push(socket);
87
87
  socket.binaryType = 'arraybuffer';
88
- const { connectionTimeout = DEFAULT_WS_CONNECTION_TIMEOUT_MS } = await this
89
- .configPromise;
88
+ const { connectionTimeout = DEFAULT_WS_CONNECTION_TIMEOUT_MS } = await this.configPromise;
90
89
  await this.waitForReady(socket, connectionTimeout);
91
90
  const { body } = request;
92
91
  const bodyStream = getIterator(body);