smartcomply-web-sdk 1.0.90 → 1.0.91
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/camera/ActionDetector.d.ts +2 -1
- package/dist/camera/ActionDetector.d.ts.map +1 -1
- package/dist/camera/ActionDetector.js +21 -5
- package/dist/camera/ActionDetector.js.map +1 -1
- package/dist/client/Smartcomply.d.ts +2 -2
- package/dist/client/Smartcomply.js +2 -2
- package/dist/esm/camera/ActionDetector.d.ts +2 -1
- package/dist/esm/camera/ActionDetector.d.ts.map +1 -1
- package/dist/esm/camera/ActionDetector.js +21 -5
- package/dist/esm/camera/ActionDetector.js.map +1 -1
- package/dist/esm/client/Smartcomply.d.ts +2 -2
- package/dist/esm/client/Smartcomply.js +2 -2
- package/dist/esm/flow/SmartComplyFlow.d.ts +10 -0
- package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.js +92 -32
- package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
- package/dist/esm/flow/spinner.js +14 -14
- package/dist/esm/modules/liveness/LivenessUI.js +83 -83
- package/dist/flow/SmartComplyFlow.d.ts +10 -0
- package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/flow/SmartComplyFlow.js +93 -32
- package/dist/flow/SmartComplyFlow.js.map +1 -1
- package/dist/flow/spinner.js +14 -14
- package/dist/modules/liveness/LivenessUI.js +83 -83
- package/dist/smartcomply.browser.js +46 -15
- package/dist/smartcomply.browser.js.map +2 -2
- package/package.json +1 -1
- package/dist/esm/components/CameraView.d.ts +0 -59
- package/dist/esm/components/CameraView.d.ts.map +0 -1
- package/dist/esm/components/CameraView.js +0 -238
- package/dist/esm/components/CameraView.js.map +0 -1
- package/dist/esm/components/DocumentUpload.d.ts +0 -21
- package/dist/esm/components/DocumentUpload.d.ts.map +0 -1
- package/dist/esm/components/DocumentUpload.js +0 -216
- package/dist/esm/components/DocumentUpload.js.map +0 -1
|
@@ -9,7 +9,8 @@ export declare class ActionDetector {
|
|
|
9
9
|
private blinkHoldCount;
|
|
10
10
|
private blinkDetected;
|
|
11
11
|
private motionDetected;
|
|
12
|
-
private
|
|
12
|
+
private minYaw;
|
|
13
|
+
private maxYaw;
|
|
13
14
|
check(result: FaceDetectionResult): ScanProgress;
|
|
14
15
|
/** Snapshot of what's been detected so far — for reading the result after
|
|
15
16
|
* the scan loop has already ended (e.g. to report alongside the submit
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAwBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;
|
|
1
|
+
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAwBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAG/B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAuB;IAErC,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY;IA2ChD;;4DAEwD;IACxD,WAAW,IAAI,YAAY;IAI3B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;CAInB"}
|
|
@@ -26,7 +26,10 @@ class ActionDetector {
|
|
|
26
26
|
this.blinkHoldCount = 0;
|
|
27
27
|
this.blinkDetected = false;
|
|
28
28
|
this.motionDetected = false;
|
|
29
|
-
|
|
29
|
+
// Running min/max yaw seen so far in the scan, not a single fixed
|
|
30
|
+
// first-frame baseline (see check() below for why).
|
|
31
|
+
this.minYaw = null;
|
|
32
|
+
this.maxYaw = null;
|
|
30
33
|
}
|
|
31
34
|
check(result) {
|
|
32
35
|
if (!result.faceDetected) {
|
|
@@ -47,10 +50,23 @@ class ActionDetector {
|
|
|
47
50
|
}
|
|
48
51
|
if (!this.motionDetected) {
|
|
49
52
|
const yaw = this.getHeadYaw(result.transformMatrix);
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
53
|
+
// A single first-frame baseline used to anchor this check — but the
|
|
54
|
+
// scan's first frame is essentially never a settled, neutral pose
|
|
55
|
+
// (camera/UI is still initializing, the user hasn't found center
|
|
56
|
+
// yet), and that baseline was never re-anchored for the rest of the
|
|
57
|
+
// window. A genuine head turn that happened to move TOWARD that
|
|
58
|
+
// arbitrary first reading, rather than away from it, read as a small
|
|
59
|
+
// delta and was missed — reported live as "blink saved, motion not,"
|
|
60
|
+
// on an ordinary fast look-around. Tracking the running min/max yaw
|
|
61
|
+
// and firing on their SPREAD instead fixes this: it's baseline-free,
|
|
62
|
+
// so it doesn't matter which frame happened to come first or which
|
|
63
|
+
// direction the real turn went — only that a genuine range of motion
|
|
64
|
+
// occurred somewhere across the window.
|
|
65
|
+
if (this.minYaw === null || yaw < this.minYaw)
|
|
66
|
+
this.minYaw = yaw;
|
|
67
|
+
if (this.maxYaw === null || yaw > this.maxYaw)
|
|
68
|
+
this.maxYaw = yaw;
|
|
69
|
+
if (this.maxYaw - this.minYaw >= YAW_MOTION_THRESHOLD_DEG) {
|
|
54
70
|
this.motionDetected = true;
|
|
55
71
|
}
|
|
56
72
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":";;;AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,oDAAoD;AASxF,MAAa,cAAc;IAA3B;QACU,mBAAc,GAAG,CAAC,CAAC;QACnB,kBAAa,GAAG,KAAK,CAAC;QACtB,mBAAc,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../src/camera/ActionDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ export declare class SmartComply {
|
|
|
22
22
|
* CDN tag they installed with (e.g. @1, which floats to the latest
|
|
23
23
|
* matching release) actually resolved to the version they expect.
|
|
24
24
|
*/
|
|
25
|
-
static readonly VERSION = "1.0.
|
|
25
|
+
static readonly VERSION = "1.0.91";
|
|
26
26
|
private http;
|
|
27
27
|
private clientId;
|
|
28
28
|
private _sessionToken;
|
|
@@ -62,7 +62,7 @@ export declare class SmartComply {
|
|
|
62
62
|
* the request, so the resume_token has to be the one in use throughout.
|
|
63
63
|
*
|
|
64
64
|
* No expires_at is set here — the resume_token's own issuance response
|
|
65
|
-
* only carries resume_expires_at (a
|
|
65
|
+
* only carries resume_expires_at (a 24h invite-link window), not the
|
|
66
66
|
* session's own runtime expiry the way createSession() returns one. The
|
|
67
67
|
* backend still enforces the real expiry server-side regardless; this
|
|
68
68
|
* only means the client-side "session about to expire" warning timer
|
|
@@ -75,7 +75,7 @@ class SmartComply {
|
|
|
75
75
|
* the request, so the resume_token has to be the one in use throughout.
|
|
76
76
|
*
|
|
77
77
|
* No expires_at is set here — the resume_token's own issuance response
|
|
78
|
-
* only carries resume_expires_at (a
|
|
78
|
+
* only carries resume_expires_at (a 24h invite-link window), not the
|
|
79
79
|
* session's own runtime expiry the way createSession() returns one. The
|
|
80
80
|
* backend still enforces the real expiry server-side regardless; this
|
|
81
81
|
* only means the client-side "session about to expire" warning timer
|
|
@@ -125,5 +125,5 @@ exports.SmartComply = SmartComply;
|
|
|
125
125
|
* CDN tag they installed with (e.g. @1, which floats to the latest
|
|
126
126
|
* matching release) actually resolved to the version they expect.
|
|
127
127
|
*/
|
|
128
|
-
SmartComply.VERSION = "1.0.
|
|
128
|
+
SmartComply.VERSION = "1.0.91";
|
|
129
129
|
//# sourceMappingURL=Smartcomply.js.map
|
|
@@ -9,7 +9,8 @@ export declare class ActionDetector {
|
|
|
9
9
|
private blinkHoldCount;
|
|
10
10
|
private blinkDetected;
|
|
11
11
|
private motionDetected;
|
|
12
|
-
private
|
|
12
|
+
private minYaw;
|
|
13
|
+
private maxYaw;
|
|
13
14
|
check(result: FaceDetectionResult): ScanProgress;
|
|
14
15
|
/** Snapshot of what's been detected so far — for reading the result after
|
|
15
16
|
* the scan loop has already ended (e.g. to report alongside the submit
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAwBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;
|
|
1
|
+
{"version":3,"file":"ActionDetector.d.ts","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAwBrD,MAAM,WAAW,YAAY;IAC3B,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,cAAc,CAAS;IAG/B,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,MAAM,CAAuB;IAErC,KAAK,CAAC,MAAM,EAAE,mBAAmB,GAAG,YAAY;IA2ChD;;4DAEwD;IACxD,WAAW,IAAI,YAAY;IAI3B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,UAAU;CAInB"}
|
|
@@ -23,7 +23,10 @@ export class ActionDetector {
|
|
|
23
23
|
this.blinkHoldCount = 0;
|
|
24
24
|
this.blinkDetected = false;
|
|
25
25
|
this.motionDetected = false;
|
|
26
|
-
|
|
26
|
+
// Running min/max yaw seen so far in the scan, not a single fixed
|
|
27
|
+
// first-frame baseline (see check() below for why).
|
|
28
|
+
this.minYaw = null;
|
|
29
|
+
this.maxYaw = null;
|
|
27
30
|
}
|
|
28
31
|
check(result) {
|
|
29
32
|
if (!result.faceDetected) {
|
|
@@ -44,10 +47,23 @@ export class ActionDetector {
|
|
|
44
47
|
}
|
|
45
48
|
if (!this.motionDetected) {
|
|
46
49
|
const yaw = this.getHeadYaw(result.transformMatrix);
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
// A single first-frame baseline used to anchor this check — but the
|
|
51
|
+
// scan's first frame is essentially never a settled, neutral pose
|
|
52
|
+
// (camera/UI is still initializing, the user hasn't found center
|
|
53
|
+
// yet), and that baseline was never re-anchored for the rest of the
|
|
54
|
+
// window. A genuine head turn that happened to move TOWARD that
|
|
55
|
+
// arbitrary first reading, rather than away from it, read as a small
|
|
56
|
+
// delta and was missed — reported live as "blink saved, motion not,"
|
|
57
|
+
// on an ordinary fast look-around. Tracking the running min/max yaw
|
|
58
|
+
// and firing on their SPREAD instead fixes this: it's baseline-free,
|
|
59
|
+
// so it doesn't matter which frame happened to come first or which
|
|
60
|
+
// direction the real turn went — only that a genuine range of motion
|
|
61
|
+
// occurred somewhere across the window.
|
|
62
|
+
if (this.minYaw === null || yaw < this.minYaw)
|
|
63
|
+
this.minYaw = yaw;
|
|
64
|
+
if (this.maxYaw === null || yaw > this.maxYaw)
|
|
65
|
+
this.maxYaw = yaw;
|
|
66
|
+
if (this.maxYaw - this.minYaw >= YAW_MOTION_THRESHOLD_DEG) {
|
|
51
67
|
this.motionDetected = true;
|
|
52
68
|
}
|
|
53
69
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,MAAM,eAAe,GAAG,IAAI,CAAC;AAC7B,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAC5B,MAAM,wBAAwB,GAAG,CAAC,CAAC,CAAC,oDAAoD;AASxF,MAAM,OAAO,cAAc;IAA3B;QACU,mBAAc,GAAG,CAAC,CAAC;QACnB,kBAAa,GAAG,KAAK,CAAC;QACtB,mBAAc,GAAG,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"ActionDetector.js","sourceRoot":"","sources":["../../../src/camera/ActionDetector.ts"],"names":[],"mappings":"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"}
|
|
@@ -22,7 +22,7 @@ export declare class SmartComply {
|
|
|
22
22
|
* CDN tag they installed with (e.g. @1, which floats to the latest
|
|
23
23
|
* matching release) actually resolved to the version they expect.
|
|
24
24
|
*/
|
|
25
|
-
static readonly VERSION = "1.0.
|
|
25
|
+
static readonly VERSION = "1.0.91";
|
|
26
26
|
private http;
|
|
27
27
|
private clientId;
|
|
28
28
|
private _sessionToken;
|
|
@@ -62,7 +62,7 @@ export declare class SmartComply {
|
|
|
62
62
|
* the request, so the resume_token has to be the one in use throughout.
|
|
63
63
|
*
|
|
64
64
|
* No expires_at is set here — the resume_token's own issuance response
|
|
65
|
-
* only carries resume_expires_at (a
|
|
65
|
+
* only carries resume_expires_at (a 24h invite-link window), not the
|
|
66
66
|
* session's own runtime expiry the way createSession() returns one. The
|
|
67
67
|
* backend still enforces the real expiry server-side regardless; this
|
|
68
68
|
* only means the client-side "session about to expire" warning timer
|
|
@@ -72,7 +72,7 @@ export class SmartComply {
|
|
|
72
72
|
* the request, so the resume_token has to be the one in use throughout.
|
|
73
73
|
*
|
|
74
74
|
* No expires_at is set here — the resume_token's own issuance response
|
|
75
|
-
* only carries resume_expires_at (a
|
|
75
|
+
* only carries resume_expires_at (a 24h invite-link window), not the
|
|
76
76
|
* session's own runtime expiry the way createSession() returns one. The
|
|
77
77
|
* backend still enforces the real expiry server-side regardless; this
|
|
78
78
|
* only means the client-side "session about to expire" warning timer
|
|
@@ -121,5 +121,5 @@ export class SmartComply {
|
|
|
121
121
|
* CDN tag they installed with (e.g. @1, which floats to the latest
|
|
122
122
|
* matching release) actually resolved to the version they expect.
|
|
123
123
|
*/
|
|
124
|
-
SmartComply.VERSION = "1.0.
|
|
124
|
+
SmartComply.VERSION = "1.0.91";
|
|
125
125
|
//# sourceMappingURL=Smartcomply.js.map
|
|
@@ -40,6 +40,16 @@ export interface FlowResult {
|
|
|
40
40
|
submittedAt: string | null;
|
|
41
41
|
verificationResult?: VerifyIdentityResponse;
|
|
42
42
|
}
|
|
43
|
+
/**
|
|
44
|
+
* Whether a showErrorStep() message is about an expired/invalid resume or
|
|
45
|
+
* resubmit link (RESUME_TARGET_UNAVAILABLE / NOT_A_RESUME_TOKEN — see
|
|
46
|
+
* SmartComplyFlow._resolveResumeStep), rather than a plain session timeout.
|
|
47
|
+
* Extracted to a standalone function so this specific classification is
|
|
48
|
+
* independently testable, same as resolveIdTypeInfo below — showErrorStep's
|
|
49
|
+
* own regex-based classification block is otherwise tightly coupled to DOM
|
|
50
|
+
* rendering it doesn't make sense to extract wholesale for this fix.
|
|
51
|
+
*/
|
|
52
|
+
export declare function isResumeLinkErrorMessage(message: string): boolean;
|
|
43
53
|
export declare function resolveIdTypeInfo(typeName: string, isDocumentFlow: boolean): {
|
|
44
54
|
icon: string;
|
|
45
55
|
desc: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SmartComplyFlow.d.ts","sourceRoot":"","sources":["../../../src/flow/SmartComplyFlow.ts"],"names":[],"mappings":"AACA,OAAO,EAA6B,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAIxF,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAoB,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"SmartComplyFlow.d.ts","sourceRoot":"","sources":["../../../src/flow/SmartComplyFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,7 @@ import { requiresBackSide } from "../utils/documentRules";
|
|
|
6
6
|
import { DEFAULT_CHALLENGE_ACTIONS } from "../utils/constants";
|
|
7
7
|
import { icon } from "./icons";
|
|
8
8
|
import { renderSpinner, renderInlineSpinner } from "./spinner";
|
|
9
|
+
import { SDKError } from "../errors/SDKError";
|
|
9
10
|
// A dropped camera/network/upload error is not the user's fault and must not
|
|
10
11
|
// cost them a retry attempt — only a genuine verification outcome should.
|
|
11
12
|
// Classified by message rather than a typed error class since the errors
|
|
@@ -66,6 +67,18 @@ const COUNTRY_LABELS = {
|
|
|
66
67
|
function isUploadFieldType(type) {
|
|
67
68
|
return type === "upload" || type === "image" || type === "file";
|
|
68
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Whether a showErrorStep() message is about an expired/invalid resume or
|
|
72
|
+
* resubmit link (RESUME_TARGET_UNAVAILABLE / NOT_A_RESUME_TOKEN — see
|
|
73
|
+
* SmartComplyFlow._resolveResumeStep), rather than a plain session timeout.
|
|
74
|
+
* Extracted to a standalone function so this specific classification is
|
|
75
|
+
* independently testable, same as resolveIdTypeInfo below — showErrorStep's
|
|
76
|
+
* own regex-based classification block is otherwise tightly coupled to DOM
|
|
77
|
+
* rendering it doesn't make sense to extract wholesale for this fix.
|
|
78
|
+
*/
|
|
79
|
+
export function isResumeLinkErrorMessage(message) {
|
|
80
|
+
return /resume link|resubmit link/i.test(message);
|
|
81
|
+
}
|
|
69
82
|
export function resolveIdTypeInfo(typeName, isDocumentFlow) {
|
|
70
83
|
const u = typeName.toUpperCase();
|
|
71
84
|
const advanced = u.includes("ADVANCED");
|
|
@@ -654,7 +667,18 @@ export class SmartComplyFlow {
|
|
|
654
667
|
}
|
|
655
668
|
if (this.isDestroyed)
|
|
656
669
|
return;
|
|
657
|
-
|
|
670
|
+
if (this.options.resumeToken) {
|
|
671
|
+
// null means _resolveResumeStep already rendered an error itself
|
|
672
|
+
// (a provably expired/invalid resume link — see that method) and
|
|
673
|
+
// there is no step left to show; calling showStep() in that case
|
|
674
|
+
// would wipe the error message straight back out.
|
|
675
|
+
const resumeStep = await this._resolveResumeStep();
|
|
676
|
+
if (resumeStep !== null)
|
|
677
|
+
this.showStep(resumeStep);
|
|
678
|
+
}
|
|
679
|
+
else {
|
|
680
|
+
this.showStep("welcome");
|
|
681
|
+
}
|
|
658
682
|
}
|
|
659
683
|
catch (err) {
|
|
660
684
|
this.showErrorStep(err.message || "Failed to initialize. Please try again.");
|
|
@@ -665,9 +689,23 @@ export class SmartComplyFlow {
|
|
|
665
689
|
// same state renderCountrySelect/renderIdTypeSelect's own click handlers
|
|
666
690
|
// set) so document_capture/liveness render correctly instead of assuming
|
|
667
691
|
// state that was never set. Falls back to "welcome" on anything that
|
|
668
|
-
// doesn't resolve cleanly
|
|
669
|
-
//
|
|
670
|
-
//
|
|
692
|
+
// doesn't resolve cleanly for an UNCERTAIN reason (network error, timeout)
|
|
693
|
+
// — this is a UX improvement, not a requirement: the backend's own
|
|
694
|
+
// resume-match at create/ time still works correctly even if the widget
|
|
695
|
+
// can't figure out which screen to pre-select.
|
|
696
|
+
//
|
|
697
|
+
// Returns null instead when the lookup fails for a CERTAIN, known reason
|
|
698
|
+
// — the resume link itself is provably expired or already used
|
|
699
|
+
// (RESUME_TARGET_UNAVAILABLE) or was never a resume link at all
|
|
700
|
+
// (NOT_A_RESUME_TOKEN). Unlike a transient failure, there is no "try the
|
|
701
|
+
// real request and it'll still work" fallback for these: create/'s own
|
|
702
|
+
// resume-match reads the exact same resume_target_entry binding this
|
|
703
|
+
// lookup just found missing/invalid, so falling through to a generic
|
|
704
|
+
// welcome screen would silently walk the customer into a brand-new,
|
|
705
|
+
// unrelated verification attempt with no explanation — worse than telling
|
|
706
|
+
// them plainly that their link no longer works. The caller shows this
|
|
707
|
+
// error itself (via showErrorStep, called here directly) rather than
|
|
708
|
+
// rendering a step.
|
|
671
709
|
async _resolveResumeStep() {
|
|
672
710
|
try {
|
|
673
711
|
const info = await this.sdk.getResumeInfo();
|
|
@@ -719,10 +757,21 @@ export class SmartComplyFlow {
|
|
|
719
757
|
// server-side regardless of which screen the widget shows first.
|
|
720
758
|
return "welcome";
|
|
721
759
|
}
|
|
722
|
-
catch {
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
760
|
+
catch (err) {
|
|
761
|
+
const code = err instanceof SDKError ? err.errorCode : undefined;
|
|
762
|
+
if (code === "RESUME_TARGET_UNAVAILABLE" || code === "NOT_A_RESUME_TOKEN") {
|
|
763
|
+
// A certain, known failure — this specific link is provably no
|
|
764
|
+
// longer usable (already used, expired, or was never a resume link
|
|
765
|
+
// at all). Tell the customer plainly rather than silently starting
|
|
766
|
+
// a new, unrelated verification on a welcome screen with no
|
|
767
|
+
// explanation — see this method's own docstring above.
|
|
768
|
+
this.showErrorStep("This resume link has expired or is no longer valid.");
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
// Anything else (network error, timeout, an SDKError with a
|
|
772
|
+
// different/absent code) — never block the flow on this lookup.
|
|
773
|
+
// create/'s own resume-match still runs correctly once the customer
|
|
774
|
+
// gets there, so falling through to a generic welcome screen is safe.
|
|
726
775
|
return "welcome";
|
|
727
776
|
}
|
|
728
777
|
}
|
|
@@ -2330,7 +2379,14 @@ export class SmartComplyFlow {
|
|
|
2330
2379
|
// Classify the error into a user-friendly category
|
|
2331
2380
|
const isCameraErr = /camera|permission|notallowed|notfound/i.test(message);
|
|
2332
2381
|
const isNetworkErr = /network|timeout|connection|fetch/i.test(message);
|
|
2333
|
-
|
|
2382
|
+
// Checked before the generic isAuthErr below — a resume/resubmit link
|
|
2383
|
+
// (RESUME_TARGET_UNAVAILABLE / NOT_A_RESUME_TOKEN from the backend, see
|
|
2384
|
+
// _resolveResumeStep) also matches "token...expired"/"link" wording, but
|
|
2385
|
+
// the corrective action is different from a plain session timeout: the
|
|
2386
|
+
// customer can't just "start again" themselves, they need a fresh link
|
|
2387
|
+
// from whoever sent them this one.
|
|
2388
|
+
const isResumeLinkErr = isResumeLinkErrorMessage(message);
|
|
2389
|
+
const isAuthErr = !isResumeLinkErr && /session.*expired|token.*expired|authentication/i.test(message);
|
|
2334
2390
|
const isDocQuality = /blurry|blur|quality|glare|dark|bright|lighting/i.test(message);
|
|
2335
2391
|
const isExpiredDoc = /document.*expired|expired.*document/i.test(message);
|
|
2336
2392
|
const isFaceMatch = /face.*match|selfie.*match|does not match/i.test(message);
|
|
@@ -2340,36 +2396,40 @@ export class SmartComplyFlow {
|
|
|
2340
2396
|
const isBillingErr = /wallet|balance|insufficient.*fund|payment.*required/i.test(message);
|
|
2341
2397
|
const errorIconName = isCameraErr ? "camera"
|
|
2342
2398
|
: isNetworkErr ? "network"
|
|
2343
|
-
:
|
|
2344
|
-
:
|
|
2345
|
-
:
|
|
2346
|
-
:
|
|
2347
|
-
:
|
|
2348
|
-
: "
|
|
2399
|
+
: isResumeLinkErr ? "clock"
|
|
2400
|
+
: isAuthErr ? "clock"
|
|
2401
|
+
: isDocQuality ? "search"
|
|
2402
|
+
: isExpiredDoc ? "calendar"
|
|
2403
|
+
: isFaceMatch ? "face"
|
|
2404
|
+
: isBillingErr ? "warning"
|
|
2405
|
+
: "close";
|
|
2349
2406
|
const errorTitle = isCameraErr ? "Camera Access Required"
|
|
2350
2407
|
: isNetworkErr ? "Connection Problem"
|
|
2351
|
-
:
|
|
2352
|
-
:
|
|
2353
|
-
:
|
|
2354
|
-
:
|
|
2355
|
-
:
|
|
2356
|
-
: "Verification
|
|
2408
|
+
: isResumeLinkErr ? "Link No Longer Valid"
|
|
2409
|
+
: isAuthErr ? "Session Expired"
|
|
2410
|
+
: isDocQuality ? "Document Photo Unclear"
|
|
2411
|
+
: isExpiredDoc ? "Document Expired"
|
|
2412
|
+
: isFaceMatch ? "Face Match Failed"
|
|
2413
|
+
: isBillingErr ? "Verification Unavailable"
|
|
2414
|
+
: "Verification Unsuccessful";
|
|
2357
2415
|
// Map to user-facing guidance — never show raw internal message
|
|
2358
2416
|
const userMessage = isCameraErr
|
|
2359
2417
|
? "Please allow camera access in your browser settings and try again."
|
|
2360
2418
|
: isNetworkErr
|
|
2361
2419
|
? "Check your internet connection and try again."
|
|
2362
|
-
:
|
|
2363
|
-
? "
|
|
2364
|
-
:
|
|
2365
|
-
?
|
|
2366
|
-
:
|
|
2367
|
-
? "
|
|
2368
|
-
:
|
|
2369
|
-
? "
|
|
2370
|
-
:
|
|
2371
|
-
? "
|
|
2372
|
-
:
|
|
2420
|
+
: isResumeLinkErr
|
|
2421
|
+
? "This link has expired or has already been used. Please contact us to request a new one."
|
|
2422
|
+
: isAuthErr
|
|
2423
|
+
? "Your session has expired. Please start again."
|
|
2424
|
+
: isDocQuality
|
|
2425
|
+
? _sanitizeUserMessage(message) || "Please retake your document photo in good lighting with no glare."
|
|
2426
|
+
: isExpiredDoc
|
|
2427
|
+
? "The document you submitted has expired. Please use a valid, current ID."
|
|
2428
|
+
: isFaceMatch
|
|
2429
|
+
? "Your selfie did not match the photo on your ID. Please ensure you are using your own valid document and face the camera directly."
|
|
2430
|
+
: isBillingErr
|
|
2431
|
+
? "Verification is temporarily unavailable. Please contact support."
|
|
2432
|
+
: _sanitizeUserMessage(message) || "We were unable to complete your verification. Please try again.";
|
|
2373
2433
|
const iconWrap = document.createElement("div");
|
|
2374
2434
|
iconWrap.style.cssText = `
|
|
2375
2435
|
width:72px;height:72px;border-radius:50%;
|