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
|
@@ -5210,7 +5210,9 @@ var SmartComplySDK = (() => {
|
|
|
5210
5210
|
*/
|
|
5211
5211
|
async create(params) {
|
|
5212
5212
|
const formData = new FormData();
|
|
5213
|
-
|
|
5213
|
+
const hasDocument = !!(params.document || params.document_front || params.id_file);
|
|
5214
|
+
if (params.identity_check || !hasDocument && !params.identifier) {
|
|
5215
|
+
} else {
|
|
5214
5216
|
const rawIdentifier = params.identifier || `ID-${Date.now()}`;
|
|
5215
5217
|
const safeIdentifier = rawIdentifier.length > 20 ? rawIdentifier.slice(0, 20) : rawIdentifier;
|
|
5216
5218
|
formData.append("identifier", safeIdentifier);
|
|
@@ -7227,10 +7229,13 @@ var SmartComplySDK = (() => {
|
|
|
7227
7229
|
this._uiTimeoutId = null;
|
|
7228
7230
|
// Session expiry
|
|
7229
7231
|
this.sessionExpiryTimer = null;
|
|
7232
|
+
this.sessionExpiredTimer = null;
|
|
7230
7233
|
// Status polling (result screen)
|
|
7231
7234
|
this._pollStatusTimer = null;
|
|
7232
7235
|
// Components
|
|
7233
7236
|
this.docCapture = null;
|
|
7237
|
+
// 12 * 5s = 60s grace
|
|
7238
|
+
this._expiryDeferrals = 0;
|
|
7234
7239
|
this.options = options;
|
|
7235
7240
|
this.sdk = new SmartComply({
|
|
7236
7241
|
apiKey: options.apiKey,
|
|
@@ -7291,6 +7296,10 @@ var SmartComplySDK = (() => {
|
|
|
7291
7296
|
clearTimeout(this.sessionExpiryTimer);
|
|
7292
7297
|
this.sessionExpiryTimer = null;
|
|
7293
7298
|
}
|
|
7299
|
+
if (this.sessionExpiredTimer) {
|
|
7300
|
+
clearTimeout(this.sessionExpiredTimer);
|
|
7301
|
+
this.sessionExpiredTimer = null;
|
|
7302
|
+
}
|
|
7294
7303
|
if (this._pollStatusTimer) {
|
|
7295
7304
|
clearTimeout(this._pollStatusTimer);
|
|
7296
7305
|
this._pollStatusTimer = null;
|
|
@@ -7448,6 +7457,10 @@ var SmartComplySDK = (() => {
|
|
|
7448
7457
|
() => this._showExpiryWarningWhenSafe(),
|
|
7449
7458
|
warnMs
|
|
7450
7459
|
);
|
|
7460
|
+
this.sessionExpiredTimer = setTimeout(
|
|
7461
|
+
() => this._enforceSessionExpiry(),
|
|
7462
|
+
Math.max(expiresMs, 0)
|
|
7463
|
+
);
|
|
7451
7464
|
}
|
|
7452
7465
|
this.sdkConfig = await this.sdk.initializeConfig();
|
|
7453
7466
|
if (this.sdkConfig.theme) {
|
|
@@ -7475,6 +7488,17 @@ var SmartComplySDK = (() => {
|
|
|
7475
7488
|
}
|
|
7476
7489
|
this.showErrorStep("Your session is about to expire. Please complete verification quickly or restart.");
|
|
7477
7490
|
}
|
|
7491
|
+
_enforceSessionExpiry() {
|
|
7492
|
+
if (this.isDestroyed) return;
|
|
7493
|
+
const cameraActiveSteps = ["document_capture", "liveness"];
|
|
7494
|
+
if (cameraActiveSteps.includes(this.currentStep) && this._expiryDeferrals < _SmartComplyFlow.MAX_EXPIRY_DEFERRALS) {
|
|
7495
|
+
this._expiryDeferrals += 1;
|
|
7496
|
+
this.sessionExpiredTimer = setTimeout(() => this._enforceSessionExpiry(), 5e3);
|
|
7497
|
+
return;
|
|
7498
|
+
}
|
|
7499
|
+
this.showErrorStep("Your session has expired. Please restart verification.");
|
|
7500
|
+
this.close();
|
|
7501
|
+
}
|
|
7478
7502
|
// ─────────────────────────────────────────────────────────────────
|
|
7479
7503
|
// Step rendering
|
|
7480
7504
|
// ─────────────────────────────────────────────────────────────────
|
|
@@ -7579,7 +7603,8 @@ var SmartComplySDK = (() => {
|
|
|
7579
7603
|
// ── Welcome ────────────────────────────────────────────────────
|
|
7580
7604
|
renderWelcome(container) {
|
|
7581
7605
|
container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:12px;";
|
|
7582
|
-
const
|
|
7606
|
+
const isLivenessOnly = this.isLivenessOnlyFlow();
|
|
7607
|
+
const isDocFlow = isLivenessOnly ? false : this.isDocumentFlow();
|
|
7583
7608
|
const topRow = document.createElement("div");
|
|
7584
7609
|
topRow.style.cssText = "display:flex;flex-direction:column;align-items:center;gap:8px;";
|
|
7585
7610
|
const iconWrap = document.createElement("div");
|
|
@@ -7601,7 +7626,7 @@ var SmartComplySDK = (() => {
|
|
|
7601
7626
|
color:${this.theme.primary};
|
|
7602
7627
|
border:1px solid ${this.theme.primary}30;
|
|
7603
7628
|
`;
|
|
7604
|
-
badge.textContent = isDocFlow ? "📄 Document Verification" : "🔍 Data Verification";
|
|
7629
|
+
badge.textContent = isLivenessOnly ? "🤳 Liveness Check" : isDocFlow ? "📄 Document Verification" : "🔍 Data Verification";
|
|
7605
7630
|
topRow.appendChild(badge);
|
|
7606
7631
|
container.appendChild(topRow);
|
|
7607
7632
|
const titleWrap = document.createElement("div");
|
|
@@ -7619,10 +7644,12 @@ var SmartComplySDK = (() => {
|
|
|
7619
7644
|
color:${this.theme.textSecondary};font-size:13px;line-height:1.5;
|
|
7620
7645
|
margin:0 auto;max-width:300px;text-align:center;
|
|
7621
7646
|
`;
|
|
7622
|
-
desc.textContent = isDocFlow ? "You'll need your document and camera access. This takes about 2 minutes." : "You'll need your ID number and camera access. This takes about 2 minutes.";
|
|
7647
|
+
desc.textContent = isLivenessOnly ? "You'll just need camera access. This takes about 30 seconds." : isDocFlow ? "You'll need your document and camera access. This takes about 2 minutes." : "You'll need your ID number and camera access. This takes about 2 minutes.";
|
|
7623
7648
|
titleWrap.appendChild(desc);
|
|
7624
7649
|
container.appendChild(titleWrap);
|
|
7625
|
-
const steps =
|
|
7650
|
+
const steps = isLivenessOnly ? [
|
|
7651
|
+
{ icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
|
|
7652
|
+
] : isDocFlow ? [
|
|
7626
7653
|
{ icon: "🪪", text: "Choose your document type", sub: "Passport, National ID, Driver License" },
|
|
7627
7654
|
{ icon: "📷", text: "Scan your document", sub: "Upload or capture a photo of your ID" },
|
|
7628
7655
|
{ icon: "🤳", text: "Face check", sub: "Quick selfie to confirm it's you" }
|
|
@@ -7671,7 +7698,14 @@ var SmartComplySDK = (() => {
|
|
|
7671
7698
|
container.appendChild(stepsWrap);
|
|
7672
7699
|
const btn = this.createPrimaryButton("Get Started →");
|
|
7673
7700
|
btn.style.cssText += "margin-top:2px;";
|
|
7674
|
-
btn.addEventListener("click", () =>
|
|
7701
|
+
btn.addEventListener("click", () => {
|
|
7702
|
+
if (isLivenessOnly) {
|
|
7703
|
+
this.selectedCountry = this.selectedCountry || "global";
|
|
7704
|
+
this.showStep("liveness");
|
|
7705
|
+
} else {
|
|
7706
|
+
this.showStep("country");
|
|
7707
|
+
}
|
|
7708
|
+
});
|
|
7675
7709
|
container.appendChild(btn);
|
|
7676
7710
|
const trust = document.createElement("div");
|
|
7677
7711
|
trust.style.cssText = `
|
|
@@ -8962,6 +8996,20 @@ var SmartComplySDK = (() => {
|
|
|
8962
8996
|
const allFields = Object.values(channels).flat().flatMap((ch) => ch.fields || []);
|
|
8963
8997
|
return allFields.some((f2) => isUploadFieldType(f2.type));
|
|
8964
8998
|
}
|
|
8999
|
+
/**
|
|
9000
|
+
* True when the SDK Config is set to skip data/document verification
|
|
9001
|
+
* entirely and only run the liveness/selfie check — no country picker,
|
|
9002
|
+
* no ID-type picker, no ID-number entry or document capture. Unlike
|
|
9003
|
+
* isDocumentFlow(), there's no channel-shape fallback to infer this from:
|
|
9004
|
+
* a liveness-only config carries no channels at all, so the only signal
|
|
9005
|
+
* is verification_type itself.
|
|
9006
|
+
*/
|
|
9007
|
+
isLivenessOnlyFlow() {
|
|
9008
|
+
const vType = this.sdkConfig?.verification_type;
|
|
9009
|
+
if (!vType) return false;
|
|
9010
|
+
const types = Array.isArray(vType) ? vType : [vType];
|
|
9011
|
+
return types.includes("liveness_only");
|
|
9012
|
+
}
|
|
8965
9013
|
/**
|
|
8966
9014
|
* The "go back one step" target for a given step, if that step is
|
|
8967
9015
|
* navigable — shared by the header back button and the browser
|
|
@@ -8987,10 +9035,11 @@ var SmartComplySDK = (() => {
|
|
|
8987
9035
|
return backTargets[step];
|
|
8988
9036
|
}
|
|
8989
9037
|
updateProgress() {
|
|
8990
|
-
const
|
|
9038
|
+
const isLivenessOnly = this.isLivenessOnlyFlow();
|
|
9039
|
+
const isDocFlow = isLivenessOnly ? false : this.isDocumentFlow();
|
|
8991
9040
|
const countries = Object.keys(this.sdkConfig?.channels || {});
|
|
8992
9041
|
const singleCountry = countries.length <= 1;
|
|
8993
|
-
const stage1Steps = isDocFlow ? ["country", "id_type", "document_capture", "ocr_gate", "document_confirm"].filter((s2) => !(s2 === "country" && singleCountry)) : ["country", "id_type", "id_input", "confirm_identity"].filter((s2) => !(s2 === "country" && singleCountry));
|
|
9042
|
+
const stage1Steps = isLivenessOnly ? [] : isDocFlow ? ["country", "id_type", "document_capture", "ocr_gate", "document_confirm"].filter((s2) => !(s2 === "country" && singleCountry)) : ["country", "id_type", "id_input", "confirm_identity"].filter((s2) => !(s2 === "country" && singleCountry));
|
|
8994
9043
|
const stage2Steps = ["liveness"];
|
|
8995
9044
|
const allActionSteps = [...stage1Steps, ...stage2Steps];
|
|
8996
9045
|
const totalSteps = allActionSteps.length;
|
|
@@ -9005,7 +9054,7 @@ var SmartComplySDK = (() => {
|
|
|
9005
9054
|
} else if (this.currentStep === "done") {
|
|
9006
9055
|
this.stepLabel.textContent = "Complete ✓";
|
|
9007
9056
|
} else if (stage2Steps.includes(this.currentStep)) {
|
|
9008
|
-
this.stepLabel.textContent = "Stage 2 of 2: Face Check";
|
|
9057
|
+
this.stepLabel.textContent = isLivenessOnly ? "Face Check" : "Stage 2 of 2: Face Check";
|
|
9009
9058
|
} else if (stage1Steps.includes(this.currentStep)) {
|
|
9010
9059
|
this.stepLabel.textContent = isDocFlow ? "Stage 1 of 2: Scan Document" : "Stage 1 of 2: Verify Identity";
|
|
9011
9060
|
} else {
|
|
@@ -9085,6 +9134,13 @@ var SmartComplySDK = (() => {
|
|
|
9085
9134
|
}
|
|
9086
9135
|
};
|
|
9087
9136
|
_SmartComplyFlow.MAX_RETRIES = 3;
|
|
9137
|
+
// Hard stop once the backend session (SessionToken.expires_at, 30 min)
|
|
9138
|
+
// has actually passed. Deferred the same way as the warning above while
|
|
9139
|
+
// a camera is live so we don't tear down an in-progress scan, but capped
|
|
9140
|
+
// — the earlier warning already gave the user 2 minutes' notice, so
|
|
9141
|
+
// there's no reason to keep deferring past a short grace window the way
|
|
9142
|
+
// the advisory warning does.
|
|
9143
|
+
_SmartComplyFlow.MAX_EXPIRY_DEFERRALS = 12;
|
|
9088
9144
|
var SmartComplyFlow = _SmartComplyFlow;
|
|
9089
9145
|
|
|
9090
9146
|
// src/index.ts
|