vesant-sdk 1.7.0-dev.362ac6b → 1.7.0-dev.7d59b3e

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/react.mjs CHANGED
@@ -885,6 +885,7 @@ var Close = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0id
885
885
 
886
886
  // src/kyc/FaceCaptureModal.tsx
887
887
  var MOBILE_UA = /Mobi|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i;
888
+ var SESSION_EXPIRY_MS = 15 * 60 * 1e3;
888
889
  var LIVENESS_MESSAGES = [
889
890
  "Position your face inside the circle",
890
891
  "Make sure your face is well lit",
@@ -936,17 +937,25 @@ function FaceCaptureModal({
936
937
  const qrPayload = session.link || `vesant://reuse-kyc?token=${encodeURIComponent(session.token)}`;
937
938
  const cancelledRef = useRef(false);
938
939
  const submittingRef = useRef(false);
940
+ useEffect(() => {
941
+ const timer = setTimeout(() => {
942
+ setStage(
943
+ (prev) => prev.kind === "choose" || prev.kind === "qr" || prev.kind === "capture" ? { kind: "error", message: "Session expired" } : prev
944
+ );
945
+ }, SESSION_EXPIRY_MS);
946
+ return () => clearTimeout(timer);
947
+ }, [session.token]);
939
948
  useEffect(() => {
940
949
  if (stage.kind !== "qr") return;
941
950
  let stopped = false;
942
951
  const intervalMs = 2e3;
943
- const deadline = Date.now() + 15 * 60 * 1e3;
952
+ const deadline = Date.now() + SESSION_EXPIRY_MS;
944
953
  let mobileSeen = stage.mobileConnected;
945
954
  const tick = async () => {
946
955
  if (stopped || cancelledRef.current) return;
947
956
  try {
948
957
  if (mobileSeen) {
949
- const result = await client.getReuseKycSessionStatus(session.reference);
958
+ const result = await client.getEventBasedFaceVerificationSessionStatus(session.token);
950
959
  if (result.status === "accepted") {
951
960
  setStage({ kind: "accepted", result });
952
961
  stopped = true;
@@ -1018,7 +1027,7 @@ function FaceCaptureModal({
1018
1027
  try {
1019
1028
  const postPromise = (async () => {
1020
1029
  try {
1021
- const data = await client.submitReuseKycSession({
1030
+ const data = await client.submitEventBasedFaceVerificationSession({
1022
1031
  token: session.token,
1023
1032
  reference: ref,
1024
1033
  proof
@@ -1034,7 +1043,7 @@ function FaceCaptureModal({
1034
1043
  while (Date.now() < deadline) {
1035
1044
  if (settled || cancelledRef.current) return null;
1036
1045
  try {
1037
- const r = await client.getReuseKycSessionStatus(ref);
1046
+ const r = await client.getEventBasedFaceVerificationSessionStatus(session.token);
1038
1047
  if (isFreshPollResult(r)) return r;
1039
1048
  } catch {
1040
1049
  }
@@ -1155,7 +1164,7 @@ function FaceCaptureModal({
1155
1164
  if (captureMode === "preview" && capturedPreview) {
1156
1165
  return /* @__PURE__ */ React.createElement("div", { style: contentStyle }, declinedReason && /* @__PURE__ */ React.createElement("div", { style: alertBoxStyle }, /* @__PURE__ */ React.createElement("strong", null, "Verification declined."), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, declinedReason)), /* @__PURE__ */ React.createElement("p", { style: subtitleStyle }, "Looks good? Submit this selfie or retake it."), /* @__PURE__ */ React.createElement("div", { style: previewBoxStyle }, /* @__PURE__ */ React.createElement("img", { src: capturedPreview, alt: "Captured selfie preview", style: previewImgStyle })), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: handleConfirmSubmit }, /* @__PURE__ */ React.createElement("img", { src: Done, alt: "", width: 20, height: 20 }), /* @__PURE__ */ React.createElement("span", null, "Submit")), /* @__PURE__ */ React.createElement("button", { style: secondaryButtonStyle, onClick: handleRetake }, "Retake"), /* @__PURE__ */ React.createElement("button", { style: cancelButtonStyle, onClick: () => close(null) }, "Cancel")), /* @__PURE__ */ React.createElement("p", { style: attemptsTextStyle }, "Attempt ", attempts + 1, " of ", maxAttempts));
1157
1166
  }
1158
- return /* @__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("div", { style: badgeStyle }, /* @__PURE__ */ React.createElement("img", { src: Done, alt: "", width: 16, height: 16 })))), declinedReason && /* @__PURE__ */ React.createElement("div", { style: alertBoxStyle }, /* @__PURE__ */ React.createElement("strong", null, "Verification declined."), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, declinedReason)), /* @__PURE__ */ React.createElement("div", { style: instructionsBoxStyle }, /* @__PURE__ */ React.createElement("h3", { style: instructionsTitleStyle }, "Tips for best results:"), /* @__PURE__ */ React.createElement("ul", { style: instructionsListStyle }, /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Ensure good lighting on your face")), /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Remove glasses or accessories if possible")), /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Look directly at the camera")))), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: handleOpenCamera }, /* @__PURE__ */ React.createElement("img", { src: Camera, alt: "", width: 20, height: 20 }), /* @__PURE__ */ React.createElement("span", null, declinedReason ? "Try again" : "Open Camera")), hasMethodChoice && /* @__PURE__ */ React.createElement(
1167
+ return /* @__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("div", { style: badgeStyle }, /* @__PURE__ */ React.createElement("img", { src: Done, alt: "", width: 16, height: 16 })))), declinedReason && /* @__PURE__ */ React.createElement("div", { style: alertBoxStyle }, /* @__PURE__ */ React.createElement("strong", null, "Verification declined."), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, declinedReason)), /* @__PURE__ */ React.createElement("div", { style: instructionsBoxStyle }, /* @__PURE__ */ React.createElement("h3", { style: instructionsTitleStyle }, "Tips for best results:"), /* @__PURE__ */ React.createElement("ul", { style: instructionsListStyle }, /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Ensure good lighting on your face")), /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Remove glasses or accessories if possible")), /* @__PURE__ */ React.createElement("li", { style: instructionItemStyle }, /* @__PURE__ */ React.createElement("span", { style: bulletStyle }, "\u2022"), /* @__PURE__ */ React.createElement("span", null, "Look directly at the camera")))), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: handleOpenCamera }, /* @__PURE__ */ React.createElement("img", { src: Camera, alt: "", width: 20, height: 20 }), /* @__PURE__ */ React.createElement("span", null, declinedReason ? "Try Again" : "Open Camera")), hasMethodChoice && /* @__PURE__ */ React.createElement(
1159
1168
  "button",
1160
1169
  {
1161
1170
  style: secondaryButtonStyle,
@@ -1167,10 +1176,10 @@ function FaceCaptureModal({
1167
1176
  const renderSubmitting = () => /* @__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("p", { style: subtitleStyle }, "Verifying your photo\u2026"), /* @__PURE__ */ React.createElement("p", { style: { ...attemptsTextStyle, marginTop: 8 } }, "This usually takes a few seconds."));
1168
1177
  const renderAccepted = (result) => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: successCircleStyle }, /* @__PURE__ */ React.createElement("img", { src: Done, alt: "", width: 48, height: 48 })), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, "Verified"), /* @__PURE__ */ React.createElement("p", { style: subtitleStyle }, "Your identity has been confirmed. You can continue."), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => close(result) }, "Continue")));
1169
1178
  const renderDeclined = (result) => /* @__PURE__ */ React.createElement("div", { style: contentStyle }, /* @__PURE__ */ React.createElement("div", { style: alertBoxStyle }, /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, result.declined_reason ?? "We couldn't match your selfie. Please take a new one.")), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: handleRetakeAfterDecline }, /* @__PURE__ */ React.createElement("img", { src: Camera, alt: "", width: 20, height: 20 }), /* @__PURE__ */ React.createElement("span", null, "Retake")), /* @__PURE__ */ React.createElement("button", { style: cancelButtonStyle, onClick: () => close(result) }, "Cancel")), /* @__PURE__ */ React.createElement("p", { style: attemptsTextStyle }, "Attempt ", Math.min(attempts + 1, maxAttempts), " of ", maxAttempts));
