@dynamicore/jumio-sdk 1.0.1 → 1.0.2
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 +235 -160
- package/dist/client-BwEiGMPy.d.mts +515 -0
- package/dist/client-BwEiGMPy.d.ts +515 -0
- package/dist/core/index.d.mts +94 -4
- package/dist/core/index.d.ts +94 -4
- package/dist/core/index.js +545 -125
- package/dist/core/index.js.map +1 -1
- package/dist/core/index.mjs +506 -83
- package/dist/core/index.mjs.map +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +747 -126
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +706 -83
- package/dist/index.mjs.map +1 -1
- package/dist/react/index.d.mts +146 -2
- package/dist/react/index.d.ts +146 -2
- package/dist/react/index.js +766 -142
- package/dist/react/index.js.map +1 -1
- package/dist/react/index.mjs +766 -143
- package/dist/react/index.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/client-BR1xIZ0X.d.mts +0 -252
- package/dist/client-BR1xIZ0X.d.ts +0 -252
package/dist/react/index.js
CHANGED
|
@@ -7,24 +7,17 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
7
7
|
|
|
8
8
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
var __defProp = Object.defineProperty;
|
|
11
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
12
|
+
var __esm = (fn, res) => function __init() {
|
|
13
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
14
|
+
};
|
|
15
|
+
var __export = (target, all) => {
|
|
16
|
+
for (var name in all)
|
|
17
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
18
|
+
};
|
|
11
19
|
|
|
12
20
|
// src/core/envelope.ts
|
|
13
|
-
var FINAL_JUMIO_STATUSES = [
|
|
14
|
-
"PROCESSED",
|
|
15
|
-
"APPROVED_VERIFIED",
|
|
16
|
-
"REJECTED",
|
|
17
|
-
"FAILED",
|
|
18
|
-
"ERROR",
|
|
19
|
-
"DENIED",
|
|
20
|
-
"EXPIRED",
|
|
21
|
-
"ABANDONED",
|
|
22
|
-
"DONE",
|
|
23
|
-
"COMPLETED",
|
|
24
|
-
"NOT_READABLE",
|
|
25
|
-
"FRAUD",
|
|
26
|
-
"UNSUPPORTED_ID_TYPE"
|
|
27
|
-
];
|
|
28
21
|
function toLowerText(value) {
|
|
29
22
|
return String(value ?? "").trim().toLowerCase();
|
|
30
23
|
}
|
|
@@ -32,10 +25,13 @@ function toUpperText(value) {
|
|
|
32
25
|
return String(value ?? "").trim().toUpperCase();
|
|
33
26
|
}
|
|
34
27
|
function extractEnvelopeData(responseData) {
|
|
35
|
-
if (responseData && typeof responseData === "object"
|
|
36
|
-
const
|
|
37
|
-
if (
|
|
38
|
-
return
|
|
28
|
+
if (responseData && typeof responseData === "object") {
|
|
29
|
+
const obj = responseData;
|
|
30
|
+
if ("data" in obj && obj.data !== void 0) {
|
|
31
|
+
return obj.data;
|
|
32
|
+
}
|
|
33
|
+
if ("values" in obj && obj.values !== void 0) {
|
|
34
|
+
return obj.values;
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
37
|
return responseData;
|
|
@@ -106,62 +102,442 @@ function resolveVerificationValidity(data, fallbackStatus) {
|
|
|
106
102
|
}
|
|
107
103
|
return isApprovedJumioStatus(fallbackStatus);
|
|
108
104
|
}
|
|
105
|
+
function encodeUrlToBase64UrlSafe(url) {
|
|
106
|
+
try {
|
|
107
|
+
let base64;
|
|
108
|
+
if (typeof Buffer !== "undefined") {
|
|
109
|
+
base64 = Buffer.from(url, "utf-8").toString("base64");
|
|
110
|
+
} else if (typeof TextEncoder !== "undefined") {
|
|
111
|
+
const encoder = new TextEncoder();
|
|
112
|
+
const data = encoder.encode(url);
|
|
113
|
+
base64 = btoa(String.fromCharCode(...new Uint8Array(data)));
|
|
114
|
+
} else {
|
|
115
|
+
base64 = btoa(url);
|
|
116
|
+
}
|
|
117
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
var FINAL_JUMIO_STATUSES;
|
|
123
|
+
var init_envelope = __esm({
|
|
124
|
+
"src/core/envelope.ts"() {
|
|
125
|
+
FINAL_JUMIO_STATUSES = [
|
|
126
|
+
"PROCESSED",
|
|
127
|
+
"APPROVED_VERIFIED",
|
|
128
|
+
"REJECTED",
|
|
129
|
+
"FAILED",
|
|
130
|
+
"ERROR",
|
|
131
|
+
"DENIED",
|
|
132
|
+
"EXPIRED",
|
|
133
|
+
"ABANDONED",
|
|
134
|
+
"DONE",
|
|
135
|
+
"COMPLETED",
|
|
136
|
+
"NOT_READABLE",
|
|
137
|
+
"FRAUD",
|
|
138
|
+
"UNSUPPORTED_ID_TYPE"
|
|
139
|
+
];
|
|
140
|
+
}
|
|
141
|
+
});
|
|
109
142
|
|
|
110
143
|
// src/core/errors.ts
|
|
111
|
-
var JumioError
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
144
|
+
var JumioError, JumioTimeoutError, JumioNetworkError, JumioValidationError, JumioImageProcessingError, JumioPollingTimeoutError, JumioAbortError;
|
|
145
|
+
var init_errors = __esm({
|
|
146
|
+
"src/core/errors.ts"() {
|
|
147
|
+
JumioError = class extends Error {
|
|
148
|
+
isJumioError = true;
|
|
149
|
+
statusCode;
|
|
150
|
+
rawData;
|
|
151
|
+
code;
|
|
152
|
+
constructor(message, options) {
|
|
153
|
+
super(message);
|
|
154
|
+
this.name = "JumioError";
|
|
155
|
+
this.statusCode = options?.statusCode;
|
|
156
|
+
this.rawData = options?.rawData;
|
|
157
|
+
this.code = options?.code;
|
|
158
|
+
if (options?.cause) {
|
|
159
|
+
this.cause = options.cause;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
JumioTimeoutError = class extends JumioError {
|
|
164
|
+
constructor(message = "El servicio de verificaci\xF3n de Jumio excedi\xF3 el tiempo l\xEDmite de espera.", rawData) {
|
|
165
|
+
super(message, { code: "TIMEOUT", rawData });
|
|
166
|
+
this.name = "JumioTimeoutError";
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
JumioNetworkError = class extends JumioError {
|
|
170
|
+
constructor(message = "No fue posible comunicarse con los servidores de validaci\xF3n de identidad.", cause) {
|
|
171
|
+
super(message, { code: "NETWORK_ERROR", cause });
|
|
172
|
+
this.name = "JumioNetworkError";
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
JumioValidationError = class extends JumioError {
|
|
176
|
+
constructor(message = "El documento no pudo ser validado o fue rechazado por Jumio.", rawData) {
|
|
177
|
+
super(message, { code: "VALIDATION_FAILED", rawData });
|
|
178
|
+
this.name = "JumioValidationError";
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
JumioImageProcessingError = class extends JumioError {
|
|
182
|
+
constructor(message, cause) {
|
|
183
|
+
super(message, { code: "IMAGE_PROCESSING_ERROR", cause });
|
|
184
|
+
this.name = "JumioImageProcessingError";
|
|
185
|
+
}
|
|
186
|
+
};
|
|
187
|
+
JumioPollingTimeoutError = class extends JumioError {
|
|
188
|
+
attempts;
|
|
189
|
+
constructor(attempts, message = "La validaci\xF3n sigue en proceso. Por favor verifica nuevamente m\xE1s tarde.", rawData) {
|
|
190
|
+
super(message, { code: "POLLING_TIMEOUT", rawData });
|
|
191
|
+
this.name = "JumioPollingTimeoutError";
|
|
192
|
+
this.attempts = attempts;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
JumioAbortError = class extends JumioError {
|
|
196
|
+
constructor(message = "La operaci\xF3n de validaci\xF3n de Jumio fue cancelada.") {
|
|
197
|
+
super(message, { code: "ABORTED" });
|
|
198
|
+
this.name = "JumioAbortError";
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
// src/core/retry.ts
|
|
205
|
+
function delay(ms, signal) {
|
|
206
|
+
return new Promise((resolve, reject) => {
|
|
207
|
+
if (signal?.aborted) {
|
|
208
|
+
return reject(new JumioAbortError());
|
|
124
209
|
}
|
|
210
|
+
const timer = setTimeout(() => {
|
|
211
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
212
|
+
resolve();
|
|
213
|
+
}, ms);
|
|
214
|
+
const abortHandler = () => {
|
|
215
|
+
clearTimeout(timer);
|
|
216
|
+
reject(new JumioAbortError());
|
|
217
|
+
};
|
|
218
|
+
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
function shouldRetryJumio(errorOrMessage) {
|
|
222
|
+
if (!errorOrMessage) return false;
|
|
223
|
+
const text = toLowerText(
|
|
224
|
+
typeof errorOrMessage === "string" ? errorOrMessage : extractJumioMessage(errorOrMessage)
|
|
225
|
+
);
|
|
226
|
+
const errorObj = errorOrMessage;
|
|
227
|
+
const status = errorObj?.status || errorObj?.response?.status;
|
|
228
|
+
const code = String(errorObj?.code || "").toUpperCase();
|
|
229
|
+
if (status === 408 || status === 502 || status === 503 || status === 504) {
|
|
230
|
+
return true;
|
|
125
231
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
constructor(message = "El servicio de verificaci\xF3n de Jumio excedi\xF3 el tiempo l\xEDmite de espera.", rawData) {
|
|
129
|
-
super(message, { code: "TIMEOUT", rawData });
|
|
130
|
-
this.name = "JumioTimeoutError";
|
|
232
|
+
if (code === "ECONNABORTED" || code === "ETIMEDOUT" || code === "ECONNRESET" || code === "EAI_AGAIN") {
|
|
233
|
+
return true;
|
|
131
234
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
235
|
+
return text.includes("timed out") || text.includes("timeout") || text.includes("temporarily unavailable") || text.includes("network error") || text.includes("socket hang up") || text.includes("gateway timeout") || text.includes("service unavailable") || text.includes("excedi\xF3 el tiempo de espera");
|
|
236
|
+
}
|
|
237
|
+
async function withRetry(operation, options = {}) {
|
|
238
|
+
const {
|
|
239
|
+
maxRetries = 3,
|
|
240
|
+
initialDelayMs = 800,
|
|
241
|
+
maxDelayMs = 1e4,
|
|
242
|
+
factor = 1.5,
|
|
243
|
+
shouldRetry = shouldRetryJumio,
|
|
244
|
+
signal,
|
|
245
|
+
onRetry
|
|
246
|
+
} = options;
|
|
247
|
+
let lastError;
|
|
248
|
+
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
|
249
|
+
if (signal?.aborted) {
|
|
250
|
+
throw new JumioAbortError();
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
return await operation(attempt);
|
|
254
|
+
} catch (error) {
|
|
255
|
+
lastError = error;
|
|
256
|
+
if (signal?.aborted) {
|
|
257
|
+
throw new JumioAbortError();
|
|
258
|
+
}
|
|
259
|
+
const isLastAttempt = attempt >= maxRetries;
|
|
260
|
+
const isRetryable = shouldRetry(error);
|
|
261
|
+
if (isLastAttempt || !isRetryable) {
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
const currentDelay = Math.min(
|
|
265
|
+
Math.round(initialDelayMs * Math.pow(factor, attempt - 1)),
|
|
266
|
+
maxDelayMs
|
|
267
|
+
);
|
|
268
|
+
onRetry?.(attempt, error, currentDelay);
|
|
269
|
+
await delay(currentDelay, signal);
|
|
270
|
+
}
|
|
137
271
|
}
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
272
|
+
throw lastError;
|
|
273
|
+
}
|
|
274
|
+
var init_retry = __esm({
|
|
275
|
+
"src/core/retry.ts"() {
|
|
276
|
+
init_envelope();
|
|
277
|
+
init_errors();
|
|
143
278
|
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
// src/core/webflow.ts
|
|
282
|
+
var webflow_exports = {};
|
|
283
|
+
__export(webflow_exports, {
|
|
284
|
+
buildRedirectUrl: () => buildRedirectUrl,
|
|
285
|
+
parseWebflowReturnParams: () => parseWebflowReturnParams,
|
|
286
|
+
pollWebflowStatus: () => pollWebflowStatus,
|
|
287
|
+
resolveWebflowResult: () => resolveWebflowResult,
|
|
288
|
+
startWebflowSession: () => startWebflowSession
|
|
289
|
+
});
|
|
290
|
+
function buildRedirectUrl(returnUrl, proxyUrl) {
|
|
291
|
+
if (!proxyUrl) {
|
|
292
|
+
return returnUrl;
|
|
149
293
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
this.name = "JumioPollingTimeoutError";
|
|
156
|
-
this.attempts = attempts;
|
|
294
|
+
const encoded = encodeUrlToBase64UrlSafe(returnUrl);
|
|
295
|
+
if (!encoded) {
|
|
296
|
+
throw new JumioValidationError(
|
|
297
|
+
`No fue posible codificar la URL de retorno: "${returnUrl}"`
|
|
298
|
+
);
|
|
157
299
|
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
300
|
+
const normalizedProxy = proxyUrl.endsWith("/") ? proxyUrl : `${proxyUrl}/`;
|
|
301
|
+
return `${normalizedProxy}${encoded}`;
|
|
302
|
+
}
|
|
303
|
+
function parseWebflowReturnParams(source) {
|
|
304
|
+
let searchString;
|
|
305
|
+
if (!source) {
|
|
306
|
+
if (typeof window !== "undefined" && window.location) {
|
|
307
|
+
searchString = window.location.search;
|
|
308
|
+
} else {
|
|
309
|
+
return { allParams: {} };
|
|
310
|
+
}
|
|
311
|
+
} else if (typeof source === "string") {
|
|
312
|
+
const questionIdx = source.indexOf("?");
|
|
313
|
+
searchString = questionIdx >= 0 ? source.slice(questionIdx) : "";
|
|
314
|
+
} else if (source instanceof URLSearchParams) {
|
|
315
|
+
searchString = `?${source.toString()}`;
|
|
316
|
+
} else {
|
|
317
|
+
const hrefSearch = source.href ? (() => {
|
|
318
|
+
try {
|
|
319
|
+
return new URL(source.href).search;
|
|
320
|
+
} catch {
|
|
321
|
+
return "";
|
|
322
|
+
}
|
|
323
|
+
})() : "";
|
|
324
|
+
searchString = source.search ?? hrefSearch;
|
|
163
325
|
}
|
|
164
|
-
|
|
326
|
+
const params = new URLSearchParams(searchString);
|
|
327
|
+
const allParams = {};
|
|
328
|
+
params.forEach((value, key) => {
|
|
329
|
+
allParams[key] = value;
|
|
330
|
+
});
|
|
331
|
+
const accountId = params.get("accountId") ?? void 0;
|
|
332
|
+
let workflowId = params.get("workflowExecutionId") ?? params.get("workflowId") ?? void 0;
|
|
333
|
+
const rawStatus = params.get("status") ?? void 0;
|
|
334
|
+
if (rawStatus && (!accountId || !workflowId)) {
|
|
335
|
+
const statusParts = rawStatus.split("?");
|
|
336
|
+
const nestedSearch = statusParts.length > 1 ? `?${statusParts.slice(1).join("?")}` : "";
|
|
337
|
+
if (nestedSearch && nestedSearch !== "?") {
|
|
338
|
+
const nestedParams = new URLSearchParams(nestedSearch);
|
|
339
|
+
nestedParams.forEach((value, key) => {
|
|
340
|
+
if (!allParams[key]) allParams[key] = value;
|
|
341
|
+
});
|
|
342
|
+
if (!workflowId) {
|
|
343
|
+
workflowId = nestedParams.get("workflowExecutionId") ?? nestedParams.get("workflowId") ?? workflowId;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
return {
|
|
348
|
+
accountId: accountId || void 0,
|
|
349
|
+
workflowId: workflowId || void 0,
|
|
350
|
+
rawStatus,
|
|
351
|
+
allParams
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
function resolveWebflowResult(rawData, accountId, workflowId) {
|
|
355
|
+
if (!rawData || typeof rawData !== "object") return null;
|
|
356
|
+
const data = rawData;
|
|
357
|
+
if (data.valid === true) {
|
|
358
|
+
return {
|
|
359
|
+
valid: true,
|
|
360
|
+
status: String(data.workflowStatus ?? data.status ?? "APPROVED_VERIFIED"),
|
|
361
|
+
decision: data.decision,
|
|
362
|
+
extraction: data.extraction,
|
|
363
|
+
accountId,
|
|
364
|
+
workflowId,
|
|
365
|
+
data: rawData
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
if (data.valid === false) {
|
|
369
|
+
return {
|
|
370
|
+
valid: false,
|
|
371
|
+
status: String(data.workflowStatus ?? data.status ?? "REJECTED"),
|
|
372
|
+
decision: data.decision,
|
|
373
|
+
accountId,
|
|
374
|
+
workflowId,
|
|
375
|
+
data: rawData,
|
|
376
|
+
errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado durante la verificacion."
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
const capData = data;
|
|
380
|
+
const decisionType = capData?.decision?.type;
|
|
381
|
+
const extractionArr = capData?.capabilities?.extraction ?? [];
|
|
382
|
+
const extraction = extractionArr[0];
|
|
383
|
+
const isExtractionEmpty = extraction !== void 0 && Object.keys(extraction).length === 0;
|
|
384
|
+
if (decisionType === "REJECTED") {
|
|
385
|
+
return {
|
|
386
|
+
valid: false,
|
|
387
|
+
status: "REJECTED",
|
|
388
|
+
decision: decisionType,
|
|
389
|
+
accountId,
|
|
390
|
+
workflowId,
|
|
391
|
+
data: rawData,
|
|
392
|
+
errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado por Jumio."
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
if (extraction && !isExtractionEmpty) {
|
|
396
|
+
const isApproved = decisionType === "PASSED" || decisionType === "WARNING";
|
|
397
|
+
return {
|
|
398
|
+
valid: isApproved,
|
|
399
|
+
status: isApproved ? decisionType ?? "PASSED" : decisionType ?? "REJECTED",
|
|
400
|
+
decision: decisionType,
|
|
401
|
+
extraction,
|
|
402
|
+
accountId,
|
|
403
|
+
workflowId,
|
|
404
|
+
data: rawData,
|
|
405
|
+
...!isApproved ? {
|
|
406
|
+
errorMessage: extractJumioMessage(rawData) || "La verificacion no fue aprobada."
|
|
407
|
+
} : {}
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
async function pollWebflowStatus(http, params, options = {}) {
|
|
413
|
+
const config = http.getConfig();
|
|
414
|
+
const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
|
|
415
|
+
const intervalMs = options.pollingIntervalMs ?? config.pollingIntervalMs ?? 1e4;
|
|
416
|
+
const signal = options.signal;
|
|
417
|
+
let lastRawData = {};
|
|
418
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
419
|
+
if (signal?.aborted) {
|
|
420
|
+
throw new JumioAbortError();
|
|
421
|
+
}
|
|
422
|
+
const responseData = await withRetry(
|
|
423
|
+
() => http.getVerificationStatus(params.accountId, params.workflowId, {
|
|
424
|
+
signal,
|
|
425
|
+
timeout: config.statusTimeout,
|
|
426
|
+
clientId: params.clientId
|
|
427
|
+
}),
|
|
428
|
+
{
|
|
429
|
+
maxRetries: config.maxRetries ?? 3,
|
|
430
|
+
initialDelayMs: config.retryDelayMs ?? 800,
|
|
431
|
+
signal
|
|
432
|
+
}
|
|
433
|
+
);
|
|
434
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
435
|
+
const statusData = extractNestedData(firstLevel) ?? {};
|
|
436
|
+
lastRawData = statusData;
|
|
437
|
+
options.onAttempt?.(attempt, maxAttempts, statusData);
|
|
438
|
+
const result = resolveWebflowResult(
|
|
439
|
+
statusData,
|
|
440
|
+
params.accountId,
|
|
441
|
+
params.workflowId
|
|
442
|
+
);
|
|
443
|
+
if (result !== null) {
|
|
444
|
+
return result;
|
|
445
|
+
}
|
|
446
|
+
if (attempt < maxAttempts) {
|
|
447
|
+
await delay(intervalMs, signal);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
const lastMessage = extractJumioMessage(lastRawData) || "La verificacion Jumio sigue en proceso. Intenta nuevamente en unos momentos.";
|
|
451
|
+
throw new JumioPollingTimeoutError(maxAttempts, lastMessage, lastRawData);
|
|
452
|
+
}
|
|
453
|
+
async function startWebflowSession(http, config, input) {
|
|
454
|
+
const {
|
|
455
|
+
clientId,
|
|
456
|
+
successUrl,
|
|
457
|
+
errorUrl,
|
|
458
|
+
useRedirectProxy = false,
|
|
459
|
+
autoRedirect = false,
|
|
460
|
+
openInNewTab = false,
|
|
461
|
+
signal
|
|
462
|
+
} = input;
|
|
463
|
+
if (!clientId?.trim()) {
|
|
464
|
+
throw new JumioValidationError(
|
|
465
|
+
"Se requiere un identificador de cliente valido (clientId)."
|
|
466
|
+
);
|
|
467
|
+
}
|
|
468
|
+
if (!successUrl?.trim()) {
|
|
469
|
+
throw new JumioValidationError("Se requiere la URL de exito (successUrl).");
|
|
470
|
+
}
|
|
471
|
+
if (!errorUrl?.trim()) {
|
|
472
|
+
throw new JumioValidationError("Se requiere la URL de error (errorUrl).");
|
|
473
|
+
}
|
|
474
|
+
if (signal?.aborted) {
|
|
475
|
+
throw new JumioAbortError();
|
|
476
|
+
}
|
|
477
|
+
const proxyUrl = useRedirectProxy ? config.redirectProxyUrl ?? void 0 : void 0;
|
|
478
|
+
const finalSuccessUrl = buildRedirectUrl(successUrl, proxyUrl);
|
|
479
|
+
const finalErrorUrl = buildRedirectUrl(errorUrl, proxyUrl);
|
|
480
|
+
try {
|
|
481
|
+
const responseData = await withRetry(
|
|
482
|
+
() => http.postVerification(
|
|
483
|
+
{
|
|
484
|
+
client: clientId.trim(),
|
|
485
|
+
successUrl: finalSuccessUrl,
|
|
486
|
+
errorUrl: finalErrorUrl
|
|
487
|
+
},
|
|
488
|
+
{ signal, timeout: config.requestTimeout }
|
|
489
|
+
),
|
|
490
|
+
{
|
|
491
|
+
maxRetries: config.maxRetries ?? 3,
|
|
492
|
+
initialDelayMs: config.retryDelayMs ?? 800,
|
|
493
|
+
signal
|
|
494
|
+
}
|
|
495
|
+
);
|
|
496
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
497
|
+
const payload = extractNestedData(firstLevel) ?? {};
|
|
498
|
+
const href = payload?.href;
|
|
499
|
+
if (!href) {
|
|
500
|
+
throw new JumioError(
|
|
501
|
+
extractJumioMessage(payload) || "El backend no devolvio la URL de verificacion de Jumio (href).",
|
|
502
|
+
{ rawData: payload }
|
|
503
|
+
);
|
|
504
|
+
}
|
|
505
|
+
const result = {
|
|
506
|
+
href,
|
|
507
|
+
accountId: payload?.accountId,
|
|
508
|
+
workflowId: payload?.workflowId,
|
|
509
|
+
data: payload
|
|
510
|
+
};
|
|
511
|
+
if (typeof window !== "undefined") {
|
|
512
|
+
if (openInNewTab) {
|
|
513
|
+
const win = window.open(href, "_blank");
|
|
514
|
+
if (!win || win.closed || typeof win.closed === "undefined") {
|
|
515
|
+
window.location.href = href;
|
|
516
|
+
}
|
|
517
|
+
} else if (autoRedirect) {
|
|
518
|
+
window.location.href = href;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return result;
|
|
522
|
+
} catch (err) {
|
|
523
|
+
throw err;
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
var init_webflow = __esm({
|
|
527
|
+
"src/core/webflow.ts"() {
|
|
528
|
+
init_envelope();
|
|
529
|
+
init_errors();
|
|
530
|
+
init_retry();
|
|
531
|
+
}
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// src/core/client.ts
|
|
535
|
+
init_envelope();
|
|
536
|
+
init_errors();
|
|
537
|
+
|
|
538
|
+
// src/core/http.ts
|
|
539
|
+
init_errors();
|
|
540
|
+
init_envelope();
|
|
165
541
|
var JumioHttpClient = class {
|
|
166
542
|
client;
|
|
167
543
|
config;
|
|
@@ -277,6 +653,7 @@ var JumioHttpClient = class {
|
|
|
277
653
|
}
|
|
278
654
|
/**
|
|
279
655
|
* Ejecuta una petición GET para consultar el estado actual de una verificación de INE.
|
|
656
|
+
* Soporta un `clientId` opcional requerido por algunos endpoints de DynamiCore (p. ej. Hosted Webflow).
|
|
280
657
|
*/
|
|
281
658
|
async getVerificationStatus(accountId, workflowId, options) {
|
|
282
659
|
if (options?.signal?.aborted) {
|
|
@@ -286,12 +663,16 @@ var JumioHttpClient = class {
|
|
|
286
663
|
const dynamicHeaders = await this.resolveHeaders();
|
|
287
664
|
const endpoint = this.config.endpoint || "/marketplace/apps/jumio";
|
|
288
665
|
const timeout = options?.timeout ?? this.config.statusTimeout ?? 12e4;
|
|
666
|
+
const queryParams = {
|
|
667
|
+
type: "ine",
|
|
668
|
+
accountId,
|
|
669
|
+
workflowId
|
|
670
|
+
};
|
|
671
|
+
if (options?.clientId) {
|
|
672
|
+
queryParams.clientId = options.clientId;
|
|
673
|
+
}
|
|
289
674
|
const response = await this.client.get(endpoint, {
|
|
290
|
-
params:
|
|
291
|
-
type: "ine",
|
|
292
|
-
accountId,
|
|
293
|
-
workflowId
|
|
294
|
-
},
|
|
675
|
+
params: queryParams,
|
|
295
676
|
headers: dynamicHeaders,
|
|
296
677
|
timeout,
|
|
297
678
|
signal: options?.signal
|
|
@@ -307,6 +688,7 @@ var JumioHttpClient = class {
|
|
|
307
688
|
};
|
|
308
689
|
|
|
309
690
|
// src/core/image.ts
|
|
691
|
+
init_errors();
|
|
310
692
|
function stripDataUrlPrefix(dataUrl) {
|
|
311
693
|
if (!dataUrl) return "";
|
|
312
694
|
const commaIndex = dataUrl.indexOf(",");
|
|
@@ -463,78 +845,10 @@ async function resolveImageSourceToBase64(source, s3Signer, signal) {
|
|
|
463
845
|
throw new JumioImageProcessingError("Tipo de dato de imagen no soportado.");
|
|
464
846
|
}
|
|
465
847
|
|
|
466
|
-
// src/core/retry.ts
|
|
467
|
-
function delay(ms, signal) {
|
|
468
|
-
return new Promise((resolve, reject) => {
|
|
469
|
-
if (signal?.aborted) {
|
|
470
|
-
return reject(new JumioAbortError());
|
|
471
|
-
}
|
|
472
|
-
const timer = setTimeout(() => {
|
|
473
|
-
signal?.removeEventListener("abort", abortHandler);
|
|
474
|
-
resolve();
|
|
475
|
-
}, ms);
|
|
476
|
-
const abortHandler = () => {
|
|
477
|
-
clearTimeout(timer);
|
|
478
|
-
reject(new JumioAbortError());
|
|
479
|
-
};
|
|
480
|
-
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
481
|
-
});
|
|
482
|
-
}
|
|
483
|
-
function shouldRetryJumio(errorOrMessage) {
|
|
484
|
-
if (!errorOrMessage) return false;
|
|
485
|
-
const text = toLowerText(
|
|
486
|
-
typeof errorOrMessage === "string" ? errorOrMessage : extractJumioMessage(errorOrMessage)
|
|
487
|
-
);
|
|
488
|
-
const errorObj = errorOrMessage;
|
|
489
|
-
const status = errorObj?.status || errorObj?.response?.status;
|
|
490
|
-
const code = String(errorObj?.code || "").toUpperCase();
|
|
491
|
-
if (status === 408 || status === 502 || status === 503 || status === 504) {
|
|
492
|
-
return true;
|
|
493
|
-
}
|
|
494
|
-
if (code === "ECONNABORTED" || code === "ETIMEDOUT" || code === "ECONNRESET" || code === "EAI_AGAIN") {
|
|
495
|
-
return true;
|
|
496
|
-
}
|
|
497
|
-
return text.includes("timed out") || text.includes("timeout") || text.includes("temporarily unavailable") || text.includes("network error") || text.includes("socket hang up") || text.includes("gateway timeout") || text.includes("service unavailable") || text.includes("excedi\xF3 el tiempo de espera");
|
|
498
|
-
}
|
|
499
|
-
async function withRetry(operation, options = {}) {
|
|
500
|
-
const {
|
|
501
|
-
maxRetries = 3,
|
|
502
|
-
initialDelayMs = 800,
|
|
503
|
-
maxDelayMs = 1e4,
|
|
504
|
-
factor = 1.5,
|
|
505
|
-
shouldRetry = shouldRetryJumio,
|
|
506
|
-
signal,
|
|
507
|
-
onRetry
|
|
508
|
-
} = options;
|
|
509
|
-
let lastError;
|
|
510
|
-
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
|
511
|
-
if (signal?.aborted) {
|
|
512
|
-
throw new JumioAbortError();
|
|
513
|
-
}
|
|
514
|
-
try {
|
|
515
|
-
return await operation(attempt);
|
|
516
|
-
} catch (error) {
|
|
517
|
-
lastError = error;
|
|
518
|
-
if (signal?.aborted) {
|
|
519
|
-
throw new JumioAbortError();
|
|
520
|
-
}
|
|
521
|
-
const isLastAttempt = attempt >= maxRetries;
|
|
522
|
-
const isRetryable = shouldRetry(error);
|
|
523
|
-
if (isLastAttempt || !isRetryable) {
|
|
524
|
-
throw error;
|
|
525
|
-
}
|
|
526
|
-
const currentDelay = Math.min(
|
|
527
|
-
Math.round(initialDelayMs * Math.pow(factor, attempt - 1)),
|
|
528
|
-
maxDelayMs
|
|
529
|
-
);
|
|
530
|
-
onRetry?.(attempt, error, currentDelay);
|
|
531
|
-
await delay(currentDelay, signal);
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
throw lastError;
|
|
535
|
-
}
|
|
536
|
-
|
|
537
848
|
// src/core/polling.ts
|
|
849
|
+
init_envelope();
|
|
850
|
+
init_errors();
|
|
851
|
+
init_retry();
|
|
538
852
|
async function pollJumioStatus(http, accountId, workflowId, options = {}) {
|
|
539
853
|
const config = http.getConfig();
|
|
540
854
|
const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
|
|
@@ -591,6 +905,8 @@ async function pollJumioStatus(http, accountId, workflowId, options = {}) {
|
|
|
591
905
|
}
|
|
592
906
|
|
|
593
907
|
// src/core/client.ts
|
|
908
|
+
init_retry();
|
|
909
|
+
init_webflow();
|
|
594
910
|
var JumioClient = class {
|
|
595
911
|
http;
|
|
596
912
|
config;
|
|
@@ -730,9 +1046,109 @@ var JumioClient = class {
|
|
|
730
1046
|
onStatusResolved?.(finalResult);
|
|
731
1047
|
return finalResult;
|
|
732
1048
|
}
|
|
1049
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1050
|
+
// Hosted Webflow (Redirección)
|
|
1051
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1052
|
+
/**
|
|
1053
|
+
* Construye la URL de redirección de retorno para el flujo Hosted Webflow.
|
|
1054
|
+
*
|
|
1055
|
+
* Si el cliente está configurado con un `redirectProxyUrl` y `useProxy` es `true`,
|
|
1056
|
+
* la URL de retorno se codifica en Base64 URL-safe y se adjunta al proxy.
|
|
1057
|
+
*
|
|
1058
|
+
* @param returnUrl URL de la aplicación a la que Jumio redirigirá tras la verificación.
|
|
1059
|
+
* @param useProxy Si es `true` y hay `redirectProxyUrl` configurado, usa el proxy.
|
|
1060
|
+
* @returns URL de redirección construida.
|
|
1061
|
+
*/
|
|
1062
|
+
buildRedirectUrl(returnUrl, useProxy = false) {
|
|
1063
|
+
const proxyUrl = useProxy ? this.config.redirectProxyUrl ?? void 0 : void 0;
|
|
1064
|
+
return buildRedirectUrl(returnUrl, proxyUrl);
|
|
1065
|
+
}
|
|
1066
|
+
/**
|
|
1067
|
+
* Inicia el flujo Hosted Webflow solicitando al backend de DynamiCore la URL
|
|
1068
|
+
* de verificación de Jumio (`href`).
|
|
1069
|
+
*
|
|
1070
|
+
* El usuario debe ser redirigido a esa URL para completar la verificación en la
|
|
1071
|
+
* página oficial de Jumio. Al terminar, Jumio redirige de vuelta a la aplicación
|
|
1072
|
+
* con `accountId` y `workflowExecutionId` como query params.
|
|
1073
|
+
*
|
|
1074
|
+
* @param input Parámetros del flujo: `clientId`, `successUrl`, `errorUrl`, opciones de proxy y redirección.
|
|
1075
|
+
* @returns `StartWebflowResult` con la URL de Jumio (`href`) y datos adicionales.
|
|
1076
|
+
*
|
|
1077
|
+
* @example
|
|
1078
|
+
* ```ts
|
|
1079
|
+
* const { href } = await client.startWebflow({
|
|
1080
|
+
* clientId: "usr_123",
|
|
1081
|
+
* successUrl: "https://app.example.com/verify/success",
|
|
1082
|
+
* errorUrl: "https://app.example.com/verify/error",
|
|
1083
|
+
* });
|
|
1084
|
+
* window.location.href = href;
|
|
1085
|
+
* ```
|
|
1086
|
+
*/
|
|
1087
|
+
async startWebflow(input) {
|
|
1088
|
+
return startWebflowSession(this.http, this.config, input);
|
|
1089
|
+
}
|
|
1090
|
+
/**
|
|
1091
|
+
* Extrae los parámetros de seguimiento de Jumio de la URL de retorno.
|
|
1092
|
+
*
|
|
1093
|
+
* Jumio añade `accountId` y `workflowExecutionId` (o `workflowId`) como query
|
|
1094
|
+
* params al redirigir de vuelta a la aplicación tras la verificación.
|
|
1095
|
+
*
|
|
1096
|
+
* @param source URL completa, `URLSearchParams`, objeto con `search`/`href`, o nada para leer `window.location`.
|
|
1097
|
+
* @returns `WebflowReturnParams` con `accountId`, `workflowId`, `rawStatus` y todos los params.
|
|
1098
|
+
*
|
|
1099
|
+
* @example En React, en el componente de retorno:
|
|
1100
|
+
* ```ts
|
|
1101
|
+
* const { accountId, workflowId } = client.parseWebflowReturnParams(window.location.href);
|
|
1102
|
+
* ```
|
|
1103
|
+
*/
|
|
1104
|
+
parseWebflowReturnParams(source) {
|
|
1105
|
+
return parseWebflowReturnParams(source);
|
|
1106
|
+
}
|
|
1107
|
+
/**
|
|
1108
|
+
* Consulta una única vez el estado actual de la verificación del flujo Hosted Webflow.
|
|
1109
|
+
*
|
|
1110
|
+
* @param input Parámetros de consulta: `accountId`, `workflowId`, y `clientId` opcional.
|
|
1111
|
+
* @returns `WebflowResult | null` — `null` si la verificación aún está pendiente.
|
|
1112
|
+
*/
|
|
1113
|
+
async getWebflowStatus(input) {
|
|
1114
|
+
const { accountId, workflowId, clientId, signal } = input;
|
|
1115
|
+
const responseData = await this.http.getVerificationStatus(accountId, workflowId, {
|
|
1116
|
+
signal,
|
|
1117
|
+
timeout: this.config.statusTimeout,
|
|
1118
|
+
clientId
|
|
1119
|
+
});
|
|
1120
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
1121
|
+
const statusData = extractNestedData(firstLevel) ?? {};
|
|
1122
|
+
const { resolveWebflowResult: resolveWebflowResult2 } = await Promise.resolve().then(() => (init_webflow(), webflow_exports));
|
|
1123
|
+
return resolveWebflowResult2(statusData, accountId, workflowId);
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* Sondea periódicamente el estado de verificación de un flujo Hosted Webflow de Jumio.
|
|
1127
|
+
*
|
|
1128
|
+
* Continúa consultando hasta obtener un resultado definitivo o agotar los intentos.
|
|
1129
|
+
*
|
|
1130
|
+
* @param params `accountId`, `workflowId` y `clientId` opcional.
|
|
1131
|
+
* @param options Opciones de sondeo (`maxAttempts`, `pollingIntervalMs`, `signal`, `onAttempt`).
|
|
1132
|
+
* @returns `WebflowResult` con el resultado definitivo.
|
|
1133
|
+
*
|
|
1134
|
+
* @example
|
|
1135
|
+
* ```ts
|
|
1136
|
+
* // En el componente de retorno, tras leer los params de la URL:
|
|
1137
|
+
* const result = await client.pollWebflowStatus({ accountId, workflowId, clientId });
|
|
1138
|
+
* if (result.valid) {
|
|
1139
|
+
* console.log("Verificación aprobada:", result.extraction);
|
|
1140
|
+
* } else {
|
|
1141
|
+
* console.warn("Rechazado:", result.errorMessage);
|
|
1142
|
+
* }
|
|
1143
|
+
* ```
|
|
1144
|
+
*/
|
|
1145
|
+
async pollWebflowStatus(params, options) {
|
|
1146
|
+
return pollWebflowStatus(this.http, params, options);
|
|
1147
|
+
}
|
|
733
1148
|
};
|
|
734
1149
|
|
|
735
1150
|
// src/react/useJumioVerification.ts
|
|
1151
|
+
init_errors();
|
|
736
1152
|
var INITIAL_STATE = {
|
|
737
1153
|
isSubmitting: false,
|
|
738
1154
|
isPolling: false,
|
|
@@ -884,6 +1300,13 @@ function useJumioVerification(options = {}) {
|
|
|
884
1300
|
};
|
|
885
1301
|
const handleError = (err) => {
|
|
886
1302
|
if (err instanceof JumioAbortError) {
|
|
1303
|
+
setState((prev) => ({
|
|
1304
|
+
...prev,
|
|
1305
|
+
isSubmitting: false,
|
|
1306
|
+
isPolling: false,
|
|
1307
|
+
isLoading: false,
|
|
1308
|
+
stage: "CANCELLED"
|
|
1309
|
+
}));
|
|
887
1310
|
return;
|
|
888
1311
|
}
|
|
889
1312
|
setState((prev) => ({
|
|
@@ -947,7 +1370,208 @@ function useJumioVerification(options = {}) {
|
|
|
947
1370
|
client
|
|
948
1371
|
};
|
|
949
1372
|
}
|
|
1373
|
+
init_errors();
|
|
1374
|
+
var INITIAL_STATE2 = {
|
|
1375
|
+
isStarting: false,
|
|
1376
|
+
isChecking: false,
|
|
1377
|
+
isLoading: false,
|
|
1378
|
+
result: null,
|
|
1379
|
+
error: null,
|
|
1380
|
+
isValid: false,
|
|
1381
|
+
isRejected: false
|
|
1382
|
+
};
|
|
1383
|
+
function useJumioWebflow(options = {}) {
|
|
1384
|
+
const {
|
|
1385
|
+
client: customClient,
|
|
1386
|
+
baseUrl,
|
|
1387
|
+
endpoint,
|
|
1388
|
+
context,
|
|
1389
|
+
authToken,
|
|
1390
|
+
authTokenPrefix,
|
|
1391
|
+
requestTimeout,
|
|
1392
|
+
statusTimeout,
|
|
1393
|
+
maxRetries,
|
|
1394
|
+
retryDelayMs,
|
|
1395
|
+
pollingIntervalMs,
|
|
1396
|
+
maxPollingAttempts,
|
|
1397
|
+
redirectProxyUrl,
|
|
1398
|
+
s3Signer,
|
|
1399
|
+
customHeaders,
|
|
1400
|
+
axiosInstance,
|
|
1401
|
+
onResult: globalOnResult,
|
|
1402
|
+
onError: globalOnError
|
|
1403
|
+
} = options;
|
|
1404
|
+
const client = react.useMemo(() => {
|
|
1405
|
+
if (customClient) return customClient;
|
|
1406
|
+
return new JumioClient({
|
|
1407
|
+
baseUrl,
|
|
1408
|
+
endpoint,
|
|
1409
|
+
context,
|
|
1410
|
+
authToken,
|
|
1411
|
+
authTokenPrefix,
|
|
1412
|
+
requestTimeout,
|
|
1413
|
+
statusTimeout,
|
|
1414
|
+
maxRetries,
|
|
1415
|
+
retryDelayMs,
|
|
1416
|
+
pollingIntervalMs,
|
|
1417
|
+
maxPollingAttempts,
|
|
1418
|
+
redirectProxyUrl,
|
|
1419
|
+
s3Signer,
|
|
1420
|
+
customHeaders,
|
|
1421
|
+
axiosInstance
|
|
1422
|
+
});
|
|
1423
|
+
}, [
|
|
1424
|
+
customClient,
|
|
1425
|
+
baseUrl,
|
|
1426
|
+
endpoint,
|
|
1427
|
+
context,
|
|
1428
|
+
authToken,
|
|
1429
|
+
authTokenPrefix,
|
|
1430
|
+
requestTimeout,
|
|
1431
|
+
statusTimeout,
|
|
1432
|
+
maxRetries,
|
|
1433
|
+
retryDelayMs,
|
|
1434
|
+
pollingIntervalMs,
|
|
1435
|
+
maxPollingAttempts,
|
|
1436
|
+
redirectProxyUrl,
|
|
1437
|
+
s3Signer,
|
|
1438
|
+
customHeaders,
|
|
1439
|
+
axiosInstance
|
|
1440
|
+
]);
|
|
1441
|
+
const [state, setState] = react.useState(INITIAL_STATE2);
|
|
1442
|
+
const abortControllerRef = react.useRef(null);
|
|
1443
|
+
const callbacksRef = react.useRef({ onResult: globalOnResult, onError: globalOnError });
|
|
1444
|
+
react.useEffect(() => {
|
|
1445
|
+
callbacksRef.current = { onResult: globalOnResult, onError: globalOnError };
|
|
1446
|
+
}, [globalOnResult, globalOnError]);
|
|
1447
|
+
react.useEffect(() => {
|
|
1448
|
+
return () => {
|
|
1449
|
+
abortControllerRef.current?.abort();
|
|
1450
|
+
};
|
|
1451
|
+
}, []);
|
|
1452
|
+
const cancel = react.useCallback(() => {
|
|
1453
|
+
abortControllerRef.current?.abort();
|
|
1454
|
+
abortControllerRef.current = null;
|
|
1455
|
+
setState((prev) => ({
|
|
1456
|
+
...prev,
|
|
1457
|
+
isStarting: false,
|
|
1458
|
+
isChecking: false,
|
|
1459
|
+
isLoading: false
|
|
1460
|
+
}));
|
|
1461
|
+
}, []);
|
|
1462
|
+
const reset = react.useCallback(() => {
|
|
1463
|
+
cancel();
|
|
1464
|
+
setState(INITIAL_STATE2);
|
|
1465
|
+
}, [cancel]);
|
|
1466
|
+
const handleError = react.useCallback((err) => {
|
|
1467
|
+
if (err instanceof JumioAbortError) {
|
|
1468
|
+
setState((prev) => ({
|
|
1469
|
+
...prev,
|
|
1470
|
+
isStarting: false,
|
|
1471
|
+
isChecking: false,
|
|
1472
|
+
isLoading: false
|
|
1473
|
+
}));
|
|
1474
|
+
return;
|
|
1475
|
+
}
|
|
1476
|
+
setState((prev) => ({
|
|
1477
|
+
...prev,
|
|
1478
|
+
isStarting: false,
|
|
1479
|
+
isChecking: false,
|
|
1480
|
+
isLoading: false,
|
|
1481
|
+
error: err,
|
|
1482
|
+
isRejected: true
|
|
1483
|
+
}));
|
|
1484
|
+
callbacksRef.current.onError?.(err);
|
|
1485
|
+
}, []);
|
|
1486
|
+
const handleResult = react.useCallback((result) => {
|
|
1487
|
+
setState((prev) => ({
|
|
1488
|
+
...prev,
|
|
1489
|
+
isChecking: false,
|
|
1490
|
+
isLoading: false,
|
|
1491
|
+
result,
|
|
1492
|
+
isValid: result.valid,
|
|
1493
|
+
isRejected: !result.valid,
|
|
1494
|
+
error: result.valid ? null : new Error(result.errorMessage ?? "Verificacion de identidad rechazada")
|
|
1495
|
+
}));
|
|
1496
|
+
callbacksRef.current.onResult?.(result);
|
|
1497
|
+
}, []);
|
|
1498
|
+
const startWebflow = react.useCallback(
|
|
1499
|
+
async (input) => {
|
|
1500
|
+
if (abortControllerRef.current) {
|
|
1501
|
+
abortControllerRef.current.abort();
|
|
1502
|
+
}
|
|
1503
|
+
const controller = new AbortController();
|
|
1504
|
+
abortControllerRef.current = controller;
|
|
1505
|
+
setState({
|
|
1506
|
+
...INITIAL_STATE2,
|
|
1507
|
+
isStarting: true,
|
|
1508
|
+
isLoading: true
|
|
1509
|
+
});
|
|
1510
|
+
try {
|
|
1511
|
+
const result = await client.startWebflow({
|
|
1512
|
+
...input,
|
|
1513
|
+
signal: input.signal ?? controller.signal
|
|
1514
|
+
});
|
|
1515
|
+
setState((prev) => ({
|
|
1516
|
+
...prev,
|
|
1517
|
+
isStarting: false,
|
|
1518
|
+
isLoading: false
|
|
1519
|
+
}));
|
|
1520
|
+
return result;
|
|
1521
|
+
} catch (err) {
|
|
1522
|
+
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
1523
|
+
handleError(normalizedError);
|
|
1524
|
+
throw normalizedError;
|
|
1525
|
+
}
|
|
1526
|
+
},
|
|
1527
|
+
[client, handleError]
|
|
1528
|
+
);
|
|
1529
|
+
const checkResult = react.useCallback(
|
|
1530
|
+
async (params, pollOptions) => {
|
|
1531
|
+
if (abortControllerRef.current) {
|
|
1532
|
+
abortControllerRef.current.abort();
|
|
1533
|
+
}
|
|
1534
|
+
const controller = new AbortController();
|
|
1535
|
+
abortControllerRef.current = controller;
|
|
1536
|
+
setState((prev) => ({
|
|
1537
|
+
...prev,
|
|
1538
|
+
isChecking: true,
|
|
1539
|
+
isLoading: true,
|
|
1540
|
+
error: null
|
|
1541
|
+
}));
|
|
1542
|
+
try {
|
|
1543
|
+
const result = await client.pollWebflowStatus(params, {
|
|
1544
|
+
...pollOptions,
|
|
1545
|
+
signal: pollOptions?.signal ?? controller.signal
|
|
1546
|
+
});
|
|
1547
|
+
handleResult(result);
|
|
1548
|
+
return result;
|
|
1549
|
+
} catch (err) {
|
|
1550
|
+
const normalizedError = err instanceof Error ? err : new Error(String(err));
|
|
1551
|
+
handleError(normalizedError);
|
|
1552
|
+
throw normalizedError;
|
|
1553
|
+
}
|
|
1554
|
+
},
|
|
1555
|
+
[client, handleResult, handleError]
|
|
1556
|
+
);
|
|
1557
|
+
const parseReturnParams = react.useCallback(
|
|
1558
|
+
(source) => {
|
|
1559
|
+
return client.parseWebflowReturnParams(source);
|
|
1560
|
+
},
|
|
1561
|
+
[client]
|
|
1562
|
+
);
|
|
1563
|
+
return {
|
|
1564
|
+
...state,
|
|
1565
|
+
startWebflow,
|
|
1566
|
+
checkResult,
|
|
1567
|
+
parseReturnParams,
|
|
1568
|
+
cancel,
|
|
1569
|
+
reset,
|
|
1570
|
+
client
|
|
1571
|
+
};
|
|
1572
|
+
}
|
|
950
1573
|
|
|
951
1574
|
exports.useJumioVerification = useJumioVerification;
|
|
1575
|
+
exports.useJumioWebflow = useJumioWebflow;
|
|
952
1576
|
//# sourceMappingURL=index.js.map
|
|
953
1577
|
//# sourceMappingURL=index.js.map
|