Skip to content

Commit 8b77604

Browse files
authored
fix(liveness): replace nanoid with uuid (#6606)
* fix(liveness): replace nanoid with uuid * Add changeset for the liveness package upcoming release.
1 parent 06a6f9a commit 8b77604

File tree

4 files changed

+33
-76
lines changed

4 files changed

+33
-76
lines changed

.changeset/nice-coins-hang.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@aws-amplify/ui-react-liveness': minor
3+
---
4+
5+
feat(liveness): add support for face movement only/no light challenge

packages/react-liveness/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@
6464
"@tensorflow/tfjs-converter": "4.11.0",
6565
"@tensorflow/tfjs-core": "4.11.0",
6666
"@xstate/react": "^3.2.2",
67-
"nanoid": "3.3.8",
6867
"tslib": "^2.5.2",
68+
"uuid": "^11.1.0",
6969
"xstate": "^4.33.6"
7070
},
7171
"devDependencies": {

packages/react-liveness/src/components/FaceLivenessDetector/service/machine/machine.ts

Lines changed: 22 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type {
22
LivenessResponseStream,
33
SessionInformation as ServerSessionInformation,
44
} from '@aws-sdk/client-rekognitionstreaming';
5-
import { nanoid } from 'nanoid';
5+
import { v4 as uuidv4 } from 'uuid';
66
import { createMachine, assign, actions, spawn } from 'xstate';
77

88
import {
@@ -138,7 +138,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
138138
initial: 'initCamera',
139139
predictableActionArguments: true,
140140
context: {
141-
challengeId: nanoid(),
141+
challengeId: uuidv4(),
142142
errorMessage: undefined,
143143
maxFailedAttempts: 0, // Set to 0 for now as we are not allowing front end based retries for streaming
144144
failedAttempts: 0,
@@ -196,10 +196,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
196196
target: 'error',
197197
actions: 'updateErrorStateForConnectionTimeout',
198198
},
199-
RUNTIME_ERROR: {
200-
target: 'error',
201-
actions: 'updateErrorStateForRuntime',
202-
},
199+
RUNTIME_ERROR: { target: 'error', actions: 'updateErrorStateForRuntime' },
203200
MOBILE_LANDSCAPE_WARNING: {
204201
target: 'mobileLandscapeWarning',
205202
actions: 'updateErrorStateForServer',
@@ -223,9 +220,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
223220
target: 'waitForDOMAndCameraDetails',
224221
actions: 'updateVideoMediaStream',
225222
},
226-
onError: {
227-
target: '#livenessMachine.permissionDenied',
228-
},
223+
onError: { target: '#livenessMachine.permissionDenied' },
229224
},
230225
},
231226
waitForDOMAndCameraDetails: {},
@@ -262,14 +257,9 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
262257
start: {
263258
entry: ['initializeFaceDetector', () => {}],
264259
always: [
265-
{
266-
target: 'detectFaceBeforeStart',
267-
cond: 'shouldSkipStartScreen',
268-
},
260+
{ target: 'detectFaceBeforeStart', cond: 'shouldSkipStartScreen' },
269261
],
270-
on: {
271-
BEGIN: 'detectFaceBeforeStart',
272-
},
262+
on: { BEGIN: 'detectFaceBeforeStart' },
273263
},
274264
detectFaceBeforeStart: {
275265
invoke: {
@@ -333,10 +323,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
333323
},
334324
checkFaceDetected: {
335325
after: {
336-
0: {
337-
target: 'cancelOvalDrawingTimeout',
338-
cond: 'hasSingleFace',
339-
},
326+
0: { target: 'cancelOvalDrawingTimeout', cond: 'hasSingleFace' },
340327
100: { target: 'ovalDrawing' },
341328
},
342329
},
@@ -345,11 +332,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
345332
'cancelOvalDrawingTimeout',
346333
'sendTimeoutAfterRecordingDelay',
347334
],
348-
after: {
349-
0: {
350-
target: 'checkRecordingStarted',
351-
},
352-
},
335+
after: { 0: { target: 'checkRecordingStarted' } },
353336
},
354337
checkRecordingStarted: {
355338
entry: () => {},
@@ -401,10 +384,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
401384
target: 'delayBeforeFlash',
402385
cond: 'isFaceMovementAndLightChallenge',
403386
},
404-
{
405-
target: 'success',
406-
cond: 'isFaceMovementChallenge',
407-
},
387+
{ target: 'success', cond: 'isFaceMovementChallenge' },
408388
],
409389
},
410390
delayBeforeFlash: {
@@ -415,21 +395,15 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
415395
invoke: {
416396
src: 'flashColors',
417397
onDone: [
418-
{
419-
target: 'success',
420-
cond: 'hasFreshnessColorShown',
421-
},
398+
{ target: 'success', cond: 'hasFreshnessColorShown' },
422399
{
423400
target: 'flashFreshnessColors',
424401
actions: 'updateFreshnessDetails',
425402
},
426403
],
427404
},
428405
},
429-
success: {
430-
entry: 'stopRecording',
431-
type: 'final',
432-
},
406+
success: { entry: 'stopRecording', type: 'final' },
433407
},
434408
onDone: 'uploading',
435409
},
@@ -469,10 +443,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
469443
retryableTimeout: {
470444
entry: 'updateFailedAttempts',
471445
always: [
472-
{
473-
target: 'timeout',
474-
cond: 'shouldTimeoutOnFailedAttempts',
475-
},
446+
{ target: 'timeout', cond: 'shouldTimeoutOnFailedAttempts' },
476447
{ target: 'start' },
477448
],
478449
},
@@ -723,35 +694,23 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
723694
sendTimeoutAfterOvalDrawingDelay: actions.send(
724695
{
725696
type: 'RUNTIME_ERROR',
726-
data: {
727-
message: 'Client failed to draw oval.',
728-
},
697+
data: { message: 'Client failed to draw oval.' },
729698
},
730-
{
731-
delay: 5000,
732-
id: 'ovalDrawingTimeout',
733-
}
699+
{ delay: 5000, id: 'ovalDrawingTimeout' }
734700
),
735701
cancelOvalDrawingTimeout: actions.cancel('ovalDrawingTimeout'),
736702
sendTimeoutAfterRecordingDelay: actions.send(
737703
{
738704
type: 'RUNTIME_ERROR',
739-
data: {
740-
message: 'Client failed to start recording.',
741-
},
705+
data: { message: 'Client failed to start recording.' },
742706
},
743-
{
744-
delay: 5000,
745-
id: 'recordingTimeout',
746-
}
707+
{ delay: 5000, id: 'recordingTimeout' }
747708
),
748709
cancelRecordingTimeout: actions.cancel('recordingTimeout'),
749710
sendTimeoutAfterOvalMatchDelay: actions.send(
750711
{
751712
type: 'TIMEOUT',
752-
data: {
753-
message: 'Client timed out waiting for face to match oval.',
754-
},
713+
data: { message: 'Client timed out waiting for face to match oval.' },
755714
},
756715
{
757716
delay: (context) => {
@@ -852,15 +811,13 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
852811
videoEl!.pause();
853812
},
854813
resetContext: assign({
855-
challengeId: nanoid(),
814+
challengeId: uuidv4(),
856815
maxFailedAttempts: 0, // Set to 0 for now as we are not allowing front end based retries for streaming
857816
failedAttempts: 0,
858817
componentProps: (context) => context.componentProps,
859818
parsedSessionInformation: (_) => undefined,
860819
videoAssociatedParams: (_) => {
861-
return {
862-
videoConstraints: STATIC_VIDEO_CONSTRAINTS,
863-
};
820+
return { videoConstraints: STATIC_VIDEO_CONSTRAINTS };
864821
},
865822
ovalAssociatedParams: (_) => undefined,
866823
errorState: (_) => undefined,
@@ -939,9 +896,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
939896

940897
// Get initial stream to enumerate devices with non-empty labels
941898
const initialStream = await navigator.mediaDevices.getUserMedia({
942-
video: {
943-
...videoConstraints,
944-
},
899+
video: { ...videoConstraints },
945900
audio: false,
946901
});
947902
const devices = await navigator.mediaDevices.enumerateDevices();
@@ -979,10 +934,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
979934
let realVideoDeviceStream = initialStream;
980935
if (!isInitialStreamFromRealDevice) {
981936
realVideoDeviceStream = await navigator.mediaDevices.getUserMedia({
982-
video: {
983-
...videoConstraints,
984-
deviceId: { exact: deviceId },
985-
},
937+
video: { ...videoConstraints, deviceId: { exact: deviceId } },
986938
audio: false,
987939
});
988940
}
@@ -1168,12 +1120,7 @@ export const livenessMachine = createMachine<LivenessContext, LivenessEvent>(
11681120
videoEl: videoEl!,
11691121
});
11701122

1171-
return {
1172-
faceMatchState,
1173-
ovalDetails,
1174-
scaleFactor,
1175-
initialFace,
1176-
};
1123+
return { faceMatchState, ovalDetails, scaleFactor, initialFace };
11771124
},
11781125
async detectFaceAndMatchOval(context) {
11791126
const { parsedSessionInformation } = context;

yarn.lock

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)