1170
- const renderMaxAttempts = (result) => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: errorCircleStyle }, "!"), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, "Maximum Attempts Reached"), /* @__PURE__ */ React.createElement("p", { style: subtitleStyle }, result.declined_reason ?? "We couldn't verify your identity after several attempts."), result.data?.freeze_account && /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, "For your security, your account has been temporarily restricted", result.data.freeze_duration_minutes ? ` for ${result.data.freeze_duration_minutes} minutes` : "", ". Please contact support if you need immediate help."), result.data?.enforce_logout && /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, "You will be signed out of your session."), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => close(result) }, "Close")));
1179
+ const renderMaxAttempts = (result) => /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: errorCircleStyle }, "!"), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, "Maximum Attempts Reached"), /* @__PURE__ */ React.createElement("p", { style: subtitleStyle }, result.declined_reason ?? "We couldn't verify your identity after several attempts."), result.data?.freeze_account && /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, "For your security, your account has been temporarily restricted", result.data.freeze_duration_minutes ? ` for ${result.data.freeze_duration_minutes} minutes` : "", ". Please contact support if you need immediate help."), result.data?.enforce_logout && /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, "You will be signed out of your session."), result.data?.block && /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, "This action has been blocked for security reasons."), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => close(result) }, "Close")));
1171
1180
  const renderError = (message) => {
1172
1181
  const sessionExpired = /session\s+expired/i.test(message);
1173
- return /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: errorCircleStyle }, "!"), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, sessionExpired ? "Session expired" : "Something went wrong"), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, sessionExpired ? "Your verification session is no longer valid. Please start a new verification from the beginning." : message), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, !sessionExpired && /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => setStage({ kind: "capture" }) }, "Try again"), /* @__PURE__ */ React.createElement("button", { style: cancelButtonStyle, onClick: () => close(null) }, sessionExpired ? "Close" : "Cancel")));
1182
+ return /* @__PURE__ */ React.createElement("div", { style: { ...contentStyle, alignItems: "center", textAlign: "center" } }, /* @__PURE__ */ React.createElement("div", { style: errorCircleStyle }, "!"), /* @__PURE__ */ React.createElement("h3", { style: titleStyle }, sessionExpired ? "Session expired" : "Something Went Wrong"), /* @__PURE__ */ React.createElement("p", { style: alertTextStyle }, sessionExpired ? "Your verification session is no longer valid. Please start a new verification from the beginning." : message), /* @__PURE__ */ React.createElement("div", { style: buttonsContainerStyle }, !sessionExpired && /* @__PURE__ */ React.createElement("button", { style: primaryButtonStyle, onClick: () => setStage({ kind: "capture" }) }, "Try Again"), /* @__PURE__ */ React.createElement("button", { style: cancelButtonStyle, onClick: () => close(null) }, sessionExpired ? "Close" : "Cancel")));
1174
1183
  };
