smartcomply-web-sdk 1.0.99 → 1.0.101
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/client/Smartcomply.d.ts +1 -1
- package/dist/client/Smartcomply.d.ts.map +1 -1
- package/dist/client/Smartcomply.js +1 -1
- package/dist/client/Smartcomply.js.map +1 -1
- package/dist/esm/client/Smartcomply.d.ts +1 -1
- package/dist/esm/client/Smartcomply.d.ts.map +1 -1
- package/dist/esm/client/Smartcomply.js +1 -1
- package/dist/esm/client/Smartcomply.js.map +1 -1
- package/dist/esm/flow/DocumentCapture.d.ts +3 -19
- package/dist/esm/flow/DocumentCapture.d.ts.map +1 -1
- package/dist/esm/flow/DocumentCapture.js +22 -170
- package/dist/esm/flow/DocumentCapture.js.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.d.ts +0 -1
- package/dist/esm/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/esm/flow/SmartComplyFlow.js +67 -94
- package/dist/esm/flow/SmartComplyFlow.js.map +1 -1
- package/dist/esm/types/onboarding.d.ts +2 -0
- package/dist/esm/types/onboarding.d.ts.map +1 -1
- package/dist/esm/utils/channels.d.ts +15 -0
- package/dist/esm/utils/channels.d.ts.map +1 -1
- package/dist/esm/utils/channels.js +41 -0
- package/dist/esm/utils/channels.js.map +1 -1
- package/dist/esm/utils/constants.d.ts +9 -8
- package/dist/esm/utils/constants.d.ts.map +1 -1
- package/dist/esm/utils/constants.js +10 -9
- package/dist/esm/utils/constants.js.map +1 -1
- package/dist/esm/utils/documentRules.d.ts +1 -2
- package/dist/esm/utils/documentRules.d.ts.map +1 -1
- package/dist/esm/utils/documentRules.js +1 -2
- package/dist/esm/utils/documentRules.js.map +1 -1
- package/dist/flow/DocumentCapture.d.ts +3 -19
- package/dist/flow/DocumentCapture.d.ts.map +1 -1
- package/dist/flow/DocumentCapture.js +22 -170
- package/dist/flow/DocumentCapture.js.map +1 -1
- package/dist/flow/SmartComplyFlow.d.ts +0 -1
- package/dist/flow/SmartComplyFlow.d.ts.map +1 -1
- package/dist/flow/SmartComplyFlow.js +65 -92
- package/dist/flow/SmartComplyFlow.js.map +1 -1
- package/dist/smartcomply.browser.js +94 -256
- package/dist/smartcomply.browser.js.map +3 -3
- package/dist/types/onboarding.d.ts +2 -0
- package/dist/types/onboarding.d.ts.map +1 -1
- package/dist/utils/channels.d.ts +15 -0
- package/dist/utils/channels.d.ts.map +1 -1
- package/dist/utils/channels.js +44 -0
- package/dist/utils/channels.js.map +1 -1
- package/dist/utils/constants.d.ts +9 -8
- package/dist/utils/constants.d.ts.map +1 -1
- package/dist/utils/constants.js +10 -9
- package/dist/utils/constants.js.map +1 -1
- package/dist/utils/documentRules.d.ts +1 -2
- package/dist/utils/documentRules.d.ts.map +1 -1
- package/dist/utils/documentRules.js +1 -2
- package/dist/utils/documentRules.js.map +1 -1
- package/package.json +1 -1
|
@@ -293,7 +293,7 @@ var SmartComplySDK = (() => {
|
|
|
293
293
|
var SESSION_WARN_BEFORE_MS = 2 * 60 * 1e3;
|
|
294
294
|
var MAX_RETRIES = 2;
|
|
295
295
|
var RETRY_DELAY_MS = 1e3;
|
|
296
|
-
var MAX_DOCUMENT_BYTES =
|
|
296
|
+
var MAX_DOCUMENT_BYTES = 10 * 1024 * 1024;
|
|
297
297
|
var MAX_VIDEO_BYTES = 50 * 1024 * 1024;
|
|
298
298
|
var MAX_SNAPSHOT_BYTES = 2 * 1024 * 1024;
|
|
299
299
|
var DEFAULT_CHALLENGE_ACTIONS = ["BLINK", "TURN_HEAD"];
|
|
@@ -5760,10 +5760,29 @@ var SmartComplySDK = (() => {
|
|
|
5760
5760
|
data_verification: isChannelList(byCategory.data_verification) ? byCategory.data_verification : [],
|
|
5761
5761
|
document_verification: isChannelList(byCategory.document_verification) ? byCategory.document_verification : []
|
|
5762
5762
|
};
|
|
5763
|
+
if (typeof byCategory.code === "string") grouped[country].code = byCategory.code;
|
|
5764
|
+
if (typeof byCategory.name === "string") grouped[country].name = byCategory.name;
|
|
5763
5765
|
}
|
|
5764
5766
|
}
|
|
5765
5767
|
return grouped;
|
|
5766
5768
|
}
|
|
5769
|
+
var NO_COUNTRY = "global";
|
|
5770
|
+
function countryCodeFor(channels, country) {
|
|
5771
|
+
if (!country || country === NO_COUNTRY) return NO_COUNTRY;
|
|
5772
|
+
return channels[country]?.code || country;
|
|
5773
|
+
}
|
|
5774
|
+
function countryLabel(channels, country) {
|
|
5775
|
+
const name = channels[country]?.name;
|
|
5776
|
+
if (name) return name;
|
|
5777
|
+
return country.replace(/\b\w/g, (letter) => letter.toUpperCase());
|
|
5778
|
+
}
|
|
5779
|
+
function searchable(text) {
|
|
5780
|
+
return text.normalize("NFD").replace(/[̀-ͯ]/g, "").toLowerCase().trim();
|
|
5781
|
+
}
|
|
5782
|
+
function filterCountries(channels, query) {
|
|
5783
|
+
const needle = searchable(query);
|
|
5784
|
+
return Object.keys(channels).map((country) => ({ country, label: countryLabel(channels, country) })).filter(({ country, label }) => !needle || searchable(label).includes(needle) || searchable(country).includes(needle)).sort((a2, b2) => a2.label.localeCompare(b2.label)).map(({ country }) => country);
|
|
5785
|
+
}
|
|
5767
5786
|
|
|
5768
5787
|
// src/client/Smartcomply.ts
|
|
5769
5788
|
var _SmartComply = class _SmartComply {
|
|
@@ -5886,7 +5905,7 @@ var SmartComplySDK = (() => {
|
|
|
5886
5905
|
* CDN tag they installed with (e.g. @1, which floats to the latest
|
|
5887
5906
|
* matching release) actually resolved to the version they expect.
|
|
5888
5907
|
*/
|
|
5889
|
-
_SmartComply.VERSION = "1.0.
|
|
5908
|
+
_SmartComply.VERSION = "1.0.101";
|
|
5890
5909
|
var SmartComply = _SmartComply;
|
|
5891
5910
|
|
|
5892
5911
|
// src/flow/theme.ts
|
|
@@ -6566,7 +6585,7 @@ var SmartComplySDK = (() => {
|
|
|
6566
6585
|
this.showPdfPreview(container, theme, file, documentType);
|
|
6567
6586
|
return;
|
|
6568
6587
|
}
|
|
6569
|
-
this.
|
|
6588
|
+
this.handleFileUploadComplete(file, container, theme, documentType);
|
|
6570
6589
|
}
|
|
6571
6590
|
});
|
|
6572
6591
|
this.root.appendChild(fileInput);
|
|
@@ -6980,7 +6999,14 @@ var SmartComplySDK = (() => {
|
|
|
6980
6999
|
useBtn.textContent = "Confirming photo…";
|
|
6981
7000
|
useBtn.disabled = true;
|
|
6982
7001
|
rotateBtn.disabled = true;
|
|
6983
|
-
|
|
7002
|
+
if (currentBlob.size > MAX_DOCUMENT_BYTES) {
|
|
7003
|
+
useBtn.textContent = "Use Photo ✓";
|
|
7004
|
+
useBtn.disabled = false;
|
|
7005
|
+
rotateBtn.disabled = false;
|
|
7006
|
+
this.showError(this.tooLargeMessage());
|
|
7007
|
+
return;
|
|
7008
|
+
}
|
|
7009
|
+
this.handleCaptureComplete(currentBlob, container, theme, documentType, viaCamera);
|
|
6984
7010
|
});
|
|
6985
7011
|
btnRow.appendChild(retakeBtn);
|
|
6986
7012
|
btnRow.appendChild(useBtn);
|
|
@@ -7063,9 +7089,8 @@ var SmartComplySDK = (() => {
|
|
|
7063
7089
|
/**
|
|
7064
7090
|
* Rotate an image blob by a multiple of 90° and re-encode it — used by the
|
|
7065
7091
|
* preview screen's rotate control for a document photographed or uploaded
|
|
7066
|
-
* sideways/upside-down.
|
|
7067
|
-
*
|
|
7068
|
-
* document whose actual pixel content is sideways (e.g. the phone itself
|
|
7092
|
+
* sideways/upside-down. Orientation metadata can't help a document
|
|
7093
|
+
* whose actual pixel content is sideways (e.g. the phone itself
|
|
7069
7094
|
* was held rotated relative to the document, or a pre-cropped/scanned
|
|
7070
7095
|
* upload with no EXIF at all) — that needs the user to say so directly.
|
|
7071
7096
|
*/
|
|
@@ -7199,29 +7224,15 @@ var SmartComplySDK = (() => {
|
|
|
7199
7224
|
return "Invalid file type. Please upload a JPEG or PNG photo, or a PDF.";
|
|
7200
7225
|
}
|
|
7201
7226
|
if (file.size > MAX_DOCUMENT_BYTES) {
|
|
7202
|
-
return
|
|
7227
|
+
return this.tooLargeMessage();
|
|
7203
7228
|
}
|
|
7204
7229
|
if (file.size < 1024) {
|
|
7205
7230
|
return "File is too small. Please upload a valid photo or PDF.";
|
|
7206
7231
|
}
|
|
7207
7232
|
return null;
|
|
7208
7233
|
}
|
|
7209
|
-
|
|
7210
|
-
|
|
7211
|
-
* ceiling — otherwise returns the original bytes completely untouched.
|
|
7212
|
-
* Document photos become the face-comparison reference image later
|
|
7213
|
-
* (see backend _crop_and_save_face), so any avoidable re-encode is a
|
|
7214
|
-
* quality loss with no upside; compression here exists solely to keep
|
|
7215
|
-
* oversized captures under MAX_DOCUMENT_BYTES, not to "optimize" images
|
|
7216
|
-
* that already fit.
|
|
7217
|
-
*/
|
|
7218
|
-
async ensureUnderUploadLimit(source) {
|
|
7219
|
-
if (source.size <= MAX_DOCUMENT_BYTES) return source;
|
|
7220
|
-
try {
|
|
7221
|
-
return await this.compressImage(source, DOC_CAMERA_IDEAL_WIDTH, DOC_CAMERA_IDEAL_HEIGHT, 0.92);
|
|
7222
|
-
} catch {
|
|
7223
|
-
return source;
|
|
7224
|
-
}
|
|
7234
|
+
tooLargeMessage() {
|
|
7235
|
+
return `File is too large. Please upload a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`;
|
|
7225
7236
|
}
|
|
7226
7237
|
handleFileUpload(container, theme) {
|
|
7227
7238
|
const input = this.root?.querySelector("#sc-doc-file-input");
|
|
@@ -7299,141 +7310,6 @@ var SmartComplySDK = (() => {
|
|
|
7299
7310
|
});
|
|
7300
7311
|
return btn;
|
|
7301
7312
|
}
|
|
7302
|
-
compressImage(source, maxWidth, maxHeight, quality) {
|
|
7303
|
-
return new Promise((resolve, reject) => {
|
|
7304
|
-
this._readExifOrientation(source).then((orientation) => {
|
|
7305
|
-
const url = URL.createObjectURL(source);
|
|
7306
|
-
const imgEl = document.createElement("img");
|
|
7307
|
-
imgEl.onload = () => {
|
|
7308
|
-
URL.revokeObjectURL(url);
|
|
7309
|
-
let { naturalWidth: w2, naturalHeight: h2 } = imgEl;
|
|
7310
|
-
const swapped = orientation >= 5 && orientation <= 8;
|
|
7311
|
-
const srcW = swapped ? h2 : w2;
|
|
7312
|
-
const srcH = swapped ? w2 : h2;
|
|
7313
|
-
const ratio = computeScaleRatio(srcW, srcH, maxWidth, maxHeight);
|
|
7314
|
-
const outW = Math.round(srcW * ratio);
|
|
7315
|
-
const outH = Math.round(srcH * ratio);
|
|
7316
|
-
const canvas = document.createElement("canvas");
|
|
7317
|
-
canvas.width = outW;
|
|
7318
|
-
canvas.height = outH;
|
|
7319
|
-
const ctx = canvas.getContext("2d");
|
|
7320
|
-
if (!ctx) {
|
|
7321
|
-
reject(new Error("Canvas unavailable"));
|
|
7322
|
-
return;
|
|
7323
|
-
}
|
|
7324
|
-
ctx.save();
|
|
7325
|
-
if (orientation === 2) {
|
|
7326
|
-
ctx.transform(-1, 0, 0, 1, outW, 0);
|
|
7327
|
-
} else if (orientation === 3) {
|
|
7328
|
-
ctx.transform(-1, 0, 0, -1, outW, outH);
|
|
7329
|
-
} else if (orientation === 4) {
|
|
7330
|
-
ctx.transform(1, 0, 0, -1, 0, outH);
|
|
7331
|
-
} else if (orientation === 5) {
|
|
7332
|
-
ctx.transform(0, 1, 1, 0, 0, 0);
|
|
7333
|
-
} else if (orientation === 6) {
|
|
7334
|
-
ctx.transform(0, 1, -1, 0, outH, 0);
|
|
7335
|
-
} else if (orientation === 7) {
|
|
7336
|
-
ctx.transform(0, -1, -1, 0, outH, outW);
|
|
7337
|
-
} else if (orientation === 8) {
|
|
7338
|
-
ctx.transform(0, -1, 1, 0, 0, outW);
|
|
7339
|
-
}
|
|
7340
|
-
ctx.drawImage(imgEl, 0, 0, swapped ? outH : outW, swapped ? outW : outH);
|
|
7341
|
-
ctx.restore();
|
|
7342
|
-
canvas.toBlob(
|
|
7343
|
-
(blob) => {
|
|
7344
|
-
blob ? resolve(blob) : reject(new Error("Compression failed"));
|
|
7345
|
-
},
|
|
7346
|
-
"image/jpeg",
|
|
7347
|
-
quality
|
|
7348
|
-
);
|
|
7349
|
-
};
|
|
7350
|
-
imgEl.onerror = () => {
|
|
7351
|
-
URL.revokeObjectURL(url);
|
|
7352
|
-
reject(new Error("Image load failed"));
|
|
7353
|
-
};
|
|
7354
|
-
imgEl.src = url;
|
|
7355
|
-
}).catch(() => {
|
|
7356
|
-
const url = URL.createObjectURL(source);
|
|
7357
|
-
const imgEl = document.createElement("img");
|
|
7358
|
-
imgEl.onload = () => {
|
|
7359
|
-
URL.revokeObjectURL(url);
|
|
7360
|
-
let { naturalWidth: w2, naturalHeight: h2 } = imgEl;
|
|
7361
|
-
const ratio = computeScaleRatio(w2, h2, maxWidth, maxHeight);
|
|
7362
|
-
const canvas = document.createElement("canvas");
|
|
7363
|
-
canvas.width = Math.round(w2 * ratio);
|
|
7364
|
-
canvas.height = Math.round(h2 * ratio);
|
|
7365
|
-
const ctx = canvas.getContext("2d");
|
|
7366
|
-
if (!ctx) {
|
|
7367
|
-
reject(new Error("Canvas unavailable"));
|
|
7368
|
-
return;
|
|
7369
|
-
}
|
|
7370
|
-
ctx.drawImage(imgEl, 0, 0, canvas.width, canvas.height);
|
|
7371
|
-
canvas.toBlob(
|
|
7372
|
-
(blob) => {
|
|
7373
|
-
blob ? resolve(blob) : reject(new Error("Compression failed"));
|
|
7374
|
-
},
|
|
7375
|
-
"image/jpeg",
|
|
7376
|
-
quality
|
|
7377
|
-
);
|
|
7378
|
-
};
|
|
7379
|
-
imgEl.onerror = () => {
|
|
7380
|
-
URL.revokeObjectURL(url);
|
|
7381
|
-
reject(new Error("Image load failed"));
|
|
7382
|
-
};
|
|
7383
|
-
imgEl.src = url;
|
|
7384
|
-
});
|
|
7385
|
-
});
|
|
7386
|
-
}
|
|
7387
|
-
/**
|
|
7388
|
-
* Read JPEG EXIF orientation tag (1–8) from a Blob/File.
|
|
7389
|
-
* Returns 1 (no rotation) if EXIF is absent or unreadable.
|
|
7390
|
-
*/
|
|
7391
|
-
_readExifOrientation(source) {
|
|
7392
|
-
return new Promise((resolve) => {
|
|
7393
|
-
const reader = new FileReader();
|
|
7394
|
-
reader.onload = (e2) => {
|
|
7395
|
-
try {
|
|
7396
|
-
const buf = e2.target?.result;
|
|
7397
|
-
const view = new DataView(buf);
|
|
7398
|
-
if (view.getUint16(0, false) !== 65496) {
|
|
7399
|
-
resolve(1);
|
|
7400
|
-
return;
|
|
7401
|
-
}
|
|
7402
|
-
let offset = 2;
|
|
7403
|
-
while (offset < view.byteLength) {
|
|
7404
|
-
const marker = view.getUint16(offset, false);
|
|
7405
|
-
offset += 2;
|
|
7406
|
-
if (marker === 65505) {
|
|
7407
|
-
if (view.getUint32(offset + 2, false) !== 1165519206) {
|
|
7408
|
-
resolve(1);
|
|
7409
|
-
return;
|
|
7410
|
-
}
|
|
7411
|
-
const little = view.getUint16(offset + 8, false) === 18761;
|
|
7412
|
-
const ifdOff = offset + 8 + view.getUint32(offset + 12, little);
|
|
7413
|
-
const tags = view.getUint16(ifdOff, little);
|
|
7414
|
-
for (let i2 = 0; i2 < tags; i2++) {
|
|
7415
|
-
if (view.getUint16(ifdOff + 2 + 12 * i2, little) === 274) {
|
|
7416
|
-
resolve(view.getUint16(ifdOff + 2 + 12 * i2 + 8, little));
|
|
7417
|
-
return;
|
|
7418
|
-
}
|
|
7419
|
-
}
|
|
7420
|
-
resolve(1);
|
|
7421
|
-
return;
|
|
7422
|
-
} else if ((marker & 65280) !== 65280) {
|
|
7423
|
-
break;
|
|
7424
|
-
} else {
|
|
7425
|
-
offset += view.getUint16(offset, false);
|
|
7426
|
-
}
|
|
7427
|
-
}
|
|
7428
|
-
resolve(1);
|
|
7429
|
-
} catch {
|
|
7430
|
-
resolve(1);
|
|
7431
|
-
}
|
|
7432
|
-
};
|
|
7433
|
-
reader.onerror = () => resolve(1);
|
|
7434
|
-
reader.readAsArrayBuffer(source.slice(0, 65536));
|
|
7435
|
-
});
|
|
7436
|
-
}
|
|
7437
7313
|
getDocumentLabel(type) {
|
|
7438
7314
|
const t2 = type.toLowerCase();
|
|
7439
7315
|
if (t2.includes("passport")) return "passport";
|
|
@@ -7470,15 +7346,7 @@ var SmartComplySDK = (() => {
|
|
|
7470
7346
|
}
|
|
7471
7347
|
return err?.message || "We couldn't verify your face. Please try again.";
|
|
7472
7348
|
}
|
|
7473
|
-
var
|
|
7474
|
-
nigeria: "🇳🇬 Nigeria",
|
|
7475
|
-
global: "🌍 Other Countries",
|
|
7476
|
-
ghana: "🇬🇭 Ghana",
|
|
7477
|
-
kenya: "🇰🇪 Kenya",
|
|
7478
|
-
south_africa: "🇿🇦 South Africa",
|
|
7479
|
-
united_states: "🇺🇸 United States",
|
|
7480
|
-
united_kingdom: "🇬🇧 United Kingdom"
|
|
7481
|
-
};
|
|
7349
|
+
var COUNTRY_SEARCH_MIN = 7;
|
|
7482
7350
|
function isChannelDocumentFlow(idType, globalDocFlow) {
|
|
7483
7351
|
if (typeof idType === "string") return globalDocFlow;
|
|
7484
7352
|
return (idType.fields || []).some((f2) => isUploadFieldType(f2.type));
|
|
@@ -7618,24 +7486,6 @@ var SmartComplySDK = (() => {
|
|
|
7618
7486
|
const d2 = new Date(s2);
|
|
7619
7487
|
return isNaN(d2.getTime()) ? null : d2;
|
|
7620
7488
|
}
|
|
7621
|
-
async function _compressImage(blob, maxWidth = 1600, quality = 0.85) {
|
|
7622
|
-
try {
|
|
7623
|
-
const bmp = await createImageBitmap(blob);
|
|
7624
|
-
const scale = Math.min(1, maxWidth / bmp.width);
|
|
7625
|
-
const w2 = Math.round(bmp.width * scale);
|
|
7626
|
-
const h2 = Math.round(bmp.height * scale);
|
|
7627
|
-
const canvas = document.createElement("canvas");
|
|
7628
|
-
canvas.width = w2;
|
|
7629
|
-
canvas.height = h2;
|
|
7630
|
-
canvas.getContext("2d").drawImage(bmp, 0, 0, w2, h2);
|
|
7631
|
-
bmp.close();
|
|
7632
|
-
return await new Promise(
|
|
7633
|
-
(res, rej) => canvas.toBlob((b2) => b2 ? res(b2) : rej(new Error("Compression failed")), "image/jpeg", quality)
|
|
7634
|
-
);
|
|
7635
|
-
} catch {
|
|
7636
|
-
return blob;
|
|
7637
|
-
}
|
|
7638
|
-
}
|
|
7639
7489
|
function _formatDocType(code) {
|
|
7640
7490
|
const map = {
|
|
7641
7491
|
passport: "Passport",
|
|
@@ -8321,18 +8171,50 @@ var SmartComplySDK = (() => {
|
|
|
8321
8171
|
subtitle.style.cssText = `color:${this.theme.textSecondary};font-size:13px;margin-top:-8px;`;
|
|
8322
8172
|
subtitle.textContent = "Choose the country that issued your ID";
|
|
8323
8173
|
container.appendChild(subtitle);
|
|
8324
|
-
|
|
8325
|
-
|
|
8326
|
-
|
|
8327
|
-
|
|
8328
|
-
|
|
8329
|
-
|
|
8330
|
-
|
|
8331
|
-
|
|
8332
|
-
|
|
8333
|
-
|
|
8334
|
-
|
|
8174
|
+
const list = document.createElement("div");
|
|
8175
|
+
list.setAttribute("role", "list");
|
|
8176
|
+
list.style.cssText = "display:flex;flex-direction:column;gap:10px;max-height:min(52vh,420px);overflow-y:auto;padding:2px;";
|
|
8177
|
+
const renderList = (query) => {
|
|
8178
|
+
list.innerHTML = "";
|
|
8179
|
+
const matches = filterCountries(channels, query);
|
|
8180
|
+
if (matches.length === 0) {
|
|
8181
|
+
const empty = document.createElement("div");
|
|
8182
|
+
empty.setAttribute("role", "status");
|
|
8183
|
+
empty.style.cssText = `color:${this.theme.textSecondary};font-size:13px;line-height:1.6;padding:8px 2px;`;
|
|
8184
|
+
empty.textContent = `No country matches "${query.trim()}". Check the spelling or try another name.`;
|
|
8185
|
+
list.appendChild(empty);
|
|
8186
|
+
return;
|
|
8187
|
+
}
|
|
8188
|
+
for (const country of matches) {
|
|
8189
|
+
const count = channels[country].data_verification.length + channels[country].document_verification.length;
|
|
8190
|
+
const card = this.createOptionCard(
|
|
8191
|
+
countryLabel(channels, country),
|
|
8192
|
+
`${count} ID type${count > 1 ? "s" : ""} available`,
|
|
8193
|
+
() => {
|
|
8194
|
+
this.selectedCountry = country;
|
|
8195
|
+
this.showStep("id_type");
|
|
8196
|
+
}
|
|
8197
|
+
);
|
|
8198
|
+
card.setAttribute("role", "listitem");
|
|
8199
|
+
list.appendChild(card);
|
|
8200
|
+
}
|
|
8201
|
+
};
|
|
8202
|
+
if (countries.length >= COUNTRY_SEARCH_MIN) {
|
|
8203
|
+
const search = document.createElement("input");
|
|
8204
|
+
search.type = "search";
|
|
8205
|
+
search.placeholder = "Search countries";
|
|
8206
|
+
search.setAttribute("aria-label", "Search countries");
|
|
8207
|
+
search.autocomplete = "off";
|
|
8208
|
+
search.style.cssText = `
|
|
8209
|
+
width:100%;box-sizing:border-box;padding:11px 14px;border-radius:${RADIUS.md}px;
|
|
8210
|
+
background:${this.theme.cardBg};color:${this.theme.text};
|
|
8211
|
+
border:1.5px solid ${this.theme.border};font-size:14px;outline-offset:2px;
|
|
8212
|
+
`;
|
|
8213
|
+
search.addEventListener("input", () => renderList(search.value));
|
|
8214
|
+
container.appendChild(search);
|
|
8335
8215
|
}
|
|
8216
|
+
renderList("");
|
|
8217
|
+
container.appendChild(list);
|
|
8336
8218
|
}
|
|
8337
8219
|
// ── ID Type Select ──────────────────────────────────────────────
|
|
8338
8220
|
renderIdTypeSelect(container) {
|
|
@@ -8820,7 +8702,13 @@ var SmartComplySDK = (() => {
|
|
|
8820
8702
|
faceWrap.appendChild(faceImg);
|
|
8821
8703
|
container.appendChild(faceWrap);
|
|
8822
8704
|
}
|
|
8823
|
-
if (this.
|
|
8705
|
+
if (this._ocrIsExpired) {
|
|
8706
|
+
const expired = document.createElement("div");
|
|
8707
|
+
expired.setAttribute("role", "alert");
|
|
8708
|
+
expired.style.cssText = `width:100%;padding:10px 14px;border-radius:10px;background:${this.theme.errorBg};border:1px solid ${this.theme.error}40;color:${this.theme.error};font-size:12px;text-align:left;line-height:1.5;`;
|
|
8709
|
+
expired.textContent = "⚠️ This document has expired. You can continue, but a check with an expired document won't be approved. Use a valid document if you have one.";
|
|
8710
|
+
container.appendChild(expired);
|
|
8711
|
+
} else if (this._ocrExpirySoon) {
|
|
8824
8712
|
const warn = document.createElement("div");
|
|
8825
8713
|
warn.style.cssText = `width:100%;padding:10px 14px;border-radius:10px;background:${this.theme.warning}18;border:1px solid ${this.theme.warning}40;color:${this.theme.warning};font-size:12px;text-align:left;line-height:1.5;`;
|
|
8826
8714
|
warn.textContent = "⚠️ Your document expires soon. Some services may not accept it, but you can still continue.";
|
|
@@ -8903,11 +8791,6 @@ var SmartComplySDK = (() => {
|
|
|
8903
8791
|
polls++;
|
|
8904
8792
|
try {
|
|
8905
8793
|
const result = await this.sdk.liveness.pollResult(entryId);
|
|
8906
|
-
if (result.is_expired === true) {
|
|
8907
|
-
container.innerHTML = "";
|
|
8908
|
-
this._renderExpiredDocument(container);
|
|
8909
|
-
return;
|
|
8910
|
-
}
|
|
8911
8794
|
if (result.ocr_quality_failed === true) {
|
|
8912
8795
|
container.innerHTML = "";
|
|
8913
8796
|
this._renderOcrQualityFail(container, result.ocr_rejection_reason);
|
|
@@ -8956,35 +8839,6 @@ var SmartComplySDK = (() => {
|
|
|
8956
8839
|
};
|
|
8957
8840
|
this._ocrPollTimer = setTimeout(poll, 3e3);
|
|
8958
8841
|
}
|
|
8959
|
-
_renderExpiredDocument(container) {
|
|
8960
|
-
container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
|
|
8961
|
-
const icon2 = document.createElement("div");
|
|
8962
|
-
icon2.style.cssText = `width:72px;height:72px;border-radius:50%;background:${this.theme.errorBg};border:3px solid ${this.theme.error};display:flex;align-items:center;justify-content:center;font-size:28px;`;
|
|
8963
|
-
icon2.textContent = "📅";
|
|
8964
|
-
container.appendChild(icon2);
|
|
8965
|
-
const t2 = document.createElement("h2");
|
|
8966
|
-
t2.style.cssText = `color:${this.theme.text};font-size:${TYPE.heading}px;font-weight:700;margin:0;`;
|
|
8967
|
-
t2.textContent = "Document Expired";
|
|
8968
|
-
container.appendChild(t2);
|
|
8969
|
-
const d2 = document.createElement("p");
|
|
8970
|
-
d2.style.cssText = `color:${this.theme.textSecondary};font-size:13px;margin:0;max-width:280px;line-height:1.6;`;
|
|
8971
|
-
d2.textContent = "The document you submitted has expired. Please use a valid, current ID.";
|
|
8972
|
-
container.appendChild(d2);
|
|
8973
|
-
const retryBtn = this.createPrimaryButton("Try a different document");
|
|
8974
|
-
retryBtn.addEventListener("click", () => {
|
|
8975
|
-
this.livenessEntryId = null;
|
|
8976
|
-
this.documentBlob = null;
|
|
8977
|
-
this.documentBackBlob = null;
|
|
8978
|
-
this.showStep("document_capture");
|
|
8979
|
-
});
|
|
8980
|
-
container.appendChild(retryBtn);
|
|
8981
|
-
const endBtn = this.createSecondaryButton("End session");
|
|
8982
|
-
endBtn.addEventListener("click", () => {
|
|
8983
|
-
this.options.onError?.(new Error("Document expired"));
|
|
8984
|
-
this.close();
|
|
8985
|
-
});
|
|
8986
|
-
container.appendChild(endBtn);
|
|
8987
|
-
}
|
|
8988
8842
|
_renderOcrQualityFail(container, reason) {
|
|
8989
8843
|
container.style.cssText += "display:flex;flex-direction:column;align-items:center;text-align:center;gap:14px;padding:20px 0;";
|
|
8990
8844
|
const icon2 = document.createElement("div");
|
|
@@ -9148,8 +9002,8 @@ var SmartComplySDK = (() => {
|
|
|
9148
9002
|
* Process document capture result with front/back support
|
|
9149
9003
|
*/
|
|
9150
9004
|
async processDocumentCaptureResult(result, captureContainer, container) {
|
|
9151
|
-
this.documentBlob =
|
|
9152
|
-
this.documentBackBlob =
|
|
9005
|
+
this.documentBlob = result.front;
|
|
9006
|
+
this.documentBackBlob = result.back || null;
|
|
9153
9007
|
this._documentViaCamera = result.viaCamera;
|
|
9154
9008
|
await this.processDocumentBlob(this.documentBlob, captureContainer, container);
|
|
9155
9009
|
}
|
|
@@ -9164,8 +9018,10 @@ var SmartComplySDK = (() => {
|
|
|
9164
9018
|
if (!blob || blob.size === 0) {
|
|
9165
9019
|
throw new Error("Failed to capture document. Please try again.");
|
|
9166
9020
|
}
|
|
9167
|
-
if (blob.size >
|
|
9168
|
-
throw new Error(
|
|
9021
|
+
if (blob.size > MAX_DOCUMENT_BYTES) {
|
|
9022
|
+
throw new Error(
|
|
9023
|
+
`Document is too large. Please use a file smaller than ${Math.round(MAX_DOCUMENT_BYTES / (1024 * 1024))}MB.`
|
|
9024
|
+
);
|
|
9169
9025
|
}
|
|
9170
9026
|
this.documentBlob = blob;
|
|
9171
9027
|
captureContainer.innerHTML = "";
|
|
@@ -9175,16 +9031,7 @@ var SmartComplySDK = (() => {
|
|
|
9175
9031
|
<div style="color:${this.theme.text};font-size:14px;font-weight:600;">Scanning document...</div>
|
|
9176
9032
|
<div style="color:${this.theme.textSecondary};font-size:12px;text-align:center;max-width:200px;line-height:1.5;">Running OCR and verifying your identity</div>`);
|
|
9177
9033
|
const identifier = Object.values(this.collectedFields)[0] || this.idNumber || this.selectedIdType || `DOC-${Date.now()}`;
|
|
9178
|
-
const
|
|
9179
|
-
nigeria: "NG",
|
|
9180
|
-
ghana: "GH",
|
|
9181
|
-
kenya: "KE",
|
|
9182
|
-
south_africa: "ZA",
|
|
9183
|
-
united_states: "US",
|
|
9184
|
-
united_kingdom: "GB",
|
|
9185
|
-
global: "US"
|
|
9186
|
-
};
|
|
9187
|
-
const country = COUNTRY_CODES[this.selectedCountry] || this.selectedCountry.toUpperCase().slice(0, 2);
|
|
9034
|
+
const country = countryCodeFor(this.sdkConfig?.channels || {}, this.selectedCountry);
|
|
9188
9035
|
const deviceMeta = collectDeviceMetadata();
|
|
9189
9036
|
let createResult;
|
|
9190
9037
|
try {
|
|
@@ -9331,16 +9178,7 @@ var SmartComplySDK = (() => {
|
|
|
9331
9178
|
const isDataVerification = !!this.identityCheckId;
|
|
9332
9179
|
const identifier = isDataVerification ? "" : this.idNumber || Object.values(this.collectedFields)[0] || this.selectedIdType || `DOC-${Date.now()}`;
|
|
9333
9180
|
const identifierType = isDataVerification ? "" : this.selectedIdType;
|
|
9334
|
-
const
|
|
9335
|
-
nigeria: "NG",
|
|
9336
|
-
ghana: "GH",
|
|
9337
|
-
kenya: "KE",
|
|
9338
|
-
south_africa: "ZA",
|
|
9339
|
-
united_states: "US",
|
|
9340
|
-
united_kingdom: "GB",
|
|
9341
|
-
global: "US"
|
|
9342
|
-
};
|
|
9343
|
-
const country = COUNTRY_CODES[this.selectedCountry] || this.selectedCountry.toUpperCase().slice(0, 2);
|
|
9181
|
+
const country = countryCodeFor(this.sdkConfig?.channels || {}, this.selectedCountry);
|
|
9344
9182
|
this.sdk.liveness.startCheck(
|
|
9345
9183
|
livenessContainer,
|
|
9346
9184
|
{
|