smartcomply-web-sdk 1.0.75 → 1.0.77
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/esm/flow/SmartComplyFlow.d.ts +13 -0
- package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.js +113 -20
- package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
- package/dist/esm/modules/liveness/liveness.d.ts.map +1 -1
- package/dist/esm/modules/liveness/liveness.js +12 -1
- package/dist/esm/modules/liveness/liveness.js.map +1 -1
- package/dist/flow/SmartComplyFlow.d.ts +13 -0
- package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/flow/SmartComplyFlow.js +113 -20
- package/dist/flow/SmartComplyFlow.js.map +1 -1
- package/dist/modules/liveness/liveness.d.ts.map +1 -1
- package/dist/modules/liveness/liveness.js +12 -1
- package/dist/modules/liveness/liveness.js.map +1 -1
- package/dist/smartcomply.browser.js +65 -9
- package/dist/smartcomply.browser.js.map +2 -2
- package/package.json +1 -1
|
@@ -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;AAwC/C,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,kBAAkB,CAAC,EAAE,sBAAsB,CAAC;CAC7C;AAsRD,qBAAa,eAAe;IAC1B,OAAO,CAAC,GAAG,CAAc;IACzB,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,KAAK,CAAoC;IAGjD,OAAO,CAAC,OAAO,CAA+B;IAC9C,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,WAAW,CAA+B;IAClD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,SAAS,CAA+B;IAChD,OAAO,CAAC,UAAU,CAA+B;IAGjD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,qBAAqB,CAA6D;IAC1F,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,oBAAoB,CAAuC;IACnE,OAAO,CAAC,eAAe,CAA8B;IACrD,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,gBAAgB,CAAqB;IAK7C,OAAO,CAAC,kBAAkB,CAAS;IACnC,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,kBAAkB,CAAuC;IACjE,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,aAAa,CAAkC;IACvD,OAAO,CAAC,eAAe,CAA6C;IACpE,OAAO,CAAC,kBAAkB,CAA6B;IACvD,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,gBAAgB,CAA6B;IACrD,OAAO,CAAC,mBAAmB,CAAS;IAGpC,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAK;IAGxC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,UAAU,CAAc;IAGhC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,UAAU,CAAc;IAChC,OAAO,CAAC,gBAAgB,CAAc;IACtC,OAAO,CAAC,aAAa,CAAkB;IACvC,OAAO,CAAC,cAAc,CAAkB;IAGxC,OAAO,CAAC,gBAAgB,CAA4B;IAGpD,OAAO,CAAC,aAAa,CAA8C;IAGnE,OAAO,CAAC,YAAY,CAA8C;IAGlE,OAAO,CAAC,kBAAkB,CAA8C;
|
|
1
|
+
{"version":3,"file":"SmartComplyFlow.d.ts","sourceRoot":"","sources":["../../src/flow/SmartComplyFlow.ts"],"names":[],"mappings":"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"}
|
|
@@ -331,10 +331,12 @@ class SmartComplyFlow {
|
|
|
331
331
|
this._uiTimeoutId = null;
|
|
332
332
|
// Session expiry
|
|
333
333
|
this.sessionExpiryTimer = null;
|
|
334
|
+
this.sessionExpiredTimer = null;
|
|
334
335
|
// Status polling (result screen)
|
|
335
336
|
this._pollStatusTimer = null;
|
|
336
337
|
// Components
|
|
337
338
|
this.docCapture = null;
|
|
339
|
+
this._expiryDeferrals = 0;
|
|
338
340
|
this.options = options;
|
|
339
341
|
this.sdk = new Smartcomply_1.SmartComply({
|
|
340
342
|
apiKey: options.apiKey,
|
|
@@ -401,6 +403,10 @@ class SmartComplyFlow {
|
|
|
401
403
|
clearTimeout(this.sessionExpiryTimer);
|
|
402
404
|
this.sessionExpiryTimer = null;
|
|
403
405
|
}
|
|
406
|
+
if (this.sessionExpiredTimer) {
|
|
407
|
+
clearTimeout(this.sessionExpiredTimer);
|
|
408
|
+
this.sessionExpiredTimer = null;
|
|
409
|
+
}
|
|
404
410
|
if (this._pollStatusTimer) {
|
|
405
411
|
clearTimeout(this._pollStatusTimer);
|
|
406
412
|
this._pollStatusTimer = null;
|
|
@@ -591,6 +597,15 @@ class SmartComplyFlow {
|
|
|
591
597
|
const expiresMs = new Date(expiresAt).getTime() - Date.now();
|
|
592
598
|
const warnMs = Math.max(expiresMs - 120000, 0); // warn 2 min before
|
|
593
599
|
this.sessionExpiryTimer = setTimeout(() => this._showExpiryWarningWhenSafe(), warnMs);
|
|
600
|
+
// The warning above is advisory only and can defer indefinitely
|
|
601
|
+
// while the user sits on a camera-active step — without a hard
|
|
602
|
+
// stop, an ignored/deferred warning left the widget open against
|
|
603
|
+
// an already-expired backend session (SessionToken.expires_at,
|
|
604
|
+
// 30 min — see sdk/views.py's SessionToken.objects.create call)
|
|
605
|
+
// for as long as the host page stayed open. Force-close once the
|
|
606
|
+
// real deadline passes so the widget's lifetime never exceeds
|
|
607
|
+
// what the backend actually honors.
|
|
608
|
+
this.sessionExpiredTimer = setTimeout(() => this._enforceSessionExpiry(), Math.max(expiresMs, 0));
|
|
594
609
|
}
|
|
595
610
|
// Load config
|
|
596
611
|
this.sdkConfig = await this.sdk.initializeConfig();
|
|
@@ -624,6 +639,19 @@ class SmartComplyFlow {
|
|
|
624
639
|
}
|
|
625
640
|
this.showErrorStep("Your session is about to expire. Please complete verification quickly or restart.");
|
|
626
641
|
}
|
|
642
|
+
_enforceSessionExpiry() {
|
|
643
|
+
if (this.isDestroyed)
|
|
644
|
+
return;
|
|
645
|
+
const cameraActiveSteps = ["document_capture", "liveness"];
|
|
646
|
+
if (cameraActiveSteps.includes(this.currentStep) &&
|
|
647
|
+
this._expiryDeferrals < SmartComplyFlow.MAX_EXPIRY_DEFERRALS) {
|
|
648
|
+
this._expiryDeferrals += 1;
|
|
649
|
+
this.sessionExpiredTimer = setTimeout(() => this._enforceSessionExpiry(), 5000);
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
this.showErrorStep("Your session has expired. Please restart verification.");
|
|
653
|
+
this.close();
|
|
654
|
+
}
|
|
627
655
|
// ─────────────────────────────────────────────────────────────────
|
|
628
656
|
// Step rendering
|
|
629
657
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -742,7 +770,8 @@ class SmartComplyFlow {
|
|
|
742
770
|
// ── Welcome ────────────────────────────────────────────────────
|
|
743
771
|
renderWelcome(container) {
|
|
744
772
|
container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;";
|
|
745
|
-
const
|
|
773
|
+
const isLivenessOnly = this.isLivenessOnlyFlow();
|
|
774
|
+
const isDocFlow = isLivenessOnly ? false : this.isDocumentFlow();
|
|
746
775
|
// Icon + badge row (side by side to save vertical space)
|
|
747
776
|
const topRow = document.createElement("div");
|
|
748
777
|
topRow.style.cssText = "display:flex;flex-direction:column;align-items:center;gap:8px;";
|
|
@@ -765,7 +794,9 @@ class SmartComplyFlow {
|
|
|
765
794
|
color:${this.theme.primary};
|
|
766
795
|
border:1px solid ${this.theme.primary}30;
|
|
767
796
|
`;
|
|
768
|
-
badge.textContent =
|
|
797
|
+
badge.textContent = isLivenessOnly
|
|
798
|
+
? "🤳 Liveness Check"
|
|
799
|
+
: isDocFlow ? "📄 Document Verification" : "🔍 Data Verification";
|
|
769
800
|
topRow.appendChild(badge);
|
|
770
801
|
container.appendChild(topRow);
|
|
771
802
|
// Title + subtitle (compact)
|
|
@@ -787,23 +818,29 @@ class SmartComplyFlow {
|
|
|
787
818
|
color:${this.theme.textSecondary};font-size:13px;line-height:1.5;
|
|
788
819
|
margin:0 auto;max-width:300px;text-align:center;
|
|
789
820
|
`;
|
|
790
|
-
desc.textContent =
|
|
791
|
-
? "You'll need
|
|
792
|
-
:
|
|
821
|
+
desc.textContent = isLivenessOnly
|
|
822
|
+
? "You'll just need camera access. This takes about 30 seconds."
|
|
823
|
+
: isDocFlow
|
|
824
|
+
? "You'll need your document and camera access. This takes about 2 minutes."
|
|
825
|
+
: "You'll need your ID number and camera access. This takes about 2 minutes.";
|
|
793
826
|
titleWrap.appendChild(desc);
|
|
794
827
|
container.appendChild(titleWrap);
|
|
795
828
|
// Steps preview — compact rows
|
|
796
|
-
const steps =
|
|
829
|
+
const steps = isLivenessOnly
|
|
797
830
|
? [
|
|
798
|
-
{ icon: "🪪", text: "Choose your document type", sub: "Passport, National ID, Driver License" },
|
|
799
|
-
{ icon: "📷", text: "Scan your document", sub: "Upload or capture a photo of your ID" },
|
|
800
831
|
{ icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" },
|
|
801
832
|
]
|
|
802
|
-
:
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
833
|
+
: isDocFlow
|
|
834
|
+
? [
|
|
835
|
+
{ icon: "🪪", text: "Choose your document type", sub: "Passport, National ID, Driver License" },
|
|
836
|
+
{ icon: "📷", text: "Scan your document", sub: "Upload or capture a photo of your ID" },
|
|
837
|
+
{ icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" },
|
|
838
|
+
]
|
|
839
|
+
: [
|
|
840
|
+
{ icon: "🆔", text: "Choose your ID type", sub: "NIN, BVN, Voter's Card and more" },
|
|
841
|
+
{ icon: "📝", text: "Enter your ID details", sub: "Exactly as shown on your ID" },
|
|
842
|
+
{ icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" },
|
|
843
|
+
];
|
|
807
844
|
const stepsWrap = document.createElement("div");
|
|
808
845
|
stepsWrap.style.cssText = `
|
|
809
846
|
width:100%;display:flex;flex-direction:column;gap:0;
|
|
@@ -845,7 +882,27 @@ class SmartComplyFlow {
|
|
|
845
882
|
// CTA
|
|
846
883
|
const btn = this.createPrimaryButton("Get Started →");
|
|
847
884
|
btn.style.cssText += "margin-top:2px;";
|
|
848
|
-
btn.addEventListener("click", () =>
|
|
885
|
+
btn.addEventListener("click", () => {
|
|
886
|
+
if (isLivenessOnly) {
|
|
887
|
+
// Liveness-only has no channels at all, so renderCountrySelect's
|
|
888
|
+
// single-country auto-skip (countries.length === 1) never fires for
|
|
889
|
+
// it — going through "country" here would render an empty,
|
|
890
|
+
// dead-end country-picker screen. Go straight to liveness instead.
|
|
891
|
+
//
|
|
892
|
+
// selectedCountry defaults to "" and is otherwise only ever set by
|
|
893
|
+
// renderCountrySelect, which this mode never visits — renderLiveness
|
|
894
|
+
// sends it as a required, non-blank `country` field, so leaving it
|
|
895
|
+
// empty would fail create() validation before the scan even starts.
|
|
896
|
+
// There's no real country to report here (no identity lookup runs
|
|
897
|
+
// in this mode), so this is a neutral placeholder, not a claim
|
|
898
|
+
// about the user's actual location.
|
|
899
|
+
this.selectedCountry = this.selectedCountry || "global";
|
|
900
|
+
this.showStep("liveness");
|
|
901
|
+
}
|
|
902
|
+
else {
|
|
903
|
+
this.showStep("country");
|
|
904
|
+
}
|
|
905
|
+
});
|
|
849
906
|
container.appendChild(btn);
|
|
850
907
|
// Plain-language line on what the camera/photo is for and what happens
|
|
851
908
|
// to it — shown before the "Get Started" tap that leads to the first
|
|
@@ -2389,6 +2446,21 @@ class SmartComplyFlow {
|
|
|
2389
2446
|
.flatMap((ch) => ch.fields || []);
|
|
2390
2447
|
return allFields.some((f) => isUploadFieldType(f.type));
|
|
2391
2448
|
}
|
|
2449
|
+
/**
|
|
2450
|
+
* True when the SDK Config is set to skip data/document verification
|
|
2451
|
+
* entirely and only run the liveness/selfie check — no country picker,
|
|
2452
|
+
* no ID-type picker, no ID-number entry or document capture. Unlike
|
|
2453
|
+
* isDocumentFlow(), there's no channel-shape fallback to infer this from:
|
|
2454
|
+
* a liveness-only config carries no channels at all, so the only signal
|
|
2455
|
+
* is verification_type itself.
|
|
2456
|
+
*/
|
|
2457
|
+
isLivenessOnlyFlow() {
|
|
2458
|
+
const vType = this.sdkConfig?.verification_type;
|
|
2459
|
+
if (!vType)
|
|
2460
|
+
return false;
|
|
2461
|
+
const types = Array.isArray(vType) ? vType : [vType];
|
|
2462
|
+
return types.includes("liveness_only");
|
|
2463
|
+
}
|
|
2392
2464
|
/**
|
|
2393
2465
|
* The "go back one step" target for a given step, if that step is
|
|
2394
2466
|
* navigable — shared by the header back button and the browser
|
|
@@ -2405,16 +2477,28 @@ class SmartComplyFlow {
|
|
|
2405
2477
|
document_capture: () => { this.docCapture?.destroy(); this.showStep("id_type"); },
|
|
2406
2478
|
document_confirm: () => { this.docCapture?.destroy(); this.showStep("document_capture"); },
|
|
2407
2479
|
};
|
|
2480
|
+
// liveness-only skips straight from welcome to liveness with nothing in
|
|
2481
|
+
// between — deliberately no backTargets["liveness"] entry added here,
|
|
2482
|
+
// so the back button stays hidden on that step in this mode, same as
|
|
2483
|
+
// it already is for every other mode (liveness has no back target for
|
|
2484
|
+
// document/data flows either — nothing to go back to except closing).
|
|
2408
2485
|
return backTargets[step];
|
|
2409
2486
|
}
|
|
2410
2487
|
updateProgress() {
|
|
2411
|
-
const
|
|
2488
|
+
const isLivenessOnly = this.isLivenessOnlyFlow();
|
|
2489
|
+
const isDocFlow = isLivenessOnly ? false : this.isDocumentFlow();
|
|
2412
2490
|
const countries = Object.keys(this.sdkConfig?.channels || {});
|
|
2413
2491
|
const singleCountry = countries.length <= 1;
|
|
2414
|
-
// Two-stage action steps — Stage 1: validate identity, Stage 2: liveness
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2492
|
+
// Two-stage action steps — Stage 1: validate identity, Stage 2: liveness.
|
|
2493
|
+
// Liveness-only has no Stage 1 at all — welcome goes straight to
|
|
2494
|
+
// liveness — so stage1Steps stays empty and the progress bar reflects
|
|
2495
|
+
// a genuinely single-stage flow instead of implying a step that never
|
|
2496
|
+
// happens in this mode.
|
|
2497
|
+
const stage1Steps = isLivenessOnly
|
|
2498
|
+
? []
|
|
2499
|
+
: isDocFlow
|
|
2500
|
+
? ["country", "id_type", "document_capture", "ocr_gate", "document_confirm"].filter(s => !(s === "country" && singleCountry))
|
|
2501
|
+
: ["country", "id_type", "id_input", "confirm_identity"].filter(s => !(s === "country" && singleCountry));
|
|
2418
2502
|
const stage2Steps = ["liveness"];
|
|
2419
2503
|
const allActionSteps = [...stage1Steps, ...stage2Steps];
|
|
2420
2504
|
const totalSteps = allActionSteps.length;
|
|
@@ -2426,6 +2510,8 @@ class SmartComplyFlow {
|
|
|
2426
2510
|
this.progressBar.style.width = `${pct}%`;
|
|
2427
2511
|
}
|
|
2428
2512
|
// Stage label: "Stage 1 of 2: Verify Identity" / "Stage 2 of 2: Face Check"
|
|
2513
|
+
// — liveness-only has no Stage 1, so it just says "Face Check" with no
|
|
2514
|
+
// "of 2" framing, since there's only ever the one stage in this mode.
|
|
2429
2515
|
if (this.stepLabel) {
|
|
2430
2516
|
if (this.currentStep === "loading" || this.currentStep === "welcome") {
|
|
2431
2517
|
this.stepLabel.textContent = "";
|
|
@@ -2434,7 +2520,7 @@ class SmartComplyFlow {
|
|
|
2434
2520
|
this.stepLabel.textContent = "Complete ✓";
|
|
2435
2521
|
}
|
|
2436
2522
|
else if (stage2Steps.includes(this.currentStep)) {
|
|
2437
|
-
this.stepLabel.textContent = "Stage 2 of 2: Face Check";
|
|
2523
|
+
this.stepLabel.textContent = isLivenessOnly ? "Face Check" : "Stage 2 of 2: Face Check";
|
|
2438
2524
|
}
|
|
2439
2525
|
else if (stage1Steps.includes(this.currentStep)) {
|
|
2440
2526
|
this.stepLabel.textContent = isDocFlow ? "Stage 1 of 2: Scan Document" : "Stage 1 of 2: Verify Identity";
|
|
@@ -2525,4 +2611,11 @@ class SmartComplyFlow {
|
|
|
2525
2611
|
}
|
|
2526
2612
|
exports.SmartComplyFlow = SmartComplyFlow;
|
|
2527
2613
|
SmartComplyFlow.MAX_RETRIES = 3;
|
|
2614
|
+
// Hard stop once the backend session (SessionToken.expires_at, 30 min)
|
|
2615
|
+
// has actually passed. Deferred the same way as the warning above while
|
|
2616
|
+
// a camera is live so we don't tear down an in-progress scan, but capped
|
|
2617
|
+
// — the earlier warning already gave the user 2 minutes' notice, so
|
|
2618
|
+
// there's no reason to keep deferring past a short grace window the way
|
|
2619
|
+
// the advisory warning does.
|
|
2620
|
+
SmartComplyFlow.MAX_EXPIRY_DEFERRALS = 12; // 12 * 5s = 60s grace
|
|
2528
2621
|
//# sourceMappingURL=SmartComplyFlow.js.map
|