@hexar/biometric-identity-sdk-core 1.0.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/BiometricIdentitySDK.d.ts +111 -0
- package/dist/BiometricIdentitySDK.js +395 -0
- package/dist/ai-models/FaceDetector.d.ts +59 -0
- package/dist/ai-models/FaceDetector.js +167 -0
- package/dist/ai-models/LivenessDetector.d.ts +61 -0
- package/dist/ai-models/LivenessDetector.js +218 -0
- package/dist/api/BackendClient.d.ts +178 -0
- package/dist/api/BackendClient.js +199 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.js +8 -0
- package/dist/encryption/index.d.ts +38 -0
- package/dist/encryption/index.js +99 -0
- package/dist/i18n/index.d.ts +6 -0
- package/dist/i18n/index.js +47 -0
- package/dist/i18n/languages/en.d.ts +2 -0
- package/dist/i18n/languages/en.js +112 -0
- package/dist/i18n/languages/es-AR.d.ts +2 -0
- package/dist/i18n/languages/es-AR.js +112 -0
- package/dist/i18n/languages/es.d.ts +2 -0
- package/dist/i18n/languages/es.js +112 -0
- package/dist/i18n/languages/pt-BR.d.ts +2 -0
- package/dist/i18n/languages/pt-BR.js +112 -0
- package/dist/i18n/types.d.ts +110 -0
- package/dist/i18n/types.js +2 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.js +64 -0
- package/dist/services/BackendValidationService.d.ts +84 -0
- package/dist/services/BackendValidationService.js +174 -0
- package/dist/services/IValidationService.d.ts +132 -0
- package/dist/services/IValidationService.js +8 -0
- package/dist/services/index.d.ts +8 -0
- package/dist/services/index.js +10 -0
- package/dist/types/index.d.ts +288 -0
- package/dist/types/index.js +34 -0
- package/dist/validation/DocumentValidator.d.ts +84 -0
- package/dist/validation/DocumentValidator.js +295 -0
- package/dist/validation/OCREngine.d.ts +75 -0
- package/dist/validation/OCREngine.js +225 -0
- package/package.json +24 -0
- package/src/BiometricIdentitySDK.ts +493 -0
- package/src/ai-models/FaceDetector.ts +200 -0
- package/src/ai-models/LivenessDetector.ts +274 -0
- package/src/api/BackendClient.ts +395 -0
- package/src/api/index.ts +15 -0
- package/src/encryption/index.ts +108 -0
- package/src/i18n/index.ts +35 -0
- package/src/i18n/languages/en.ts +121 -0
- package/src/i18n/languages/es-AR.ts +121 -0
- package/src/i18n/languages/es.ts +121 -0
- package/src/i18n/languages/pt-BR.ts +121 -0
- package/src/i18n/types.ts +121 -0
- package/src/index.ts +54 -0
- package/src/services/BackendValidationService.ts +228 -0
- package/src/services/IValidationService.ts +158 -0
- package/src/services/index.ts +17 -0
- package/src/types/index.ts +380 -0
- package/src/validation/DocumentValidator.ts +353 -0
- package/src/validation/OCREngine.ts +265 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
export type SupportedLanguage = 'en' | 'es' | 'es-AR' | 'pt-BR';
|
|
2
|
+
|
|
3
|
+
export interface LanguageStrings {
|
|
4
|
+
common: {
|
|
5
|
+
loading: string;
|
|
6
|
+
error: string;
|
|
7
|
+
retry: string;
|
|
8
|
+
cancel: string;
|
|
9
|
+
continue: string;
|
|
10
|
+
close: string;
|
|
11
|
+
done: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
initialization: {
|
|
15
|
+
initializing: string;
|
|
16
|
+
connectingToServer: string;
|
|
17
|
+
loadingModels: string;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
instructions: {
|
|
21
|
+
title: string;
|
|
22
|
+
subtitle: string;
|
|
23
|
+
step1: string;
|
|
24
|
+
step2: string;
|
|
25
|
+
step3: string;
|
|
26
|
+
startButton: string;
|
|
27
|
+
requirements: {
|
|
28
|
+
goodLighting: string;
|
|
29
|
+
clearDocument: string;
|
|
30
|
+
stableHand: string;
|
|
31
|
+
followInstructions: string;
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
capture: {
|
|
36
|
+
frontId: {
|
|
37
|
+
title: string;
|
|
38
|
+
instruction: string;
|
|
39
|
+
button: string;
|
|
40
|
+
};
|
|
41
|
+
backId: {
|
|
42
|
+
title: string;
|
|
43
|
+
instruction: string;
|
|
44
|
+
button: string;
|
|
45
|
+
};
|
|
46
|
+
selfie: {
|
|
47
|
+
title: string;
|
|
48
|
+
instruction: string;
|
|
49
|
+
button: string;
|
|
50
|
+
};
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
liveness: {
|
|
54
|
+
title: string;
|
|
55
|
+
preparing: string;
|
|
56
|
+
instructions: {
|
|
57
|
+
lookLeft: string;
|
|
58
|
+
lookRight: string;
|
|
59
|
+
lookUp: string;
|
|
60
|
+
lookDown: string;
|
|
61
|
+
smile: string;
|
|
62
|
+
blink: string;
|
|
63
|
+
turnHeadLeft: string;
|
|
64
|
+
turnHeadRight: string;
|
|
65
|
+
stayStill: string;
|
|
66
|
+
};
|
|
67
|
+
recording: string;
|
|
68
|
+
processing: string;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
validation: {
|
|
72
|
+
title: string;
|
|
73
|
+
validating: string;
|
|
74
|
+
checkingDocument: string;
|
|
75
|
+
checkingLiveness: string;
|
|
76
|
+
matchingFaces: string;
|
|
77
|
+
almostDone: string;
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
result: {
|
|
81
|
+
success: {
|
|
82
|
+
title: string;
|
|
83
|
+
message: string;
|
|
84
|
+
verificationComplete: string;
|
|
85
|
+
};
|
|
86
|
+
failure: {
|
|
87
|
+
title: string;
|
|
88
|
+
message: string;
|
|
89
|
+
tryAgain: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
errors: {
|
|
94
|
+
cameraPermissionDenied: string;
|
|
95
|
+
cameraNotAvailable: string;
|
|
96
|
+
faceNotDetected: string;
|
|
97
|
+
multipleFacesDetected: string;
|
|
98
|
+
documentNotDetected: string;
|
|
99
|
+
poorImageQuality: string;
|
|
100
|
+
livenessCheckFailed: string;
|
|
101
|
+
faceMatchFailed: string;
|
|
102
|
+
documentTampered: string;
|
|
103
|
+
networkError: string;
|
|
104
|
+
timeout: string;
|
|
105
|
+
unknownError: string;
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
badges: {
|
|
109
|
+
secureVerification: string;
|
|
110
|
+
aiPowered: string;
|
|
111
|
+
verified: string;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
steps: {
|
|
115
|
+
frontId: string;
|
|
116
|
+
backId: string;
|
|
117
|
+
faceVideo: string;
|
|
118
|
+
validation: string;
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Biometric Identity SDK - Core Package
|
|
3
|
+
* Main entry point for the SDK
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
// Main SDK class
|
|
7
|
+
export { BiometricIdentitySDK } from './BiometricIdentitySDK';
|
|
8
|
+
export { default } from './BiometricIdentitySDK';
|
|
9
|
+
|
|
10
|
+
// Type definitions
|
|
11
|
+
export * from './types';
|
|
12
|
+
|
|
13
|
+
// AI Models
|
|
14
|
+
export { FaceDetector, calculateFaceSimilarity, calculateFaceDistance } from './ai-models/FaceDetector';
|
|
15
|
+
export { LivenessDetector } from './ai-models/LivenessDetector';
|
|
16
|
+
|
|
17
|
+
// Validation
|
|
18
|
+
export { DocumentValidator, meetsQualityStandards } from './validation/DocumentValidator';
|
|
19
|
+
export { OCREngine, cleanText, isValidDate } from './validation/OCREngine';
|
|
20
|
+
|
|
21
|
+
// Encryption
|
|
22
|
+
export { EncryptionService, encryptImages, createIntegritySignature } from './encryption';
|
|
23
|
+
|
|
24
|
+
// Backend API Client
|
|
25
|
+
export { BackendClient } from './api/BackendClient';
|
|
26
|
+
export type {
|
|
27
|
+
ChallengeAction,
|
|
28
|
+
ChallengeResponse,
|
|
29
|
+
LivenessResponse as BackendLivenessResponse,
|
|
30
|
+
FaceMatchResponse,
|
|
31
|
+
DocumentValidationResponse as BackendDocumentResponse,
|
|
32
|
+
FullValidationResponse,
|
|
33
|
+
BackendClientConfig,
|
|
34
|
+
} from './api/BackendClient';
|
|
35
|
+
|
|
36
|
+
// Validation Services (Clean Architecture)
|
|
37
|
+
export { BackendValidationService } from './services/BackendValidationService';
|
|
38
|
+
export type { BackendValidationServiceConfig } from './services/BackendValidationService';
|
|
39
|
+
export type {
|
|
40
|
+
IValidationService,
|
|
41
|
+
LivenessChallenge,
|
|
42
|
+
DocumentValidationResult,
|
|
43
|
+
LivenessResult,
|
|
44
|
+
FaceMatchResult,
|
|
45
|
+
} from './services/IValidationService';
|
|
46
|
+
|
|
47
|
+
// Internationalization
|
|
48
|
+
export { getStrings, setLanguage, getCurrentLanguage } from './i18n';
|
|
49
|
+
export type { SupportedLanguage, LanguageStrings } from './i18n';
|
|
50
|
+
|
|
51
|
+
// Version
|
|
52
|
+
export const SDK_VERSION = '1.0.0';
|
|
53
|
+
|
|
54
|
+
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Backend Validation Service
|
|
3
|
+
*
|
|
4
|
+
* Implements IValidationService using the Python backend API.
|
|
5
|
+
* This is the recommended service for production use.
|
|
6
|
+
*
|
|
7
|
+
* SOLID Principles Applied:
|
|
8
|
+
* - Single Responsibility: Only handles backend API communication
|
|
9
|
+
* - Open/Closed: Implements interface, can be extended without modification
|
|
10
|
+
* - Liskov Substitution: Can replace any IValidationService implementation
|
|
11
|
+
* - Interface Segregation: Uses focused IValidationService interface
|
|
12
|
+
* - Dependency Inversion: Depends on abstractions (IValidationService)
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
IValidationService,
|
|
17
|
+
LivenessChallenge,
|
|
18
|
+
DocumentValidationResult,
|
|
19
|
+
LivenessResult,
|
|
20
|
+
FaceMatchResult,
|
|
21
|
+
} from './IValidationService';
|
|
22
|
+
import { ValidationResult } from '../types';
|
|
23
|
+
import { BackendClient } from '../api/BackendClient';
|
|
24
|
+
|
|
25
|
+
export interface BackendValidationServiceConfig {
|
|
26
|
+
apiEndpoint: string;
|
|
27
|
+
apiKey: string;
|
|
28
|
+
timeout?: number;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class BackendValidationService implements IValidationService {
|
|
32
|
+
private client: BackendClient;
|
|
33
|
+
private _isAvailable: boolean = false;
|
|
34
|
+
|
|
35
|
+
constructor(config: BackendValidationServiceConfig) {
|
|
36
|
+
this.client = new BackendClient({
|
|
37
|
+
apiEndpoint: config.apiEndpoint,
|
|
38
|
+
apiKey: config.apiKey,
|
|
39
|
+
timeout: config.timeout || 60000,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Check if backend is available
|
|
45
|
+
*/
|
|
46
|
+
async isAvailable(): Promise<boolean> {
|
|
47
|
+
try {
|
|
48
|
+
this._isAvailable = await this.client.healthCheck();
|
|
49
|
+
return this._isAvailable;
|
|
50
|
+
} catch (error) {
|
|
51
|
+
this._isAvailable = false;
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Generate liveness challenge from backend
|
|
58
|
+
*
|
|
59
|
+
* API Endpoint: POST /api/v1/liveness/challenge
|
|
60
|
+
*/
|
|
61
|
+
async generateLivenessChallenge(type: 'active' | 'passive'): Promise<LivenessChallenge> {
|
|
62
|
+
const response = await this.client.generateChallenge(type);
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
sessionId: response.session_id,
|
|
66
|
+
challenges: response.challenges.map(c => ({
|
|
67
|
+
action: c.action,
|
|
68
|
+
instruction: c.instruction,
|
|
69
|
+
durationMs: c.duration_ms,
|
|
70
|
+
order: c.order,
|
|
71
|
+
})),
|
|
72
|
+
totalDurationMs: response.total_duration_ms,
|
|
73
|
+
expiresAt: new Date(response.expires_at),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Validate document using backend
|
|
79
|
+
*
|
|
80
|
+
* API Endpoint: POST /api/v1/document/validate
|
|
81
|
+
*/
|
|
82
|
+
async validateDocument(
|
|
83
|
+
frontImage: string,
|
|
84
|
+
backImage?: string,
|
|
85
|
+
options?: { documentType?: string; countryCode?: string }
|
|
86
|
+
): Promise<DocumentValidationResult> {
|
|
87
|
+
const response = await this.client.validateDocument(
|
|
88
|
+
frontImage,
|
|
89
|
+
backImage,
|
|
90
|
+
options?.documentType,
|
|
91
|
+
options?.countryCode
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
return {
|
|
95
|
+
isAuthentic: response.is_authentic,
|
|
96
|
+
authenticityScore: response.authenticity_score,
|
|
97
|
+
documentTypeDetected: response.document_type_detected,
|
|
98
|
+
extractedData: {
|
|
99
|
+
firstName: response.extracted_data.first_name || '',
|
|
100
|
+
lastName: response.extracted_data.last_name || '',
|
|
101
|
+
documentNumber: response.extracted_data.document_number || '',
|
|
102
|
+
dateOfBirth: response.extracted_data.date_of_birth || '',
|
|
103
|
+
expirationDate: response.extracted_data.expiration_date || '',
|
|
104
|
+
nationality: response.extracted_data.nationality || '',
|
|
105
|
+
documentType: response.extracted_data.document_type,
|
|
106
|
+
gender: response.extracted_data.gender,
|
|
107
|
+
address: response.extracted_data.address,
|
|
108
|
+
issuingCountry: response.extracted_data.issuing_country,
|
|
109
|
+
rawText: response.extracted_data.raw_text,
|
|
110
|
+
},
|
|
111
|
+
quality: {
|
|
112
|
+
overallScore: response.quality.overall_score,
|
|
113
|
+
hasGlare: response.quality.has_glare,
|
|
114
|
+
hasBlur: response.quality.has_blur,
|
|
115
|
+
hasCropping: response.quality.has_cropping,
|
|
116
|
+
hasShadows: response.quality.has_shadows,
|
|
117
|
+
},
|
|
118
|
+
tamperDetection: {
|
|
119
|
+
isTampered: response.tamper_detection.is_tampered,
|
|
120
|
+
tamperScore: response.tamper_detection.tamper_score,
|
|
121
|
+
suspiciousRegions: response.tamper_detection.suspicious_regions,
|
|
122
|
+
},
|
|
123
|
+
faceDetectedInDocument: response.face_detected_in_document,
|
|
124
|
+
warnings: response.warnings,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Validate liveness from video frames
|
|
130
|
+
*
|
|
131
|
+
* API Endpoint: POST /api/v1/liveness/validate
|
|
132
|
+
*/
|
|
133
|
+
async validateLiveness(
|
|
134
|
+
sessionId: string,
|
|
135
|
+
videoFrames: string[],
|
|
136
|
+
videoDurationMs: number,
|
|
137
|
+
challengesCompleted: string[]
|
|
138
|
+
): Promise<LivenessResult> {
|
|
139
|
+
const response = await this.client.validateLiveness(
|
|
140
|
+
videoFrames,
|
|
141
|
+
videoDurationMs,
|
|
142
|
+
challengesCompleted
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
return {
|
|
146
|
+
isLive: response.is_live,
|
|
147
|
+
livenessScore: response.liveness_score,
|
|
148
|
+
checks: response.checks.map(c => ({
|
|
149
|
+
name: c.name,
|
|
150
|
+
passed: c.passed,
|
|
151
|
+
score: c.score,
|
|
152
|
+
details: c.details,
|
|
153
|
+
})),
|
|
154
|
+
faceDetected: response.face_detected,
|
|
155
|
+
faceCount: response.face_count,
|
|
156
|
+
bestFrameIndex: response.best_frame_index,
|
|
157
|
+
warnings: response.warnings,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Compare faces between document and live capture
|
|
163
|
+
*
|
|
164
|
+
* API Endpoint: POST /api/v1/face/match
|
|
165
|
+
*/
|
|
166
|
+
async matchFaces(documentImage: string, liveImage: string): Promise<FaceMatchResult> {
|
|
167
|
+
const response = await this.client.matchFaces(documentImage, liveImage);
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
isMatch: response.is_match,
|
|
171
|
+
matchScore: response.match_score,
|
|
172
|
+
distance: response.distance,
|
|
173
|
+
documentFaceDetected: response.document_face_detected,
|
|
174
|
+
liveFaceDetected: response.live_face_detected,
|
|
175
|
+
documentFaceConfidence: response.document_face_confidence,
|
|
176
|
+
liveFaceConfidence: response.live_face_confidence,
|
|
177
|
+
warnings: response.warnings,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Perform full biometric validation
|
|
183
|
+
*
|
|
184
|
+
* API Endpoint: POST /api/v1/validate
|
|
185
|
+
*
|
|
186
|
+
* This is the main validation endpoint that combines:
|
|
187
|
+
* 1. Document validation
|
|
188
|
+
* 2. Liveness detection
|
|
189
|
+
* 3. Face matching
|
|
190
|
+
*/
|
|
191
|
+
async fullValidation(params: {
|
|
192
|
+
frontIdImage: string;
|
|
193
|
+
backIdImage?: string;
|
|
194
|
+
videoFrames: string[];
|
|
195
|
+
videoDurationMs: number;
|
|
196
|
+
sessionId: string;
|
|
197
|
+
challengesCompleted: string[];
|
|
198
|
+
documentType?: string;
|
|
199
|
+
countryCode?: string;
|
|
200
|
+
}): Promise<ValidationResult> {
|
|
201
|
+
const response = await this.client.fullValidation({
|
|
202
|
+
frontIdImage: params.frontIdImage,
|
|
203
|
+
backIdImage: params.backIdImage,
|
|
204
|
+
videoFrames: params.videoFrames,
|
|
205
|
+
videoDurationMs: params.videoDurationMs,
|
|
206
|
+
challengesCompleted: params.challengesCompleted,
|
|
207
|
+
documentType: params.documentType,
|
|
208
|
+
countryCode: params.countryCode,
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
return this.client.convertToValidationResult(response);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get current session ID
|
|
216
|
+
*/
|
|
217
|
+
getSessionId(): string | null {
|
|
218
|
+
return this.client.getSessionId();
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Reset session
|
|
223
|
+
*/
|
|
224
|
+
resetSession(): void {
|
|
225
|
+
this.client.resetSession();
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validation Service Interface (Dependency Inversion Principle)
|
|
3
|
+
*
|
|
4
|
+
* This interface defines the contract for validation services.
|
|
5
|
+
* Both local and backend implementations must adhere to this contract.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
ValidationResult,
|
|
10
|
+
DocumentData,
|
|
11
|
+
LivenessValidationResult,
|
|
12
|
+
FaceEmbedding,
|
|
13
|
+
} from '../types';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Liveness Challenge definition
|
|
17
|
+
*/
|
|
18
|
+
export interface LivenessChallenge {
|
|
19
|
+
sessionId: string;
|
|
20
|
+
challenges: Array<{
|
|
21
|
+
action: string;
|
|
22
|
+
instruction: string;
|
|
23
|
+
durationMs: number;
|
|
24
|
+
order: number;
|
|
25
|
+
}>;
|
|
26
|
+
totalDurationMs: number;
|
|
27
|
+
expiresAt: Date;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Document validation result from service
|
|
32
|
+
*/
|
|
33
|
+
export interface DocumentValidationResult {
|
|
34
|
+
isAuthentic: boolean;
|
|
35
|
+
authenticityScore: number;
|
|
36
|
+
documentTypeDetected?: string;
|
|
37
|
+
extractedData: DocumentData;
|
|
38
|
+
quality: {
|
|
39
|
+
overallScore: number;
|
|
40
|
+
hasGlare: boolean;
|
|
41
|
+
hasBlur: boolean;
|
|
42
|
+
hasCropping: boolean;
|
|
43
|
+
hasShadows: boolean;
|
|
44
|
+
};
|
|
45
|
+
tamperDetection: {
|
|
46
|
+
isTampered: boolean;
|
|
47
|
+
tamperScore: number;
|
|
48
|
+
suspiciousRegions: Array<{ x: number; y: number; width: number; height: number }>;
|
|
49
|
+
};
|
|
50
|
+
faceDetectedInDocument: boolean;
|
|
51
|
+
warnings: string[];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Liveness validation result from service
|
|
56
|
+
*/
|
|
57
|
+
export interface LivenessResult {
|
|
58
|
+
isLive: boolean;
|
|
59
|
+
livenessScore: number;
|
|
60
|
+
checks: Array<{
|
|
61
|
+
name: string;
|
|
62
|
+
passed: boolean;
|
|
63
|
+
score: number;
|
|
64
|
+
details?: string;
|
|
65
|
+
}>;
|
|
66
|
+
faceDetected: boolean;
|
|
67
|
+
faceCount: number;
|
|
68
|
+
bestFrameIndex?: number;
|
|
69
|
+
warnings: string[];
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Face match result from service
|
|
74
|
+
*/
|
|
75
|
+
export interface FaceMatchResult {
|
|
76
|
+
isMatch: boolean;
|
|
77
|
+
matchScore: number;
|
|
78
|
+
distance: number;
|
|
79
|
+
documentFaceDetected: boolean;
|
|
80
|
+
liveFaceDetected: boolean;
|
|
81
|
+
documentFaceConfidence: number;
|
|
82
|
+
liveFaceConfidence: number;
|
|
83
|
+
warnings: string[];
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Validation Service Interface
|
|
88
|
+
*
|
|
89
|
+
* Implementations:
|
|
90
|
+
* - BackendValidationService: Uses Python backend API
|
|
91
|
+
* - LocalValidationService: Uses local AI models (fallback)
|
|
92
|
+
*/
|
|
93
|
+
export interface IValidationService {
|
|
94
|
+
/**
|
|
95
|
+
* Check if the service is available
|
|
96
|
+
*/
|
|
97
|
+
isAvailable(): Promise<boolean>;
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Generate a liveness challenge for the user
|
|
101
|
+
*/
|
|
102
|
+
generateLivenessChallenge(type: 'active' | 'passive'): Promise<LivenessChallenge>;
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Validate document authenticity and extract data
|
|
106
|
+
*/
|
|
107
|
+
validateDocument(
|
|
108
|
+
frontImage: string,
|
|
109
|
+
backImage?: string,
|
|
110
|
+
options?: {
|
|
111
|
+
documentType?: string;
|
|
112
|
+
countryCode?: string;
|
|
113
|
+
}
|
|
114
|
+
): Promise<DocumentValidationResult>;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Validate liveness from video frames
|
|
118
|
+
*/
|
|
119
|
+
validateLiveness(
|
|
120
|
+
sessionId: string,
|
|
121
|
+
videoFrames: string[],
|
|
122
|
+
videoDurationMs: number,
|
|
123
|
+
challengesCompleted: string[]
|
|
124
|
+
): Promise<LivenessResult>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Compare faces between document and live capture
|
|
128
|
+
*/
|
|
129
|
+
matchFaces(
|
|
130
|
+
documentImage: string,
|
|
131
|
+
liveImage: string
|
|
132
|
+
): Promise<FaceMatchResult>;
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Perform full biometric validation in one call
|
|
136
|
+
*/
|
|
137
|
+
fullValidation(params: {
|
|
138
|
+
frontIdImage: string;
|
|
139
|
+
backIdImage?: string;
|
|
140
|
+
videoFrames: string[];
|
|
141
|
+
videoDurationMs: number;
|
|
142
|
+
sessionId: string;
|
|
143
|
+
challengesCompleted: string[];
|
|
144
|
+
documentType?: string;
|
|
145
|
+
countryCode?: string;
|
|
146
|
+
}): Promise<ValidationResult>;
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Get current session ID
|
|
150
|
+
*/
|
|
151
|
+
getSessionId(): string | null;
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Reset session state
|
|
155
|
+
*/
|
|
156
|
+
resetSession(): void;
|
|
157
|
+
}
|
|
158
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Services Module
|
|
3
|
+
*
|
|
4
|
+
* Exports validation service interfaces and implementations
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export type {
|
|
8
|
+
IValidationService,
|
|
9
|
+
LivenessChallenge,
|
|
10
|
+
DocumentValidationResult,
|
|
11
|
+
LivenessResult,
|
|
12
|
+
FaceMatchResult,
|
|
13
|
+
} from './IValidationService';
|
|
14
|
+
|
|
15
|
+
export { BackendValidationService } from './BackendValidationService';
|
|
16
|
+
export type { BackendValidationServiceConfig } from './BackendValidationService';
|
|
17
|
+
|