1175
1184
  const body = (() => {
1176
1185
  switch (stage.kind) {
@@ -2078,9 +2087,9 @@ function getRiskColor(risk) {
2078
2087
  };
2079
2088
  return colorMap[risk] || "#6b7280";
2080
2089
  }
2081
- function useReuseKYCSubmission(client) {
2090
+ function useEventBasedFaceVerificationSubmission(client) {
2082
2091
  const startSession = useCallback(
2083
- (request) => client.createReuseKycSession(request),
2092
+ (request) => client.createEventBasedFaceVerificationSession(request),
2084
2093
  [client]
2085
2094
  );
2086
2095
  const verifyFace = useCallback(
@@ -2124,6 +2133,6 @@ function useReuseKYCSubmission(client) {
2124
2133
  return { startSession, verifyFace, runFlow };
2125
2134
  }
2126
2135
 
2127
- export { createDeviceFingerprint, fileToBase64, formatKycStatus, getBrowserInfo, getRiskColor, getStatusColor, isValidFileSize, isValidFileType, useCipherText, useCustomerProfile, useGeolocation, useKycAlerts, useKycOverview, useKycPreferences, useKycRequests, useKycSubmission, useLocationCapture, useLocationRequests, useLoginVerification, useRegistration, useReuseKYCSubmission, useTransactionVerification };
2136
+ export { createDeviceFingerprint, fileToBase64, formatKycStatus, getBrowserInfo, getRiskColor, getStatusColor, isValidFileSize, isValidFileType, useCipherText, useCustomerProfile, useEventBasedFaceVerificationSubmission, useGeolocation, useKycAlerts, useKycOverview, useKycPreferences, useKycRequests, useKycSubmission, useLocationCapture, useLocationRequests, useLoginVerification, useRegistration, useTransactionVerification };
2128
2137
  //# sourceMappingURL=react.mjs.map
2129
2138
  //# sourceMappingURL=react.mjs.map