smartcomply-web-sdk 1.0.3
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/LICENSE +15 -0
- package/README.md +482 -0
- package/dist/camera/ActionDetector.d.ts +26 -0
- package/dist/camera/ActionDetector.d.ts.map +1 -0
- package/dist/camera/ActionDetector.js +114 -0
- package/dist/camera/ActionDetector.js.map +1 -0
- package/dist/camera/CameraManager.d.ts +7 -0
- package/dist/camera/CameraManager.d.ts.map +1 -0
- package/dist/camera/CameraManager.js +31 -0
- package/dist/camera/CameraManager.js.map +1 -0
- package/dist/camera/FaceDetector.d.ts +12 -0
- package/dist/camera/FaceDetector.d.ts.map +1 -0
- package/dist/camera/FaceDetector.js +55 -0
- package/dist/camera/FaceDetector.js.map +1 -0
- package/dist/camera/Permission.d.ts +42 -0
- package/dist/camera/Permission.d.ts.map +1 -0
- package/dist/camera/Permission.js +107 -0
- package/dist/camera/Permission.js.map +1 -0
- package/dist/camera/VideoRecorder.d.ts +12 -0
- package/dist/camera/VideoRecorder.d.ts.map +1 -0
- package/dist/camera/VideoRecorder.js +51 -0
- package/dist/camera/VideoRecorder.js.map +1 -0
- package/dist/client/Config.d.ts +9 -0
- package/dist/client/Config.d.ts.map +1 -0
- package/dist/client/Config.js +8 -0
- package/dist/client/Config.js.map +1 -0
- package/dist/client/HttpClient.d.ts +44 -0
- package/dist/client/HttpClient.d.ts.map +1 -0
- package/dist/client/HttpClient.js +149 -0
- package/dist/client/HttpClient.js.map +1 -0
- package/dist/client/Smartcomply.d.ts +50 -0
- package/dist/client/Smartcomply.d.ts.map +1 -0
- package/dist/client/Smartcomply.js +77 -0
- package/dist/client/Smartcomply.js.map +1 -0
- package/dist/components/CameraView.d.ts +59 -0
- package/dist/components/CameraView.d.ts.map +1 -0
- package/dist/components/CameraView.js +242 -0
- package/dist/components/CameraView.js.map +1 -0
- package/dist/components/DocumentUpload.d.ts +21 -0
- package/dist/components/DocumentUpload.d.ts.map +1 -0
- package/dist/components/DocumentUpload.js +220 -0
- package/dist/components/DocumentUpload.js.map +1 -0
- package/dist/errors/AuthError.d.ts +8 -0
- package/dist/errors/AuthError.d.ts.map +1 -0
- package/dist/errors/AuthError.js +15 -0
- package/dist/errors/AuthError.js.map +1 -0
- package/dist/errors/NetworkError.d.ts +8 -0
- package/dist/errors/NetworkError.d.ts.map +1 -0
- package/dist/errors/NetworkError.js +15 -0
- package/dist/errors/NetworkError.js.map +1 -0
- package/dist/errors/SDKError.d.ts +7 -0
- package/dist/errors/SDKError.d.ts.map +1 -0
- package/dist/errors/SDKError.js +14 -0
- package/dist/errors/SDKError.js.map +1 -0
- package/dist/flow/DocumentCapture.d.ts +54 -0
- package/dist/flow/DocumentCapture.d.ts.map +1 -0
- package/dist/flow/DocumentCapture.js +801 -0
- package/dist/flow/DocumentCapture.js.map +1 -0
- package/dist/flow/SmartComplyFlow.d.ts +104 -0
- package/dist/flow/SmartComplyFlow.d.ts.map +1 -0
- package/dist/flow/SmartComplyFlow.js +1726 -0
- package/dist/flow/SmartComplyFlow.js.map +1 -0
- package/dist/flow/theme.d.ts +30 -0
- package/dist/flow/theme.d.ts.map +1 -0
- package/dist/flow/theme.js +103 -0
- package/dist/flow/theme.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/modules/liveness/LivenessUI.d.ts +46 -0
- package/dist/modules/liveness/LivenessUI.d.ts.map +1 -0
- package/dist/modules/liveness/LivenessUI.js +609 -0
- package/dist/modules/liveness/LivenessUI.js.map +1 -0
- package/dist/modules/liveness/index.d.ts +5 -0
- package/dist/modules/liveness/index.d.ts.map +1 -0
- package/dist/modules/liveness/index.js +10 -0
- package/dist/modules/liveness/index.js.map +1 -0
- package/dist/modules/liveness/liveness.d.ts +85 -0
- package/dist/modules/liveness/liveness.d.ts.map +1 -0
- package/dist/modules/liveness/liveness.js +425 -0
- package/dist/modules/liveness/liveness.js.map +1 -0
- package/dist/modules/liveness/uploader.d.ts +34 -0
- package/dist/modules/liveness/uploader.d.ts.map +1 -0
- package/dist/modules/liveness/uploader.js +106 -0
- package/dist/modules/liveness/uploader.js.map +1 -0
- package/dist/modules/onboarding/index.d.ts +2 -0
- package/dist/modules/onboarding/index.d.ts.map +1 -0
- package/dist/modules/onboarding/index.js +6 -0
- package/dist/modules/onboarding/index.js.map +1 -0
- package/dist/modules/onboarding/onboarding.d.ts +25 -0
- package/dist/modules/onboarding/onboarding.d.ts.map +1 -0
- package/dist/modules/onboarding/onboarding.js +33 -0
- package/dist/modules/onboarding/onboarding.js.map +1 -0
- package/dist/smartcomply.browser.js +8147 -0
- package/dist/smartcomply.browser.js.map +7 -0
- package/dist/types/common.d.ts +27 -0
- package/dist/types/common.d.ts.map +1 -0
- package/dist/types/common.js +3 -0
- package/dist/types/common.js.map +1 -0
- package/dist/types/liveness.d.ts +142 -0
- package/dist/types/liveness.d.ts.map +1 -0
- package/dist/types/liveness.js +3 -0
- package/dist/types/liveness.js.map +1 -0
- package/dist/types/onboarding.d.ts +53 -0
- package/dist/types/onboarding.d.ts.map +1 -0
- package/dist/types/onboarding.js +3 -0
- package/dist/types/onboarding.js.map +1 -0
- package/dist/types/quality.d.ts +23 -0
- package/dist/types/quality.d.ts.map +1 -0
- package/dist/types/quality.js +6 -0
- package/dist/types/quality.js.map +1 -0
- package/dist/utils/ImageQuality.d.ts +48 -0
- package/dist/utils/ImageQuality.d.ts.map +1 -0
- package/dist/utils/ImageQuality.js +186 -0
- package/dist/utils/ImageQuality.js.map +1 -0
- package/dist/utils/constants.d.ts +59 -0
- package/dist/utils/constants.d.ts.map +1 -0
- package/dist/utils/constants.js +70 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/device.d.ts +14 -0
- package/dist/utils/device.d.ts.map +1 -0
- package/dist/utils/device.js +55 -0
- package/dist/utils/device.js.map +1 -0
- package/dist/utils/logger.d.ts +28 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +67 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/validator.d.ts +35 -0
- package/dist/utils/validator.d.ts.map +1 -0
- package/dist/utils/validator.js +116 -0
- package/dist/utils/validator.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { HttpClient } from "../../client/HttpClient";
|
|
2
|
+
import { ChallengeAction, LivenessCreateRequest, LivenessCreateResponse, LivenessSubmitResponse } from "../../types/liveness";
|
|
3
|
+
/**
|
|
4
|
+
* Liveness module — 3-step flow aligned with Adhere backend.
|
|
5
|
+
*
|
|
6
|
+
* Flow:
|
|
7
|
+
* Step 1: liveness.create() → POST /v1/sdk/liveness/create/ (multipart)
|
|
8
|
+
* Step 2: [camera runs, user performs challenge actions]
|
|
9
|
+
* Step 3: liveness.submit() → POST /v1/sdk/liveness/submit/ (multipart)
|
|
10
|
+
*
|
|
11
|
+
* After submit, the backend returns status: "processing".
|
|
12
|
+
* Final results are delivered via webhook (liveness.completed event).
|
|
13
|
+
*/
|
|
14
|
+
export declare class LivenessModule {
|
|
15
|
+
private http;
|
|
16
|
+
constructor(http: HttpClient);
|
|
17
|
+
/**
|
|
18
|
+
* Step 1: Create a liveness challenge entry.
|
|
19
|
+
*
|
|
20
|
+
* POST /v1/sdk/liveness/create/
|
|
21
|
+
* Auth: x-access-token: <sessionToken>
|
|
22
|
+
* Content-Type: multipart/form-data
|
|
23
|
+
*/
|
|
24
|
+
create(params: LivenessCreateRequest): Promise<LivenessCreateResponse>;
|
|
25
|
+
/**
|
|
26
|
+
* Step 3: Submit liveness video recording.
|
|
27
|
+
*
|
|
28
|
+
* POST /v1/sdk/liveness/submit/
|
|
29
|
+
* Auth: x-access-token: <sessionToken>
|
|
30
|
+
* Content-Type: multipart/form-data
|
|
31
|
+
*
|
|
32
|
+
* Note: After submission, the session is revoked (single-use).
|
|
33
|
+
* The backend returns status: "processing" — results come via webhook.
|
|
34
|
+
*/
|
|
35
|
+
submit(entryId: number, videoBlob: Blob, snapshotBlob: Blob, autoshotBlob?: Blob, videoDurationSeconds?: number, videoSizeBytes?: number): Promise<LivenessSubmitResponse>;
|
|
36
|
+
/**
|
|
37
|
+
* Poll the public SDK status endpoint for the final verification result.
|
|
38
|
+
* Safe to call after the session has been revoked (no auth required).
|
|
39
|
+
*
|
|
40
|
+
* GET /v1/sdk/liveness/<entryId>/sdk-result/
|
|
41
|
+
*/
|
|
42
|
+
pollResult(entryId: number): Promise<{
|
|
43
|
+
id: number;
|
|
44
|
+
status: string;
|
|
45
|
+
failure_reason: string | null;
|
|
46
|
+
completed_at: string | null;
|
|
47
|
+
}>;
|
|
48
|
+
/**
|
|
49
|
+
* Full liveness check — orchestrates the entire flow:
|
|
50
|
+
*
|
|
51
|
+
* 1. Take autoshot selfie from camera
|
|
52
|
+
* 2. Create liveness entry on backend (with challenge actions + selfie + optional doc)
|
|
53
|
+
* 3. Run action detection loop (camera + MediaPipe)
|
|
54
|
+
* 4. Record video and submit to backend
|
|
55
|
+
* 5. Return submit response (status: "processing")
|
|
56
|
+
*
|
|
57
|
+
* @param container - DOM element to mount the liveness UI into
|
|
58
|
+
* @param params - identifier info and optional document image
|
|
59
|
+
* @param actions - override challenge actions (default: BLINK, TURN_LEFT, OPEN_MOUTH)
|
|
60
|
+
*/
|
|
61
|
+
startCheck(container: HTMLElement, params: {
|
|
62
|
+
identifier: string;
|
|
63
|
+
identifier_type: string;
|
|
64
|
+
country: string;
|
|
65
|
+
id_file?: File | Blob;
|
|
66
|
+
document?: File | Blob;
|
|
67
|
+
document_front?: File | Blob;
|
|
68
|
+
document_back?: File | Blob;
|
|
69
|
+
identity_check?: number;
|
|
70
|
+
verification_type?: "data_verification" | "document_verification" | "liveness_only";
|
|
71
|
+
}, actions?: ChallengeAction[], existingEntryId?: number): Promise<LivenessSubmitResponse>;
|
|
72
|
+
/**
|
|
73
|
+
* Capture a single sharp frame from a video element as a JPEG Blob.
|
|
74
|
+
* Retries up to maxAttempts times (300 ms apart) if the Laplacian blur
|
|
75
|
+
* score is below threshold, then falls back to the best frame captured.
|
|
76
|
+
*/
|
|
77
|
+
private captureFrame;
|
|
78
|
+
/**
|
|
79
|
+
* Laplacian variance blur metric on a centre-cropped region (320×240 max).
|
|
80
|
+
* Higher score = sharper image. Score < 80 is considered blurry.
|
|
81
|
+
*/
|
|
82
|
+
private _computeBlurScore;
|
|
83
|
+
private describeAction;
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=liveness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveness.d.ts","sourceRoot":"","sources":["../../../src/modules/liveness/liveness.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,sBAAsB,CAAC;AAQ9B;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IACb,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpC;;;;;;OAMG;IACG,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAuD5E;;;;;;;;;OASG;IACG,MAAM,CACV,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,IAAI,EACf,YAAY,EAAE,IAAI,EAClB,YAAY,CAAC,EAAE,IAAI,EACnB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,sBAAsB,CAAC;IAqBlC;;;;;OAKG;IACG,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QACzC,EAAE,EAAE,MAAM,CAAC;QACX,MAAM,EAAE,MAAM,CAAC;QACf,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,CAAC;IAIF;;;;;;;;;;;;OAYG;IACG,UAAU,CACd,SAAS,EAAE,WAAW,EACtB,MAAM,EAAE;QACN,UAAU,EAAE,MAAM,CAAC;QACnB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QACtB,QAAQ,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QACvB,cAAc,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QAC7B,aAAa,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;QAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;QACxB,iBAAiB,CAAC,EAAE,mBAAmB,GAAG,uBAAuB,GAAG,eAAe,CAAC;KACrF,EACD,OAAO,CAAC,EAAE,eAAe,EAAE,EAC3B,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,sBAAsB,CAAC;IAmQlC;;;;OAIG;YACW,YAAY;IAuC1B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAuCzB,OAAO,CAAC,cAAc;CAUvB"}
|
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LivenessModule = void 0;
|
|
4
|
+
const device_1 = require("../../utils/device");
|
|
5
|
+
const CameraManager_1 = require("../../camera/CameraManager");
|
|
6
|
+
const VideoRecorder_1 = require("../../camera/VideoRecorder");
|
|
7
|
+
const FaceDetector_1 = require("../../camera/FaceDetector");
|
|
8
|
+
const ActionDetector_1 = require("../../camera/ActionDetector");
|
|
9
|
+
const LivenessUI_1 = require("./LivenessUI");
|
|
10
|
+
/**
|
|
11
|
+
* Liveness module — 3-step flow aligned with Adhere backend.
|
|
12
|
+
*
|
|
13
|
+
* Flow:
|
|
14
|
+
* Step 1: liveness.create() → POST /v1/sdk/liveness/create/ (multipart)
|
|
15
|
+
* Step 2: [camera runs, user performs challenge actions]
|
|
16
|
+
* Step 3: liveness.submit() → POST /v1/sdk/liveness/submit/ (multipart)
|
|
17
|
+
*
|
|
18
|
+
* After submit, the backend returns status: "processing".
|
|
19
|
+
* Final results are delivered via webhook (liveness.completed event).
|
|
20
|
+
*/
|
|
21
|
+
class LivenessModule {
|
|
22
|
+
constructor(http) {
|
|
23
|
+
this.http = http;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Step 1: Create a liveness challenge entry.
|
|
27
|
+
*
|
|
28
|
+
* POST /v1/sdk/liveness/create/
|
|
29
|
+
* Auth: x-access-token: <sessionToken>
|
|
30
|
+
* Content-Type: multipart/form-data
|
|
31
|
+
*/
|
|
32
|
+
async create(params) {
|
|
33
|
+
const formData = new FormData();
|
|
34
|
+
formData.append("identifier", params.identifier);
|
|
35
|
+
formData.append("identifier_type", params.identifier_type);
|
|
36
|
+
formData.append("country", params.country);
|
|
37
|
+
formData.append("challenge_actions", JSON.stringify(params.challenge_actions));
|
|
38
|
+
if (params.autoshot_file) {
|
|
39
|
+
formData.append("autoshot", params.autoshot_file, "autoshot.jpg");
|
|
40
|
+
}
|
|
41
|
+
// Handle document upload - support both legacy and new front/back fields
|
|
42
|
+
if (params.document) {
|
|
43
|
+
formData.append("document", params.document, "document.jpg");
|
|
44
|
+
if (params.document_back) {
|
|
45
|
+
formData.append("document_back", params.document_back, "document_back.jpg");
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
else if (params.document_front) {
|
|
49
|
+
// Legacy support - map to document for backward compatibility
|
|
50
|
+
formData.append("document", params.document_front, "document_front.jpg");
|
|
51
|
+
if (params.document_back) {
|
|
52
|
+
formData.append("document_back", params.document_back, "document_back.jpg");
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (params.id_file) {
|
|
56
|
+
// Legacy support - map to document for backward compatibility
|
|
57
|
+
formData.append("document", params.id_file, "id_document.jpg");
|
|
58
|
+
}
|
|
59
|
+
if (params.identity_check) {
|
|
60
|
+
formData.append("identity_check", String(params.identity_check));
|
|
61
|
+
}
|
|
62
|
+
if (params.snapshot_file) {
|
|
63
|
+
formData.append("snapshot", params.snapshot_file, "snapshot.jpg");
|
|
64
|
+
}
|
|
65
|
+
if (params.device_type) {
|
|
66
|
+
formData.append("device_type", params.device_type);
|
|
67
|
+
}
|
|
68
|
+
if (params.os_name) {
|
|
69
|
+
formData.append("os_name", params.os_name);
|
|
70
|
+
}
|
|
71
|
+
if (params.browser_timezone) {
|
|
72
|
+
formData.append("browser_timezone", params.browser_timezone);
|
|
73
|
+
}
|
|
74
|
+
if (params.fingerprint_id) {
|
|
75
|
+
formData.append("fingerprint_id", params.fingerprint_id);
|
|
76
|
+
}
|
|
77
|
+
return this.http.uploadWithSession("/v1/sdk/liveness/create/", formData);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Step 3: Submit liveness video recording.
|
|
81
|
+
*
|
|
82
|
+
* POST /v1/sdk/liveness/submit/
|
|
83
|
+
* Auth: x-access-token: <sessionToken>
|
|
84
|
+
* Content-Type: multipart/form-data
|
|
85
|
+
*
|
|
86
|
+
* Note: After submission, the session is revoked (single-use).
|
|
87
|
+
* The backend returns status: "processing" — results come via webhook.
|
|
88
|
+
*/
|
|
89
|
+
async submit(entryId, videoBlob, snapshotBlob, autoshotBlob, videoDurationSeconds, videoSizeBytes) {
|
|
90
|
+
const formData = new FormData();
|
|
91
|
+
formData.append("entry", String(entryId));
|
|
92
|
+
formData.append("video", videoBlob, "liveness.webm");
|
|
93
|
+
formData.append("snapshot", snapshotBlob, "snapshot.jpg");
|
|
94
|
+
if (autoshotBlob) {
|
|
95
|
+
formData.append("autoshot", autoshotBlob, "autoshot.jpg");
|
|
96
|
+
}
|
|
97
|
+
if (videoDurationSeconds !== undefined) {
|
|
98
|
+
formData.append("video_duration_seconds", String(videoDurationSeconds));
|
|
99
|
+
}
|
|
100
|
+
if (videoSizeBytes !== undefined) {
|
|
101
|
+
formData.append("video_size_bytes", String(videoSizeBytes));
|
|
102
|
+
}
|
|
103
|
+
return this.http.uploadWithSession("/v1/sdk/liveness/submit/", formData);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Poll the public SDK status endpoint for the final verification result.
|
|
107
|
+
* Safe to call after the session has been revoked (no auth required).
|
|
108
|
+
*
|
|
109
|
+
* GET /v1/sdk/liveness/<entryId>/sdk-result/
|
|
110
|
+
*/
|
|
111
|
+
async pollResult(entryId) {
|
|
112
|
+
return this.http.publicGet(`/v1/sdk/liveness/${entryId}/sdk-result/`);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Full liveness check — orchestrates the entire flow:
|
|
116
|
+
*
|
|
117
|
+
* 1. Take autoshot selfie from camera
|
|
118
|
+
* 2. Create liveness entry on backend (with challenge actions + selfie + optional doc)
|
|
119
|
+
* 3. Run action detection loop (camera + MediaPipe)
|
|
120
|
+
* 4. Record video and submit to backend
|
|
121
|
+
* 5. Return submit response (status: "processing")
|
|
122
|
+
*
|
|
123
|
+
* @param container - DOM element to mount the liveness UI into
|
|
124
|
+
* @param params - identifier info and optional document image
|
|
125
|
+
* @param actions - override challenge actions (default: BLINK, TURN_LEFT, OPEN_MOUTH)
|
|
126
|
+
*/
|
|
127
|
+
async startCheck(container, params, actions, existingEntryId) {
|
|
128
|
+
const camera = new CameraManager_1.CameraManager();
|
|
129
|
+
const recorder = new VideoRecorder_1.VideoRecorder();
|
|
130
|
+
const faceEngine = new FaceDetector_1.FaceDetectorEngine();
|
|
131
|
+
const ui = new LivenessUI_1.LivenessUI();
|
|
132
|
+
// Tracks whether cleanup has already been called (so the finally block
|
|
133
|
+
// doesn't double-destroy when retry takes over).
|
|
134
|
+
let cleanedUp = false;
|
|
135
|
+
const cleanup = () => {
|
|
136
|
+
if (cleanedUp)
|
|
137
|
+
return;
|
|
138
|
+
cleanedUp = true;
|
|
139
|
+
faceEngine.destroy();
|
|
140
|
+
camera.stop();
|
|
141
|
+
ui.unmount();
|
|
142
|
+
};
|
|
143
|
+
try {
|
|
144
|
+
// 1. Open camera (with permission error handling)
|
|
145
|
+
let stream;
|
|
146
|
+
try {
|
|
147
|
+
stream = await camera.open();
|
|
148
|
+
}
|
|
149
|
+
catch (camErr) {
|
|
150
|
+
if (camErr.name === "NotAllowedError" || camErr.name === "PermissionDeniedError") {
|
|
151
|
+
throw new Error("Camera access denied. Please allow camera permission in your browser settings and try again.");
|
|
152
|
+
}
|
|
153
|
+
if (camErr.name === "NotFoundError" || camErr.name === "DevicesNotFoundError") {
|
|
154
|
+
throw new Error("No camera found. Please connect a camera and try again.");
|
|
155
|
+
}
|
|
156
|
+
throw new Error(`Camera error: ${camErr.message || "Unable to access camera"}`);
|
|
157
|
+
}
|
|
158
|
+
// 2. Document capture step — document_verification only, when no id_file pre-supplied
|
|
159
|
+
let capturedDocBlob = params.id_file;
|
|
160
|
+
if (!capturedDocBlob && params.verification_type === "document_verification") {
|
|
161
|
+
capturedDocBlob = await ui.mountDocumentCapture(container, stream);
|
|
162
|
+
}
|
|
163
|
+
// 3. Create a temporary video element to capture autoshot
|
|
164
|
+
const tempVideo = document.createElement("video");
|
|
165
|
+
tempVideo.srcObject = stream;
|
|
166
|
+
tempVideo.muted = true;
|
|
167
|
+
tempVideo.playsInline = true;
|
|
168
|
+
await tempVideo.play();
|
|
169
|
+
// Wait for face to be detected before capturing autoshot
|
|
170
|
+
ui.mount(container, { actions: [], time_limit_seconds: 0, instruction: "Centre your face in the oval" });
|
|
171
|
+
const uiVideo = ui.getVideoElement();
|
|
172
|
+
if (uiVideo) {
|
|
173
|
+
uiVideo.srcObject = stream;
|
|
174
|
+
await uiVideo.play();
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
tempVideo.style.cssText = "width:100%;border-radius:12px;transform:scaleX(-1);";
|
|
178
|
+
container.appendChild(tempVideo);
|
|
179
|
+
}
|
|
180
|
+
await faceEngine.init();
|
|
181
|
+
ui.updateInstruction("Centre your face in the oval");
|
|
182
|
+
// Wait until face is stably centred (5 consecutive detected frames, max 12 s)
|
|
183
|
+
const videoForDetection = uiVideo || tempVideo;
|
|
184
|
+
await new Promise((resolve) => {
|
|
185
|
+
let attempts = 0;
|
|
186
|
+
let stableFrames = 0;
|
|
187
|
+
const STABLE_REQUIRED = 5;
|
|
188
|
+
const maxAttempts = 120; // 12 seconds at 100ms intervals
|
|
189
|
+
const checkFace = () => {
|
|
190
|
+
attempts++;
|
|
191
|
+
if (videoForDetection.readyState >= 2) {
|
|
192
|
+
const detection = faceEngine.detect(videoForDetection, performance.now());
|
|
193
|
+
if (detection.faceDetected) {
|
|
194
|
+
stableFrames++;
|
|
195
|
+
if (stableFrames >= STABLE_REQUIRED) {
|
|
196
|
+
resolve();
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
stableFrames = 0; // reset on any lost-face frame
|
|
202
|
+
ui.updateInstruction("Move your face into the oval");
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (attempts >= maxAttempts) {
|
|
206
|
+
resolve(); // proceed anyway after timeout
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
setTimeout(checkFace, 100);
|
|
210
|
+
};
|
|
211
|
+
checkFace();
|
|
212
|
+
});
|
|
213
|
+
ui.updateInstruction("Hold still — capturing your selfie...");
|
|
214
|
+
await new Promise((r) => setTimeout(r, 700)); // wait for camera auto-focus
|
|
215
|
+
// 3. Capture autoshot (selfie) — face stable, camera focused
|
|
216
|
+
const autoshotBlob = await this.captureFrame(videoForDetection);
|
|
217
|
+
tempVideo.pause();
|
|
218
|
+
// Validate autoshot blob is not empty
|
|
219
|
+
if (!autoshotBlob || autoshotBlob.size === 0) {
|
|
220
|
+
throw new Error("Failed to capture autoshot selfie. Please ensure camera is working.");
|
|
221
|
+
}
|
|
222
|
+
// 4. Create liveness entry on backend (skip if retrying with existing entry)
|
|
223
|
+
const challengeActions = actions || ["BLINK", "TURN_LEFT", "OPEN_MOUTH"];
|
|
224
|
+
let entry;
|
|
225
|
+
if (existingEntryId) {
|
|
226
|
+
// Reuse existing entry on retry (D1: prevent duplicate wallet charges)
|
|
227
|
+
entry = { id: existingEntryId, challenge_actions: challengeActions, status: "pending", client_id: "", expires_at: null };
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
const deviceMeta = (0, device_1.collectDeviceMetadata)();
|
|
231
|
+
entry = await this.create({
|
|
232
|
+
identifier: params.identifier,
|
|
233
|
+
identifier_type: params.identifier_type,
|
|
234
|
+
country: params.country,
|
|
235
|
+
challenge_actions: challengeActions,
|
|
236
|
+
autoshot_file: autoshotBlob,
|
|
237
|
+
document: params.document || params.document_front || params.id_file || capturedDocBlob,
|
|
238
|
+
document_back: params.document_back,
|
|
239
|
+
identity_check: params.identity_check,
|
|
240
|
+
device_type: deviceMeta.device_type,
|
|
241
|
+
os_name: deviceMeta.os_name,
|
|
242
|
+
browser_timezone: deviceMeta.browser_timezone,
|
|
243
|
+
fingerprint_id: deviceMeta.fingerprint_id,
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
// 5. Mount UI with challenge actions from backend
|
|
247
|
+
const uiChallenge = {
|
|
248
|
+
actions: entry.challenge_actions,
|
|
249
|
+
time_limit_seconds: 45,
|
|
250
|
+
instruction: "Complete each action below to verify it's you",
|
|
251
|
+
};
|
|
252
|
+
// Re-mount UI with challenge actions (face engine already initialized)
|
|
253
|
+
ui.unmount();
|
|
254
|
+
const videoEl = ui.mount(container, uiChallenge);
|
|
255
|
+
videoEl.srcObject = stream;
|
|
256
|
+
await videoEl.play();
|
|
257
|
+
// 7. Start recording
|
|
258
|
+
recorder.start(stream);
|
|
259
|
+
ui.updateInstruction(uiChallenge.instruction);
|
|
260
|
+
// 8. Run detection loop (sequential — one action at a time)
|
|
261
|
+
const actionDetector = new ActionDetector_1.ActionDetector(entry.challenge_actions);
|
|
262
|
+
let lastAction = null;
|
|
263
|
+
const detectionResult = await new Promise((resolve) => {
|
|
264
|
+
let animFrameId;
|
|
265
|
+
const timeout = setTimeout(() => {
|
|
266
|
+
cancelAnimationFrame(animFrameId);
|
|
267
|
+
resolve("timeout");
|
|
268
|
+
}, uiChallenge.time_limit_seconds * 1000);
|
|
269
|
+
const detectLoop = () => {
|
|
270
|
+
if (videoEl.readyState >= 2) {
|
|
271
|
+
const detection = faceEngine.detect(videoEl, performance.now());
|
|
272
|
+
const states = actionDetector.check(detection);
|
|
273
|
+
ui.updateActions(states);
|
|
274
|
+
const current = actionDetector.getCurrentAction();
|
|
275
|
+
if (!detection.faceDetected) {
|
|
276
|
+
ui.updateInstruction("Move your face into the oval");
|
|
277
|
+
}
|
|
278
|
+
else if (current) {
|
|
279
|
+
if (current !== lastAction) {
|
|
280
|
+
lastAction = current;
|
|
281
|
+
ui.updateInstruction(this.describeAction(current));
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
ui.updateInstruction("All actions completed! ✓");
|
|
286
|
+
}
|
|
287
|
+
if (actionDetector.allCompleted()) {
|
|
288
|
+
clearTimeout(timeout);
|
|
289
|
+
cancelAnimationFrame(animFrameId);
|
|
290
|
+
resolve("completed");
|
|
291
|
+
return;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
animFrameId = requestAnimationFrame(detectLoop);
|
|
295
|
+
};
|
|
296
|
+
detectLoop();
|
|
297
|
+
});
|
|
298
|
+
// ── On timeout: show retry screen, clean up, restart ──────────
|
|
299
|
+
if (detectionResult === "timeout") {
|
|
300
|
+
// IMPORTANT: mark cleanedUp=true BEFORE returning the new Promise so
|
|
301
|
+
// the outer `finally` block does NOT call cleanup() immediately —
|
|
302
|
+
// which would destroy the UI before the user sees the timeout screen.
|
|
303
|
+
cleanedUp = true;
|
|
304
|
+
recorder.stop().catch(() => { }); // discard partial recording
|
|
305
|
+
return new Promise((resolveRetry, rejectRetry) => {
|
|
306
|
+
ui.showTimeout(() => {
|
|
307
|
+
// User clicked "Try Again" — now it is safe to destroy this attempt
|
|
308
|
+
faceEngine.destroy();
|
|
309
|
+
camera.stop();
|
|
310
|
+
ui.unmount();
|
|
311
|
+
// Restart liveness with same entry ID to prevent duplicate charges (D1)
|
|
312
|
+
// Pass capturedDocBlob forward so document scan step is not repeated
|
|
313
|
+
this.startCheck(container, { ...params, id_file: capturedDocBlob }, actions, entry.id)
|
|
314
|
+
.then(resolveRetry)
|
|
315
|
+
.catch(rejectRetry);
|
|
316
|
+
});
|
|
317
|
+
// showTimeout waits for the user to click — the promise stays pending.
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
// ── On completion: stop recording, submit, show success ────────
|
|
321
|
+
// Wait for user to return to neutral face after last action before
|
|
322
|
+
// capturing snapshot — prevents mid-action pose from skewing DeepFace
|
|
323
|
+
// embeddings (open mouth / head turned = high cosine distance).
|
|
324
|
+
ui.updateInstruction("Almost done — hold still...");
|
|
325
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
326
|
+
// Capture a snapshot frame while the video is still playing
|
|
327
|
+
const snapshotBlob = await this.captureFrame(videoEl);
|
|
328
|
+
// 9. Stop recording
|
|
329
|
+
const { blob: videoBlob, durationSeconds } = await recorder.stop();
|
|
330
|
+
// 10. Submit to backend — always include autoshot so document-flow
|
|
331
|
+
// entries (which bypassed create() via existingEntryId) still get it.
|
|
332
|
+
const submitResult = await this.submit(entry.id, videoBlob, snapshotBlob, autoshotBlob, durationSeconds, videoBlob.size);
|
|
333
|
+
// 11. Show success overlay briefly before the flow advances
|
|
334
|
+
await ui.showResult(submitResult.status === "processing" ? "processing" : "failed", submitResult.id);
|
|
335
|
+
return submitResult;
|
|
336
|
+
}
|
|
337
|
+
finally {
|
|
338
|
+
cleanup();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Capture a single sharp frame from a video element as a JPEG Blob.
|
|
343
|
+
* Retries up to maxAttempts times (300 ms apart) if the Laplacian blur
|
|
344
|
+
* score is below threshold, then falls back to the best frame captured.
|
|
345
|
+
*/
|
|
346
|
+
async captureFrame(video, maxAttempts = 4) {
|
|
347
|
+
const MIN_BLUR_SCORE = 80; // Laplacian variance — above this = acceptably sharp
|
|
348
|
+
const RETRY_DELAY_MS = 300;
|
|
349
|
+
let bestBlob = null;
|
|
350
|
+
let bestScore = -1;
|
|
351
|
+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
352
|
+
const canvas = document.createElement("canvas");
|
|
353
|
+
canvas.width = video.videoWidth || 640;
|
|
354
|
+
canvas.height = video.videoHeight || 480;
|
|
355
|
+
const ctx = canvas.getContext("2d");
|
|
356
|
+
if (!ctx)
|
|
357
|
+
throw new Error("Failed to get canvas context");
|
|
358
|
+
ctx.drawImage(video, 0, 0);
|
|
359
|
+
const score = this._computeBlurScore(canvas);
|
|
360
|
+
const blob = await new Promise((res) => canvas.toBlob((b) => res(b), "image/jpeg", 0.92));
|
|
361
|
+
if (blob && score > bestScore) {
|
|
362
|
+
bestBlob = blob;
|
|
363
|
+
bestScore = score;
|
|
364
|
+
}
|
|
365
|
+
if (score >= MIN_BLUR_SCORE)
|
|
366
|
+
break; // sharp enough — stop early
|
|
367
|
+
if (attempt < maxAttempts - 1) {
|
|
368
|
+
await new Promise((r) => setTimeout(r, RETRY_DELAY_MS));
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
if (bestBlob)
|
|
372
|
+
return bestBlob;
|
|
373
|
+
throw new Error("Failed to capture frame");
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* Laplacian variance blur metric on a centre-cropped region (320×240 max).
|
|
377
|
+
* Higher score = sharper image. Score < 80 is considered blurry.
|
|
378
|
+
*/
|
|
379
|
+
_computeBlurScore(canvas) {
|
|
380
|
+
const ctx = canvas.getContext("2d");
|
|
381
|
+
if (!ctx)
|
|
382
|
+
return 0;
|
|
383
|
+
// Sample a 320×240 centre crop for performance
|
|
384
|
+
const sw = Math.min(canvas.width, 320);
|
|
385
|
+
const sh = Math.min(canvas.height, 240);
|
|
386
|
+
const sx = Math.floor((canvas.width - sw) / 2);
|
|
387
|
+
const sy = Math.floor((canvas.height - sh) / 2);
|
|
388
|
+
const { data, width, height } = ctx.getImageData(sx, sy, sw, sh);
|
|
389
|
+
// Convert to greyscale
|
|
390
|
+
const gray = new Float32Array(width * height);
|
|
391
|
+
for (let i = 0; i < width * height; i++) {
|
|
392
|
+
gray[i] =
|
|
393
|
+
0.299 * data[i * 4] +
|
|
394
|
+
0.587 * data[i * 4 + 1] +
|
|
395
|
+
0.114 * data[i * 4 + 2];
|
|
396
|
+
}
|
|
397
|
+
// Laplacian convolution [0,1,0 / 1,-4,1 / 0,1,0] — sum of squared responses
|
|
398
|
+
let sum = 0;
|
|
399
|
+
let n = 0;
|
|
400
|
+
for (let y = 1; y < height - 1; y++) {
|
|
401
|
+
for (let x = 1; x < width - 1; x++) {
|
|
402
|
+
const l = gray[(y - 1) * width + x] +
|
|
403
|
+
gray[(y + 1) * width + x] +
|
|
404
|
+
gray[y * width + (x - 1)] +
|
|
405
|
+
gray[y * width + (x + 1)] -
|
|
406
|
+
4 * gray[y * width + x];
|
|
407
|
+
sum += l * l;
|
|
408
|
+
n++;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return n > 0 ? sum / n : 0;
|
|
412
|
+
}
|
|
413
|
+
describeAction(action) {
|
|
414
|
+
const descriptions = {
|
|
415
|
+
BLINK: "Blink your eyes",
|
|
416
|
+
TURN_LEFT: "Turn your head left",
|
|
417
|
+
TURN_RIGHT: "Turn your head right",
|
|
418
|
+
TURN_HEAD: "Turn your head side to side",
|
|
419
|
+
OPEN_MOUTH: "Open your mouth wide",
|
|
420
|
+
};
|
|
421
|
+
return descriptions[action] || action.replace(/_/g, " ").toLowerCase();
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
exports.LivenessModule = LivenessModule;
|
|
425
|
+
//# sourceMappingURL=liveness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"liveness.js","sourceRoot":"","sources":["../../../src/modules/liveness/liveness.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LivenessUploader — thin wrapper around the HttpClient's uploadWithSession()
|
|
3
|
+
* that adds:
|
|
4
|
+
* - Progress callbacks (onProgress)
|
|
5
|
+
* - Upload cancellation via AbortController
|
|
6
|
+
* - Automatic retry on transient network failure (configurable)
|
|
7
|
+
*
|
|
8
|
+
* Used internally by LivenessModule.create() and LivenessModule.submit() when
|
|
9
|
+
* the caller needs progress reporting (e.g. for a progress bar during video
|
|
10
|
+
* upload on slow connections).
|
|
11
|
+
*/
|
|
12
|
+
import { HttpClient } from "../../client/HttpClient";
|
|
13
|
+
export interface UploadOptions {
|
|
14
|
+
/** Called with a value 0–1 as the upload progresses. */
|
|
15
|
+
onProgress?: (fraction: number) => void;
|
|
16
|
+
/** Optional AbortSignal to cancel the upload mid-flight. */
|
|
17
|
+
signal?: AbortSignal;
|
|
18
|
+
/** Override the default number of retries on transient errors. */
|
|
19
|
+
retries?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare class LivenessUploader {
|
|
22
|
+
private http;
|
|
23
|
+
constructor(http: HttpClient);
|
|
24
|
+
/**
|
|
25
|
+
* Upload a FormData payload to `path` with optional progress and
|
|
26
|
+
* cancellation support.
|
|
27
|
+
*
|
|
28
|
+
* Falls back to the standard `uploadWithSession()` on browsers that do not
|
|
29
|
+
* support XMLHttpRequest upload progress (very rare).
|
|
30
|
+
*/
|
|
31
|
+
upload<T>(path: string, formData: FormData, options?: UploadOptions): Promise<T>;
|
|
32
|
+
private uploadWithProgress;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=uploader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uploader.d.ts","sourceRoot":"","sources":["../../../src/modules/liveness/uploader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAIrD,MAAM,WAAW,aAAa;IAC5B,wDAAwD;IACxD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAExC,4DAA4D;IAC5D,MAAM,CAAC,EAAE,WAAW,CAAC;IAErB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB;IACf,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,UAAU;IAEpC;;;;;;OAMG;IACG,MAAM,CAAC,CAAC,EACZ,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,CAAC,CAAC;YAcC,kBAAkB;CAkFjC"}
|