@hexar/biometric-identity-sdk-core 1.0.21 → 1.1.1
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.
|
@@ -62,6 +62,22 @@ export declare class BiometricIdentitySDK {
|
|
|
62
62
|
duration?: number;
|
|
63
63
|
instructions?: string[];
|
|
64
64
|
}): Promise<VideoResult>;
|
|
65
|
+
/**
|
|
66
|
+
* Validate profile picture with liveness detection
|
|
67
|
+
* Uses backend AI for validation
|
|
68
|
+
*/
|
|
69
|
+
validateProfilePicture(params: {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
videoFrames: string[];
|
|
72
|
+
videoDurationMs: number;
|
|
73
|
+
challengesCompleted?: string[];
|
|
74
|
+
}): Promise<{
|
|
75
|
+
isValid: boolean;
|
|
76
|
+
profilePicture: string;
|
|
77
|
+
livenessScore: number;
|
|
78
|
+
faceDetected: boolean;
|
|
79
|
+
warnings: string[];
|
|
80
|
+
}>;
|
|
65
81
|
/**
|
|
66
82
|
* Validate identity using all collected data
|
|
67
83
|
* Uses backend AI for validation
|
|
@@ -234,6 +234,58 @@ class BiometricIdentitySDK {
|
|
|
234
234
|
throw error;
|
|
235
235
|
}
|
|
236
236
|
}
|
|
237
|
+
/**
|
|
238
|
+
* Validate profile picture with liveness detection
|
|
239
|
+
* Uses backend AI for validation
|
|
240
|
+
*/
|
|
241
|
+
async validateProfilePicture(params) {
|
|
242
|
+
try {
|
|
243
|
+
if (!this.isBackendAvailable) {
|
|
244
|
+
throw this.createError(types_1.BiometricErrorCode.NETWORK_ERROR, 'Backend not available. Cannot perform validation.');
|
|
245
|
+
}
|
|
246
|
+
if (!params.videoFrames || params.videoFrames.length === 0) {
|
|
247
|
+
throw this.createError(types_1.BiometricErrorCode.UNKNOWN_ERROR, 'No video frames provided for validation.');
|
|
248
|
+
}
|
|
249
|
+
this.updateState({
|
|
250
|
+
isLoading: true,
|
|
251
|
+
currentStep: types_1.SDKStep.VALIDATING,
|
|
252
|
+
progress: 75
|
|
253
|
+
});
|
|
254
|
+
// Reduce number of frames to prevent payload size issues (same as validateIdentity)
|
|
255
|
+
let videoFrames = params.videoFrames;
|
|
256
|
+
const MAX_FRAMES = 5; // Reduced to 5 to reduce payload size and processing time
|
|
257
|
+
if (videoFrames.length > MAX_FRAMES) {
|
|
258
|
+
const step = Math.floor(videoFrames.length / MAX_FRAMES);
|
|
259
|
+
videoFrames = videoFrames.filter((_, index) => index % step === 0).slice(0, MAX_FRAMES);
|
|
260
|
+
logger_1.logger.info('Sampled frames for profile picture validation', {
|
|
261
|
+
originalCount: params.videoFrames.length,
|
|
262
|
+
sampledCount: videoFrames.length
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
// Perform backend validation
|
|
266
|
+
const response = await this.backendClient.validateProfilePicture({
|
|
267
|
+
sessionId: params.sessionId,
|
|
268
|
+
videoFrames: videoFrames,
|
|
269
|
+
videoDurationMs: params.videoDurationMs,
|
|
270
|
+
challengesCompleted: params.challengesCompleted,
|
|
271
|
+
});
|
|
272
|
+
this.updateState({
|
|
273
|
+
progress: 100,
|
|
274
|
+
isLoading: false,
|
|
275
|
+
});
|
|
276
|
+
return {
|
|
277
|
+
isValid: response.is_valid,
|
|
278
|
+
profilePicture: response.profile_picture,
|
|
279
|
+
livenessScore: response.liveness_score,
|
|
280
|
+
faceDetected: response.face_detected,
|
|
281
|
+
warnings: response.warnings || [],
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
catch (error) {
|
|
285
|
+
this.handleError(error);
|
|
286
|
+
throw error;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
237
289
|
/**
|
|
238
290
|
* Validate identity using all collected data
|
|
239
291
|
* Uses backend AI for validation
|
|
@@ -110,6 +110,21 @@ export interface FullValidationResponse {
|
|
|
110
110
|
timestamp: string;
|
|
111
111
|
transaction_id: string;
|
|
112
112
|
}
|
|
113
|
+
export interface ProfilePictureValidationResponse {
|
|
114
|
+
success: boolean;
|
|
115
|
+
is_valid: boolean;
|
|
116
|
+
liveness_score: number;
|
|
117
|
+
profile_picture: string;
|
|
118
|
+
face_detected: boolean;
|
|
119
|
+
checks: Array<{
|
|
120
|
+
name: string;
|
|
121
|
+
passed: boolean;
|
|
122
|
+
score: number;
|
|
123
|
+
details?: string;
|
|
124
|
+
}>;
|
|
125
|
+
warnings: string[];
|
|
126
|
+
session_id?: string;
|
|
127
|
+
}
|
|
113
128
|
export interface BackendClientConfig {
|
|
114
129
|
/** Backend API URL */
|
|
115
130
|
apiEndpoint: string;
|
|
@@ -160,6 +175,15 @@ export declare class BackendClient {
|
|
|
160
175
|
countryCode?: string;
|
|
161
176
|
deviceInfo?: Record<string, any>;
|
|
162
177
|
}): Promise<FullValidationResponse>;
|
|
178
|
+
/**
|
|
179
|
+
* Validate profile picture with liveness detection
|
|
180
|
+
*/
|
|
181
|
+
validateProfilePicture(params: {
|
|
182
|
+
sessionId: string;
|
|
183
|
+
videoFrames: string[];
|
|
184
|
+
videoDurationMs: number;
|
|
185
|
+
challengesCompleted?: string[];
|
|
186
|
+
}): Promise<ProfilePictureValidationResponse>;
|
|
163
187
|
/**
|
|
164
188
|
* Convert backend response to SDK ValidationResult format
|
|
165
189
|
*/
|
|
@@ -116,6 +116,27 @@ class BackendClient {
|
|
|
116
116
|
});
|
|
117
117
|
return this.request('/api/v1/validate', 'POST', requestBody);
|
|
118
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Validate profile picture with liveness detection
|
|
121
|
+
*/
|
|
122
|
+
async validateProfilePicture(params) {
|
|
123
|
+
if (!this.currentSessionId && params.sessionId) {
|
|
124
|
+
this.currentSessionId = params.sessionId;
|
|
125
|
+
}
|
|
126
|
+
const requestBody = {
|
|
127
|
+
session_id: this.currentSessionId || params.sessionId,
|
|
128
|
+
video_frames: params.videoFrames,
|
|
129
|
+
video_duration_ms: params.videoDurationMs,
|
|
130
|
+
challenges_completed: params.challengesCompleted || [],
|
|
131
|
+
};
|
|
132
|
+
logger_1.logger.info('Profile picture validation request', {
|
|
133
|
+
hasSessionId: !!this.currentSessionId,
|
|
134
|
+
sessionId: this.currentSessionId || params.sessionId,
|
|
135
|
+
videoFramesCount: params.videoFrames.length,
|
|
136
|
+
videoDurationMs: params.videoDurationMs,
|
|
137
|
+
});
|
|
138
|
+
return this.request('/api/v1/profile/validate-face', 'POST', requestBody);
|
|
139
|
+
}
|
|
119
140
|
/**
|
|
120
141
|
* Convert backend response to SDK ValidationResult format
|
|
121
142
|
*/
|
package/package.json
CHANGED
|
@@ -298,6 +298,81 @@ export class BiometricIdentitySDK {
|
|
|
298
298
|
}
|
|
299
299
|
}
|
|
300
300
|
|
|
301
|
+
/**
|
|
302
|
+
* Validate profile picture with liveness detection
|
|
303
|
+
* Uses backend AI for validation
|
|
304
|
+
*/
|
|
305
|
+
async validateProfilePicture(params: {
|
|
306
|
+
sessionId: string;
|
|
307
|
+
videoFrames: string[];
|
|
308
|
+
videoDurationMs: number;
|
|
309
|
+
challengesCompleted?: string[];
|
|
310
|
+
}): Promise<{
|
|
311
|
+
isValid: boolean;
|
|
312
|
+
profilePicture: string;
|
|
313
|
+
livenessScore: number;
|
|
314
|
+
faceDetected: boolean;
|
|
315
|
+
warnings: string[];
|
|
316
|
+
}> {
|
|
317
|
+
try {
|
|
318
|
+
if (!this.isBackendAvailable) {
|
|
319
|
+
throw this.createError(
|
|
320
|
+
BiometricErrorCode.NETWORK_ERROR,
|
|
321
|
+
'Backend not available. Cannot perform validation.'
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
if (!params.videoFrames || params.videoFrames.length === 0) {
|
|
326
|
+
throw this.createError(
|
|
327
|
+
BiometricErrorCode.UNKNOWN_ERROR,
|
|
328
|
+
'No video frames provided for validation.'
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
this.updateState({
|
|
333
|
+
isLoading: true,
|
|
334
|
+
currentStep: SDKStep.VALIDATING,
|
|
335
|
+
progress: 75
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// Reduce number of frames to prevent payload size issues (same as validateIdentity)
|
|
339
|
+
let videoFrames = params.videoFrames;
|
|
340
|
+
const MAX_FRAMES = 5; // Reduced to 5 to reduce payload size and processing time
|
|
341
|
+
if (videoFrames.length > MAX_FRAMES) {
|
|
342
|
+
const step = Math.floor(videoFrames.length / MAX_FRAMES);
|
|
343
|
+
videoFrames = videoFrames.filter((_, index) => index % step === 0).slice(0, MAX_FRAMES);
|
|
344
|
+
logger.info('Sampled frames for profile picture validation', {
|
|
345
|
+
originalCount: params.videoFrames.length,
|
|
346
|
+
sampledCount: videoFrames.length
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Perform backend validation
|
|
351
|
+
const response = await this.backendClient.validateProfilePicture({
|
|
352
|
+
sessionId: params.sessionId,
|
|
353
|
+
videoFrames: videoFrames,
|
|
354
|
+
videoDurationMs: params.videoDurationMs,
|
|
355
|
+
challengesCompleted: params.challengesCompleted,
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
this.updateState({
|
|
359
|
+
progress: 100,
|
|
360
|
+
isLoading: false,
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
return {
|
|
364
|
+
isValid: response.is_valid,
|
|
365
|
+
profilePicture: response.profile_picture,
|
|
366
|
+
livenessScore: response.liveness_score,
|
|
367
|
+
faceDetected: response.face_detected,
|
|
368
|
+
warnings: response.warnings || [],
|
|
369
|
+
};
|
|
370
|
+
} catch (error) {
|
|
371
|
+
this.handleError(error);
|
|
372
|
+
throw error;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
|
|
301
376
|
/**
|
|
302
377
|
* Validate identity using all collected data
|
|
303
378
|
* Uses backend AI for validation
|
package/src/api/BackendClient.ts
CHANGED
|
@@ -120,6 +120,22 @@ export interface FullValidationResponse {
|
|
|
120
120
|
transaction_id: string;
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
+
export interface ProfilePictureValidationResponse {
|
|
124
|
+
success: boolean;
|
|
125
|
+
is_valid: boolean;
|
|
126
|
+
liveness_score: number;
|
|
127
|
+
profile_picture: string;
|
|
128
|
+
face_detected: boolean;
|
|
129
|
+
checks: Array<{
|
|
130
|
+
name: string;
|
|
131
|
+
passed: boolean;
|
|
132
|
+
score: number;
|
|
133
|
+
details?: string;
|
|
134
|
+
}>;
|
|
135
|
+
warnings: string[];
|
|
136
|
+
session_id?: string;
|
|
137
|
+
}
|
|
138
|
+
|
|
123
139
|
export interface BackendClientConfig {
|
|
124
140
|
/** Backend API URL */
|
|
125
141
|
apiEndpoint: string;
|
|
@@ -297,6 +313,40 @@ export class BackendClient {
|
|
|
297
313
|
);
|
|
298
314
|
}
|
|
299
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Validate profile picture with liveness detection
|
|
318
|
+
*/
|
|
319
|
+
async validateProfilePicture(params: {
|
|
320
|
+
sessionId: string;
|
|
321
|
+
videoFrames: string[];
|
|
322
|
+
videoDurationMs: number;
|
|
323
|
+
challengesCompleted?: string[];
|
|
324
|
+
}): Promise<ProfilePictureValidationResponse> {
|
|
325
|
+
if (!this.currentSessionId && params.sessionId) {
|
|
326
|
+
this.currentSessionId = params.sessionId;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
const requestBody = {
|
|
330
|
+
session_id: this.currentSessionId || params.sessionId,
|
|
331
|
+
video_frames: params.videoFrames,
|
|
332
|
+
video_duration_ms: params.videoDurationMs,
|
|
333
|
+
challenges_completed: params.challengesCompleted || [],
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
logger.info('Profile picture validation request', {
|
|
337
|
+
hasSessionId: !!this.currentSessionId,
|
|
338
|
+
sessionId: this.currentSessionId || params.sessionId,
|
|
339
|
+
videoFramesCount: params.videoFrames.length,
|
|
340
|
+
videoDurationMs: params.videoDurationMs,
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
return this.request<ProfilePictureValidationResponse>(
|
|
344
|
+
'/api/v1/profile/validate-face',
|
|
345
|
+
'POST',
|
|
346
|
+
requestBody
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
300
350
|
/**
|
|
301
351
|
* Convert backend response to SDK ValidationResult format
|
|
302
352
|
*/
|