@aws-amplify/ui-react-liveness 3.0.24 → 3.1.0
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/esm/components/FaceLivenessDetector/service/machine/machine.mjs +4 -3
- package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/CustomWebSocketFetchHandler.mjs +21 -5
- package/dist/esm/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.mjs +2 -1
- package/dist/esm/components/FaceLivenessDetector/service/utils/streamProvider.mjs +3 -1
- package/dist/esm/version.mjs +1 -1
- package/dist/index.js +31 -11
- package/dist/types/components/FaceLivenessDetector/service/types/liveness.d.ts +6 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/CustomWebSocketFetchHandler.d.ts +4 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/createStreamingClient/createStreamingClient.d.ts +2 -1
- package/dist/types/components/FaceLivenessDetector/service/utils/streamProvider.d.ts +3 -1
- package/dist/types/version.d.ts +1 -1
- package/package.json +3 -3
|
@@ -884,14 +884,15 @@ const livenessMachine = createMachine({
|
|
|
884
884
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
885
885
|
async openLivenessStreamConnection(context) {
|
|
886
886
|
const { config } = context.componentProps;
|
|
887
|
-
const { credentialProvider, endpointOverride } = config;
|
|
887
|
+
const { credentialProvider, endpointOverride, systemClockOffset } = config;
|
|
888
888
|
const livenessStreamProvider = new LivenessStreamProvider({
|
|
889
889
|
sessionId: context.componentProps.sessionId,
|
|
890
890
|
region: context.componentProps.region,
|
|
891
|
+
systemClockOffset,
|
|
891
892
|
stream: context.videoAssociatedParams.videoMediaStream,
|
|
892
893
|
videoEl: context.videoAssociatedParams.videoEl,
|
|
893
|
-
credentialProvider
|
|
894
|
-
endpointOverride
|
|
894
|
+
credentialProvider,
|
|
895
|
+
endpointOverride,
|
|
895
896
|
});
|
|
896
897
|
responseStream = livenessStreamProvider.getResponseStream();
|
|
897
898
|
return { livenessStreamProvider };
|
|
@@ -56,10 +56,12 @@ class CustomWebSocketFetchHandler {
|
|
|
56
56
|
this.utf8decoder = new TextDecoder(); // default 'utf-8' or 'utf8'
|
|
57
57
|
this.httpHandler = httpHandler;
|
|
58
58
|
if (typeof options === 'function') {
|
|
59
|
-
this.
|
|
59
|
+
this.config = {};
|
|
60
|
+
this.configPromise = options().then((opts) => (this.config = opts ?? {}));
|
|
60
61
|
}
|
|
61
62
|
else {
|
|
62
|
-
this.
|
|
63
|
+
this.config = options ?? {};
|
|
64
|
+
this.configPromise = Promise.resolve(this.config);
|
|
63
65
|
}
|
|
64
66
|
}
|
|
65
67
|
/**
|
|
@@ -99,11 +101,23 @@ class CustomWebSocketFetchHandler {
|
|
|
99
101
|
}),
|
|
100
102
|
};
|
|
101
103
|
}
|
|
104
|
+
updateHttpClientConfig(key, value) {
|
|
105
|
+
this.configPromise = this.configPromise.then((config) => {
|
|
106
|
+
return {
|
|
107
|
+
...config,
|
|
108
|
+
[key]: value,
|
|
109
|
+
};
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
httpHandlerConfigs() {
|
|
113
|
+
return this.config ?? {};
|
|
114
|
+
}
|
|
102
115
|
/**
|
|
103
116
|
* Removes all closing/closed sockets from the socket pool for URL.
|
|
104
117
|
*/
|
|
105
118
|
removeNotUsableSockets(url) {
|
|
106
|
-
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => !
|
|
119
|
+
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => !(socket.readyState === WebSocket.CLOSING ||
|
|
120
|
+
socket.readyState === WebSocket.CLOSED));
|
|
107
121
|
}
|
|
108
122
|
waitForReady(socket, connectionTimeout) {
|
|
109
123
|
return new Promise((resolve, reject) => {
|
|
@@ -147,7 +161,7 @@ class CustomWebSocketFetchHandler {
|
|
|
147
161
|
else {
|
|
148
162
|
resolve({
|
|
149
163
|
done: true,
|
|
150
|
-
value: undefined,
|
|
164
|
+
value: undefined,
|
|
151
165
|
});
|
|
152
166
|
}
|
|
153
167
|
};
|
|
@@ -181,7 +195,9 @@ class CustomWebSocketFetchHandler {
|
|
|
181
195
|
// would already be settled by the time sending chunk throws error.
|
|
182
196
|
// Instead, the notify the output stream to throw if there's
|
|
183
197
|
// exceptions
|
|
184
|
-
|
|
198
|
+
if (err instanceof Error) {
|
|
199
|
+
streamError = err;
|
|
200
|
+
}
|
|
185
201
|
}
|
|
186
202
|
finally {
|
|
187
203
|
// WS status code: https://tools.ietf.org/html/rfc6455#section-7.4
|
|
@@ -7,7 +7,7 @@ import { Signer } from './Signer.mjs';
|
|
|
7
7
|
|
|
8
8
|
const CONNECTION_TIMEOUT = 10000;
|
|
9
9
|
const CUSTOM_USER_AGENT = `${getAmplifyUserAgent()} ${getLivenessUserAgent()}`;
|
|
10
|
-
async function createStreamingClient({ credentialsProvider, endpointOverride, region, }) {
|
|
10
|
+
async function createStreamingClient({ credentialsProvider, endpointOverride, region, systemClockOffset, }) {
|
|
11
11
|
const credentials = await resolveCredentials(credentialsProvider);
|
|
12
12
|
const clientconfig = {
|
|
13
13
|
credentials,
|
|
@@ -17,6 +17,7 @@ async function createStreamingClient({ credentialsProvider, endpointOverride, re
|
|
|
17
17
|
connectionTimeout: CONNECTION_TIMEOUT,
|
|
18
18
|
}),
|
|
19
19
|
signerConstructor: Signer,
|
|
20
|
+
systemClockOffset,
|
|
20
21
|
};
|
|
21
22
|
if (endpointOverride) {
|
|
22
23
|
clientconfig.endpointProvider = () => ({ url: new URL(endpointOverride) });
|
|
@@ -13,7 +13,7 @@ function isEndStreamWithCodeEvent(obj) {
|
|
|
13
13
|
return obj.code !== undefined;
|
|
14
14
|
}
|
|
15
15
|
class LivenessStreamProvider {
|
|
16
|
-
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, }) {
|
|
16
|
+
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, systemClockOffset, }) {
|
|
17
17
|
this.sessionId = sessionId;
|
|
18
18
|
this.region = region;
|
|
19
19
|
this._stream = stream;
|
|
@@ -21,6 +21,7 @@ class LivenessStreamProvider {
|
|
|
21
21
|
this.videoRecorder = new VideoRecorder(stream);
|
|
22
22
|
this.credentialProvider = credentialProvider;
|
|
23
23
|
this.endpointOverride = endpointOverride;
|
|
24
|
+
this.systemClockOffset = systemClockOffset;
|
|
24
25
|
this.initPromise = this.init();
|
|
25
26
|
}
|
|
26
27
|
async getResponseStream() {
|
|
@@ -51,6 +52,7 @@ class LivenessStreamProvider {
|
|
|
51
52
|
credentialsProvider: this.credentialProvider,
|
|
52
53
|
endpointOverride: this.endpointOverride,
|
|
53
54
|
region: this.region,
|
|
55
|
+
systemClockOffset: this.systemClockOffset,
|
|
54
56
|
});
|
|
55
57
|
this.responseStream = await this.startLivenessVideoConnection();
|
|
56
58
|
}
|
package/dist/esm/version.mjs
CHANGED
package/dist/index.js
CHANGED
|
@@ -833,7 +833,7 @@ function getFaceMatchStateInLivenessOval({ face, ovalDetails, initialFaceInterse
|
|
|
833
833
|
return { faceMatchState, faceMatchPercentage };
|
|
834
834
|
}
|
|
835
835
|
|
|
836
|
-
const VERSION = '3.0
|
|
836
|
+
const VERSION = '3.1.0';
|
|
837
837
|
|
|
838
838
|
const BASE_USER_AGENT = `ui-react-liveness/${VERSION}`;
|
|
839
839
|
const getLivenessUserAgent = () => {
|
|
@@ -892,10 +892,12 @@ class CustomWebSocketFetchHandler {
|
|
|
892
892
|
this.utf8decoder = new TextDecoder(); // default 'utf-8' or 'utf8'
|
|
893
893
|
this.httpHandler = httpHandler;
|
|
894
894
|
if (typeof options === 'function') {
|
|
895
|
-
this.
|
|
895
|
+
this.config = {};
|
|
896
|
+
this.configPromise = options().then((opts) => (this.config = opts ?? {}));
|
|
896
897
|
}
|
|
897
898
|
else {
|
|
898
|
-
this.
|
|
899
|
+
this.config = options ?? {};
|
|
900
|
+
this.configPromise = Promise.resolve(this.config);
|
|
899
901
|
}
|
|
900
902
|
}
|
|
901
903
|
/**
|
|
@@ -935,11 +937,23 @@ class CustomWebSocketFetchHandler {
|
|
|
935
937
|
}),
|
|
936
938
|
};
|
|
937
939
|
}
|
|
940
|
+
updateHttpClientConfig(key, value) {
|
|
941
|
+
this.configPromise = this.configPromise.then((config) => {
|
|
942
|
+
return {
|
|
943
|
+
...config,
|
|
944
|
+
[key]: value,
|
|
945
|
+
};
|
|
946
|
+
});
|
|
947
|
+
}
|
|
948
|
+
httpHandlerConfigs() {
|
|
949
|
+
return this.config ?? {};
|
|
950
|
+
}
|
|
938
951
|
/**
|
|
939
952
|
* Removes all closing/closed sockets from the socket pool for URL.
|
|
940
953
|
*/
|
|
941
954
|
removeNotUsableSockets(url) {
|
|
942
|
-
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => !
|
|
955
|
+
this.sockets[url] = (this.sockets[url] ?? []).filter((socket) => !(socket.readyState === WebSocket.CLOSING ||
|
|
956
|
+
socket.readyState === WebSocket.CLOSED));
|
|
943
957
|
}
|
|
944
958
|
waitForReady(socket, connectionTimeout) {
|
|
945
959
|
return new Promise((resolve, reject) => {
|
|
@@ -983,7 +997,7 @@ class CustomWebSocketFetchHandler {
|
|
|
983
997
|
else {
|
|
984
998
|
resolve({
|
|
985
999
|
done: true,
|
|
986
|
-
value: undefined,
|
|
1000
|
+
value: undefined,
|
|
987
1001
|
});
|
|
988
1002
|
}
|
|
989
1003
|
};
|
|
@@ -1017,7 +1031,9 @@ class CustomWebSocketFetchHandler {
|
|
|
1017
1031
|
// would already be settled by the time sending chunk throws error.
|
|
1018
1032
|
// Instead, the notify the output stream to throw if there's
|
|
1019
1033
|
// exceptions
|
|
1020
|
-
|
|
1034
|
+
if (err instanceof Error) {
|
|
1035
|
+
streamError = err;
|
|
1036
|
+
}
|
|
1021
1037
|
}
|
|
1022
1038
|
finally {
|
|
1023
1039
|
// WS status code: https://tools.ietf.org/html/rfc6455#section-7.4
|
|
@@ -1081,7 +1097,7 @@ class Signer extends signatureV4.SignatureV4 {
|
|
|
1081
1097
|
|
|
1082
1098
|
const CONNECTION_TIMEOUT = 10000;
|
|
1083
1099
|
const CUSTOM_USER_AGENT = `${utils.getAmplifyUserAgent()} ${getLivenessUserAgent()}`;
|
|
1084
|
-
async function createStreamingClient({ credentialsProvider, endpointOverride, region, }) {
|
|
1100
|
+
async function createStreamingClient({ credentialsProvider, endpointOverride, region, systemClockOffset, }) {
|
|
1085
1101
|
const credentials = await resolveCredentials(credentialsProvider);
|
|
1086
1102
|
const clientconfig = {
|
|
1087
1103
|
credentials,
|
|
@@ -1091,6 +1107,7 @@ async function createStreamingClient({ credentialsProvider, endpointOverride, re
|
|
|
1091
1107
|
connectionTimeout: CONNECTION_TIMEOUT,
|
|
1092
1108
|
}),
|
|
1093
1109
|
signerConstructor: Signer,
|
|
1110
|
+
systemClockOffset,
|
|
1094
1111
|
};
|
|
1095
1112
|
if (endpointOverride) {
|
|
1096
1113
|
clientconfig.endpointProvider = () => ({ url: new URL(endpointOverride) });
|
|
@@ -1109,7 +1126,7 @@ function isEndStreamWithCodeEvent(obj) {
|
|
|
1109
1126
|
return obj.code !== undefined;
|
|
1110
1127
|
}
|
|
1111
1128
|
class LivenessStreamProvider {
|
|
1112
|
-
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, }) {
|
|
1129
|
+
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, systemClockOffset, }) {
|
|
1113
1130
|
this.sessionId = sessionId;
|
|
1114
1131
|
this.region = region;
|
|
1115
1132
|
this._stream = stream;
|
|
@@ -1117,6 +1134,7 @@ class LivenessStreamProvider {
|
|
|
1117
1134
|
this.videoRecorder = new VideoRecorder(stream);
|
|
1118
1135
|
this.credentialProvider = credentialProvider;
|
|
1119
1136
|
this.endpointOverride = endpointOverride;
|
|
1137
|
+
this.systemClockOffset = systemClockOffset;
|
|
1120
1138
|
this.initPromise = this.init();
|
|
1121
1139
|
}
|
|
1122
1140
|
async getResponseStream() {
|
|
@@ -1147,6 +1165,7 @@ class LivenessStreamProvider {
|
|
|
1147
1165
|
credentialsProvider: this.credentialProvider,
|
|
1148
1166
|
endpointOverride: this.endpointOverride,
|
|
1149
1167
|
region: this.region,
|
|
1168
|
+
systemClockOffset: this.systemClockOffset,
|
|
1150
1169
|
});
|
|
1151
1170
|
this.responseStream = await this.startLivenessVideoConnection();
|
|
1152
1171
|
}
|
|
@@ -2263,14 +2282,15 @@ const livenessMachine = xstate.createMachine({
|
|
|
2263
2282
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
2264
2283
|
async openLivenessStreamConnection(context) {
|
|
2265
2284
|
const { config } = context.componentProps;
|
|
2266
|
-
const { credentialProvider, endpointOverride } = config;
|
|
2285
|
+
const { credentialProvider, endpointOverride, systemClockOffset } = config;
|
|
2267
2286
|
const livenessStreamProvider = new LivenessStreamProvider({
|
|
2268
2287
|
sessionId: context.componentProps.sessionId,
|
|
2269
2288
|
region: context.componentProps.region,
|
|
2289
|
+
systemClockOffset,
|
|
2270
2290
|
stream: context.videoAssociatedParams.videoMediaStream,
|
|
2271
2291
|
videoEl: context.videoAssociatedParams.videoEl,
|
|
2272
|
-
credentialProvider
|
|
2273
|
-
endpointOverride
|
|
2292
|
+
credentialProvider,
|
|
2293
|
+
endpointOverride,
|
|
2274
2294
|
});
|
|
2275
2295
|
responseStream = livenessStreamProvider.getResponseStream();
|
|
2276
2296
|
return { livenessStreamProvider };
|
|
@@ -63,8 +63,13 @@ export interface FaceLivenessDetectorCoreConfig {
|
|
|
63
63
|
* Internal use only - parameter for overriding the liveness endpoint
|
|
64
64
|
*/
|
|
65
65
|
endpointOverride?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Optional parameter for overriding the systemClockOffset for the streaming client
|
|
68
|
+
* Represents the difference between the system clock and the AWS server clock in milliseconds
|
|
69
|
+
*/
|
|
70
|
+
systemClockOffset?: number;
|
|
66
71
|
}
|
|
67
|
-
export type FaceLivenessDetectorConfig = Omit<FaceLivenessDetectorCoreConfig, 'credentialProvider' | 'endpointOverride'>;
|
|
72
|
+
export type FaceLivenessDetectorConfig = Omit<FaceLivenessDetectorCoreConfig, 'credentialProvider' | 'endpointOverride' | 'systemClockOffset'>;
|
|
68
73
|
/**
|
|
69
74
|
* The coordiates of any bounding box
|
|
70
75
|
*/
|
|
@@ -16,7 +16,8 @@ export interface WebSocketFetchHandlerOptions {
|
|
|
16
16
|
*/
|
|
17
17
|
export declare class CustomWebSocketFetchHandler {
|
|
18
18
|
readonly metadata: RequestHandlerMetadata;
|
|
19
|
-
private
|
|
19
|
+
private config;
|
|
20
|
+
private configPromise;
|
|
20
21
|
private readonly httpHandler;
|
|
21
22
|
private readonly sockets;
|
|
22
23
|
private readonly utf8decoder;
|
|
@@ -29,6 +30,8 @@ export declare class CustomWebSocketFetchHandler {
|
|
|
29
30
|
handle(request: HttpRequest): Promise<{
|
|
30
31
|
response: HttpResponse;
|
|
31
32
|
}>;
|
|
33
|
+
updateHttpClientConfig(key: keyof WebSocketFetchHandlerOptions, value: WebSocketFetchHandlerOptions[typeof key]): void;
|
|
34
|
+
httpHandlerConfigs(): WebSocketFetchHandlerOptions;
|
|
32
35
|
/**
|
|
33
36
|
* Removes all closing/closed sockets from the socket pool for URL.
|
|
34
37
|
*/
|
|
@@ -4,6 +4,7 @@ interface CreateClientConfig {
|
|
|
4
4
|
credentialsProvider?: AwsCredentialProvider;
|
|
5
5
|
endpointOverride?: string;
|
|
6
6
|
region: string;
|
|
7
|
+
systemClockOffset?: number;
|
|
7
8
|
}
|
|
8
|
-
export declare function createStreamingClient({ credentialsProvider, endpointOverride, region, }: CreateClientConfig): Promise<RekognitionStreamingClient>;
|
|
9
|
+
export declare function createStreamingClient({ credentialsProvider, endpointOverride, region, systemClockOffset, }: CreateClientConfig): Promise<RekognitionStreamingClient>;
|
|
9
10
|
export {};
|
|
@@ -13,6 +13,7 @@ interface StreamProviderArgs extends StartLivenessStreamInput {
|
|
|
13
13
|
videoEl: HTMLVideoElement;
|
|
14
14
|
credentialProvider?: AwsCredentialProvider;
|
|
15
15
|
endpointOverride?: string;
|
|
16
|
+
systemClockOffset?: number;
|
|
16
17
|
}
|
|
17
18
|
export declare class LivenessStreamProvider {
|
|
18
19
|
sessionId: string;
|
|
@@ -21,12 +22,13 @@ export declare class LivenessStreamProvider {
|
|
|
21
22
|
responseStream: AsyncIterable<LivenessResponseStream>;
|
|
22
23
|
credentialProvider?: AwsCredentialProvider;
|
|
23
24
|
endpointOverride?: string;
|
|
25
|
+
systemClockOffset?: number;
|
|
24
26
|
private _reader;
|
|
25
27
|
private videoEl;
|
|
26
28
|
private _client;
|
|
27
29
|
private _stream;
|
|
28
30
|
private initPromise;
|
|
29
|
-
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, }: StreamProviderArgs);
|
|
31
|
+
constructor({ sessionId, region, stream, videoEl, credentialProvider, endpointOverride, systemClockOffset, }: StreamProviderArgs);
|
|
30
32
|
getResponseStream(): Promise<AsyncIterable<LivenessResponseStream>>;
|
|
31
33
|
startRecordingLivenessVideo(): void;
|
|
32
34
|
sendClientInfo(clientInfo: ClientSessionInformationEvent): void;
|
package/dist/types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const VERSION = "3.0
|
|
1
|
+
export declare const VERSION = "3.1.0";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aws-amplify/ui-react-liveness",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"module": "dist/esm/index.mjs",
|
|
6
6
|
"exports": {
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"dependencies": {
|
|
50
50
|
"@aws-amplify/ui": "6.0.16",
|
|
51
51
|
"@aws-amplify/ui-react": "6.1.12",
|
|
52
|
-
"@aws-sdk/client-rekognitionstreaming": "3.
|
|
52
|
+
"@aws-sdk/client-rekognitionstreaming": "3.605.0",
|
|
53
53
|
"@aws-sdk/util-format-url": "^3.410.0",
|
|
54
54
|
"@smithy/eventstream-serde-browser": "^2.0.4",
|
|
55
55
|
"@smithy/fetch-http-handler": "^2.1.3",
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
"name": "FaceLivenessDetector",
|
|
82
82
|
"path": "dist/esm/index.mjs",
|
|
83
83
|
"import": "{ FaceLivenessDetector }",
|
|
84
|
-
"limit": "
|
|
84
|
+
"limit": "287 kB"
|
|
85
85
|
}
|
|
86
86
|
]
|
|
87
87
|
}
|