@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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hexar/biometric-identity-sdk-core",
3
- "version": "1.0.21",
3
+ "version": "1.1.1",
4
4
  "description": "Core AI engine for biometric identity verification",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -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
@@ -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
  */