@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,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Backend Validation Service
|
|
4
|
+
*
|
|
5
|
+
* Implements IValidationService using the Python backend API.
|
|
6
|
+
* This is the recommended service for production use.
|
|
7
|
+
*
|
|
8
|
+
* SOLID Principles Applied:
|
|
9
|
+
* - Single Responsibility: Only handles backend API communication
|
|
10
|
+
* - Open/Closed: Implements interface, can be extended without modification
|
|
11
|
+
* - Liskov Substitution: Can replace any IValidationService implementation
|
|
12
|
+
* - Interface Segregation: Uses focused IValidationService interface
|
|
13
|
+
* - Dependency Inversion: Depends on abstractions (IValidationService)
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.BackendValidationService = void 0;
|
|
17
|
+
const BackendClient_1 = require("../api/BackendClient");
|
|
18
|
+
class BackendValidationService {
|
|
19
|
+
constructor(config) {
|
|
20
|
+
this._isAvailable = false;
|
|
21
|
+
this.client = new BackendClient_1.BackendClient({
|
|
22
|
+
apiEndpoint: config.apiEndpoint,
|
|
23
|
+
apiKey: config.apiKey,
|
|
24
|
+
timeout: config.timeout || 60000,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if backend is available
|
|
29
|
+
*/
|
|
30
|
+
async isAvailable() {
|
|
31
|
+
try {
|
|
32
|
+
this._isAvailable = await this.client.healthCheck();
|
|
33
|
+
return this._isAvailable;
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
this._isAvailable = false;
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generate liveness challenge from backend
|
|
42
|
+
*
|
|
43
|
+
* API Endpoint: POST /api/v1/liveness/challenge
|
|
44
|
+
*/
|
|
45
|
+
async generateLivenessChallenge(type) {
|
|
46
|
+
const response = await this.client.generateChallenge(type);
|
|
47
|
+
return {
|
|
48
|
+
sessionId: response.session_id,
|
|
49
|
+
challenges: response.challenges.map(c => ({
|
|
50
|
+
action: c.action,
|
|
51
|
+
instruction: c.instruction,
|
|
52
|
+
durationMs: c.duration_ms,
|
|
53
|
+
order: c.order,
|
|
54
|
+
})),
|
|
55
|
+
totalDurationMs: response.total_duration_ms,
|
|
56
|
+
expiresAt: new Date(response.expires_at),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Validate document using backend
|
|
61
|
+
*
|
|
62
|
+
* API Endpoint: POST /api/v1/document/validate
|
|
63
|
+
*/
|
|
64
|
+
async validateDocument(frontImage, backImage, options) {
|
|
65
|
+
const response = await this.client.validateDocument(frontImage, backImage, options?.documentType, options?.countryCode);
|
|
66
|
+
return {
|
|
67
|
+
isAuthentic: response.is_authentic,
|
|
68
|
+
authenticityScore: response.authenticity_score,
|
|
69
|
+
documentTypeDetected: response.document_type_detected,
|
|
70
|
+
extractedData: {
|
|
71
|
+
firstName: response.extracted_data.first_name || '',
|
|
72
|
+
lastName: response.extracted_data.last_name || '',
|
|
73
|
+
documentNumber: response.extracted_data.document_number || '',
|
|
74
|
+
dateOfBirth: response.extracted_data.date_of_birth || '',
|
|
75
|
+
expirationDate: response.extracted_data.expiration_date || '',
|
|
76
|
+
nationality: response.extracted_data.nationality || '',
|
|
77
|
+
documentType: response.extracted_data.document_type,
|
|
78
|
+
gender: response.extracted_data.gender,
|
|
79
|
+
address: response.extracted_data.address,
|
|
80
|
+
issuingCountry: response.extracted_data.issuing_country,
|
|
81
|
+
rawText: response.extracted_data.raw_text,
|
|
82
|
+
},
|
|
83
|
+
quality: {
|
|
84
|
+
overallScore: response.quality.overall_score,
|
|
85
|
+
hasGlare: response.quality.has_glare,
|
|
86
|
+
hasBlur: response.quality.has_blur,
|
|
87
|
+
hasCropping: response.quality.has_cropping,
|
|
88
|
+
hasShadows: response.quality.has_shadows,
|
|
89
|
+
},
|
|
90
|
+
tamperDetection: {
|
|
91
|
+
isTampered: response.tamper_detection.is_tampered,
|
|
92
|
+
tamperScore: response.tamper_detection.tamper_score,
|
|
93
|
+
suspiciousRegions: response.tamper_detection.suspicious_regions,
|
|
94
|
+
},
|
|
95
|
+
faceDetectedInDocument: response.face_detected_in_document,
|
|
96
|
+
warnings: response.warnings,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Validate liveness from video frames
|
|
101
|
+
*
|
|
102
|
+
* API Endpoint: POST /api/v1/liveness/validate
|
|
103
|
+
*/
|
|
104
|
+
async validateLiveness(sessionId, videoFrames, videoDurationMs, challengesCompleted) {
|
|
105
|
+
const response = await this.client.validateLiveness(videoFrames, videoDurationMs, challengesCompleted);
|
|
106
|
+
return {
|
|
107
|
+
isLive: response.is_live,
|
|
108
|
+
livenessScore: response.liveness_score,
|
|
109
|
+
checks: response.checks.map(c => ({
|
|
110
|
+
name: c.name,
|
|
111
|
+
passed: c.passed,
|
|
112
|
+
score: c.score,
|
|
113
|
+
details: c.details,
|
|
114
|
+
})),
|
|
115
|
+
faceDetected: response.face_detected,
|
|
116
|
+
faceCount: response.face_count,
|
|
117
|
+
bestFrameIndex: response.best_frame_index,
|
|
118
|
+
warnings: response.warnings,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Compare faces between document and live capture
|
|
123
|
+
*
|
|
124
|
+
* API Endpoint: POST /api/v1/face/match
|
|
125
|
+
*/
|
|
126
|
+
async matchFaces(documentImage, liveImage) {
|
|
127
|
+
const response = await this.client.matchFaces(documentImage, liveImage);
|
|
128
|
+
return {
|
|
129
|
+
isMatch: response.is_match,
|
|
130
|
+
matchScore: response.match_score,
|
|
131
|
+
distance: response.distance,
|
|
132
|
+
documentFaceDetected: response.document_face_detected,
|
|
133
|
+
liveFaceDetected: response.live_face_detected,
|
|
134
|
+
documentFaceConfidence: response.document_face_confidence,
|
|
135
|
+
liveFaceConfidence: response.live_face_confidence,
|
|
136
|
+
warnings: response.warnings,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Perform full biometric validation
|
|
141
|
+
*
|
|
142
|
+
* API Endpoint: POST /api/v1/validate
|
|
143
|
+
*
|
|
144
|
+
* This is the main validation endpoint that combines:
|
|
145
|
+
* 1. Document validation
|
|
146
|
+
* 2. Liveness detection
|
|
147
|
+
* 3. Face matching
|
|
148
|
+
*/
|
|
149
|
+
async fullValidation(params) {
|
|
150
|
+
const response = await this.client.fullValidation({
|
|
151
|
+
frontIdImage: params.frontIdImage,
|
|
152
|
+
backIdImage: params.backIdImage,
|
|
153
|
+
videoFrames: params.videoFrames,
|
|
154
|
+
videoDurationMs: params.videoDurationMs,
|
|
155
|
+
challengesCompleted: params.challengesCompleted,
|
|
156
|
+
documentType: params.documentType,
|
|
157
|
+
countryCode: params.countryCode,
|
|
158
|
+
});
|
|
159
|
+
return this.client.convertToValidationResult(response);
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Get current session ID
|
|
163
|
+
*/
|
|
164
|
+
getSessionId() {
|
|
165
|
+
return this.client.getSessionId();
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Reset session
|
|
169
|
+
*/
|
|
170
|
+
resetSession() {
|
|
171
|
+
this.client.resetSession();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.BackendValidationService = BackendValidationService;
|
|
@@ -0,0 +1,132 @@
|
|
|
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
|
+
import { ValidationResult, DocumentData } from '../types';
|
|
8
|
+
/**
|
|
9
|
+
* Liveness Challenge definition
|
|
10
|
+
*/
|
|
11
|
+
export interface LivenessChallenge {
|
|
12
|
+
sessionId: string;
|
|
13
|
+
challenges: Array<{
|
|
14
|
+
action: string;
|
|
15
|
+
instruction: string;
|
|
16
|
+
durationMs: number;
|
|
17
|
+
order: number;
|
|
18
|
+
}>;
|
|
19
|
+
totalDurationMs: number;
|
|
20
|
+
expiresAt: Date;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Document validation result from service
|
|
24
|
+
*/
|
|
25
|
+
export interface DocumentValidationResult {
|
|
26
|
+
isAuthentic: boolean;
|
|
27
|
+
authenticityScore: number;
|
|
28
|
+
documentTypeDetected?: string;
|
|
29
|
+
extractedData: DocumentData;
|
|
30
|
+
quality: {
|
|
31
|
+
overallScore: number;
|
|
32
|
+
hasGlare: boolean;
|
|
33
|
+
hasBlur: boolean;
|
|
34
|
+
hasCropping: boolean;
|
|
35
|
+
hasShadows: boolean;
|
|
36
|
+
};
|
|
37
|
+
tamperDetection: {
|
|
38
|
+
isTampered: boolean;
|
|
39
|
+
tamperScore: number;
|
|
40
|
+
suspiciousRegions: Array<{
|
|
41
|
+
x: number;
|
|
42
|
+
y: number;
|
|
43
|
+
width: number;
|
|
44
|
+
height: number;
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
faceDetectedInDocument: boolean;
|
|
48
|
+
warnings: string[];
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Liveness validation result from service
|
|
52
|
+
*/
|
|
53
|
+
export interface LivenessResult {
|
|
54
|
+
isLive: boolean;
|
|
55
|
+
livenessScore: number;
|
|
56
|
+
checks: Array<{
|
|
57
|
+
name: string;
|
|
58
|
+
passed: boolean;
|
|
59
|
+
score: number;
|
|
60
|
+
details?: string;
|
|
61
|
+
}>;
|
|
62
|
+
faceDetected: boolean;
|
|
63
|
+
faceCount: number;
|
|
64
|
+
bestFrameIndex?: number;
|
|
65
|
+
warnings: string[];
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Face match result from service
|
|
69
|
+
*/
|
|
70
|
+
export interface FaceMatchResult {
|
|
71
|
+
isMatch: boolean;
|
|
72
|
+
matchScore: number;
|
|
73
|
+
distance: number;
|
|
74
|
+
documentFaceDetected: boolean;
|
|
75
|
+
liveFaceDetected: boolean;
|
|
76
|
+
documentFaceConfidence: number;
|
|
77
|
+
liveFaceConfidence: number;
|
|
78
|
+
warnings: string[];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Validation Service Interface
|
|
82
|
+
*
|
|
83
|
+
* Implementations:
|
|
84
|
+
* - BackendValidationService: Uses Python backend API
|
|
85
|
+
* - LocalValidationService: Uses local AI models (fallback)
|
|
86
|
+
*/
|
|
87
|
+
export interface IValidationService {
|
|
88
|
+
/**
|
|
89
|
+
* Check if the service is available
|
|
90
|
+
*/
|
|
91
|
+
isAvailable(): Promise<boolean>;
|
|
92
|
+
/**
|
|
93
|
+
* Generate a liveness challenge for the user
|
|
94
|
+
*/
|
|
95
|
+
generateLivenessChallenge(type: 'active' | 'passive'): Promise<LivenessChallenge>;
|
|
96
|
+
/**
|
|
97
|
+
* Validate document authenticity and extract data
|
|
98
|
+
*/
|
|
99
|
+
validateDocument(frontImage: string, backImage?: string, options?: {
|
|
100
|
+
documentType?: string;
|
|
101
|
+
countryCode?: string;
|
|
102
|
+
}): Promise<DocumentValidationResult>;
|
|
103
|
+
/**
|
|
104
|
+
* Validate liveness from video frames
|
|
105
|
+
*/
|
|
106
|
+
validateLiveness(sessionId: string, videoFrames: string[], videoDurationMs: number, challengesCompleted: string[]): Promise<LivenessResult>;
|
|
107
|
+
/**
|
|
108
|
+
* Compare faces between document and live capture
|
|
109
|
+
*/
|
|
110
|
+
matchFaces(documentImage: string, liveImage: string): Promise<FaceMatchResult>;
|
|
111
|
+
/**
|
|
112
|
+
* Perform full biometric validation in one call
|
|
113
|
+
*/
|
|
114
|
+
fullValidation(params: {
|
|
115
|
+
frontIdImage: string;
|
|
116
|
+
backIdImage?: string;
|
|
117
|
+
videoFrames: string[];
|
|
118
|
+
videoDurationMs: number;
|
|
119
|
+
sessionId: string;
|
|
120
|
+
challengesCompleted: string[];
|
|
121
|
+
documentType?: string;
|
|
122
|
+
countryCode?: string;
|
|
123
|
+
}): Promise<ValidationResult>;
|
|
124
|
+
/**
|
|
125
|
+
* Get current session ID
|
|
126
|
+
*/
|
|
127
|
+
getSessionId(): string | null;
|
|
128
|
+
/**
|
|
129
|
+
* Reset session state
|
|
130
|
+
*/
|
|
131
|
+
resetSession(): void;
|
|
132
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Validation Service Interface (Dependency Inversion Principle)
|
|
4
|
+
*
|
|
5
|
+
* This interface defines the contract for validation services.
|
|
6
|
+
* Both local and backend implementations must adhere to this contract.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Services Module
|
|
3
|
+
*
|
|
4
|
+
* Exports validation service interfaces and implementations
|
|
5
|
+
*/
|
|
6
|
+
export type { IValidationService, LivenessChallenge, DocumentValidationResult, LivenessResult, FaceMatchResult, } from './IValidationService';
|
|
7
|
+
export { BackendValidationService } from './BackendValidationService';
|
|
8
|
+
export type { BackendValidationServiceConfig } from './BackendValidationService';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Services Module
|
|
4
|
+
*
|
|
5
|
+
* Exports validation service interfaces and implementations
|
|
6
|
+
*/
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.BackendValidationService = void 0;
|
|
9
|
+
var BackendValidationService_1 = require("./BackendValidationService");
|
|
10
|
+
Object.defineProperty(exports, "BackendValidationService", { enumerable: true, get: function () { return BackendValidationService_1.BackendValidationService; } });
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core type definitions for Biometric Identity SDK
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidationResult {
|
|
5
|
+
/** Face match confidence score (0-100) */
|
|
6
|
+
matchScore: number;
|
|
7
|
+
/** Whether face from video matches face in document */
|
|
8
|
+
isValidFaceMatch: boolean;
|
|
9
|
+
/** Whether document passes authenticity checks */
|
|
10
|
+
isDocumentAuthentic: boolean;
|
|
11
|
+
/** Liveness detection confidence score (0-100) */
|
|
12
|
+
livenessScore: number;
|
|
13
|
+
/** Extracted data from document OCR */
|
|
14
|
+
extractedDocumentData: DocumentData;
|
|
15
|
+
/** List of warnings detected during validation */
|
|
16
|
+
warnings: string[];
|
|
17
|
+
/** Timestamp of validation */
|
|
18
|
+
timestamp: number;
|
|
19
|
+
/** Detailed breakdown of validation steps */
|
|
20
|
+
details?: ValidationDetails;
|
|
21
|
+
}
|
|
22
|
+
export interface DocumentData {
|
|
23
|
+
firstName: string;
|
|
24
|
+
lastName: string;
|
|
25
|
+
documentNumber: string;
|
|
26
|
+
dateOfBirth: string;
|
|
27
|
+
expirationDate: string;
|
|
28
|
+
nationality: string;
|
|
29
|
+
documentType?: string;
|
|
30
|
+
gender?: string;
|
|
31
|
+
address?: string;
|
|
32
|
+
issuingCountry?: string;
|
|
33
|
+
rawText?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ValidationDetails {
|
|
36
|
+
faceDetection: {
|
|
37
|
+
detected: boolean;
|
|
38
|
+
confidence: number;
|
|
39
|
+
boundingBox?: BoundingBox;
|
|
40
|
+
};
|
|
41
|
+
documentQuality: {
|
|
42
|
+
hasGlare: boolean;
|
|
43
|
+
hasBlur: boolean;
|
|
44
|
+
hasCropping: boolean;
|
|
45
|
+
hasReflections: boolean;
|
|
46
|
+
edgeDetectionScore: number;
|
|
47
|
+
};
|
|
48
|
+
tamperDetection: {
|
|
49
|
+
isTampered: boolean;
|
|
50
|
+
tamperScore: number;
|
|
51
|
+
suspiciousRegions: BoundingBox[];
|
|
52
|
+
};
|
|
53
|
+
hologramDetection?: {
|
|
54
|
+
detected: boolean;
|
|
55
|
+
confidence: number;
|
|
56
|
+
};
|
|
57
|
+
livenessChecks: {
|
|
58
|
+
passedMotionCheck: boolean;
|
|
59
|
+
passedTextureCheck: boolean;
|
|
60
|
+
passedDepthCheck: boolean;
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
export interface BoundingBox {
|
|
64
|
+
x: number;
|
|
65
|
+
y: number;
|
|
66
|
+
width: number;
|
|
67
|
+
height: number;
|
|
68
|
+
}
|
|
69
|
+
import { SupportedLanguage } from '../i18n';
|
|
70
|
+
export interface BiometricConfig {
|
|
71
|
+
apiEndpoint?: string;
|
|
72
|
+
apiKey?: string;
|
|
73
|
+
language?: SupportedLanguage;
|
|
74
|
+
enableBackendValidation?: boolean;
|
|
75
|
+
enableLocalStorage?: boolean;
|
|
76
|
+
encryptionKey?: string;
|
|
77
|
+
minMatchScore?: number;
|
|
78
|
+
minLivenessScore?: number;
|
|
79
|
+
validationTimeout?: number;
|
|
80
|
+
modelPaths?: {
|
|
81
|
+
faceDetection?: string;
|
|
82
|
+
faceRecognition?: string;
|
|
83
|
+
livenessDetection?: string;
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
export interface ThemeConfig {
|
|
87
|
+
/** Primary brand color */
|
|
88
|
+
primaryColor?: string;
|
|
89
|
+
/** Background color */
|
|
90
|
+
backgroundColor?: string;
|
|
91
|
+
/** Text color */
|
|
92
|
+
textColor?: string;
|
|
93
|
+
/** Secondary text color */
|
|
94
|
+
secondaryTextColor?: string;
|
|
95
|
+
/** Button border radius */
|
|
96
|
+
buttonRadius?: number;
|
|
97
|
+
/** Font family */
|
|
98
|
+
fontFamily?: string;
|
|
99
|
+
/** Custom logo */
|
|
100
|
+
logo?: string | any;
|
|
101
|
+
/** Success color */
|
|
102
|
+
successColor?: string;
|
|
103
|
+
/** Error color */
|
|
104
|
+
errorColor?: string;
|
|
105
|
+
/** Warning color */
|
|
106
|
+
warningColor?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface VideoLivenessOptions {
|
|
109
|
+
/** Duration of video recording in milliseconds */
|
|
110
|
+
duration?: number;
|
|
111
|
+
/** Instructions for user to follow */
|
|
112
|
+
instructions?: LivenessInstruction[];
|
|
113
|
+
/** Frame rate for video capture */
|
|
114
|
+
frameRate?: number;
|
|
115
|
+
/** Quality of video (0-1) */
|
|
116
|
+
quality?: number;
|
|
117
|
+
}
|
|
118
|
+
export type LivenessInstruction = 'look_left' | 'look_right' | 'look_up' | 'look_down' | 'smile' | 'blink' | 'turn_head_left' | 'turn_head_right';
|
|
119
|
+
export interface VideoResult {
|
|
120
|
+
/** Video frames as base64 encoded images */
|
|
121
|
+
frames: string[];
|
|
122
|
+
/** Duration of captured video */
|
|
123
|
+
duration: number;
|
|
124
|
+
/** Whether all instructions were followed */
|
|
125
|
+
instructionsFollowed: boolean;
|
|
126
|
+
/** Quality score of the video */
|
|
127
|
+
qualityScore: number;
|
|
128
|
+
/** List of completed challenge actions (for active liveness) */
|
|
129
|
+
challengesCompleted?: string[];
|
|
130
|
+
/** Session ID from backend challenge (if using backend) */
|
|
131
|
+
sessionId?: string;
|
|
132
|
+
}
|
|
133
|
+
export interface ImageData {
|
|
134
|
+
/** Base64 encoded image data */
|
|
135
|
+
data: string;
|
|
136
|
+
/** Image width */
|
|
137
|
+
width: number;
|
|
138
|
+
/** Image height */
|
|
139
|
+
height: number;
|
|
140
|
+
/** MIME type */
|
|
141
|
+
mimeType: string;
|
|
142
|
+
/** File size in bytes */
|
|
143
|
+
size: number;
|
|
144
|
+
}
|
|
145
|
+
export interface EncryptedData {
|
|
146
|
+
/** Encrypted data payload */
|
|
147
|
+
data: string;
|
|
148
|
+
/** Initialization vector */
|
|
149
|
+
iv: string;
|
|
150
|
+
/** Authentication tag */
|
|
151
|
+
tag?: string;
|
|
152
|
+
/** Encryption algorithm used */
|
|
153
|
+
algorithm: string;
|
|
154
|
+
}
|
|
155
|
+
export interface BiometricError extends Error {
|
|
156
|
+
code: BiometricErrorCode;
|
|
157
|
+
details?: any;
|
|
158
|
+
}
|
|
159
|
+
export declare enum BiometricErrorCode {
|
|
160
|
+
CAMERA_PERMISSION_DENIED = "CAMERA_PERMISSION_DENIED",
|
|
161
|
+
CAMERA_NOT_AVAILABLE = "CAMERA_NOT_AVAILABLE",
|
|
162
|
+
FACE_NOT_DETECTED = "FACE_NOT_DETECTED",
|
|
163
|
+
MULTIPLE_FACES_DETECTED = "MULTIPLE_FACES_DETECTED",
|
|
164
|
+
DOCUMENT_NOT_DETECTED = "DOCUMENT_NOT_DETECTED",
|
|
165
|
+
POOR_IMAGE_QUALITY = "POOR_IMAGE_QUALITY",
|
|
166
|
+
LIVENESS_CHECK_FAILED = "LIVENESS_CHECK_FAILED",
|
|
167
|
+
FACE_MATCH_FAILED = "FACE_MATCH_FAILED",
|
|
168
|
+
DOCUMENT_TAMPERED = "DOCUMENT_TAMPERED",
|
|
169
|
+
OCR_FAILED = "OCR_FAILED",
|
|
170
|
+
VALIDATION_TIMEOUT = "VALIDATION_TIMEOUT",
|
|
171
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
172
|
+
MODEL_LOAD_FAILED = "MODEL_LOAD_FAILED",
|
|
173
|
+
ENCRYPTION_FAILED = "ENCRYPTION_FAILED",
|
|
174
|
+
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
175
|
+
}
|
|
176
|
+
export interface FaceEmbedding {
|
|
177
|
+
/** 512-dimensional face embedding vector */
|
|
178
|
+
vector: number[];
|
|
179
|
+
/** Confidence score of face detection */
|
|
180
|
+
confidence: number;
|
|
181
|
+
/** Bounding box of detected face */
|
|
182
|
+
boundingBox: BoundingBox;
|
|
183
|
+
}
|
|
184
|
+
export interface DocumentValidationResult {
|
|
185
|
+
/** Whether document is authentic */
|
|
186
|
+
isAuthentic: boolean;
|
|
187
|
+
/** Overall authenticity score (0-100) */
|
|
188
|
+
authenticityScore: number;
|
|
189
|
+
/** Quality assessment */
|
|
190
|
+
quality: {
|
|
191
|
+
hasGlare: boolean;
|
|
192
|
+
hasBlur: boolean;
|
|
193
|
+
hasCropping: boolean;
|
|
194
|
+
hasReflections: boolean;
|
|
195
|
+
edgeScore: number;
|
|
196
|
+
};
|
|
197
|
+
/** Tamper detection results */
|
|
198
|
+
tamper: {
|
|
199
|
+
detected: boolean;
|
|
200
|
+
score: number;
|
|
201
|
+
regions: BoundingBox[];
|
|
202
|
+
};
|
|
203
|
+
/** Hologram detection (if applicable) */
|
|
204
|
+
hologram?: {
|
|
205
|
+
detected: boolean;
|
|
206
|
+
confidence: number;
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
export interface LivenessValidationResult {
|
|
210
|
+
/** Whether liveness check passed */
|
|
211
|
+
isLive: boolean;
|
|
212
|
+
/** Overall liveness score (0-100) */
|
|
213
|
+
livenessScore: number;
|
|
214
|
+
/** Individual check results */
|
|
215
|
+
checks: {
|
|
216
|
+
motionCheck: boolean;
|
|
217
|
+
textureCheck: boolean;
|
|
218
|
+
depthCheck: boolean;
|
|
219
|
+
blinkCheck?: boolean;
|
|
220
|
+
};
|
|
221
|
+
/** Detected face in video */
|
|
222
|
+
faceEmbedding: FaceEmbedding;
|
|
223
|
+
}
|
|
224
|
+
export interface SDKState {
|
|
225
|
+
/** Current step in the flow */
|
|
226
|
+
currentStep: SDKStep;
|
|
227
|
+
/** Front ID image */
|
|
228
|
+
frontID?: ImageData;
|
|
229
|
+
/** Back ID image */
|
|
230
|
+
backID?: ImageData;
|
|
231
|
+
/** Video liveness data */
|
|
232
|
+
videoData?: VideoResult;
|
|
233
|
+
/** Validation result */
|
|
234
|
+
validationResult?: ValidationResult;
|
|
235
|
+
/** Error state */
|
|
236
|
+
error?: BiometricError;
|
|
237
|
+
/** Loading state */
|
|
238
|
+
isLoading: boolean;
|
|
239
|
+
/** Progress percentage (0-100) */
|
|
240
|
+
progress: number;
|
|
241
|
+
}
|
|
242
|
+
export declare enum SDKStep {
|
|
243
|
+
INIT = "INIT",
|
|
244
|
+
CAPTURE_FRONT_ID = "CAPTURE_FRONT_ID",
|
|
245
|
+
CAPTURE_BACK_ID = "CAPTURE_BACK_ID",
|
|
246
|
+
RECORD_LIVENESS = "RECORD_LIVENESS",
|
|
247
|
+
VALIDATING = "VALIDATING",
|
|
248
|
+
RESULT = "RESULT",
|
|
249
|
+
ERROR = "ERROR"
|
|
250
|
+
}
|
|
251
|
+
export interface ModelConfig {
|
|
252
|
+
/** Model name */
|
|
253
|
+
name: string;
|
|
254
|
+
/** Model path or URL */
|
|
255
|
+
path: string;
|
|
256
|
+
/** Model version */
|
|
257
|
+
version: string;
|
|
258
|
+
/** Input shape */
|
|
259
|
+
inputShape: number[];
|
|
260
|
+
/** Output shape */
|
|
261
|
+
outputShape: number[];
|
|
262
|
+
}
|
|
263
|
+
export interface BackendValidationRequest {
|
|
264
|
+
/** Encrypted front ID image */
|
|
265
|
+
frontID: EncryptedData;
|
|
266
|
+
/** Encrypted back ID image */
|
|
267
|
+
backID: EncryptedData;
|
|
268
|
+
/** Encrypted video frames */
|
|
269
|
+
videoFrames: EncryptedData;
|
|
270
|
+
/** Local validation result */
|
|
271
|
+
localValidationResult: ValidationResult;
|
|
272
|
+
/** SDK version */
|
|
273
|
+
sdkVersion: string;
|
|
274
|
+
/** Timestamp */
|
|
275
|
+
timestamp: number;
|
|
276
|
+
}
|
|
277
|
+
export interface BackendValidationResponse {
|
|
278
|
+
/** Whether validation was approved */
|
|
279
|
+
approved: boolean;
|
|
280
|
+
/** Match score from backend */
|
|
281
|
+
matchScore: number;
|
|
282
|
+
/** Additional checks performed by backend */
|
|
283
|
+
additionalChecks?: Record<string, any>;
|
|
284
|
+
/** Backend validation timestamp */
|
|
285
|
+
timestamp: number;
|
|
286
|
+
/** Backend session ID */
|
|
287
|
+
sessionId: string;
|
|
288
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Core type definitions for Biometric Identity SDK
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SDKStep = exports.BiometricErrorCode = void 0;
|
|
7
|
+
var BiometricErrorCode;
|
|
8
|
+
(function (BiometricErrorCode) {
|
|
9
|
+
BiometricErrorCode["CAMERA_PERMISSION_DENIED"] = "CAMERA_PERMISSION_DENIED";
|
|
10
|
+
BiometricErrorCode["CAMERA_NOT_AVAILABLE"] = "CAMERA_NOT_AVAILABLE";
|
|
11
|
+
BiometricErrorCode["FACE_NOT_DETECTED"] = "FACE_NOT_DETECTED";
|
|
12
|
+
BiometricErrorCode["MULTIPLE_FACES_DETECTED"] = "MULTIPLE_FACES_DETECTED";
|
|
13
|
+
BiometricErrorCode["DOCUMENT_NOT_DETECTED"] = "DOCUMENT_NOT_DETECTED";
|
|
14
|
+
BiometricErrorCode["POOR_IMAGE_QUALITY"] = "POOR_IMAGE_QUALITY";
|
|
15
|
+
BiometricErrorCode["LIVENESS_CHECK_FAILED"] = "LIVENESS_CHECK_FAILED";
|
|
16
|
+
BiometricErrorCode["FACE_MATCH_FAILED"] = "FACE_MATCH_FAILED";
|
|
17
|
+
BiometricErrorCode["DOCUMENT_TAMPERED"] = "DOCUMENT_TAMPERED";
|
|
18
|
+
BiometricErrorCode["OCR_FAILED"] = "OCR_FAILED";
|
|
19
|
+
BiometricErrorCode["VALIDATION_TIMEOUT"] = "VALIDATION_TIMEOUT";
|
|
20
|
+
BiometricErrorCode["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
21
|
+
BiometricErrorCode["MODEL_LOAD_FAILED"] = "MODEL_LOAD_FAILED";
|
|
22
|
+
BiometricErrorCode["ENCRYPTION_FAILED"] = "ENCRYPTION_FAILED";
|
|
23
|
+
BiometricErrorCode["UNKNOWN_ERROR"] = "UNKNOWN_ERROR";
|
|
24
|
+
})(BiometricErrorCode || (exports.BiometricErrorCode = BiometricErrorCode = {}));
|
|
25
|
+
var SDKStep;
|
|
26
|
+
(function (SDKStep) {
|
|
27
|
+
SDKStep["INIT"] = "INIT";
|
|
28
|
+
SDKStep["CAPTURE_FRONT_ID"] = "CAPTURE_FRONT_ID";
|
|
29
|
+
SDKStep["CAPTURE_BACK_ID"] = "CAPTURE_BACK_ID";
|
|
30
|
+
SDKStep["RECORD_LIVENESS"] = "RECORD_LIVENESS";
|
|
31
|
+
SDKStep["VALIDATING"] = "VALIDATING";
|
|
32
|
+
SDKStep["RESULT"] = "RESULT";
|
|
33
|
+
SDKStep["ERROR"] = "ERROR";
|
|
34
|
+
})(SDKStep || (exports.SDKStep = SDKStep = {}));
|