smartcomply-web-sdk 1.0.93 → 1.0.95

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.
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SmartComplyFlow = void 0;
4
+ exports.isChannelDocumentFlow = isChannelDocumentFlow;
5
+ exports.selectIdTypesForScreen = selectIdTypesForScreen;
4
6
  exports.isResumeLinkErrorMessage = isResumeLinkErrorMessage;
5
7
  exports.resolveIdTypeInfo = resolveIdTypeInfo;
6
8
  const Smartcomply_1 = require("../client/Smartcomply");
@@ -72,6 +74,49 @@ const COUNTRY_LABELS = {
72
74
  function isUploadFieldType(type) {
73
75
  return type === "upload" || type === "image" || type === "file";
74
76
  }
77
+ /**
78
+ * Whether a SPECIFIC channel is a document-scan item, vs. a plain
79
+ * number-entry one. channels[country] is a flat list that can mix
80
+ * data_verification channels (e.g. bare "Passport", a number-entry lookup)
81
+ * with document_verification channels (e.g. "Document Verification -
82
+ * Passport", a scan) whenever an SDK config's verification_type covers
83
+ * both modes — a real, valid dual-mode setup, not a misconfiguration.
84
+ *
85
+ * Reported live: with both modes enabled, every channel rendered and
86
+ * routed as a document scan, including number-entry ones — because the
87
+ * per-channel decision fell back to the config's overall
88
+ * globalDocFlow/verification_type the moment document_verification was
89
+ * enabled ANYWHERE in the config, instead of checking whether THIS
90
+ * channel actually has an upload field. A legacy string-only channel
91
+ * (typeof idType === "string") carries no fields array to check at all,
92
+ * so that's the only case the global flow mode is still used for.
93
+ */
94
+ function isChannelDocumentFlow(idType, globalDocFlow) {
95
+ if (typeof idType === "string")
96
+ return globalDocFlow;
97
+ return (idType.fields || []).some((f) => isUploadFieldType(f.type));
98
+ }
99
+ /**
100
+ * Picks the channel list for the "Select document type" / "Select ID type"
101
+ * screen — the one list that actually matches this screen's mode, not a
102
+ * flat list mixing both categories.
103
+ *
104
+ * Reported live: the deployed widget's document-scan screen showed a bare
105
+ * "Passport" (data_verification, number-entry) right next to "Document
106
+ * Verification - Passport" (document_verification, scan) as if they were
107
+ * the same kind of option — because channels[country] used to be one flat
108
+ * list with no category split at all. Splitting the backend response
109
+ * (SDKSecureLoaderView, adhere-backend) into {data_verification,
110
+ * document_verification} only helps if this screen then reads the ONE
111
+ * list matching globalDocFlow, instead of still flattening both — that's
112
+ * what actually removes the duplicate, not just how each entry displays
113
+ * (see isChannelDocumentFlow above, which only decides that).
114
+ */
115
+ function selectIdTypesForScreen(byCategory, globalDocFlow) {
116
+ if (!byCategory)
117
+ return [];
118
+ return (globalDocFlow ? byCategory.document_verification : byCategory.data_verification) || [];
119
+ }
75
120
  /**
76
121
  * Whether a showErrorStep() message is about an expired/invalid resume or
77
122
  * resubmit link (RESUME_TARGET_UNAVAILABLE / NOT_A_RESUME_TOKEN — see
@@ -740,8 +785,11 @@ class SmartComplyFlow {
740
785
  return "liveness";
741
786
  }
742
787
  if (info.failure_stage === "document" && info.country && info.identifier_type) {
788
+ // A document-stage resume always references a document_verification
789
+ // channel by its doc code — channels[country] is now split by
790
+ // category (see ChannelsByCategory), so search that list directly.
743
791
  const channels = this.sdkConfig?.channels || {};
744
- const idTypes = channels[info.country] || [];
792
+ const idTypes = channels[info.country]?.document_verification || [];
745
793
  const match = idTypes.find((idType) => {
746
794
  const code = typeof idType === "string" ? idType : (idType.code || idType.name);
747
795
  return code === info.identifier_type;
@@ -1117,7 +1165,9 @@ class SmartComplyFlow {
1117
1165
  subtitle.textContent = "Choose the country that issued your ID";
1118
1166
  container.appendChild(subtitle);
1119
1167
  for (const country of countries) {
1120
- const card = this.createOptionCard(COUNTRY_LABELS[country] || country, `${channels[country].length} ID type${channels[country].length > 1 ? "s" : ""} available`, () => {
1168
+ const count = channels[country].data_verification.length
1169
+ + channels[country].document_verification.length;
1170
+ const card = this.createOptionCard(COUNTRY_LABELS[country] || country, `${count} ID type${count > 1 ? "s" : ""} available`, () => {
1121
1171
  this.selectedCountry = country;
1122
1172
  this.showStep("id_type");
1123
1173
  });
@@ -1137,14 +1187,14 @@ class SmartComplyFlow {
1137
1187
  : "Choose the ID you want to verify";
1138
1188
  container.appendChild(subtitle);
1139
1189
  const channels = this.sdkConfig?.channels || {};
1140
- const idTypes = channels[this.selectedCountry] || [];
1190
+ const idTypes = selectIdTypesForScreen(channels[this.selectedCountry], globalDocFlow);
1141
1191
  for (const idType of idTypes) {
1142
1192
  const typeName = typeof idType === "string" ? idType : idType.name;
1143
1193
  // Use code (canonical) for API calls, fallback to name for backward compatibility
1144
1194
  const typeCode = typeof idType === "string" ? idType : (idType.code || idType.name);
1145
- // Detect per-channel: does THIS specific channel have upload fields?
1146
- const channelFields = typeof idType !== "string" ? (idType.fields || []) : [];
1147
- const isThisDocFlow = channelFields.some((f) => isUploadFieldType(f.type)) || globalDocFlow;
1195
+ // Detect per-channel, not from the config's overall mode — see
1196
+ // isChannelDocumentFlow's docstring for why.
1197
+ const isThisDocFlow = isChannelDocumentFlow(idType, globalDocFlow);
1148
1198
  const info = resolveIdTypeInfo(typeName, isThisDocFlow);
1149
1199
  // Prefer the backend-provided back-side flag; fall back to local heuristics only when absent.
1150
1200
  const requiresBackFromBackend = typeof idType !== "string" ? idType.requires_back_side : undefined;
@@ -1182,12 +1232,9 @@ class SmartComplyFlow {
1182
1232
  this.selectedChannelId = idType.id;
1183
1233
  this.selectedChannelFields = idType.fields || []; // guard null/undefined from backend
1184
1234
  }
1185
- // Route: use explicit verification_type when set (more reliable than inspecting all channels)
1186
- // Fallback to per-channel upload field check for mixed / unconfigured setups
1187
- const hasUpload = (this.selectedChannelFields).some((f) => isUploadFieldType(f.type));
1188
- const vType = this.sdkConfig?.verification_type;
1189
- const vTypes = vType ? (Array.isArray(vType) ? vType : [vType]) : [];
1190
- const isDocChannel = hasUpload || (vTypes.length > 0 && vTypes.includes("document_verification"));
1235
+ // Route on THIS channel, same as isThisDocFlow above — see
1236
+ // isChannelDocumentFlow's docstring.
1237
+ const isDocChannel = isChannelDocumentFlow(idType, globalDocFlow);
1191
1238
  this.showStep(isDocChannel ? "document_capture" : "id_input");
1192
1239
  });
1193
1240
  container.appendChild(card);
@@ -2733,10 +2780,16 @@ class SmartComplyFlow {
2733
2780
  if (types.includes("data_verification"))
2734
2781
  return false;
2735
2782
  }
2736
- // 2. Fallback: inspect channel fields — any upload field = document flow
2783
+ // 2. Fallback: inspect channel fields — any upload field = document flow.
2784
+ // channels[country] is now split {data_verification, document_verification}
2785
+ // (see ChannelsByCategory) — flatten both sub-lists per country, not the
2786
+ // per-country objects themselves.
2737
2787
  const channels = this.sdkConfig?.channels || {};
2738
2788
  const allFields = Object.values(channels)
2739
- .flat()
2789
+ .flatMap((byCategory) => [
2790
+ ...(byCategory.data_verification || []),
2791
+ ...(byCategory.document_verification || []),
2792
+ ])
2740
2793
  .flatMap((ch) => ch.fields || []);
2741
2794
  return allFields.some((f) => isUploadFieldType(f.type));
2742
2795
  }