vesant-sdk 1.7.1-dev.afc5a32 → 1.7.1-dev.c2ac5a5
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/README.md +4 -0
- package/dist/{client-D23KhWeh.d.mts → client-5q4whhGu.d.mts} +1 -1
- package/dist/{client-fy3trF2K.d.ts → client-BaUekQT8.d.ts} +32 -10
- package/dist/{client-B3DCAHlg.d.ts → client-DUHC-68_.d.ts} +1 -1
- package/dist/{client-BwXMQA2a.d.mts → client-XDEhh9VN.d.mts} +32 -10
- package/dist/compliance/index.d.mts +2 -2
- package/dist/compliance/index.d.ts +2 -2
- package/dist/compliance/index.js +39 -1
- package/dist/compliance/index.js.map +1 -1
- package/dist/compliance/index.mjs +39 -1
- package/dist/compliance/index.mjs.map +1 -1
- package/dist/geolocation/index.d.mts +2 -2
- package/dist/geolocation/index.d.ts +2 -2
- package/dist/geolocation/index.js +39 -1
- package/dist/geolocation/index.js.map +1 -1
- package/dist/geolocation/index.mjs +39 -1
- package/dist/geolocation/index.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +86 -23
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +86 -23
- package/dist/index.mjs.map +1 -1
- package/dist/kyc/core.d.mts +1 -1
- package/dist/kyc/core.d.ts +1 -1
- package/dist/kyc/core.js +47 -22
- package/dist/kyc/core.js.map +1 -1
- package/dist/kyc/core.mjs +47 -22
- package/dist/kyc/core.mjs.map +1 -1
- package/dist/kyc/index.d.mts +178 -39
- package/dist/kyc/index.d.ts +178 -39
- package/dist/kyc/index.js +47 -22
- package/dist/kyc/index.js.map +1 -1
- package/dist/kyc/index.mjs +47 -22
- package/dist/kyc/index.mjs.map +1 -1
- package/dist/react.d.mts +126 -48
- package/dist/react.d.ts +126 -48
- package/dist/react.js +131 -20
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +129 -21
- package/dist/react.mjs.map +1 -1
- package/package.json +1 -1
package/dist/react.mjs
CHANGED
|
@@ -423,14 +423,11 @@ function useCipherText(client) {
|
|
|
423
423
|
const [configLoading, setConfigLoading] = useState(!!client);
|
|
424
424
|
const [configError, setConfigError] = useState(null);
|
|
425
425
|
const configRef = useRef(void 0);
|
|
426
|
-
const configPromiseRef = useRef(null);
|
|
427
426
|
useEffect(() => {
|
|
428
427
|
if (!client) return;
|
|
429
428
|
let cancelled = false;
|
|
430
429
|
setConfigLoading(true);
|
|
431
|
-
|
|
432
|
-
configPromiseRef.current = promise;
|
|
433
|
-
promise.then((cfg) => {
|
|
430
|
+
client.getGPSConfig().then((cfg) => {
|
|
434
431
|
if (!cancelled) {
|
|
435
432
|
configRef.current = cfg;
|
|
436
433
|
setConfigLoading(false);
|
|
@@ -445,13 +442,21 @@ function useCipherText(client) {
|
|
|
445
442
|
cancelled = true;
|
|
446
443
|
};
|
|
447
444
|
}, [client]);
|
|
445
|
+
const refreshConfig = useCallback(async () => {
|
|
446
|
+
if (!client) return;
|
|
447
|
+
try {
|
|
448
|
+
configRef.current = await client.refreshGPSConfig();
|
|
449
|
+
setConfigError(null);
|
|
450
|
+
} catch (error) {
|
|
451
|
+
setConfigError(error instanceof Error ? error : new Error("Failed to refresh GPS config"));
|
|
452
|
+
}
|
|
453
|
+
}, [client]);
|
|
448
454
|
const generate = useCallback(
|
|
449
455
|
async (options) => {
|
|
450
456
|
try {
|
|
451
|
-
if (
|
|
457
|
+
if (client) {
|
|
452
458
|
try {
|
|
453
|
-
|
|
454
|
-
configRef.current = cfg;
|
|
459
|
+
configRef.current = await client.getGPSConfig();
|
|
455
460
|
} catch {
|
|
456
461
|
}
|
|
457
462
|
}
|
|
@@ -461,9 +466,9 @@ function useCipherText(client) {
|
|
|
461
466
|
return null;
|
|
462
467
|
}
|
|
463
468
|
},
|
|
464
|
-
[]
|
|
469
|
+
[client]
|
|
465
470
|
);
|
|
466
|
-
return { generate, configLoading, configError };
|
|
471
|
+
return { generate, refreshConfig, configLoading, configError };
|
|
467
472
|
}
|
|
468
473
|
function useLocationRequests(client, options = {}) {
|
|
469
474
|
const [requests, setRequests] = useState([]);
|
|
@@ -1003,6 +1008,46 @@ function loadMediaPipeFaceDetection(assetBasePath) {
|
|
|
1003
1008
|
|
|
1004
1009
|
// src/kyc/hostedJourney.ts
|
|
1005
1010
|
var REUSE_KYC_SESSION_EXPIRY_MS = 10 * 60 * 1e3;
|
|
1011
|
+
var JOURNEY_FRAME_HEIGHT = "clamp(500px, 64vh, 680px)";
|
|
1012
|
+
var JOURNEY_CONFIRM_TIMEOUT_MS = 45e3;
|
|
1013
|
+
function journeyOutcomeFromMessage(data) {
|
|
1014
|
+
const status = data?.verification_status;
|
|
1015
|
+
if (typeof status !== "string") return null;
|
|
1016
|
+
switch (status) {
|
|
1017
|
+
case "verification.accepted":
|
|
1018
|
+
return "accepted";
|
|
1019
|
+
case "verification.declined":
|
|
1020
|
+
return "declined";
|
|
1021
|
+
case "verification.cancelled":
|
|
1022
|
+
case "request.timeout":
|
|
1023
|
+
case "request.invalid":
|
|
1024
|
+
case "request.unauthorized":
|
|
1025
|
+
case "request.deleted":
|
|
1026
|
+
return "cancelled";
|
|
1027
|
+
default:
|
|
1028
|
+
return null;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
function journeyPollIntervalMs(confirming) {
|
|
1032
|
+
return confirming ? 1e3 : 2500;
|
|
1033
|
+
}
|
|
1034
|
+
function pendingJourneyResult(reference) {
|
|
1035
|
+
return {
|
|
1036
|
+
event: "reuse_kyc",
|
|
1037
|
+
reference,
|
|
1038
|
+
resource_id: "",
|
|
1039
|
+
status: "pending",
|
|
1040
|
+
data: {
|
|
1041
|
+
retries_remaining: 0,
|
|
1042
|
+
retry_limit_exceeded: false,
|
|
1043
|
+
trigger_alert: false,
|
|
1044
|
+
enforce_logout: false,
|
|
1045
|
+
freeze_account: false,
|
|
1046
|
+
block: false,
|
|
1047
|
+
freeze_duration_minutes: 0
|
|
1048
|
+
}
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
1006
1051
|
function tryStartOperation(guard) {
|
|
1007
1052
|
if (guard.current) return false;
|
|
1008
1053
|
guard.current = true;
|
|
@@ -1014,12 +1059,22 @@ function releaseOperation(guard) {
|
|
|
1014
1059
|
function retryTarget(hasHostedJourney) {
|
|
1015
1060
|
return hasHostedJourney ? "journey" : "capture";
|
|
1016
1061
|
}
|
|
1062
|
+
var CAPTURE_MODAL_MAX_WIDTH = 448;
|
|
1017
1063
|
function modalMaxWidth(hasHostedJourney) {
|
|
1018
|
-
return hasHostedJourney ?
|
|
1064
|
+
return hasHostedJourney ? CAPTURE_MODAL_MAX_WIDTH : CAPTURE_MODAL_MAX_WIDTH;
|
|
1065
|
+
}
|
|
1066
|
+
var JOURNEY_CONTENT_PADDING = 12;
|
|
1067
|
+
function resultForModalClose(stageKind, result, unconfirmed) {
|
|
1068
|
+
const terminal = stageKind === "accepted" || stageKind === "declined" || stageKind === "max_attempts";
|
|
1069
|
+
if (terminal && result !== void 0) return result;
|
|
1070
|
+
const awaitingConfirmation = stageKind === "confirming" || stageKind === "unconfirmed";
|
|
1071
|
+
if (awaitingConfirmation && unconfirmed !== void 0) return unconfirmed;
|
|
1072
|
+
return null;
|
|
1019
1073
|
}
|
|
1020
1074
|
|
|
1021
1075
|
// src/kyc/FaceCaptureModal.tsx
|
|
1022
1076
|
var MOBILE_UA = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
|
|
1077
|
+
var ACCEPTED_AUTO_CLOSE_MS = 1200;
|
|
1023
1078
|
var LIVENESS_MESSAGES = [
|
|
1024
1079
|
"Position your face inside the oval",
|
|
1025
1080
|
"Make sure your face is well lit",
|
|
@@ -1032,6 +1087,10 @@ function headerSubtitle(stageKind) {
|
|
|
1032
1087
|
return "Use your phone to continue";
|
|
1033
1088
|
case "journey":
|
|
1034
1089
|
return "Follow the steps to verify your identity";
|
|
1090
|
+
case "confirming":
|
|
1091
|
+
return "Confirming your result";
|
|
1092
|
+
case "unconfirmed":
|
|
1093
|
+
return "Still confirming";
|
|
1035
1094
|
case "accepted":
|
|
1036
1095
|
return "All set";
|
|
1037
1096
|
case "declined":
|
|
@@ -1131,8 +1190,10 @@ function FaceCaptureModal({
|
|
|
1131
1190
|
stopped = true;
|
|
1132
1191
|
};
|
|
1133
1192
|
}, [stage.kind, stage.kind === "qr" ? stage.mobileConnected : false]);
|
|
1193
|
+
const journeyUrl = stage.kind === "journey" || stage.kind === "confirming" ? stage.url : "";
|
|
1134
1194
|
useEffect(() => {
|
|
1135
|
-
if (stage.kind !== "journey" || !
|
|
1195
|
+
if (stage.kind !== "journey" && stage.kind !== "confirming" || !journeyUrl) return;
|
|
1196
|
+
const intervalMs = journeyPollIntervalMs(stage.kind === "confirming");
|
|
1136
1197
|
let stopped = false;
|
|
1137
1198
|
const checkOnce = async () => {
|
|
1138
1199
|
try {
|
|
@@ -1149,27 +1210,43 @@ function FaceCaptureModal({
|
|
|
1149
1210
|
if (stopped || cancelledRef.current) return;
|
|
1150
1211
|
await checkOnce();
|
|
1151
1212
|
if (!stopped && !cancelledRef.current) {
|
|
1152
|
-
setTimeout(tick,
|
|
1213
|
+
setTimeout(tick, intervalMs);
|
|
1153
1214
|
}
|
|
1154
1215
|
};
|
|
1155
1216
|
void tick();
|
|
1156
1217
|
let frameOrigin = "";
|
|
1157
1218
|
try {
|
|
1158
|
-
frameOrigin = new URL(
|
|
1219
|
+
frameOrigin = new URL(journeyUrl).origin;
|
|
1159
1220
|
} catch {
|
|
1160
1221
|
frameOrigin = "";
|
|
1161
1222
|
}
|
|
1162
1223
|
const onMessage = (e) => {
|
|
1163
1224
|
if (!frameOrigin || e.origin !== frameOrigin) return;
|
|
1164
|
-
const
|
|
1165
|
-
if (
|
|
1225
|
+
const outcome = journeyOutcomeFromMessage(e.data);
|
|
1226
|
+
if (!outcome) return;
|
|
1227
|
+
void checkOnce();
|
|
1228
|
+
setStage((prev) => {
|
|
1229
|
+
if (prev.kind !== "journey") return prev;
|
|
1230
|
+
if (outcome === "cancelled") {
|
|
1231
|
+
return { kind: "error", message: "The verification was closed before it finished. Please try again." };
|
|
1232
|
+
}
|
|
1233
|
+
return { kind: "confirming", outcome, url: prev.url };
|
|
1234
|
+
});
|
|
1166
1235
|
};
|
|
1167
1236
|
window.addEventListener("message", onMessage);
|
|
1168
1237
|
return () => {
|
|
1169
1238
|
stopped = true;
|
|
1170
1239
|
window.removeEventListener("message", onMessage);
|
|
1171
1240
|
};
|
|
1172
|
-
}, [stage.kind,
|
|
1241
|
+
}, [stage.kind, journeyUrl]);
|
|
1242
|
+
useEffect(() => {
|
|
1243
|
+
if (stage.kind !== "confirming") return;
|
|
1244
|
+
const outcome = stage.outcome;
|
|
1245
|
+
const timer = setTimeout(() => {
|
|
1246
|
+
setStage((prev) => prev.kind === "confirming" ? { kind: "unconfirmed", outcome } : prev);
|
|
1247
|
+
}, JOURNEY_CONFIRM_TIMEOUT_MS);
|
|
1248
|
+
return () => clearTimeout(timer);
|
|
1249
|
+
}, [stage.kind, stage.kind === "confirming" ? stage.outcome : ""]);
|
|
1173
1250
|
const handleJourneyRetry = async () => {
|
|
1174
1251
|
if (!tryStartOperation(journeyRetryingRef)) return;
|
|
1175
1252
|
setStage({ kind: "journey", url: "" });
|
|
@@ -1316,12 +1393,23 @@ function FaceCaptureModal({
|
|
|
1316
1393
|
}, 3e3);
|
|
1317
1394
|
return () => clearInterval(interval);
|
|
1318
1395
|
}, [captureMode]);
|
|
1319
|
-
const close = (result) => {
|
|
1396
|
+
const close = useCallback((result) => {
|
|
1320
1397
|
cancelledRef.current = true;
|
|
1321
1398
|
if (result === null && onCancel) {
|
|
1322
1399
|
onCancel();
|
|
1323
1400
|
}
|
|
1324
1401
|
onComplete(result);
|
|
1402
|
+
}, [onCancel, onComplete]);
|
|
1403
|
+
useEffect(() => {
|
|
1404
|
+
if (stage.kind !== "accepted") return;
|
|
1405
|
+
const result = stage.result;
|
|
1406
|
+
const timer = setTimeout(() => close(result), ACCEPTED_AUTO_CLOSE_MS);
|
|
1407
|
+
return () => clearTimeout(timer);
|
|
1408
|
+
}, [close, stage]);
|
|
1409
|
+
const handleHeaderClose = () => {
|
|
1410
|
+
const result = "result" in stage ? stage.result : void 0;
|
|
1411
|
+
const unconfirmed = stage.kind === "confirming" || stage.kind === "unconfirmed" ? pendingJourneyResult(session.reference) : void 0;
|
|
1412
|
+
close(resultForModalClose(stage.kind, result, unconfirmed));
|
|
1325
1413
|
};
|
|
1326
1414
|
const renderChoose = () => /* @__PURE__ */ React.createElement("div", { style: contentStyle }, /* @__PURE__ */ React.createElement("div", { style: visualGuideContainerStyle }, /* @__PURE__ */ React.createElement("div", { style: visualGuideStyle }, /* @__PURE__ */ React.createElement("div", { style: circleStyle }, /* @__PURE__ */ React.createElement("img", { src: Camera, alt: "", width: 48, height: 48 })))), /* @__PURE__ */ React.createElement("p", { style: subtitleStyle }, "How would you like to verify?"), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement(
|
|
1327
1415
|
"button",
|
|
@@ -1393,7 +1481,16 @@ function FaceCaptureModal({
|
|
|
1393
1481
|
"Try Again"
|
|
1394
1482
|
), /* @__PURE__ */ React.createElement("button", { style: cancelButtonStyle, onClick: () => close(null) }, sessionExpired ? "Close" : "Cancel")));
|
|
1395
1483
|
};
|
|
1396
|
-
const
|
|
1484
|
+
const renderConfirming = () => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: { ...spinnerStyle, margin: "24px auto", width: 32, height: 32 } }), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, "Confirming your result\u2026"), /* @__PURE__ */ React.createElement("p", { style: { ...attemptsTextStyle, marginTop: 8 } }, "This usually takes a few seconds."));
|
|
1485
|
+
const renderUnconfirmed = (outcome) => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: errorCircleStyle }, "!"), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, "Still confirming"), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, outcome === "accepted" ? "Your verification was submitted, but we haven't received the final result yet. You can close this window and we'll keep checking in the background." : "Your last attempt wasn't accepted, but we haven't received the details yet. You can try again or close this window."), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, outcome === "declined" && /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => void handleJourneyRetry() }, "Try Again"), /* @__PURE__ */ React.createElement(
|
|
1486
|
+
"button",
|
|
1487
|
+
{
|
|
1488
|
+
style: outcome === "accepted" ? primaryButtonStyle : cancelButtonStyle,
|
|
1489
|
+
onClick: () => close(pendingJourneyResult(session.reference))
|
|
1490
|
+
},
|
|
1491
|
+
"Close"
|
|
1492
|
+
)));
|
|
1493
|
+
const renderJourney = (url) => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, padding: JOURNEY_CONTENT_PADDING } }, url ? /* @__PURE__ */ React.createElement(
|
|
1397
1494
|
"iframe",
|
|
1398
1495
|
{
|
|
1399
1496
|
src: url,
|
|
@@ -1412,6 +1509,10 @@ function FaceCaptureModal({
|
|
|
1412
1509
|
return renderCapture(stage.declinedReason);
|
|
1413
1510
|
case "journey":
|
|
1414
1511
|
return renderJourney(stage.url);
|
|
1512
|
+
case "confirming":
|
|
1513
|
+
return renderConfirming();
|
|
1514
|
+
case "unconfirmed":
|
|
1515
|
+
return renderUnconfirmed(stage.outcome);
|
|
1415
1516
|
case "submitting":
|
|
1416
1517
|
return renderSubmitting();
|
|
1417
1518
|
case "accepted":
|
|
@@ -1427,7 +1528,7 @@ function FaceCaptureModal({
|
|
|
1427
1528
|
return /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement("style", null, keyframes), /* @__PURE__ */ React.createElement("div", { style: overlayStyle }, /* @__PURE__ */ React.createElement("div", { style: { ...modalStyle, maxWidth: modalMaxWidth(journeyMode) } }, /* @__PURE__ */ React.createElement("div", { style: headerStyle }, /* @__PURE__ */ React.createElement(
|
|
1428
1529
|
"button",
|
|
1429
1530
|
{
|
|
1430
|
-
onClick:
|
|
1531
|
+
onClick: handleHeaderClose,
|
|
1431
1532
|
style: closeButtonStyle,
|
|
1432
1533
|
"aria-label": "Close"
|
|
1433
1534
|
},
|
|
@@ -1486,7 +1587,7 @@ var contentStyle = {
|
|
|
1486
1587
|
};
|
|
1487
1588
|
var journeyFrameStyle = {
|
|
1488
1589
|
width: "100%",
|
|
1489
|
-
height:
|
|
1590
|
+
height: JOURNEY_FRAME_HEIGHT,
|
|
1490
1591
|
border: 0,
|
|
1491
1592
|
borderRadius: 12,
|
|
1492
1593
|
background: "#f9fafb"
|
|
@@ -2273,6 +2374,13 @@ function getRiskColor(risk) {
|
|
|
2273
2374
|
};
|
|
2274
2375
|
return colorMap[risk] || "#6b7280";
|
|
2275
2376
|
}
|
|
2377
|
+
function isMobileDevice(userAgent) {
|
|
2378
|
+
const ua = userAgent ?? (typeof navigator === "undefined" ? "" : navigator.userAgent);
|
|
2379
|
+
return /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
|
|
2380
|
+
}
|
|
2381
|
+
function buildEventBasedFaceVerificationQrPayload(token) {
|
|
2382
|
+
return `vesant://reuse-kyc?token=${encodeURIComponent(token)}`;
|
|
2383
|
+
}
|
|
2276
2384
|
function useEventBasedFaceVerificationSubmission(client) {
|
|
2277
2385
|
const startSession = useCallback(
|
|
2278
2386
|
(request) => client.createEventBasedFaceVerificationSession(request),
|
|
@@ -2320,6 +2428,6 @@ function useEventBasedFaceVerificationSubmission(client) {
|
|
|
2320
2428
|
return { startSession, verifyFace, runFlow };
|
|
2321
2429
|
}
|
|
2322
2430
|
|
|
2323
|
-
export { createDeviceFingerprint, fileToBase64, formatKycStatus, getBrowserInfo, getRiskColor, getStatusColor, isValidFileSize, isValidFileType, useCipherText, useCustomerProfile, useEventBasedFaceVerificationSubmission, useGeolocation, useKycAlerts, useKycOverview, useKycPreferences, useKycRequests, useKycSubmission, useLocationCapture, useLocationRequests, useLoginVerification, useRegistration, useTransactionVerification };
|
|
2431
|
+
export { FaceCaptureModal_default as FaceCaptureModal, buildEventBasedFaceVerificationQrPayload, createDeviceFingerprint, fileToBase64, formatKycStatus, getBrowserInfo, getRiskColor, getStatusColor, isMobileDevice, isValidFileSize, isValidFileType, useCipherText, useCustomerProfile, useEventBasedFaceVerificationSubmission, useGeolocation, useKycAlerts, useKycOverview, useKycPreferences, useKycRequests, useKycSubmission, useLocationCapture, useLocationRequests, useLoginVerification, useRegistration, useTransactionVerification };
|
|
2324
2432
|
//# sourceMappingURL=react.mjs.map
|
|
2325
2433
|
//# sourceMappingURL=react.mjs.map
|