smartcomply-web-sdk 1.0.3 → 1.0.4
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/README.md +43 -0
- package/dist/esm/camera/ActionDetector.d.ts +26 -0
- package/dist/esm/camera/ActionDetector.d.ts.map +1 -0
- package/dist/esm/camera/ActionDetector.js +110 -0
- package/dist/esm/camera/ActionDetector.js.map +1 -0
- package/dist/esm/camera/CameraManager.d.ts +7 -0
- package/dist/esm/camera/CameraManager.d.ts.map +1 -0
- package/dist/esm/camera/CameraManager.js +27 -0
- package/dist/esm/camera/CameraManager.js.map +1 -0
- package/dist/esm/camera/FaceDetector.d.ts +12 -0
- package/dist/esm/camera/FaceDetector.d.ts.map +1 -0
- package/dist/esm/camera/FaceDetector.js +51 -0
- package/dist/esm/camera/FaceDetector.js.map +1 -0
- package/dist/esm/camera/Permission.d.ts +42 -0
- package/dist/esm/camera/Permission.d.ts.map +1 -0
- package/dist/esm/camera/Permission.js +101 -0
- package/dist/esm/camera/Permission.js.map +1 -0
- package/dist/esm/camera/VideoRecorder.d.ts +12 -0
- package/dist/esm/camera/VideoRecorder.d.ts.map +1 -0
- package/dist/esm/camera/VideoRecorder.js +47 -0
- package/dist/esm/camera/VideoRecorder.js.map +1 -0
- package/dist/esm/client/Config.d.ts +9 -0
- package/dist/esm/client/Config.d.ts.map +1 -0
- package/dist/esm/client/Config.js +5 -0
- package/dist/esm/client/Config.js.map +1 -0
- package/dist/esm/client/HttpClient.d.ts +44 -0
- package/dist/esm/client/HttpClient.d.ts.map +1 -0
- package/dist/esm/client/HttpClient.js +145 -0
- package/dist/esm/client/HttpClient.js.map +1 -0
- package/dist/esm/client/Smartcomply.d.ts +50 -0
- package/dist/esm/client/Smartcomply.d.ts.map +1 -0
- package/dist/esm/client/Smartcomply.js +73 -0
- package/dist/esm/client/Smartcomply.js.map +1 -0
- package/dist/esm/components/CameraView.d.ts +59 -0
- package/dist/esm/components/CameraView.d.ts.map +1 -0
- package/dist/esm/components/CameraView.js +238 -0
- package/dist/esm/components/CameraView.js.map +1 -0
- package/dist/esm/components/DocumentUpload.d.ts +21 -0
- package/dist/esm/components/DocumentUpload.d.ts.map +1 -0
- package/dist/esm/components/DocumentUpload.js +216 -0
- package/dist/esm/components/DocumentUpload.js.map +1 -0
- package/dist/esm/errors/AuthError.d.ts +8 -0
- package/dist/esm/errors/AuthError.d.ts.map +1 -0
- package/dist/esm/errors/AuthError.js +11 -0
- package/dist/esm/errors/AuthError.js.map +1 -0
- package/dist/esm/errors/NetworkError.d.ts +8 -0
- package/dist/esm/errors/NetworkError.d.ts.map +1 -0
- package/dist/esm/errors/NetworkError.js +11 -0
- package/dist/esm/errors/NetworkError.js.map +1 -0
- package/dist/esm/errors/SDKError.d.ts +7 -0
- package/dist/esm/errors/SDKError.d.ts.map +1 -0
- package/dist/esm/errors/SDKError.js +10 -0
- package/dist/esm/errors/SDKError.js.map +1 -0
- package/dist/esm/flow/DocumentCapture.d.ts +54 -0
- package/dist/esm/flow/DocumentCapture.d.ts.map +1 -0
- package/dist/esm/flow/DocumentCapture.js +797 -0
- package/dist/esm/flow/DocumentCapture.js.map +1 -0
- package/dist/esm/flow/SmartComplyFlow.d.ts +104 -0
- package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -0
- package/dist/esm/flow/SmartComplyFlow.js +1722 -0
- package/dist/esm/flow/SmartComplyFlow.js.map +1 -0
- package/dist/esm/flow/theme.d.ts +30 -0
- package/dist/esm/flow/theme.d.ts.map +1 -0
- package/dist/esm/flow/theme.js +99 -0
- package/dist/esm/flow/theme.js.map +1 -0
- package/dist/esm/index.d.ts +20 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/modules/liveness/LivenessUI.d.ts +46 -0
- package/dist/esm/modules/liveness/LivenessUI.d.ts.map +1 -0
- package/dist/esm/modules/liveness/LivenessUI.js +605 -0
- package/dist/esm/modules/liveness/LivenessUI.js.map +1 -0
- package/dist/esm/modules/liveness/index.d.ts +5 -0
- package/dist/esm/modules/liveness/index.d.ts.map +1 -0
- package/dist/esm/modules/liveness/index.js +4 -0
- package/dist/esm/modules/liveness/index.js.map +1 -0
- package/dist/esm/modules/liveness/liveness.d.ts +85 -0
- package/dist/esm/modules/liveness/liveness.d.ts.map +1 -0
- package/dist/esm/modules/liveness/liveness.js +421 -0
- package/dist/esm/modules/liveness/liveness.js.map +1 -0
- package/dist/esm/modules/liveness/uploader.d.ts +34 -0
- package/dist/esm/modules/liveness/uploader.d.ts.map +1 -0
- package/dist/esm/modules/liveness/uploader.js +102 -0
- package/dist/esm/modules/liveness/uploader.js.map +1 -0
- package/dist/esm/modules/onboarding/index.d.ts +2 -0
- package/dist/esm/modules/onboarding/index.d.ts.map +1 -0
- package/dist/esm/modules/onboarding/index.js +2 -0
- package/dist/esm/modules/onboarding/index.js.map +1 -0
- package/dist/esm/modules/onboarding/onboarding.d.ts +25 -0
- package/dist/esm/modules/onboarding/onboarding.d.ts.map +1 -0
- package/dist/esm/modules/onboarding/onboarding.js +29 -0
- package/dist/esm/modules/onboarding/onboarding.js.map +1 -0
- package/dist/esm/types/common.d.ts +27 -0
- package/dist/esm/types/common.d.ts.map +1 -0
- package/dist/esm/types/common.js +2 -0
- package/dist/esm/types/common.js.map +1 -0
- package/dist/esm/types/liveness.d.ts +142 -0
- package/dist/esm/types/liveness.d.ts.map +1 -0
- package/dist/esm/types/liveness.js +2 -0
- package/dist/esm/types/liveness.js.map +1 -0
- package/dist/esm/types/onboarding.d.ts +53 -0
- package/dist/esm/types/onboarding.d.ts.map +1 -0
- package/dist/esm/types/onboarding.js +2 -0
- package/dist/esm/types/onboarding.js.map +1 -0
- package/dist/esm/types/quality.d.ts +23 -0
- package/dist/esm/types/quality.d.ts.map +1 -0
- package/dist/esm/types/quality.js +5 -0
- package/dist/esm/types/quality.js.map +1 -0
- package/dist/esm/utils/ImageQuality.d.ts +48 -0
- package/dist/esm/utils/ImageQuality.d.ts.map +1 -0
- package/dist/esm/utils/ImageQuality.js +177 -0
- package/dist/esm/utils/ImageQuality.js.map +1 -0
- package/dist/esm/utils/constants.d.ts +59 -0
- package/dist/esm/utils/constants.d.ts.map +1 -0
- package/dist/esm/utils/constants.js +67 -0
- package/dist/esm/utils/constants.js.map +1 -0
- package/dist/esm/utils/device.d.ts +14 -0
- package/dist/esm/utils/device.d.ts.map +1 -0
- package/dist/esm/utils/device.js +52 -0
- package/dist/esm/utils/device.js.map +1 -0
- package/dist/esm/utils/logger.d.ts +28 -0
- package/dist/esm/utils/logger.d.ts.map +1 -0
- package/dist/esm/utils/logger.js +64 -0
- package/dist/esm/utils/logger.js.map +1 -0
- package/dist/esm/utils/validator.d.ts +35 -0
- package/dist/esm/utils/validator.d.ts.map +1 -0
- package/dist/esm/utils/validator.js +102 -0
- package/dist/esm/utils/validator.js.map +1 -0
- package/package.json +13 -5
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Image Quality Assessment for Document Capture
|
|
3
|
+
* Client-side quality checks before sending to backend
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Calculate image sharpness using Laplacian variance
|
|
7
|
+
* Higher values = sharper image
|
|
8
|
+
*/
|
|
9
|
+
export function calculateSharpness(imageData) {
|
|
10
|
+
const { width, height, data } = imageData;
|
|
11
|
+
// Convert to grayscale
|
|
12
|
+
const gray = new Uint8Array(width * height);
|
|
13
|
+
for (let i = 0; i < width * height; i++) {
|
|
14
|
+
const idx = i * 4;
|
|
15
|
+
gray[i] = Math.round(0.299 * data[idx] + 0.587 * data[idx + 1] + 0.114 * data[idx + 2]);
|
|
16
|
+
}
|
|
17
|
+
// Apply Laplacian kernel
|
|
18
|
+
const laplacian = new Float32Array(width * height);
|
|
19
|
+
let sum = 0;
|
|
20
|
+
let sumSq = 0;
|
|
21
|
+
let count = 0;
|
|
22
|
+
for (let y = 1; y < height - 1; y++) {
|
|
23
|
+
for (let x = 1; x < width - 1; x++) {
|
|
24
|
+
const idx = y * width + x;
|
|
25
|
+
// Laplacian kernel
|
|
26
|
+
const val = -1 * gray[idx - width] +
|
|
27
|
+
-1 * gray[idx - 1] +
|
|
28
|
+
4 * gray[idx] +
|
|
29
|
+
-1 * gray[idx + 1] +
|
|
30
|
+
-1 * gray[idx + width];
|
|
31
|
+
laplacian[idx] = val;
|
|
32
|
+
sum += val;
|
|
33
|
+
sumSq += val * val;
|
|
34
|
+
count++;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// Calculate variance
|
|
38
|
+
const mean = sum / count;
|
|
39
|
+
const variance = (sumSq / count) - (mean * mean);
|
|
40
|
+
return Math.abs(variance);
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Detect glare (overexposed areas)
|
|
44
|
+
*/
|
|
45
|
+
export function detectGlare(imageData, threshold = 250) {
|
|
46
|
+
const { data } = imageData;
|
|
47
|
+
let overexposed = 0;
|
|
48
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
49
|
+
const brightness = (data[i] + data[i + 1] + data[i + 2]) / 3;
|
|
50
|
+
if (brightness > threshold) {
|
|
51
|
+
overexposed++;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return overexposed / (data.length / 4);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Calculate contrast (standard deviation)
|
|
58
|
+
*/
|
|
59
|
+
export function calculateContrast(imageData) {
|
|
60
|
+
const { data } = imageData;
|
|
61
|
+
let sum = 0;
|
|
62
|
+
let sumSq = 0;
|
|
63
|
+
const pixelCount = data.length / 4;
|
|
64
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
65
|
+
const gray = 0.299 * data[i] + 0.587 * data[i + 1] + 0.114 * data[i + 2];
|
|
66
|
+
sum += gray;
|
|
67
|
+
sumSq += gray * gray;
|
|
68
|
+
}
|
|
69
|
+
const mean = sum / pixelCount;
|
|
70
|
+
const variance = (sumSq / pixelCount) - (mean * mean);
|
|
71
|
+
return Math.sqrt(variance);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Calculate brightness (mean pixel value)
|
|
75
|
+
*/
|
|
76
|
+
export function calculateBrightness(imageData) {
|
|
77
|
+
const { data } = imageData;
|
|
78
|
+
let sum = 0;
|
|
79
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
80
|
+
sum += (data[i] + data[i + 1] + data[i + 2]) / 3;
|
|
81
|
+
}
|
|
82
|
+
return sum / (data.length / 4);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Full quality assessment
|
|
86
|
+
*/
|
|
87
|
+
export function assessQuality(imageData) {
|
|
88
|
+
const sharpness = calculateSharpness(imageData);
|
|
89
|
+
const glare = detectGlare(imageData);
|
|
90
|
+
const contrast = calculateContrast(imageData);
|
|
91
|
+
const brightness = calculateBrightness(imageData);
|
|
92
|
+
const isBlurry = sharpness < 80;
|
|
93
|
+
const hasGlare = glare > 0.15;
|
|
94
|
+
const isTooDark = brightness < 50;
|
|
95
|
+
const isTooBright = brightness > 200;
|
|
96
|
+
const lowContrast = contrast < 30;
|
|
97
|
+
// Calculate overall score (0-100)
|
|
98
|
+
let score = 100;
|
|
99
|
+
if (isBlurry)
|
|
100
|
+
score -= 40;
|
|
101
|
+
if (hasGlare)
|
|
102
|
+
score -= 25;
|
|
103
|
+
if (isTooDark)
|
|
104
|
+
score -= 20;
|
|
105
|
+
if (isTooBright)
|
|
106
|
+
score -= 20;
|
|
107
|
+
if (lowContrast)
|
|
108
|
+
score -= 15;
|
|
109
|
+
const metrics = {
|
|
110
|
+
sharpness: Math.round(sharpness * 10) / 10,
|
|
111
|
+
contrast: Math.round(contrast * 10) / 10,
|
|
112
|
+
brightness: Math.round(brightness * 10) / 10,
|
|
113
|
+
isBlurry,
|
|
114
|
+
hasGlare,
|
|
115
|
+
overallScore: Math.max(0, score),
|
|
116
|
+
};
|
|
117
|
+
// Generate feedback
|
|
118
|
+
const issues = [];
|
|
119
|
+
const recommendations = [];
|
|
120
|
+
if (isBlurry) {
|
|
121
|
+
issues.push("Too blurry");
|
|
122
|
+
recommendations.push("Hold camera steady");
|
|
123
|
+
recommendations.push("Ensure good lighting");
|
|
124
|
+
}
|
|
125
|
+
if (hasGlare) {
|
|
126
|
+
issues.push("Too much glare");
|
|
127
|
+
recommendations.push("Avoid direct light on document");
|
|
128
|
+
recommendations.push("Tilt document slightly");
|
|
129
|
+
}
|
|
130
|
+
if (isTooDark) {
|
|
131
|
+
issues.push("Too dark");
|
|
132
|
+
recommendations.push("Move to brighter area");
|
|
133
|
+
recommendations.push("Turn on more lights");
|
|
134
|
+
}
|
|
135
|
+
if (isTooBright) {
|
|
136
|
+
issues.push("Too bright");
|
|
137
|
+
recommendations.push("Reduce lighting");
|
|
138
|
+
recommendations.push("Move away from direct sun");
|
|
139
|
+
}
|
|
140
|
+
if (lowContrast) {
|
|
141
|
+
issues.push("Low contrast");
|
|
142
|
+
recommendations.push("Ensure even lighting");
|
|
143
|
+
}
|
|
144
|
+
const isValid = score >= 60;
|
|
145
|
+
const message = issues.length > 0
|
|
146
|
+
? issues.join(", ")
|
|
147
|
+
: "Good quality";
|
|
148
|
+
return {
|
|
149
|
+
isValid,
|
|
150
|
+
message,
|
|
151
|
+
recommendations: recommendations.slice(0, 3), // Max 3 recommendations
|
|
152
|
+
quality: metrics,
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Get quality color for UI feedback
|
|
157
|
+
*/
|
|
158
|
+
export function getQualityColor(score) {
|
|
159
|
+
if (score >= 80)
|
|
160
|
+
return "#22c55e"; // Green
|
|
161
|
+
if (score >= 60)
|
|
162
|
+
return "#eab308"; // Yellow
|
|
163
|
+
return "#ef4444"; // Red
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Get quality message for display
|
|
167
|
+
*/
|
|
168
|
+
export function getQualityMessage(score) {
|
|
169
|
+
if (score >= 80)
|
|
170
|
+
return "Excellent - Ready to capture";
|
|
171
|
+
if (score >= 60)
|
|
172
|
+
return "Good - Can capture";
|
|
173
|
+
if (score >= 40)
|
|
174
|
+
return "Fair - Improve if possible";
|
|
175
|
+
return "Poor - Please adjust";
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=ImageQuality.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImageQuality.js","sourceRoot":"","sources":["../../../src/utils/ImageQuality.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-wide constants — single source of truth for limits, defaults and
|
|
3
|
+
* backend-defined magic values.
|
|
4
|
+
*/
|
|
5
|
+
export declare const ENDPOINTS: {
|
|
6
|
+
readonly SESSION_CREATE: "/v1/sdk/session/create/";
|
|
7
|
+
readonly SDK_INITIALIZE: "/v1/sdk/initialize/";
|
|
8
|
+
readonly ONBOARDING_VERIFY: "/v1/sdk/onboarding/verify/";
|
|
9
|
+
readonly LIVENESS_CREATE: "/v1/sdk/liveness/create/";
|
|
10
|
+
readonly LIVENESS_SUBMIT: "/v1/sdk/liveness/submit/";
|
|
11
|
+
readonly AVAILABLE_CHANNELS: "/v1/sdk/available-channels/";
|
|
12
|
+
};
|
|
13
|
+
/** Backend session TTL in milliseconds (30 minutes). */
|
|
14
|
+
export declare const SESSION_TTL_MS: number;
|
|
15
|
+
/** Warn the user this many ms before session expires. */
|
|
16
|
+
export declare const SESSION_WARN_BEFORE_MS: number;
|
|
17
|
+
/** Default request timeout in milliseconds. */
|
|
18
|
+
export declare const DEFAULT_TIMEOUT_MS = 30000;
|
|
19
|
+
/** Number of automatic retries on transient network errors. */
|
|
20
|
+
export declare const MAX_RETRIES = 2;
|
|
21
|
+
/** Delay between retries in milliseconds. */
|
|
22
|
+
export declare const RETRY_DELAY_MS = 1000;
|
|
23
|
+
/** Maximum document image size the backend accepts (5 MB). */
|
|
24
|
+
export declare const MAX_DOCUMENT_BYTES: number;
|
|
25
|
+
/** Maximum video size the backend accepts (50 MB). */
|
|
26
|
+
export declare const MAX_VIDEO_BYTES: number;
|
|
27
|
+
/** Maximum snapshot / autoshot size (2 MB). */
|
|
28
|
+
export declare const MAX_SNAPSHOT_BYTES: number;
|
|
29
|
+
/** Accepted MIME types for document images. */
|
|
30
|
+
export declare const ACCEPTED_IMAGE_TYPES: readonly ["image/jpeg", "image/png", "image/webp"];
|
|
31
|
+
/** JPEG quality used when encoding captured frames (0–1). */
|
|
32
|
+
export declare const CAPTURE_JPEG_QUALITY = 0.92;
|
|
33
|
+
/** Backend-accepted challenge actions (UPPERCASE). */
|
|
34
|
+
export declare const CHALLENGE_ACTIONS: readonly ["BLINK", "TURN_LEFT", "TURN_RIGHT", "TURN_HEAD", "OPEN_MOUTH"];
|
|
35
|
+
/** Default set sent when the caller does not specify actions. */
|
|
36
|
+
export declare const DEFAULT_CHALLENGE_ACTIONS: readonly ["BLINK", "TURN_LEFT", "OPEN_MOUTH"];
|
|
37
|
+
/** Time limit per liveness attempt in seconds. */
|
|
38
|
+
export declare const LIVENESS_TIME_LIMIT_SECONDS = 45;
|
|
39
|
+
/** Milliseconds to pause after all actions before capturing the final snapshot. */
|
|
40
|
+
export declare const POST_ACTION_SETTLE_MS = 800;
|
|
41
|
+
/** Ideal resolution for the front-facing liveness camera. */
|
|
42
|
+
export declare const CAMERA_IDEAL_WIDTH = 640;
|
|
43
|
+
export declare const CAMERA_IDEAL_HEIGHT = 480;
|
|
44
|
+
/** Ideal resolution for rear-facing document capture camera. */
|
|
45
|
+
export declare const DOC_CAMERA_IDEAL_WIDTH = 1280;
|
|
46
|
+
export declare const DOC_CAMERA_IDEAL_HEIGHT = 960;
|
|
47
|
+
/** Video bitrate used by MediaRecorder for liveness recordings (~1.4 MB / 45 s). */
|
|
48
|
+
export declare const RECORDING_BITS_PER_SECOND = 250000;
|
|
49
|
+
/** Max milliseconds to wait for an initial face detection before proceeding. */
|
|
50
|
+
export declare const FACE_DETECT_TIMEOUT_MS = 10000;
|
|
51
|
+
/** Polling interval for the face-present check (ms). */
|
|
52
|
+
export declare const FACE_DETECT_POLL_MS = 100;
|
|
53
|
+
/** How long (ms) the success overlay is shown before the flow advances. */
|
|
54
|
+
export declare const RESULT_OVERLAY_DURATION_MS = 2800;
|
|
55
|
+
/** localStorage key used to persist the browser fingerprint ID. */
|
|
56
|
+
export declare const FINGERPRINT_STORAGE_KEY = "_adhere_fid";
|
|
57
|
+
/** z-index for the SDK overlay — high enough to sit above any app content. */
|
|
58
|
+
export declare const OVERLAY_Z_INDEX = 99999;
|
|
59
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,SAAS;;;;;;;CAOZ,CAAC;AAIX,wDAAwD;AACxD,eAAO,MAAM,cAAc,QAAiB,CAAC;AAE7C,yDAAyD;AACzD,eAAO,MAAM,sBAAsB,QAAgB,CAAC;AAIpD,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,QAAS,CAAC;AAEzC,+DAA+D;AAC/D,eAAO,MAAM,WAAW,IAAI,CAAC;AAE7B,6CAA6C;AAC7C,eAAO,MAAM,cAAc,OAAQ,CAAC;AAIpC,8DAA8D;AAC9D,eAAO,MAAM,kBAAkB,QAAkB,CAAC;AAElD,sDAAsD;AACtD,eAAO,MAAM,eAAe,QAAmB,CAAC;AAEhD,+CAA+C;AAC/C,eAAO,MAAM,kBAAkB,QAAkB,CAAC;AAElD,+CAA+C;AAC/C,eAAO,MAAM,oBAAoB,oDAAqD,CAAC;AAEvF,6DAA6D;AAC7D,eAAO,MAAM,oBAAoB,OAAO,CAAC;AAIzC,sDAAsD;AACtD,eAAO,MAAM,iBAAiB,0EAA2E,CAAC;AAE1G,iEAAiE;AACjE,eAAO,MAAM,yBAAyB,+CAAgD,CAAC;AAEvF,kDAAkD;AAClD,eAAO,MAAM,2BAA2B,KAAK,CAAC;AAE9C,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAIzC,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,MAAO,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAEvC,gEAAgE;AAChE,eAAO,MAAM,sBAAsB,OAAQ,CAAC;AAC5C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAE3C,oFAAoF;AACpF,eAAO,MAAM,yBAAyB,SAAU,CAAC;AAIjD,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,QAAS,CAAC;AAE7C,wDAAwD;AACxD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AAIvC,2EAA2E;AAC3E,eAAO,MAAM,0BAA0B,OAAQ,CAAC;AAEhD,mEAAmE;AACnE,eAAO,MAAM,uBAAuB,gBAAgB,CAAC;AAErD,8EAA8E;AAC9E,eAAO,MAAM,eAAe,QAAS,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SDK-wide constants — single source of truth for limits, defaults and
|
|
3
|
+
* backend-defined magic values.
|
|
4
|
+
*/
|
|
5
|
+
// ── API endpoints ────────────────────────────────────────────────────────────
|
|
6
|
+
export const ENDPOINTS = {
|
|
7
|
+
SESSION_CREATE: "/v1/sdk/session/create/",
|
|
8
|
+
SDK_INITIALIZE: "/v1/sdk/initialize/",
|
|
9
|
+
ONBOARDING_VERIFY: "/v1/sdk/onboarding/verify/",
|
|
10
|
+
LIVENESS_CREATE: "/v1/sdk/liveness/create/",
|
|
11
|
+
LIVENESS_SUBMIT: "/v1/sdk/liveness/submit/",
|
|
12
|
+
AVAILABLE_CHANNELS: "/v1/sdk/available-channels/",
|
|
13
|
+
};
|
|
14
|
+
// ── Session ──────────────────────────────────────────────────────────────────
|
|
15
|
+
/** Backend session TTL in milliseconds (30 minutes). */
|
|
16
|
+
export const SESSION_TTL_MS = 30 * 60 * 1000;
|
|
17
|
+
/** Warn the user this many ms before session expires. */
|
|
18
|
+
export const SESSION_WARN_BEFORE_MS = 2 * 60 * 1000;
|
|
19
|
+
// ── Network ──────────────────────────────────────────────────────────────────
|
|
20
|
+
/** Default request timeout in milliseconds. */
|
|
21
|
+
export const DEFAULT_TIMEOUT_MS = 30000;
|
|
22
|
+
/** Number of automatic retries on transient network errors. */
|
|
23
|
+
export const MAX_RETRIES = 2;
|
|
24
|
+
/** Delay between retries in milliseconds. */
|
|
25
|
+
export const RETRY_DELAY_MS = 1000;
|
|
26
|
+
// ── File uploads ─────────────────────────────────────────────────────────────
|
|
27
|
+
/** Maximum document image size the backend accepts (5 MB). */
|
|
28
|
+
export const MAX_DOCUMENT_BYTES = 5 * 1024 * 1024;
|
|
29
|
+
/** Maximum video size the backend accepts (50 MB). */
|
|
30
|
+
export const MAX_VIDEO_BYTES = 50 * 1024 * 1024;
|
|
31
|
+
/** Maximum snapshot / autoshot size (2 MB). */
|
|
32
|
+
export const MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
|
|
33
|
+
/** Accepted MIME types for document images. */
|
|
34
|
+
export const ACCEPTED_IMAGE_TYPES = ["image/jpeg", "image/png", "image/webp"];
|
|
35
|
+
/** JPEG quality used when encoding captured frames (0–1). */
|
|
36
|
+
export const CAPTURE_JPEG_QUALITY = 0.92;
|
|
37
|
+
// ── Liveness challenge ───────────────────────────────────────────────────────
|
|
38
|
+
/** Backend-accepted challenge actions (UPPERCASE). */
|
|
39
|
+
export const CHALLENGE_ACTIONS = ["BLINK", "TURN_LEFT", "TURN_RIGHT", "TURN_HEAD", "OPEN_MOUTH"];
|
|
40
|
+
/** Default set sent when the caller does not specify actions. */
|
|
41
|
+
export const DEFAULT_CHALLENGE_ACTIONS = ["BLINK", "TURN_LEFT", "OPEN_MOUTH"];
|
|
42
|
+
/** Time limit per liveness attempt in seconds. */
|
|
43
|
+
export const LIVENESS_TIME_LIMIT_SECONDS = 45;
|
|
44
|
+
/** Milliseconds to pause after all actions before capturing the final snapshot. */
|
|
45
|
+
export const POST_ACTION_SETTLE_MS = 800;
|
|
46
|
+
// ── Camera ───────────────────────────────────────────────────────────────────
|
|
47
|
+
/** Ideal resolution for the front-facing liveness camera. */
|
|
48
|
+
export const CAMERA_IDEAL_WIDTH = 640;
|
|
49
|
+
export const CAMERA_IDEAL_HEIGHT = 480;
|
|
50
|
+
/** Ideal resolution for rear-facing document capture camera. */
|
|
51
|
+
export const DOC_CAMERA_IDEAL_WIDTH = 1280;
|
|
52
|
+
export const DOC_CAMERA_IDEAL_HEIGHT = 960;
|
|
53
|
+
/** Video bitrate used by MediaRecorder for liveness recordings (~1.4 MB / 45 s). */
|
|
54
|
+
export const RECORDING_BITS_PER_SECOND = 250000;
|
|
55
|
+
// ── Face detection ───────────────────────────────────────────────────────────
|
|
56
|
+
/** Max milliseconds to wait for an initial face detection before proceeding. */
|
|
57
|
+
export const FACE_DETECT_TIMEOUT_MS = 10000;
|
|
58
|
+
/** Polling interval for the face-present check (ms). */
|
|
59
|
+
export const FACE_DETECT_POLL_MS = 100;
|
|
60
|
+
// ── UI / UX ──────────────────────────────────────────────────────────────────
|
|
61
|
+
/** How long (ms) the success overlay is shown before the flow advances. */
|
|
62
|
+
export const RESULT_OVERLAY_DURATION_MS = 2800;
|
|
63
|
+
/** localStorage key used to persist the browser fingerprint ID. */
|
|
64
|
+
export const FINGERPRINT_STORAGE_KEY = "_adhere_fid";
|
|
65
|
+
/** z-index for the SDK overlay — high enough to sit above any app content. */
|
|
66
|
+
export const OVERLAY_Z_INDEX = 99999;
|
|
67
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../src/utils/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,gFAAgF;AAEhF,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,cAAc,EAAO,yBAAyB;IAC9C,cAAc,EAAO,qBAAqB;IAC1C,iBAAiB,EAAI,4BAA4B;IACjD,eAAe,EAAM,0BAA0B;IAC/C,eAAe,EAAM,0BAA0B;IAC/C,kBAAkB,EAAG,6BAA6B;CAC1C,CAAC;AAEX,gFAAgF;AAEhF,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;AAE7C,yDAAyD;AACzD,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpD,gFAAgF;AAEhF,+CAA+C;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAM,CAAC;AAEzC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC;AAE7B,6CAA6C;AAC7C,MAAM,CAAC,MAAM,cAAc,GAAG,IAAK,CAAC;AAEpC,gFAAgF;AAEhF,8DAA8D;AAC9D,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,sDAAsD;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAEhD,+CAA+C;AAC/C,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAElD,+CAA+C;AAC/C,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,YAAY,EAAE,WAAW,EAAE,YAAY,CAAU,CAAC;AAEvF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAEzC,gFAAgF;AAEhF,sDAAsD;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,CAAU,CAAC;AAE1G,iEAAiE;AACjE,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,CAAU,CAAC;AAEvF,kDAAkD;AAClD,MAAM,CAAC,MAAM,2BAA2B,GAAG,EAAE,CAAC;AAE9C,mFAAmF;AACnF,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC,gFAAgF;AAEhF,6DAA6D;AAC7D,MAAM,CAAC,MAAM,kBAAkB,GAAI,GAAG,CAAC;AACvC,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,gEAAgE;AAChE,MAAM,CAAC,MAAM,sBAAsB,GAAI,IAAI,CAAC;AAC5C,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAE3C,oFAAoF;AACpF,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAO,CAAC;AAEjD,gFAAgF;AAEhF,gFAAgF;AAChF,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAM,CAAC;AAE7C,wDAAwD;AACxD,MAAM,CAAC,MAAM,mBAAmB,GAAG,GAAG,CAAC;AAEvC,gFAAgF;AAEhF,2EAA2E;AAC3E,MAAM,CAAC,MAAM,0BAA0B,GAAG,IAAK,CAAC;AAEhD,mEAAmE;AACnE,MAAM,CAAC,MAAM,uBAAuB,GAAG,aAAa,CAAC;AAErD,8EAA8E;AAC9E,MAAM,CAAC,MAAM,eAAe,GAAG,KAAM,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Collects device / browser context metadata.
|
|
3
|
+
* All values are derived from standard browser APIs — no external library needed.
|
|
4
|
+
* Sent to the backend at liveness/create so they appear in the webhook
|
|
5
|
+
* request_context block.
|
|
6
|
+
*/
|
|
7
|
+
export interface DeviceMetadata {
|
|
8
|
+
device_type: "mobile" | "desktop" | "tablet";
|
|
9
|
+
os_name: string;
|
|
10
|
+
browser_timezone: string;
|
|
11
|
+
fingerprint_id: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function collectDeviceMetadata(): DeviceMetadata;
|
|
14
|
+
//# sourceMappingURL=device.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.d.ts","sourceRoot":"","sources":["../../../src/utils/device.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;CACxB;AA8BD,wBAAgB,qBAAqB,IAAI,cAAc,CAuBtD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
function detectOs(ua) {
|
|
2
|
+
if (/Windows NT/i.test(ua))
|
|
3
|
+
return "Windows";
|
|
4
|
+
if (/Mac OS X|Macintosh/i.test(ua))
|
|
5
|
+
return "macOS";
|
|
6
|
+
if (/Android/i.test(ua))
|
|
7
|
+
return "Android";
|
|
8
|
+
if (/iPhone|iPad|iPod/i.test(ua))
|
|
9
|
+
return "iOS";
|
|
10
|
+
if (/Linux/i.test(ua))
|
|
11
|
+
return "Linux";
|
|
12
|
+
if (/CrOS/i.test(ua))
|
|
13
|
+
return "ChromeOS";
|
|
14
|
+
return "Unknown";
|
|
15
|
+
}
|
|
16
|
+
function getOrCreateFingerprintId() {
|
|
17
|
+
const KEY = "_adhere_fid";
|
|
18
|
+
try {
|
|
19
|
+
let fid = localStorage.getItem(KEY);
|
|
20
|
+
if (!fid) {
|
|
21
|
+
fid =
|
|
22
|
+
typeof crypto !== "undefined" && typeof crypto.randomUUID === "function"
|
|
23
|
+
? crypto.randomUUID()
|
|
24
|
+
: Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
25
|
+
localStorage.setItem(KEY, fid);
|
|
26
|
+
}
|
|
27
|
+
return fid;
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// localStorage unavailable (e.g. private browsing with strict settings)
|
|
31
|
+
return Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function collectDeviceMetadata() {
|
|
35
|
+
const ua = navigator.userAgent;
|
|
36
|
+
const isTablet = /iPad/i.test(ua) ||
|
|
37
|
+
(/Android/i.test(ua) && !/Mobile/i.test(ua));
|
|
38
|
+
const isMobile = !isTablet &&
|
|
39
|
+
/Mobi|Android|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
|
|
40
|
+
const device_type = isTablet
|
|
41
|
+
? "tablet"
|
|
42
|
+
: isMobile
|
|
43
|
+
? "mobile"
|
|
44
|
+
: "desktop";
|
|
45
|
+
return {
|
|
46
|
+
device_type,
|
|
47
|
+
os_name: detectOs(ua),
|
|
48
|
+
browser_timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
49
|
+
fingerprint_id: getOrCreateFingerprintId(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=device.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device.js","sourceRoot":"","sources":["../../../src/utils/device.ts"],"names":[],"mappings":"AAaA,SAAS,QAAQ,CAAC,EAAU;IAC1B,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7C,IAAI,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC;IACnD,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,SAAS,CAAC;IAC1C,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,OAAO,CAAC;IACtC,IAAI,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAAE,OAAO,UAAU,CAAC;IACxC,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,wBAAwB;IAC/B,MAAM,GAAG,GAAG,aAAa,CAAC;IAC1B,IAAI,CAAC;QACH,IAAI,GAAG,GAAG,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,GAAG;gBACD,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;oBACtE,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE;oBACrB,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACpE,YAAY,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,wEAAwE;QACxE,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IACvE,CAAC;AACH,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,MAAM,EAAE,GAAG,SAAS,CAAC,SAAS,CAAC;IAE/B,MAAM,QAAQ,GACZ,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChB,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;IAE/C,MAAM,QAAQ,GACZ,CAAC,QAAQ;QACT,0DAA0D,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEtE,MAAM,WAAW,GAAkC,QAAQ;QACzD,CAAC,CAAC,QAAQ;QACV,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,QAAQ;YACV,CAAC,CAAC,SAAS,CAAC;IAEd,OAAO;QACL,WAAW;QACX,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;QACrB,gBAAgB,EAAE,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ;QAClE,cAAc,EAAE,wBAAwB,EAAE;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight SDK logger.
|
|
3
|
+
*
|
|
4
|
+
* Debug output is suppressed in production. Enable verbose logging by calling
|
|
5
|
+
* SDKLogger.setDebug(true) before initialising the SDK, or by setting the
|
|
6
|
+
* global flag: window.__SC_DEBUG__ = true
|
|
7
|
+
*/
|
|
8
|
+
export declare const SDKLogger: {
|
|
9
|
+
/** Emit an informational message (debug mode only). */
|
|
10
|
+
info(message: string, ...args: unknown[]): void;
|
|
11
|
+
/** Emit a warning (always visible). */
|
|
12
|
+
warn(message: string, ...args: unknown[]): void;
|
|
13
|
+
/** Emit an error (always visible). */
|
|
14
|
+
error(message: string, ...args: unknown[]): void;
|
|
15
|
+
/** Emit a debug trace (debug mode only — lowest priority). */
|
|
16
|
+
debug(message: string, ...args: unknown[]): void;
|
|
17
|
+
/** Log a timed group of related messages (debug mode only). */
|
|
18
|
+
group(label: string, fn: () => void): void;
|
|
19
|
+
/**
|
|
20
|
+
* Enable or disable verbose debug output at runtime.
|
|
21
|
+
*
|
|
22
|
+
* Example:
|
|
23
|
+
* import { SDKLogger } from "smartcomply-web-sdk";
|
|
24
|
+
* SDKLogger.setDebug(true);
|
|
25
|
+
*/
|
|
26
|
+
setDebug(enabled: boolean): void;
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,eAAO,MAAM,SAAS;IACpB,uDAAuD;kBACzC,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;IAK/C,uCAAuC;kBACzB,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;IAI/C,sCAAsC;mBACvB,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;IAIhD,8DAA8D;mBAC/C,MAAM,WAAW,OAAO,EAAE,GAAG,IAAI;IAKhD,+DAA+D;iBAClD,MAAM,MAAM,MAAM,IAAI,GAAG,IAAI;IAO1C;;;;;;OAMG;sBACe,OAAO,GAAG,IAAI;CAOjC,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lightweight SDK logger.
|
|
3
|
+
*
|
|
4
|
+
* Debug output is suppressed in production. Enable verbose logging by calling
|
|
5
|
+
* SDKLogger.setDebug(true) before initialising the SDK, or by setting the
|
|
6
|
+
* global flag: window.__SC_DEBUG__ = true
|
|
7
|
+
*/
|
|
8
|
+
const PREFIX = "[SmartComply SDK]";
|
|
9
|
+
function isDebugEnabled() {
|
|
10
|
+
try {
|
|
11
|
+
return !!window.__SC_DEBUG__;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export const SDKLogger = {
|
|
18
|
+
/** Emit an informational message (debug mode only). */
|
|
19
|
+
info(message, ...args) {
|
|
20
|
+
if (!isDebugEnabled())
|
|
21
|
+
return;
|
|
22
|
+
console.info(`${PREFIX} ℹ ${message}`, ...args);
|
|
23
|
+
},
|
|
24
|
+
/** Emit a warning (always visible). */
|
|
25
|
+
warn(message, ...args) {
|
|
26
|
+
console.warn(`${PREFIX} ⚠ ${message}`, ...args);
|
|
27
|
+
},
|
|
28
|
+
/** Emit an error (always visible). */
|
|
29
|
+
error(message, ...args) {
|
|
30
|
+
console.error(`${PREFIX} ✖ ${message}`, ...args);
|
|
31
|
+
},
|
|
32
|
+
/** Emit a debug trace (debug mode only — lowest priority). */
|
|
33
|
+
debug(message, ...args) {
|
|
34
|
+
if (!isDebugEnabled())
|
|
35
|
+
return;
|
|
36
|
+
console.debug(`${PREFIX} ⬡ ${message}`, ...args);
|
|
37
|
+
},
|
|
38
|
+
/** Log a timed group of related messages (debug mode only). */
|
|
39
|
+
group(label, fn) {
|
|
40
|
+
if (!isDebugEnabled()) {
|
|
41
|
+
fn();
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
console.group(`${PREFIX} ${label}`);
|
|
45
|
+
fn();
|
|
46
|
+
console.groupEnd();
|
|
47
|
+
},
|
|
48
|
+
/**
|
|
49
|
+
* Enable or disable verbose debug output at runtime.
|
|
50
|
+
*
|
|
51
|
+
* Example:
|
|
52
|
+
* import { SDKLogger } from "smartcomply-web-sdk";
|
|
53
|
+
* SDKLogger.setDebug(true);
|
|
54
|
+
*/
|
|
55
|
+
setDebug(enabled) {
|
|
56
|
+
try {
|
|
57
|
+
window.__SC_DEBUG__ = enabled;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
/* no-op in non-browser environments */
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../../src/utils/logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,GAAG,mBAAmB,CAAC;AAEnC,SAAS,cAAc;IACrB,IAAI,CAAC;QACH,OAAO,CAAC,CAAE,MAAc,CAAC,YAAY,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,uDAAuD;IACvD,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,IAAI,CAAC,cAAc,EAAE;YAAE,OAAO;QAC9B,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,uCAAuC;IACvC,IAAI,CAAC,OAAe,EAAE,GAAG,IAAe;QACtC,OAAO,CAAC,IAAI,CAAC,GAAG,MAAM,MAAM,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,sCAAsC;IACtC,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,MAAM,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,8DAA8D;IAC9D,KAAK,CAAC,OAAe,EAAE,GAAG,IAAe;QACvC,IAAI,CAAC,cAAc,EAAE;YAAE,OAAO;QAC9B,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,MAAM,OAAO,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IACnD,CAAC;IAED,+DAA+D;IAC/D,KAAK,CAAC,KAAa,EAAE,EAAc;QACjC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAAC,EAAE,EAAE,CAAC;YAAC,OAAO;QAAC,CAAC;QACxC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;QACpC,EAAE,EAAE,CAAC;QACL,OAAO,CAAC,QAAQ,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;OAMG;IACH,QAAQ,CAAC,OAAgB;QACvB,IAAI,CAAC;YACF,MAAc,CAAC,YAAY,GAAG,OAAO,CAAC;QACzC,CAAC;QAAC,MAAM,CAAC;YACP,uCAAuC;QACzC,CAAC;IACH,CAAC;CACF,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation helpers.
|
|
3
|
+
*
|
|
4
|
+
* All functions throw a descriptive Error on invalid input so callers can
|
|
5
|
+
* surface actionable messages without catching generic exceptions.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChallengeAction } from "../types/liveness";
|
|
8
|
+
/** Returns true when s is a non-empty string after trimming. */
|
|
9
|
+
export declare function isNonEmpty(s: unknown): s is string;
|
|
10
|
+
/**
|
|
11
|
+
* Validates that apiKey looks like a SmartComply public key.
|
|
12
|
+
* Format: pk_live_<...> or pk_test_<...>
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateApiKey(apiKey: unknown): void;
|
|
15
|
+
/** Throws if clientId is not a valid UUID v4. */
|
|
16
|
+
export declare function validateClientId(clientId: unknown): void;
|
|
17
|
+
/** Throws if countryCode is not a 2-letter ISO 3166-1 alpha-2 code. */
|
|
18
|
+
export declare function validateCountryCode(countryCode: unknown): void;
|
|
19
|
+
/** Throws if the blob is empty or exceeds the given byte limit. */
|
|
20
|
+
export declare function validateFileSize(blob: Blob | File, maxBytes: number, label: string): void;
|
|
21
|
+
/** Throws if the blob's MIME type is not in the accepted image types list. */
|
|
22
|
+
export declare function validateImageType(blob: Blob | File, label: string): void;
|
|
23
|
+
/** Combined validation for a document image blob. */
|
|
24
|
+
export declare function validateDocumentBlob(blob: Blob | File): void;
|
|
25
|
+
/** Combined validation for a liveness video blob. */
|
|
26
|
+
export declare function validateVideoBlob(blob: Blob): void;
|
|
27
|
+
/** Combined validation for a snapshot / autoshot blob. */
|
|
28
|
+
export declare function validateSnapshotBlob(blob: Blob): void;
|
|
29
|
+
/** Throws if any entry in actions is not a backend-accepted challenge action. */
|
|
30
|
+
export declare function validateChallengeActions(actions: unknown[]): void;
|
|
31
|
+
/** Type-guard that narrows a string[] to ChallengeAction[]. */
|
|
32
|
+
export declare function toChallengeActions(actions: string[]): ChallengeAction[];
|
|
33
|
+
/** Throws if identifier is missing or too short to be plausible. */
|
|
34
|
+
export declare function validateIdentifier(identifier: unknown, minLength?: number): void;
|
|
35
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/utils/validator.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AASH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIzD,gEAAgE;AAChE,wBAAgB,UAAU,CAAC,CAAC,EAAE,OAAO,GAAG,CAAC,IAAI,MAAM,CAElD;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CASpD;AAOD,iDAAiD;AACjD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CASxD;AAMD,uEAAuE;AACvE,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,OAAO,GAAG,IAAI,CAM9D;AAID,mEAAmE;AACnE,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,GAAG,IAAI,EACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GACZ,IAAI,CAUN;AAED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAMxE;AAED,qDAAqD;AACrD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAG5D;AAED,qDAAqD;AACrD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAElD;AAED,0DAA0D;AAC1D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAErD;AAID,iFAAiF;AACjF,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAWjE;AAED,+DAA+D;AAC/D,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,eAAe,EAAE,CAGvE;AAID,oEAAoE;AACpE,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,OAAO,EAAE,SAAS,SAAI,GAAG,IAAI,CAS3E"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Input validation helpers.
|
|
3
|
+
*
|
|
4
|
+
* All functions throw a descriptive Error on invalid input so callers can
|
|
5
|
+
* surface actionable messages without catching generic exceptions.
|
|
6
|
+
*/
|
|
7
|
+
import { MAX_DOCUMENT_BYTES, MAX_VIDEO_BYTES, MAX_SNAPSHOT_BYTES, ACCEPTED_IMAGE_TYPES, CHALLENGE_ACTIONS, } from "./constants";
|
|
8
|
+
// ── String helpers ───────────────────────────────────────────────────────────
|
|
9
|
+
/** Returns true when s is a non-empty string after trimming. */
|
|
10
|
+
export function isNonEmpty(s) {
|
|
11
|
+
return typeof s === "string" && s.trim().length > 0;
|
|
12
|
+
}
|
|
13
|
+
// ── API key ──────────────────────────────────────────────────────────────────
|
|
14
|
+
/**
|
|
15
|
+
* Validates that apiKey looks like a SmartComply public key.
|
|
16
|
+
* Format: pk_live_<...> or pk_test_<...>
|
|
17
|
+
*/
|
|
18
|
+
export function validateApiKey(apiKey) {
|
|
19
|
+
if (!isNonEmpty(apiKey)) {
|
|
20
|
+
throw new Error("SDK: apiKey is required.");
|
|
21
|
+
}
|
|
22
|
+
if (!/^pk_(live|test|sandbox)_/.test(apiKey)) {
|
|
23
|
+
throw new Error('SDK: apiKey must start with "pk_live_", "pk_test_" or "pk_sandbox_".');
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// ── Client ID (UUID) ─────────────────────────────────────────────────────────
|
|
27
|
+
const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
28
|
+
/** Throws if clientId is not a valid UUID v4. */
|
|
29
|
+
export function validateClientId(clientId) {
|
|
30
|
+
if (!isNonEmpty(clientId)) {
|
|
31
|
+
throw new Error("SDK: clientId is required.");
|
|
32
|
+
}
|
|
33
|
+
if (!UUID_RE.test(clientId.trim())) {
|
|
34
|
+
throw new Error("SDK: clientId must be a valid UUID (e.g. a1b2c3d4-e5f6-7890-abcd-ef1234567890).");
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
// ── Country code ─────────────────────────────────────────────────────────────
|
|
38
|
+
const COUNTRY_CODE_RE = /^[A-Z]{2}$/;
|
|
39
|
+
/** Throws if countryCode is not a 2-letter ISO 3166-1 alpha-2 code. */
|
|
40
|
+
export function validateCountryCode(countryCode) {
|
|
41
|
+
if (!isNonEmpty(countryCode) || !COUNTRY_CODE_RE.test(countryCode.trim())) {
|
|
42
|
+
throw new Error(`SDK: Invalid country code "${countryCode}". Expected a 2-letter ISO code (e.g. "NG", "GH").`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
// ── File / Blob ──────────────────────────────────────────────────────────────
|
|
46
|
+
/** Throws if the blob is empty or exceeds the given byte limit. */
|
|
47
|
+
export function validateFileSize(blob, maxBytes, label) {
|
|
48
|
+
if (!blob || blob.size === 0) {
|
|
49
|
+
throw new Error(`SDK: ${label} is empty. Please capture or upload a valid file.`);
|
|
50
|
+
}
|
|
51
|
+
if (blob.size > maxBytes) {
|
|
52
|
+
const limitMB = (maxBytes / (1024 * 1024)).toFixed(0);
|
|
53
|
+
throw new Error(`SDK: ${label} exceeds the ${limitMB} MB limit (file is ${(blob.size / (1024 * 1024)).toFixed(1)} MB).`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Throws if the blob's MIME type is not in the accepted image types list. */
|
|
57
|
+
export function validateImageType(blob, label) {
|
|
58
|
+
if (blob.type && !ACCEPTED_IMAGE_TYPES.includes(blob.type)) {
|
|
59
|
+
throw new Error(`SDK: ${label} must be a JPEG, PNG or WebP image (received "${blob.type}").`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Combined validation for a document image blob. */
|
|
63
|
+
export function validateDocumentBlob(blob) {
|
|
64
|
+
validateFileSize(blob, MAX_DOCUMENT_BYTES, "Document image");
|
|
65
|
+
validateImageType(blob, "Document image");
|
|
66
|
+
}
|
|
67
|
+
/** Combined validation for a liveness video blob. */
|
|
68
|
+
export function validateVideoBlob(blob) {
|
|
69
|
+
validateFileSize(blob, MAX_VIDEO_BYTES, "Liveness video");
|
|
70
|
+
}
|
|
71
|
+
/** Combined validation for a snapshot / autoshot blob. */
|
|
72
|
+
export function validateSnapshotBlob(blob) {
|
|
73
|
+
validateFileSize(blob, MAX_SNAPSHOT_BYTES, "Snapshot");
|
|
74
|
+
}
|
|
75
|
+
// ── Challenge actions ─────────────────────────────────────────────────────────
|
|
76
|
+
/** Throws if any entry in actions is not a backend-accepted challenge action. */
|
|
77
|
+
export function validateChallengeActions(actions) {
|
|
78
|
+
if (!Array.isArray(actions) || actions.length === 0) {
|
|
79
|
+
throw new Error("SDK: At least one challenge action is required.");
|
|
80
|
+
}
|
|
81
|
+
for (const a of actions) {
|
|
82
|
+
if (!CHALLENGE_ACTIONS.includes(a)) {
|
|
83
|
+
throw new Error(`SDK: "${a}" is not a valid challenge action. Accepted: ${CHALLENGE_ACTIONS.join(", ")}.`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/** Type-guard that narrows a string[] to ChallengeAction[]. */
|
|
88
|
+
export function toChallengeActions(actions) {
|
|
89
|
+
validateChallengeActions(actions);
|
|
90
|
+
return actions;
|
|
91
|
+
}
|
|
92
|
+
// ── Identifier / ID number ────────────────────────────────────────────────────
|
|
93
|
+
/** Throws if identifier is missing or too short to be plausible. */
|
|
94
|
+
export function validateIdentifier(identifier, minLength = 3) {
|
|
95
|
+
if (!isNonEmpty(identifier)) {
|
|
96
|
+
throw new Error("SDK: identifier is required.");
|
|
97
|
+
}
|
|
98
|
+
if (identifier.trim().length < minLength) {
|
|
99
|
+
throw new Error(`SDK: identifier must be at least ${minLength} characters long.`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=validator.js.map
|