@hexar/biometric-identity-sdk-core 1.0.12 → 1.0.13
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.
|
@@ -311,7 +311,9 @@ class BiometricIdentitySDK {
|
|
|
311
311
|
logger_1.logger.info('Sending validation request to backend', {
|
|
312
312
|
framesCount: videoFrames.length,
|
|
313
313
|
duration: this.state.videoData.duration,
|
|
314
|
-
challengesCount: this.state.videoData.challengesCompleted?.length || 0
|
|
314
|
+
challengesCount: this.state.videoData.challengesCompleted?.length || 0,
|
|
315
|
+
frontImageSize: this.state.frontID.data?.length || 0,
|
|
316
|
+
backImageSize: this.state.backID?.data?.length || 0
|
|
315
317
|
});
|
|
316
318
|
const response = await this.backendClient.fullValidation({
|
|
317
319
|
frontIdImage: this.state.frontID.data,
|
|
@@ -324,8 +326,12 @@ class BiometricIdentitySDK {
|
|
|
324
326
|
return this.backendClient.convertToValidationResult(response);
|
|
325
327
|
}
|
|
326
328
|
catch (error) {
|
|
327
|
-
logger_1.logger.error('Backend validation failed',
|
|
328
|
-
|
|
329
|
+
logger_1.logger.error('Backend validation failed', {
|
|
330
|
+
errorMessage: error?.message,
|
|
331
|
+
errorName: error?.name,
|
|
332
|
+
errorStack: error?.stack
|
|
333
|
+
});
|
|
334
|
+
throw this.createError(types_1.BiometricErrorCode.NETWORK_ERROR, error?.message || 'Backend validation failed', error);
|
|
329
335
|
}
|
|
330
336
|
}
|
|
331
337
|
/**
|
|
@@ -88,10 +88,10 @@ class BackendClient {
|
|
|
88
88
|
*/
|
|
89
89
|
async fullValidation(params) {
|
|
90
90
|
if (!this.currentSessionId) {
|
|
91
|
-
|
|
91
|
+
logger_1.logger.info('No session ID, generating challenge');
|
|
92
92
|
await this.generateChallenge();
|
|
93
93
|
}
|
|
94
|
-
|
|
94
|
+
const requestBody = {
|
|
95
95
|
front_id_image: params.frontIdImage,
|
|
96
96
|
back_id_image: params.backIdImage,
|
|
97
97
|
video_frames: params.videoFrames,
|
|
@@ -101,7 +101,20 @@ class BackendClient {
|
|
|
101
101
|
document_type: params.documentType,
|
|
102
102
|
country_code: params.countryCode,
|
|
103
103
|
device_info: params.deviceInfo,
|
|
104
|
+
};
|
|
105
|
+
logger_1.logger.info('Full validation request', {
|
|
106
|
+
hasSessionId: !!this.currentSessionId,
|
|
107
|
+
sessionId: this.currentSessionId,
|
|
108
|
+
videoFramesCount: params.videoFrames.length,
|
|
109
|
+
hasFrontImage: !!params.frontIdImage,
|
|
110
|
+
hasBackImage: !!params.backIdImage,
|
|
111
|
+
frontImageLength: params.frontIdImage?.length || 0,
|
|
112
|
+
backImageLength: params.backIdImage?.length || 0,
|
|
113
|
+
averageFrameLength: params.videoFrames.length > 0
|
|
114
|
+
? Math.round(params.videoFrames.reduce((sum, f) => sum + f.length, 0) / params.videoFrames.length)
|
|
115
|
+
: 0
|
|
104
116
|
});
|
|
117
|
+
return this.request('/api/v1/validate', 'POST', requestBody);
|
|
105
118
|
}
|
|
106
119
|
/**
|
|
107
120
|
* Convert backend response to SDK ValidationResult format
|
|
@@ -189,23 +202,45 @@ class BackendClient {
|
|
|
189
202
|
});
|
|
190
203
|
clearTimeout(timeoutId);
|
|
191
204
|
if (!response.ok) {
|
|
192
|
-
|
|
205
|
+
let errorData = {};
|
|
206
|
+
try {
|
|
207
|
+
const text = await response.text();
|
|
208
|
+
if (text) {
|
|
209
|
+
errorData = JSON.parse(text);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
errorData = {};
|
|
214
|
+
}
|
|
215
|
+
const errorMessage = errorData?.error?.message ||
|
|
216
|
+
errorData?.detail ||
|
|
217
|
+
errorData?.message ||
|
|
218
|
+
`Request failed with status ${response.status}`;
|
|
219
|
+
logger_1.logger.error('Backend request failed', {
|
|
220
|
+
url,
|
|
221
|
+
method,
|
|
222
|
+
status: response.status,
|
|
223
|
+
statusText: response.statusText,
|
|
224
|
+
errorData
|
|
225
|
+
});
|
|
193
226
|
if (response.status === 413) {
|
|
194
227
|
throw new Error(`Payload too large (413). The request body exceeds the server's size limit. Try reducing the number of video frames or image sizes.`);
|
|
195
228
|
}
|
|
196
|
-
|
|
197
|
-
throw new Error(errorData?.error?.message ||
|
|
198
|
-
errorData?.detail ||
|
|
199
|
-
`Request failed with status ${response.status}`);
|
|
229
|
+
throw new Error(errorMessage);
|
|
200
230
|
}
|
|
201
231
|
return await response.json();
|
|
202
232
|
}
|
|
203
233
|
catch (error) {
|
|
204
234
|
clearTimeout(timeoutId);
|
|
205
235
|
if (error.name === 'AbortError') {
|
|
236
|
+
logger_1.logger.error('Request timeout', { url, method, timeout: this.config.timeout });
|
|
206
237
|
throw new Error('Request timeout');
|
|
207
238
|
}
|
|
208
|
-
|
|
239
|
+
if (error.message) {
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
logger_1.logger.error('Unexpected request error', { url, method, error });
|
|
243
|
+
throw new Error('Network request failed');
|
|
209
244
|
}
|
|
210
245
|
}
|
|
211
246
|
}
|
package/package.json
CHANGED
|
@@ -394,7 +394,9 @@ export class BiometricIdentitySDK {
|
|
|
394
394
|
logger.info('Sending validation request to backend', {
|
|
395
395
|
framesCount: videoFrames.length,
|
|
396
396
|
duration: this.state.videoData.duration,
|
|
397
|
-
challengesCount: this.state.videoData.challengesCompleted?.length || 0
|
|
397
|
+
challengesCount: this.state.videoData.challengesCompleted?.length || 0,
|
|
398
|
+
frontImageSize: this.state.frontID.data?.length || 0,
|
|
399
|
+
backImageSize: this.state.backID?.data?.length || 0
|
|
398
400
|
});
|
|
399
401
|
|
|
400
402
|
const response = await this.backendClient.fullValidation({
|
|
@@ -408,11 +410,15 @@ export class BiometricIdentitySDK {
|
|
|
408
410
|
this.updateState({ progress: 95 });
|
|
409
411
|
|
|
410
412
|
return this.backendClient.convertToValidationResult(response);
|
|
411
|
-
} catch (error) {
|
|
412
|
-
logger.error('Backend validation failed',
|
|
413
|
+
} catch (error: any) {
|
|
414
|
+
logger.error('Backend validation failed', {
|
|
415
|
+
errorMessage: error?.message,
|
|
416
|
+
errorName: error?.name,
|
|
417
|
+
errorStack: error?.stack
|
|
418
|
+
});
|
|
413
419
|
throw this.createError(
|
|
414
420
|
BiometricErrorCode.NETWORK_ERROR,
|
|
415
|
-
'Backend validation failed',
|
|
421
|
+
error?.message || 'Backend validation failed',
|
|
416
422
|
error
|
|
417
423
|
);
|
|
418
424
|
}
|
package/src/api/BackendClient.ts
CHANGED
|
@@ -261,24 +261,39 @@ export class BackendClient {
|
|
|
261
261
|
deviceInfo?: Record<string, any>;
|
|
262
262
|
}): Promise<FullValidationResponse> {
|
|
263
263
|
if (!this.currentSessionId) {
|
|
264
|
-
|
|
264
|
+
logger.info('No session ID, generating challenge');
|
|
265
265
|
await this.generateChallenge();
|
|
266
266
|
}
|
|
267
267
|
|
|
268
|
+
const requestBody = {
|
|
269
|
+
front_id_image: params.frontIdImage,
|
|
270
|
+
back_id_image: params.backIdImage,
|
|
271
|
+
video_frames: params.videoFrames,
|
|
272
|
+
video_duration_ms: params.videoDurationMs,
|
|
273
|
+
session_id: this.currentSessionId,
|
|
274
|
+
challenges_completed: params.challengesCompleted || [],
|
|
275
|
+
document_type: params.documentType,
|
|
276
|
+
country_code: params.countryCode,
|
|
277
|
+
device_info: params.deviceInfo,
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
logger.info('Full validation request', {
|
|
281
|
+
hasSessionId: !!this.currentSessionId,
|
|
282
|
+
sessionId: this.currentSessionId,
|
|
283
|
+
videoFramesCount: params.videoFrames.length,
|
|
284
|
+
hasFrontImage: !!params.frontIdImage,
|
|
285
|
+
hasBackImage: !!params.backIdImage,
|
|
286
|
+
frontImageLength: params.frontIdImage?.length || 0,
|
|
287
|
+
backImageLength: params.backIdImage?.length || 0,
|
|
288
|
+
averageFrameLength: params.videoFrames.length > 0
|
|
289
|
+
? Math.round(params.videoFrames.reduce((sum, f) => sum + f.length, 0) / params.videoFrames.length)
|
|
290
|
+
: 0
|
|
291
|
+
});
|
|
292
|
+
|
|
268
293
|
return this.request<FullValidationResponse>(
|
|
269
294
|
'/api/v1/validate',
|
|
270
295
|
'POST',
|
|
271
|
-
|
|
272
|
-
front_id_image: params.frontIdImage,
|
|
273
|
-
back_id_image: params.backIdImage,
|
|
274
|
-
video_frames: params.videoFrames,
|
|
275
|
-
video_duration_ms: params.videoDurationMs,
|
|
276
|
-
session_id: this.currentSessionId,
|
|
277
|
-
challenges_completed: params.challengesCompleted || [],
|
|
278
|
-
document_type: params.documentType,
|
|
279
|
-
country_code: params.countryCode,
|
|
280
|
-
device_info: params.deviceInfo,
|
|
281
|
-
}
|
|
296
|
+
requestBody
|
|
282
297
|
);
|
|
283
298
|
}
|
|
284
299
|
|
|
@@ -382,19 +397,36 @@ export class BackendClient {
|
|
|
382
397
|
clearTimeout(timeoutId);
|
|
383
398
|
|
|
384
399
|
if (!response.ok) {
|
|
385
|
-
|
|
400
|
+
let errorData: Record<string, any> = {};
|
|
401
|
+
try {
|
|
402
|
+
const text = await response.text();
|
|
403
|
+
if (text) {
|
|
404
|
+
errorData = JSON.parse(text);
|
|
405
|
+
}
|
|
406
|
+
} catch {
|
|
407
|
+
errorData = {};
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
const errorMessage = errorData?.error?.message ||
|
|
411
|
+
errorData?.detail ||
|
|
412
|
+
errorData?.message ||
|
|
413
|
+
`Request failed with status ${response.status}`;
|
|
414
|
+
|
|
415
|
+
logger.error('Backend request failed', {
|
|
416
|
+
url,
|
|
417
|
+
method,
|
|
418
|
+
status: response.status,
|
|
419
|
+
statusText: response.statusText,
|
|
420
|
+
errorData
|
|
421
|
+
});
|
|
422
|
+
|
|
386
423
|
if (response.status === 413) {
|
|
387
424
|
throw new Error(
|
|
388
425
|
`Payload too large (413). The request body exceeds the server's size limit. Try reducing the number of video frames or image sizes.`
|
|
389
426
|
);
|
|
390
427
|
}
|
|
391
428
|
|
|
392
|
-
|
|
393
|
-
throw new Error(
|
|
394
|
-
errorData?.error?.message ||
|
|
395
|
-
errorData?.detail ||
|
|
396
|
-
`Request failed with status ${response.status}`
|
|
397
|
-
);
|
|
429
|
+
throw new Error(errorMessage);
|
|
398
430
|
}
|
|
399
431
|
|
|
400
432
|
return await response.json() as T;
|
|
@@ -402,10 +434,16 @@ export class BackendClient {
|
|
|
402
434
|
clearTimeout(timeoutId);
|
|
403
435
|
|
|
404
436
|
if (error.name === 'AbortError') {
|
|
437
|
+
logger.error('Request timeout', { url, method, timeout: this.config.timeout });
|
|
405
438
|
throw new Error('Request timeout');
|
|
406
439
|
}
|
|
407
440
|
|
|
408
|
-
|
|
441
|
+
if (error.message) {
|
|
442
|
+
throw error;
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
logger.error('Unexpected request error', { url, method, error });
|
|
446
|
+
throw new Error('Network request failed');
|
|
409
447
|
}
|
|
410
448
|
}
|
|
411
449
|
}
|