@dynamicore/jumio-sdk 1.0.0 → 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 +238 -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/core/index.js
CHANGED
|
@@ -6,86 +6,81 @@ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
|
6
6
|
|
|
7
7
|
var axios__default = /*#__PURE__*/_interopDefault(axios);
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
var
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
rawData;
|
|
14
|
-
code;
|
|
15
|
-
constructor(message, options) {
|
|
16
|
-
super(message);
|
|
17
|
-
this.name = "JumioError";
|
|
18
|
-
this.statusCode = options?.statusCode;
|
|
19
|
-
this.rawData = options?.rawData;
|
|
20
|
-
this.code = options?.code;
|
|
21
|
-
if (options?.cause) {
|
|
22
|
-
this.cause = options.cause;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
9
|
+
var __defProp = Object.defineProperty;
|
|
10
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
11
|
+
var __esm = (fn, res) => function __init() {
|
|
12
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
25
13
|
};
|
|
26
|
-
var
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.name = "JumioTimeoutError";
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
var JumioNetworkError = class extends JumioError {
|
|
33
|
-
constructor(message = "No fue posible comunicarse con los servidores de validaci\xF3n de identidad.", cause) {
|
|
34
|
-
super(message, { code: "NETWORK_ERROR", cause });
|
|
35
|
-
this.name = "JumioNetworkError";
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var JumioValidationError = class extends JumioError {
|
|
39
|
-
constructor(message = "El documento no pudo ser validado o fue rechazado por Jumio.", rawData) {
|
|
40
|
-
super(message, { code: "VALIDATION_FAILED", rawData });
|
|
41
|
-
this.name = "JumioValidationError";
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
var JumioImageProcessingError = class extends JumioError {
|
|
45
|
-
constructor(message, cause) {
|
|
46
|
-
super(message, { code: "IMAGE_PROCESSING_ERROR", cause });
|
|
47
|
-
this.name = "JumioImageProcessingError";
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var JumioPollingTimeoutError = class extends JumioError {
|
|
51
|
-
attempts;
|
|
52
|
-
constructor(attempts, message = "La validaci\xF3n sigue en proceso. Por favor verifica nuevamente m\xE1s tarde.", rawData) {
|
|
53
|
-
super(message, { code: "POLLING_TIMEOUT", rawData });
|
|
54
|
-
this.name = "JumioPollingTimeoutError";
|
|
55
|
-
this.attempts = attempts;
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
var JumioAbortError = class extends JumioError {
|
|
59
|
-
constructor(message = "La operaci\xF3n de validaci\xF3n de Jumio fue cancelada.") {
|
|
60
|
-
super(message, { code: "ABORTED" });
|
|
61
|
-
this.name = "JumioAbortError";
|
|
62
|
-
}
|
|
14
|
+
var __export = (target, all) => {
|
|
15
|
+
for (var name in all)
|
|
16
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
63
17
|
};
|
|
18
|
+
|
|
19
|
+
// src/core/errors.ts
|
|
64
20
|
function isJumioError(error) {
|
|
65
|
-
return error instanceof JumioError || typeof error === "object" && error !== null && "isJumioError" in error && error.isJumioError === true;
|
|
21
|
+
return error instanceof exports.JumioError || typeof error === "object" && error !== null && "isJumioError" in error && error.isJumioError === true;
|
|
66
22
|
}
|
|
23
|
+
exports.JumioError = void 0; exports.JumioTimeoutError = void 0; exports.JumioNetworkError = void 0; exports.JumioValidationError = void 0; exports.JumioImageProcessingError = void 0; exports.JumioPollingTimeoutError = void 0; exports.JumioAbortError = void 0;
|
|
24
|
+
var init_errors = __esm({
|
|
25
|
+
"src/core/errors.ts"() {
|
|
26
|
+
exports.JumioError = class extends Error {
|
|
27
|
+
isJumioError = true;
|
|
28
|
+
statusCode;
|
|
29
|
+
rawData;
|
|
30
|
+
code;
|
|
31
|
+
constructor(message, options) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "JumioError";
|
|
34
|
+
this.statusCode = options?.statusCode;
|
|
35
|
+
this.rawData = options?.rawData;
|
|
36
|
+
this.code = options?.code;
|
|
37
|
+
if (options?.cause) {
|
|
38
|
+
this.cause = options.cause;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
exports.JumioTimeoutError = class extends exports.JumioError {
|
|
43
|
+
constructor(message = "El servicio de verificaci\xF3n de Jumio excedi\xF3 el tiempo l\xEDmite de espera.", rawData) {
|
|
44
|
+
super(message, { code: "TIMEOUT", rawData });
|
|
45
|
+
this.name = "JumioTimeoutError";
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.JumioNetworkError = class extends exports.JumioError {
|
|
49
|
+
constructor(message = "No fue posible comunicarse con los servidores de validaci\xF3n de identidad.", cause) {
|
|
50
|
+
super(message, { code: "NETWORK_ERROR", cause });
|
|
51
|
+
this.name = "JumioNetworkError";
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
exports.JumioValidationError = class extends exports.JumioError {
|
|
55
|
+
constructor(message = "El documento no pudo ser validado o fue rechazado por Jumio.", rawData) {
|
|
56
|
+
super(message, { code: "VALIDATION_FAILED", rawData });
|
|
57
|
+
this.name = "JumioValidationError";
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
exports.JumioImageProcessingError = class extends exports.JumioError {
|
|
61
|
+
constructor(message, cause) {
|
|
62
|
+
super(message, { code: "IMAGE_PROCESSING_ERROR", cause });
|
|
63
|
+
this.name = "JumioImageProcessingError";
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
exports.JumioPollingTimeoutError = class extends exports.JumioError {
|
|
67
|
+
attempts;
|
|
68
|
+
constructor(attempts, message = "La validaci\xF3n sigue en proceso. Por favor verifica nuevamente m\xE1s tarde.", rawData) {
|
|
69
|
+
super(message, { code: "POLLING_TIMEOUT", rawData });
|
|
70
|
+
this.name = "JumioPollingTimeoutError";
|
|
71
|
+
this.attempts = attempts;
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
exports.JumioAbortError = class extends exports.JumioError {
|
|
75
|
+
constructor(message = "La operaci\xF3n de validaci\xF3n de Jumio fue cancelada.") {
|
|
76
|
+
super(message, { code: "ABORTED" });
|
|
77
|
+
this.name = "JumioAbortError";
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
67
82
|
|
|
68
83
|
// src/core/envelope.ts
|
|
69
|
-
var FINAL_JUMIO_STATUSES = [
|
|
70
|
-
"PROCESSED",
|
|
71
|
-
"APPROVED_VERIFIED",
|
|
72
|
-
"REJECTED",
|
|
73
|
-
"FAILED",
|
|
74
|
-
"ERROR",
|
|
75
|
-
"DENIED",
|
|
76
|
-
"EXPIRED",
|
|
77
|
-
"ABANDONED",
|
|
78
|
-
"DONE",
|
|
79
|
-
"COMPLETED",
|
|
80
|
-
"NOT_READABLE",
|
|
81
|
-
"FRAUD",
|
|
82
|
-
"UNSUPPORTED_ID_TYPE"
|
|
83
|
-
];
|
|
84
|
-
var APPROVED_JUMIO_STATUSES = [
|
|
85
|
-
"APPROVED_VERIFIED",
|
|
86
|
-
"DONE",
|
|
87
|
-
"COMPLETED"
|
|
88
|
-
];
|
|
89
84
|
function toLowerText(value) {
|
|
90
85
|
return String(value ?? "").trim().toLowerCase();
|
|
91
86
|
}
|
|
@@ -93,10 +88,13 @@ function toUpperText(value) {
|
|
|
93
88
|
return String(value ?? "").trim().toUpperCase();
|
|
94
89
|
}
|
|
95
90
|
function extractEnvelopeData(responseData) {
|
|
96
|
-
if (responseData && typeof responseData === "object"
|
|
97
|
-
const
|
|
98
|
-
if (
|
|
99
|
-
return
|
|
91
|
+
if (responseData && typeof responseData === "object") {
|
|
92
|
+
const obj = responseData;
|
|
93
|
+
if ("data" in obj && obj.data !== void 0) {
|
|
94
|
+
return obj.data;
|
|
95
|
+
}
|
|
96
|
+
if ("values" in obj && obj.values !== void 0) {
|
|
97
|
+
return obj.values;
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
return responseData;
|
|
@@ -148,7 +146,7 @@ function extractJumioMessage(source) {
|
|
|
148
146
|
function isFinalJumioStatus(status) {
|
|
149
147
|
const upperStatus = toUpperText(status);
|
|
150
148
|
if (!upperStatus) return false;
|
|
151
|
-
return FINAL_JUMIO_STATUSES.some((s) => s === upperStatus);
|
|
149
|
+
return exports.FINAL_JUMIO_STATUSES.some((s) => s === upperStatus);
|
|
152
150
|
}
|
|
153
151
|
function isApprovedJumioStatus(status) {
|
|
154
152
|
const upperStatus = toUpperText(status);
|
|
@@ -167,12 +165,54 @@ function resolveVerificationValidity(data, fallbackStatus) {
|
|
|
167
165
|
}
|
|
168
166
|
return isApprovedJumioStatus(fallbackStatus);
|
|
169
167
|
}
|
|
168
|
+
function encodeUrlToBase64UrlSafe(url) {
|
|
169
|
+
try {
|
|
170
|
+
let base64;
|
|
171
|
+
if (typeof Buffer !== "undefined") {
|
|
172
|
+
base64 = Buffer.from(url, "utf-8").toString("base64");
|
|
173
|
+
} else if (typeof TextEncoder !== "undefined") {
|
|
174
|
+
const encoder = new TextEncoder();
|
|
175
|
+
const data = encoder.encode(url);
|
|
176
|
+
base64 = btoa(String.fromCharCode(...new Uint8Array(data)));
|
|
177
|
+
} else {
|
|
178
|
+
base64 = btoa(url);
|
|
179
|
+
}
|
|
180
|
+
return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
181
|
+
} catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.FINAL_JUMIO_STATUSES = void 0; exports.APPROVED_JUMIO_STATUSES = void 0;
|
|
186
|
+
var init_envelope = __esm({
|
|
187
|
+
"src/core/envelope.ts"() {
|
|
188
|
+
exports.FINAL_JUMIO_STATUSES = [
|
|
189
|
+
"PROCESSED",
|
|
190
|
+
"APPROVED_VERIFIED",
|
|
191
|
+
"REJECTED",
|
|
192
|
+
"FAILED",
|
|
193
|
+
"ERROR",
|
|
194
|
+
"DENIED",
|
|
195
|
+
"EXPIRED",
|
|
196
|
+
"ABANDONED",
|
|
197
|
+
"DONE",
|
|
198
|
+
"COMPLETED",
|
|
199
|
+
"NOT_READABLE",
|
|
200
|
+
"FRAUD",
|
|
201
|
+
"UNSUPPORTED_ID_TYPE"
|
|
202
|
+
];
|
|
203
|
+
exports.APPROVED_JUMIO_STATUSES = [
|
|
204
|
+
"APPROVED_VERIFIED",
|
|
205
|
+
"DONE",
|
|
206
|
+
"COMPLETED"
|
|
207
|
+
];
|
|
208
|
+
}
|
|
209
|
+
});
|
|
170
210
|
|
|
171
211
|
// src/core/retry.ts
|
|
172
212
|
function delay(ms, signal) {
|
|
173
213
|
return new Promise((resolve, reject) => {
|
|
174
214
|
if (signal?.aborted) {
|
|
175
|
-
return reject(new JumioAbortError());
|
|
215
|
+
return reject(new exports.JumioAbortError());
|
|
176
216
|
}
|
|
177
217
|
const timer = setTimeout(() => {
|
|
178
218
|
signal?.removeEventListener("abort", abortHandler);
|
|
@@ -180,7 +220,7 @@ function delay(ms, signal) {
|
|
|
180
220
|
}, ms);
|
|
181
221
|
const abortHandler = () => {
|
|
182
222
|
clearTimeout(timer);
|
|
183
|
-
reject(new JumioAbortError());
|
|
223
|
+
reject(new exports.JumioAbortError());
|
|
184
224
|
};
|
|
185
225
|
signal?.addEventListener("abort", abortHandler, { once: true });
|
|
186
226
|
});
|
|
@@ -214,14 +254,14 @@ async function withRetry(operation, options = {}) {
|
|
|
214
254
|
let lastError;
|
|
215
255
|
for (let attempt = 1; attempt <= maxRetries; attempt += 1) {
|
|
216
256
|
if (signal?.aborted) {
|
|
217
|
-
throw new JumioAbortError();
|
|
257
|
+
throw new exports.JumioAbortError();
|
|
218
258
|
}
|
|
219
259
|
try {
|
|
220
260
|
return await operation(attempt);
|
|
221
261
|
} catch (error) {
|
|
222
262
|
lastError = error;
|
|
223
263
|
if (signal?.aborted) {
|
|
224
|
-
throw new JumioAbortError();
|
|
264
|
+
throw new exports.JumioAbortError();
|
|
225
265
|
}
|
|
226
266
|
const isLastAttempt = attempt >= maxRetries;
|
|
227
267
|
const isRetryable = shouldRetry(error);
|
|
@@ -238,8 +278,273 @@ async function withRetry(operation, options = {}) {
|
|
|
238
278
|
}
|
|
239
279
|
throw lastError;
|
|
240
280
|
}
|
|
281
|
+
var init_retry = __esm({
|
|
282
|
+
"src/core/retry.ts"() {
|
|
283
|
+
init_envelope();
|
|
284
|
+
init_errors();
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
// src/core/webflow.ts
|
|
289
|
+
var webflow_exports = {};
|
|
290
|
+
__export(webflow_exports, {
|
|
291
|
+
buildRedirectUrl: () => buildRedirectUrl,
|
|
292
|
+
parseWebflowReturnParams: () => parseWebflowReturnParams,
|
|
293
|
+
pollWebflowStatus: () => pollWebflowStatus,
|
|
294
|
+
resolveWebflowResult: () => resolveWebflowResult,
|
|
295
|
+
startWebflowSession: () => startWebflowSession
|
|
296
|
+
});
|
|
297
|
+
function buildRedirectUrl(returnUrl, proxyUrl) {
|
|
298
|
+
if (!proxyUrl) {
|
|
299
|
+
return returnUrl;
|
|
300
|
+
}
|
|
301
|
+
const encoded = encodeUrlToBase64UrlSafe(returnUrl);
|
|
302
|
+
if (!encoded) {
|
|
303
|
+
throw new exports.JumioValidationError(
|
|
304
|
+
`No fue posible codificar la URL de retorno: "${returnUrl}"`
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
const normalizedProxy = proxyUrl.endsWith("/") ? proxyUrl : `${proxyUrl}/`;
|
|
308
|
+
return `${normalizedProxy}${encoded}`;
|
|
309
|
+
}
|
|
310
|
+
function parseWebflowReturnParams(source) {
|
|
311
|
+
let searchString;
|
|
312
|
+
if (!source) {
|
|
313
|
+
if (typeof window !== "undefined" && window.location) {
|
|
314
|
+
searchString = window.location.search;
|
|
315
|
+
} else {
|
|
316
|
+
return { allParams: {} };
|
|
317
|
+
}
|
|
318
|
+
} else if (typeof source === "string") {
|
|
319
|
+
const questionIdx = source.indexOf("?");
|
|
320
|
+
searchString = questionIdx >= 0 ? source.slice(questionIdx) : "";
|
|
321
|
+
} else if (source instanceof URLSearchParams) {
|
|
322
|
+
searchString = `?${source.toString()}`;
|
|
323
|
+
} else {
|
|
324
|
+
const hrefSearch = source.href ? (() => {
|
|
325
|
+
try {
|
|
326
|
+
return new URL(source.href).search;
|
|
327
|
+
} catch {
|
|
328
|
+
return "";
|
|
329
|
+
}
|
|
330
|
+
})() : "";
|
|
331
|
+
searchString = source.search ?? hrefSearch;
|
|
332
|
+
}
|
|
333
|
+
const params = new URLSearchParams(searchString);
|
|
334
|
+
const allParams = {};
|
|
335
|
+
params.forEach((value, key) => {
|
|
336
|
+
allParams[key] = value;
|
|
337
|
+
});
|
|
338
|
+
const accountId = params.get("accountId") ?? void 0;
|
|
339
|
+
let workflowId = params.get("workflowExecutionId") ?? params.get("workflowId") ?? void 0;
|
|
340
|
+
const rawStatus = params.get("status") ?? void 0;
|
|
341
|
+
if (rawStatus && (!accountId || !workflowId)) {
|
|
342
|
+
const statusParts = rawStatus.split("?");
|
|
343
|
+
const nestedSearch = statusParts.length > 1 ? `?${statusParts.slice(1).join("?")}` : "";
|
|
344
|
+
if (nestedSearch && nestedSearch !== "?") {
|
|
345
|
+
const nestedParams = new URLSearchParams(nestedSearch);
|
|
346
|
+
nestedParams.forEach((value, key) => {
|
|
347
|
+
if (!allParams[key]) allParams[key] = value;
|
|
348
|
+
});
|
|
349
|
+
if (!workflowId) {
|
|
350
|
+
workflowId = nestedParams.get("workflowExecutionId") ?? nestedParams.get("workflowId") ?? workflowId;
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return {
|
|
355
|
+
accountId: accountId || void 0,
|
|
356
|
+
workflowId: workflowId || void 0,
|
|
357
|
+
rawStatus,
|
|
358
|
+
allParams
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
function resolveWebflowResult(rawData, accountId, workflowId) {
|
|
362
|
+
if (!rawData || typeof rawData !== "object") return null;
|
|
363
|
+
const data = rawData;
|
|
364
|
+
if (data.valid === true) {
|
|
365
|
+
return {
|
|
366
|
+
valid: true,
|
|
367
|
+
status: String(data.workflowStatus ?? data.status ?? "APPROVED_VERIFIED"),
|
|
368
|
+
decision: data.decision,
|
|
369
|
+
extraction: data.extraction,
|
|
370
|
+
accountId,
|
|
371
|
+
workflowId,
|
|
372
|
+
data: rawData
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (data.valid === false) {
|
|
376
|
+
return {
|
|
377
|
+
valid: false,
|
|
378
|
+
status: String(data.workflowStatus ?? data.status ?? "REJECTED"),
|
|
379
|
+
decision: data.decision,
|
|
380
|
+
accountId,
|
|
381
|
+
workflowId,
|
|
382
|
+
data: rawData,
|
|
383
|
+
errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado durante la verificacion."
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
const capData = data;
|
|
387
|
+
const decisionType = capData?.decision?.type;
|
|
388
|
+
const extractionArr = capData?.capabilities?.extraction ?? [];
|
|
389
|
+
const extraction = extractionArr[0];
|
|
390
|
+
const isExtractionEmpty = extraction !== void 0 && Object.keys(extraction).length === 0;
|
|
391
|
+
if (decisionType === "REJECTED") {
|
|
392
|
+
return {
|
|
393
|
+
valid: false,
|
|
394
|
+
status: "REJECTED",
|
|
395
|
+
decision: decisionType,
|
|
396
|
+
accountId,
|
|
397
|
+
workflowId,
|
|
398
|
+
data: rawData,
|
|
399
|
+
errorMessage: extractJumioMessage(rawData) || "El documento fue rechazado por Jumio."
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
if (extraction && !isExtractionEmpty) {
|
|
403
|
+
const isApproved = decisionType === "PASSED" || decisionType === "WARNING";
|
|
404
|
+
return {
|
|
405
|
+
valid: isApproved,
|
|
406
|
+
status: isApproved ? decisionType ?? "PASSED" : decisionType ?? "REJECTED",
|
|
407
|
+
decision: decisionType,
|
|
408
|
+
extraction,
|
|
409
|
+
accountId,
|
|
410
|
+
workflowId,
|
|
411
|
+
data: rawData,
|
|
412
|
+
...!isApproved ? {
|
|
413
|
+
errorMessage: extractJumioMessage(rawData) || "La verificacion no fue aprobada."
|
|
414
|
+
} : {}
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
return null;
|
|
418
|
+
}
|
|
419
|
+
async function pollWebflowStatus(http, params, options = {}) {
|
|
420
|
+
const config = http.getConfig();
|
|
421
|
+
const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
|
|
422
|
+
const intervalMs = options.pollingIntervalMs ?? config.pollingIntervalMs ?? 1e4;
|
|
423
|
+
const signal = options.signal;
|
|
424
|
+
let lastRawData = {};
|
|
425
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
426
|
+
if (signal?.aborted) {
|
|
427
|
+
throw new exports.JumioAbortError();
|
|
428
|
+
}
|
|
429
|
+
const responseData = await withRetry(
|
|
430
|
+
() => http.getVerificationStatus(params.accountId, params.workflowId, {
|
|
431
|
+
signal,
|
|
432
|
+
timeout: config.statusTimeout,
|
|
433
|
+
clientId: params.clientId
|
|
434
|
+
}),
|
|
435
|
+
{
|
|
436
|
+
maxRetries: config.maxRetries ?? 3,
|
|
437
|
+
initialDelayMs: config.retryDelayMs ?? 800,
|
|
438
|
+
signal
|
|
439
|
+
}
|
|
440
|
+
);
|
|
441
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
442
|
+
const statusData = extractNestedData(firstLevel) ?? {};
|
|
443
|
+
lastRawData = statusData;
|
|
444
|
+
options.onAttempt?.(attempt, maxAttempts, statusData);
|
|
445
|
+
const result = resolveWebflowResult(
|
|
446
|
+
statusData,
|
|
447
|
+
params.accountId,
|
|
448
|
+
params.workflowId
|
|
449
|
+
);
|
|
450
|
+
if (result !== null) {
|
|
451
|
+
return result;
|
|
452
|
+
}
|
|
453
|
+
if (attempt < maxAttempts) {
|
|
454
|
+
await delay(intervalMs, signal);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
const lastMessage = extractJumioMessage(lastRawData) || "La verificacion Jumio sigue en proceso. Intenta nuevamente en unos momentos.";
|
|
458
|
+
throw new exports.JumioPollingTimeoutError(maxAttempts, lastMessage, lastRawData);
|
|
459
|
+
}
|
|
460
|
+
async function startWebflowSession(http, config, input) {
|
|
461
|
+
const {
|
|
462
|
+
clientId,
|
|
463
|
+
successUrl,
|
|
464
|
+
errorUrl,
|
|
465
|
+
useRedirectProxy = false,
|
|
466
|
+
autoRedirect = false,
|
|
467
|
+
openInNewTab = false,
|
|
468
|
+
signal
|
|
469
|
+
} = input;
|
|
470
|
+
if (!clientId?.trim()) {
|
|
471
|
+
throw new exports.JumioValidationError(
|
|
472
|
+
"Se requiere un identificador de cliente valido (clientId)."
|
|
473
|
+
);
|
|
474
|
+
}
|
|
475
|
+
if (!successUrl?.trim()) {
|
|
476
|
+
throw new exports.JumioValidationError("Se requiere la URL de exito (successUrl).");
|
|
477
|
+
}
|
|
478
|
+
if (!errorUrl?.trim()) {
|
|
479
|
+
throw new exports.JumioValidationError("Se requiere la URL de error (errorUrl).");
|
|
480
|
+
}
|
|
481
|
+
if (signal?.aborted) {
|
|
482
|
+
throw new exports.JumioAbortError();
|
|
483
|
+
}
|
|
484
|
+
const proxyUrl = useRedirectProxy ? config.redirectProxyUrl ?? void 0 : void 0;
|
|
485
|
+
const finalSuccessUrl = buildRedirectUrl(successUrl, proxyUrl);
|
|
486
|
+
const finalErrorUrl = buildRedirectUrl(errorUrl, proxyUrl);
|
|
487
|
+
try {
|
|
488
|
+
const responseData = await withRetry(
|
|
489
|
+
() => http.postVerification(
|
|
490
|
+
{
|
|
491
|
+
client: clientId.trim(),
|
|
492
|
+
successUrl: finalSuccessUrl,
|
|
493
|
+
errorUrl: finalErrorUrl
|
|
494
|
+
},
|
|
495
|
+
{ signal, timeout: config.requestTimeout }
|
|
496
|
+
),
|
|
497
|
+
{
|
|
498
|
+
maxRetries: config.maxRetries ?? 3,
|
|
499
|
+
initialDelayMs: config.retryDelayMs ?? 800,
|
|
500
|
+
signal
|
|
501
|
+
}
|
|
502
|
+
);
|
|
503
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
504
|
+
const payload = extractNestedData(firstLevel) ?? {};
|
|
505
|
+
const href = payload?.href;
|
|
506
|
+
if (!href) {
|
|
507
|
+
throw new exports.JumioError(
|
|
508
|
+
extractJumioMessage(payload) || "El backend no devolvio la URL de verificacion de Jumio (href).",
|
|
509
|
+
{ rawData: payload }
|
|
510
|
+
);
|
|
511
|
+
}
|
|
512
|
+
const result = {
|
|
513
|
+
href,
|
|
514
|
+
accountId: payload?.accountId,
|
|
515
|
+
workflowId: payload?.workflowId,
|
|
516
|
+
data: payload
|
|
517
|
+
};
|
|
518
|
+
if (typeof window !== "undefined") {
|
|
519
|
+
if (openInNewTab) {
|
|
520
|
+
const win = window.open(href, "_blank");
|
|
521
|
+
if (!win || win.closed || typeof win.closed === "undefined") {
|
|
522
|
+
window.location.href = href;
|
|
523
|
+
}
|
|
524
|
+
} else if (autoRedirect) {
|
|
525
|
+
window.location.href = href;
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
return result;
|
|
529
|
+
} catch (err) {
|
|
530
|
+
throw err;
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
var init_webflow = __esm({
|
|
534
|
+
"src/core/webflow.ts"() {
|
|
535
|
+
init_envelope();
|
|
536
|
+
init_errors();
|
|
537
|
+
init_retry();
|
|
538
|
+
}
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
// src/core/index.ts
|
|
542
|
+
init_errors();
|
|
543
|
+
init_envelope();
|
|
544
|
+
init_retry();
|
|
241
545
|
|
|
242
546
|
// src/core/image.ts
|
|
547
|
+
init_errors();
|
|
243
548
|
function stripDataUrlPrefix(dataUrl) {
|
|
244
549
|
if (!dataUrl) return "";
|
|
245
550
|
const commaIndex = dataUrl.indexOf(",");
|
|
@@ -277,7 +582,7 @@ function blobToBase64(blob) {
|
|
|
277
582
|
blob.arrayBuffer().then((buffer) => {
|
|
278
583
|
resolve(arrayBufferToBase64(buffer));
|
|
279
584
|
}).catch(
|
|
280
|
-
(err) => reject(new JumioImageProcessingError("No se pudo leer el archivo binario.", err))
|
|
585
|
+
(err) => reject(new exports.JumioImageProcessingError("No se pudo leer el archivo binario.", err))
|
|
281
586
|
);
|
|
282
587
|
return;
|
|
283
588
|
}
|
|
@@ -286,7 +591,7 @@ function blobToBase64(blob) {
|
|
|
286
591
|
const dataUrl = String(reader.result ?? "");
|
|
287
592
|
resolve(stripDataUrlPrefix(dataUrl));
|
|
288
593
|
};
|
|
289
|
-
reader.onerror = () => reject(new JumioImageProcessingError("No se pudo convertir la imagen a base64.", reader.error));
|
|
594
|
+
reader.onerror = () => reject(new exports.JumioImageProcessingError("No se pudo convertir la imagen a base64.", reader.error));
|
|
290
595
|
reader.readAsDataURL(blob);
|
|
291
596
|
});
|
|
292
597
|
}
|
|
@@ -305,7 +610,7 @@ function arrayBufferToBase64(buffer) {
|
|
|
305
610
|
}
|
|
306
611
|
async function fetchUrlAsBase64(url, signal) {
|
|
307
612
|
if (signal?.aborted) {
|
|
308
|
-
throw new JumioAbortError();
|
|
613
|
+
throw new exports.JumioAbortError();
|
|
309
614
|
}
|
|
310
615
|
const trimmed = url.trim();
|
|
311
616
|
if (trimmed.startsWith("data:")) {
|
|
@@ -314,7 +619,7 @@ async function fetchUrlAsBase64(url, signal) {
|
|
|
314
619
|
try {
|
|
315
620
|
const response = await fetch(trimmed, { signal });
|
|
316
621
|
if (!response.ok) {
|
|
317
|
-
throw new JumioImageProcessingError(
|
|
622
|
+
throw new exports.JumioImageProcessingError(
|
|
318
623
|
`No se pudo descargar la imagen desde la URL remota (HTTP ${response.status}).`
|
|
319
624
|
);
|
|
320
625
|
}
|
|
@@ -322,12 +627,12 @@ async function fetchUrlAsBase64(url, signal) {
|
|
|
322
627
|
return await blobToBase64(blob);
|
|
323
628
|
} catch (error) {
|
|
324
629
|
if (signal?.aborted || error instanceof Error && error.name === "AbortError") {
|
|
325
|
-
throw new JumioAbortError();
|
|
630
|
+
throw new exports.JumioAbortError();
|
|
326
631
|
}
|
|
327
|
-
if (error instanceof JumioImageProcessingError) {
|
|
632
|
+
if (error instanceof exports.JumioImageProcessingError) {
|
|
328
633
|
throw error;
|
|
329
634
|
}
|
|
330
|
-
throw new JumioImageProcessingError(
|
|
635
|
+
throw new exports.JumioImageProcessingError(
|
|
331
636
|
`Error al descargar o procesar la imagen desde la URL: ${url}`,
|
|
332
637
|
error
|
|
333
638
|
);
|
|
@@ -335,10 +640,10 @@ async function fetchUrlAsBase64(url, signal) {
|
|
|
335
640
|
}
|
|
336
641
|
async function resolveImageSourceToBase64(source, s3Signer, signal) {
|
|
337
642
|
if (signal?.aborted) {
|
|
338
|
-
throw new JumioAbortError();
|
|
643
|
+
throw new exports.JumioAbortError();
|
|
339
644
|
}
|
|
340
645
|
if (!source) {
|
|
341
|
-
throw new JumioImageProcessingError("No se proporcion\xF3 una imagen v\xE1lida para la verificaci\xF3n.");
|
|
646
|
+
throw new exports.JumioImageProcessingError("No se proporcion\xF3 una imagen v\xE1lida para la verificaci\xF3n.");
|
|
342
647
|
}
|
|
343
648
|
if (typeof Blob !== "undefined" && source instanceof Blob) {
|
|
344
649
|
return blobToBase64(source);
|
|
@@ -355,7 +660,7 @@ async function resolveImageSourceToBase64(source, s3Signer, signal) {
|
|
|
355
660
|
if (typeof source === "string") {
|
|
356
661
|
const text = source.trim();
|
|
357
662
|
if (!text) {
|
|
358
|
-
throw new JumioImageProcessingError("La ruta o contenido de la imagen est\xE1 vac\xEDo.");
|
|
663
|
+
throw new exports.JumioImageProcessingError("La ruta o contenido de la imagen est\xE1 vac\xEDo.");
|
|
359
664
|
}
|
|
360
665
|
if (text.startsWith("data:")) {
|
|
361
666
|
return stripDataUrlPrefix(text);
|
|
@@ -380,7 +685,7 @@ async function resolveImageSourceToBase64(source, s3Signer, signal) {
|
|
|
380
685
|
return await fetchUrlAsBase64(signedUrl, signal);
|
|
381
686
|
}
|
|
382
687
|
} catch (err) {
|
|
383
|
-
throw new JumioImageProcessingError(
|
|
688
|
+
throw new exports.JumioImageProcessingError(
|
|
384
689
|
`No se pudo firmar la ruta de almacenamiento S3: ${text}`,
|
|
385
690
|
err
|
|
386
691
|
);
|
|
@@ -389,12 +694,16 @@ async function resolveImageSourceToBase64(source, s3Signer, signal) {
|
|
|
389
694
|
if (isBase64String(text)) {
|
|
390
695
|
return stripDataUrlPrefix(text);
|
|
391
696
|
}
|
|
392
|
-
throw new JumioImageProcessingError(
|
|
697
|
+
throw new exports.JumioImageProcessingError(
|
|
393
698
|
`Formato de imagen no reconocido o ruta inv\xE1lida: ${text.slice(0, 50)}...`
|
|
394
699
|
);
|
|
395
700
|
}
|
|
396
|
-
throw new JumioImageProcessingError("Tipo de dato de imagen no soportado.");
|
|
701
|
+
throw new exports.JumioImageProcessingError("Tipo de dato de imagen no soportado.");
|
|
397
702
|
}
|
|
703
|
+
|
|
704
|
+
// src/core/http.ts
|
|
705
|
+
init_errors();
|
|
706
|
+
init_envelope();
|
|
398
707
|
var JumioHttpClient = class {
|
|
399
708
|
client;
|
|
400
709
|
config;
|
|
@@ -452,7 +761,7 @@ var JumioHttpClient = class {
|
|
|
452
761
|
* Normaliza cualquier error de Axios a una excepción tipada JumioError.
|
|
453
762
|
*/
|
|
454
763
|
normalizeError(error) {
|
|
455
|
-
if (error instanceof JumioError) {
|
|
764
|
+
if (error instanceof exports.JumioError) {
|
|
456
765
|
return error;
|
|
457
766
|
}
|
|
458
767
|
if (axios__default.default.isAxiosError(error)) {
|
|
@@ -461,18 +770,18 @@ var JumioHttpClient = class {
|
|
|
461
770
|
const responseData = axiosErr.response?.data;
|
|
462
771
|
const serverMessage = extractJumioMessage(responseData) || extractJumioMessage(axiosErr);
|
|
463
772
|
if (axiosErr.code === "ECONNABORTED" || axiosErr.code === "ETIMEDOUT") {
|
|
464
|
-
return new JumioTimeoutError(
|
|
773
|
+
return new exports.JumioTimeoutError(
|
|
465
774
|
serverMessage || "La solicitud al servicio de Jumio excedi\xF3 el tiempo l\xEDmite.",
|
|
466
775
|
responseData
|
|
467
776
|
);
|
|
468
777
|
}
|
|
469
778
|
if (!axiosErr.response) {
|
|
470
|
-
return new JumioNetworkError(
|
|
779
|
+
return new exports.JumioNetworkError(
|
|
471
780
|
serverMessage || "No fue posible comunicarse con el servicio de Jumio.",
|
|
472
781
|
axiosErr
|
|
473
782
|
);
|
|
474
783
|
}
|
|
475
|
-
return new JumioError(serverMessage || `Error en la solicitud HTTP (${status}).`, {
|
|
784
|
+
return new exports.JumioError(serverMessage || `Error en la solicitud HTTP (${status}).`, {
|
|
476
785
|
statusCode: status,
|
|
477
786
|
rawData: responseData,
|
|
478
787
|
code: axiosErr.code,
|
|
@@ -481,18 +790,18 @@ var JumioHttpClient = class {
|
|
|
481
790
|
}
|
|
482
791
|
if (error instanceof Error) {
|
|
483
792
|
if (error.name === "AbortError") {
|
|
484
|
-
return new JumioAbortError();
|
|
793
|
+
return new exports.JumioAbortError();
|
|
485
794
|
}
|
|
486
|
-
return new JumioError(error.message, { cause: error });
|
|
795
|
+
return new exports.JumioError(error.message, { cause: error });
|
|
487
796
|
}
|
|
488
|
-
return new JumioError("Ocurri\xF3 un error inesperado al contactar a Jumio.");
|
|
797
|
+
return new exports.JumioError("Ocurri\xF3 un error inesperado al contactar a Jumio.");
|
|
489
798
|
}
|
|
490
799
|
/**
|
|
491
800
|
* Ejecuta una petición POST al endpoint de Jumio para iniciar o procesar la verificación.
|
|
492
801
|
*/
|
|
493
802
|
async postVerification(payload, options) {
|
|
494
803
|
if (options?.signal?.aborted) {
|
|
495
|
-
throw new JumioAbortError();
|
|
804
|
+
throw new exports.JumioAbortError();
|
|
496
805
|
}
|
|
497
806
|
try {
|
|
498
807
|
const dynamicHeaders = await this.resolveHeaders();
|
|
@@ -510,21 +819,26 @@ var JumioHttpClient = class {
|
|
|
510
819
|
}
|
|
511
820
|
/**
|
|
512
821
|
* Ejecuta una petición GET para consultar el estado actual de una verificación de INE.
|
|
822
|
+
* Soporta un `clientId` opcional requerido por algunos endpoints de DynamiCore (p. ej. Hosted Webflow).
|
|
513
823
|
*/
|
|
514
824
|
async getVerificationStatus(accountId, workflowId, options) {
|
|
515
825
|
if (options?.signal?.aborted) {
|
|
516
|
-
throw new JumioAbortError();
|
|
826
|
+
throw new exports.JumioAbortError();
|
|
517
827
|
}
|
|
518
828
|
try {
|
|
519
829
|
const dynamicHeaders = await this.resolveHeaders();
|
|
520
830
|
const endpoint = this.config.endpoint || "/marketplace/apps/jumio";
|
|
521
831
|
const timeout = options?.timeout ?? this.config.statusTimeout ?? 12e4;
|
|
832
|
+
const queryParams = {
|
|
833
|
+
type: "ine",
|
|
834
|
+
accountId,
|
|
835
|
+
workflowId
|
|
836
|
+
};
|
|
837
|
+
if (options?.clientId) {
|
|
838
|
+
queryParams.clientId = options.clientId;
|
|
839
|
+
}
|
|
522
840
|
const response = await this.client.get(endpoint, {
|
|
523
|
-
params:
|
|
524
|
-
type: "ine",
|
|
525
|
-
accountId,
|
|
526
|
-
workflowId
|
|
527
|
-
},
|
|
841
|
+
params: queryParams,
|
|
528
842
|
headers: dynamicHeaders,
|
|
529
843
|
timeout,
|
|
530
844
|
signal: options?.signal
|
|
@@ -540,6 +854,9 @@ var JumioHttpClient = class {
|
|
|
540
854
|
};
|
|
541
855
|
|
|
542
856
|
// src/core/polling.ts
|
|
857
|
+
init_envelope();
|
|
858
|
+
init_errors();
|
|
859
|
+
init_retry();
|
|
543
860
|
async function pollJumioStatus(http, accountId, workflowId, options = {}) {
|
|
544
861
|
const config = http.getConfig();
|
|
545
862
|
const maxAttempts = options.maxAttempts ?? config.maxPollingAttempts ?? 20;
|
|
@@ -548,7 +865,7 @@ async function pollJumioStatus(http, accountId, workflowId, options = {}) {
|
|
|
548
865
|
let lastData = {};
|
|
549
866
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
550
867
|
if (signal?.aborted) {
|
|
551
|
-
throw new JumioAbortError();
|
|
868
|
+
throw new exports.JumioAbortError();
|
|
552
869
|
}
|
|
553
870
|
const responseData = await withRetry(
|
|
554
871
|
() => http.getVerificationStatus(accountId, workflowId, {
|
|
@@ -592,10 +909,17 @@ async function pollJumioStatus(http, accountId, workflowId, options = {}) {
|
|
|
592
909
|
}
|
|
593
910
|
}
|
|
594
911
|
const lastMessage = extractJumioMessage(lastData) || "La validaci\xF3n de INE sigue en proceso. Intenta nuevamente en unos momentos.";
|
|
595
|
-
throw new JumioPollingTimeoutError(maxAttempts, lastMessage, lastData);
|
|
912
|
+
throw new exports.JumioPollingTimeoutError(maxAttempts, lastMessage, lastData);
|
|
596
913
|
}
|
|
597
914
|
|
|
915
|
+
// src/core/index.ts
|
|
916
|
+
init_webflow();
|
|
917
|
+
|
|
598
918
|
// src/core/client.ts
|
|
919
|
+
init_envelope();
|
|
920
|
+
init_errors();
|
|
921
|
+
init_retry();
|
|
922
|
+
init_webflow();
|
|
599
923
|
var JumioClient = class {
|
|
600
924
|
http;
|
|
601
925
|
config;
|
|
@@ -609,10 +933,10 @@ var JumioClient = class {
|
|
|
609
933
|
async startIneVerification(params) {
|
|
610
934
|
const { clientId, frontImage, backImage, signal, onProgress } = params;
|
|
611
935
|
if (!clientId || !clientId.trim()) {
|
|
612
|
-
throw new JumioValidationError("Se requiere un identificador de cliente v\xE1lido (clientId).");
|
|
936
|
+
throw new exports.JumioValidationError("Se requiere un identificador de cliente v\xE1lido (clientId).");
|
|
613
937
|
}
|
|
614
938
|
if (signal?.aborted) {
|
|
615
|
-
throw new JumioAbortError();
|
|
939
|
+
throw new exports.JumioAbortError();
|
|
616
940
|
}
|
|
617
941
|
onProgress?.("RESOLVING_IMAGES", 10);
|
|
618
942
|
const [frontBase64, backBase64] = await Promise.all([
|
|
@@ -620,7 +944,7 @@ var JumioClient = class {
|
|
|
620
944
|
resolveImageSourceToBase64(backImage, this.config.s3Signer, signal)
|
|
621
945
|
]);
|
|
622
946
|
if (signal?.aborted) {
|
|
623
|
-
throw new JumioAbortError();
|
|
947
|
+
throw new exports.JumioAbortError();
|
|
624
948
|
}
|
|
625
949
|
onProgress?.("SENDING_PAYLOAD", 40);
|
|
626
950
|
const payload = {
|
|
@@ -708,7 +1032,7 @@ var JumioClient = class {
|
|
|
708
1032
|
const workflowId = String(startData?.workflowId ?? "").trim();
|
|
709
1033
|
if (!accountId || !workflowId) {
|
|
710
1034
|
const errorMessage = extractJumioMessage(startData) || "No fue posible obtener los identificadores de seguimiento de la validaci\xF3n.";
|
|
711
|
-
const error = new JumioError(errorMessage, { rawData: startData });
|
|
1035
|
+
const error = new exports.JumioError(errorMessage, { rawData: startData });
|
|
712
1036
|
onStatusError?.(error);
|
|
713
1037
|
throw error;
|
|
714
1038
|
}
|
|
@@ -735,26 +1059,118 @@ var JumioClient = class {
|
|
|
735
1059
|
onStatusResolved?.(finalResult);
|
|
736
1060
|
return finalResult;
|
|
737
1061
|
}
|
|
1062
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1063
|
+
// Hosted Webflow (Redirección)
|
|
1064
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
1065
|
+
/**
|
|
1066
|
+
* Construye la URL de redirección de retorno para el flujo Hosted Webflow.
|
|
1067
|
+
*
|
|
1068
|
+
* Si el cliente está configurado con un `redirectProxyUrl` y `useProxy` es `true`,
|
|
1069
|
+
* la URL de retorno se codifica en Base64 URL-safe y se adjunta al proxy.
|
|
1070
|
+
*
|
|
1071
|
+
* @param returnUrl URL de la aplicación a la que Jumio redirigirá tras la verificación.
|
|
1072
|
+
* @param useProxy Si es `true` y hay `redirectProxyUrl` configurado, usa el proxy.
|
|
1073
|
+
* @returns URL de redirección construida.
|
|
1074
|
+
*/
|
|
1075
|
+
buildRedirectUrl(returnUrl, useProxy = false) {
|
|
1076
|
+
const proxyUrl = useProxy ? this.config.redirectProxyUrl ?? void 0 : void 0;
|
|
1077
|
+
return buildRedirectUrl(returnUrl, proxyUrl);
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Inicia el flujo Hosted Webflow solicitando al backend de DynamiCore la URL
|
|
1081
|
+
* de verificación de Jumio (`href`).
|
|
1082
|
+
*
|
|
1083
|
+
* El usuario debe ser redirigido a esa URL para completar la verificación en la
|
|
1084
|
+
* página oficial de Jumio. Al terminar, Jumio redirige de vuelta a la aplicación
|
|
1085
|
+
* con `accountId` y `workflowExecutionId` como query params.
|
|
1086
|
+
*
|
|
1087
|
+
* @param input Parámetros del flujo: `clientId`, `successUrl`, `errorUrl`, opciones de proxy y redirección.
|
|
1088
|
+
* @returns `StartWebflowResult` con la URL de Jumio (`href`) y datos adicionales.
|
|
1089
|
+
*
|
|
1090
|
+
* @example
|
|
1091
|
+
* ```ts
|
|
1092
|
+
* const { href } = await client.startWebflow({
|
|
1093
|
+
* clientId: "usr_123",
|
|
1094
|
+
* successUrl: "https://app.example.com/verify/success",
|
|
1095
|
+
* errorUrl: "https://app.example.com/verify/error",
|
|
1096
|
+
* });
|
|
1097
|
+
* window.location.href = href;
|
|
1098
|
+
* ```
|
|
1099
|
+
*/
|
|
1100
|
+
async startWebflow(input) {
|
|
1101
|
+
return startWebflowSession(this.http, this.config, input);
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Extrae los parámetros de seguimiento de Jumio de la URL de retorno.
|
|
1105
|
+
*
|
|
1106
|
+
* Jumio añade `accountId` y `workflowExecutionId` (o `workflowId`) como query
|
|
1107
|
+
* params al redirigir de vuelta a la aplicación tras la verificación.
|
|
1108
|
+
*
|
|
1109
|
+
* @param source URL completa, `URLSearchParams`, objeto con `search`/`href`, o nada para leer `window.location`.
|
|
1110
|
+
* @returns `WebflowReturnParams` con `accountId`, `workflowId`, `rawStatus` y todos los params.
|
|
1111
|
+
*
|
|
1112
|
+
* @example En React, en el componente de retorno:
|
|
1113
|
+
* ```ts
|
|
1114
|
+
* const { accountId, workflowId } = client.parseWebflowReturnParams(window.location.href);
|
|
1115
|
+
* ```
|
|
1116
|
+
*/
|
|
1117
|
+
parseWebflowReturnParams(source) {
|
|
1118
|
+
return parseWebflowReturnParams(source);
|
|
1119
|
+
}
|
|
1120
|
+
/**
|
|
1121
|
+
* Consulta una única vez el estado actual de la verificación del flujo Hosted Webflow.
|
|
1122
|
+
*
|
|
1123
|
+
* @param input Parámetros de consulta: `accountId`, `workflowId`, y `clientId` opcional.
|
|
1124
|
+
* @returns `WebflowResult | null` — `null` si la verificación aún está pendiente.
|
|
1125
|
+
*/
|
|
1126
|
+
async getWebflowStatus(input) {
|
|
1127
|
+
const { accountId, workflowId, clientId, signal } = input;
|
|
1128
|
+
const responseData = await this.http.getVerificationStatus(accountId, workflowId, {
|
|
1129
|
+
signal,
|
|
1130
|
+
timeout: this.config.statusTimeout,
|
|
1131
|
+
clientId
|
|
1132
|
+
});
|
|
1133
|
+
const firstLevel = extractEnvelopeData(responseData);
|
|
1134
|
+
const statusData = extractNestedData(firstLevel) ?? {};
|
|
1135
|
+
const { resolveWebflowResult: resolveWebflowResult2 } = await Promise.resolve().then(() => (init_webflow(), webflow_exports));
|
|
1136
|
+
return resolveWebflowResult2(statusData, accountId, workflowId);
|
|
1137
|
+
}
|
|
1138
|
+
/**
|
|
1139
|
+
* Sondea periódicamente el estado de verificación de un flujo Hosted Webflow de Jumio.
|
|
1140
|
+
*
|
|
1141
|
+
* Continúa consultando hasta obtener un resultado definitivo o agotar los intentos.
|
|
1142
|
+
*
|
|
1143
|
+
* @param params `accountId`, `workflowId` y `clientId` opcional.
|
|
1144
|
+
* @param options Opciones de sondeo (`maxAttempts`, `pollingIntervalMs`, `signal`, `onAttempt`).
|
|
1145
|
+
* @returns `WebflowResult` con el resultado definitivo.
|
|
1146
|
+
*
|
|
1147
|
+
* @example
|
|
1148
|
+
* ```ts
|
|
1149
|
+
* // En el componente de retorno, tras leer los params de la URL:
|
|
1150
|
+
* const result = await client.pollWebflowStatus({ accountId, workflowId, clientId });
|
|
1151
|
+
* if (result.valid) {
|
|
1152
|
+
* console.log("Verificación aprobada:", result.extraction);
|
|
1153
|
+
* } else {
|
|
1154
|
+
* console.warn("Rechazado:", result.errorMessage);
|
|
1155
|
+
* }
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
1158
|
+
async pollWebflowStatus(params, options) {
|
|
1159
|
+
return pollWebflowStatus(this.http, params, options);
|
|
1160
|
+
}
|
|
738
1161
|
};
|
|
739
1162
|
function createJumioClient(config) {
|
|
740
1163
|
return new JumioClient(config);
|
|
741
1164
|
}
|
|
742
1165
|
|
|
743
|
-
exports.APPROVED_JUMIO_STATUSES = APPROVED_JUMIO_STATUSES;
|
|
744
|
-
exports.FINAL_JUMIO_STATUSES = FINAL_JUMIO_STATUSES;
|
|
745
|
-
exports.JumioAbortError = JumioAbortError;
|
|
746
1166
|
exports.JumioClient = JumioClient;
|
|
747
|
-
exports.JumioError = JumioError;
|
|
748
1167
|
exports.JumioHttpClient = JumioHttpClient;
|
|
749
|
-
exports.JumioImageProcessingError = JumioImageProcessingError;
|
|
750
|
-
exports.JumioNetworkError = JumioNetworkError;
|
|
751
|
-
exports.JumioPollingTimeoutError = JumioPollingTimeoutError;
|
|
752
|
-
exports.JumioTimeoutError = JumioTimeoutError;
|
|
753
|
-
exports.JumioValidationError = JumioValidationError;
|
|
754
1168
|
exports.arrayBufferToBase64 = arrayBufferToBase64;
|
|
755
1169
|
exports.blobToBase64 = blobToBase64;
|
|
1170
|
+
exports.buildRedirectUrl = buildRedirectUrl;
|
|
756
1171
|
exports.createJumioClient = createJumioClient;
|
|
757
1172
|
exports.delay = delay;
|
|
1173
|
+
exports.encodeUrlToBase64UrlSafe = encodeUrlToBase64UrlSafe;
|
|
758
1174
|
exports.extractEnvelopeData = extractEnvelopeData;
|
|
759
1175
|
exports.extractJumioMessage = extractJumioMessage;
|
|
760
1176
|
exports.extractNestedData = extractNestedData;
|
|
@@ -765,10 +1181,14 @@ exports.isFinalJumioStatus = isFinalJumioStatus;
|
|
|
765
1181
|
exports.isJumioError = isJumioError;
|
|
766
1182
|
exports.isPassedJumioDecision = isPassedJumioDecision;
|
|
767
1183
|
exports.normalizeSignedUrl = normalizeSignedUrl;
|
|
1184
|
+
exports.parseWebflowReturnParams = parseWebflowReturnParams;
|
|
768
1185
|
exports.pollJumioStatus = pollJumioStatus;
|
|
1186
|
+
exports.pollWebflowStatus = pollWebflowStatus;
|
|
769
1187
|
exports.resolveImageSourceToBase64 = resolveImageSourceToBase64;
|
|
770
1188
|
exports.resolveVerificationValidity = resolveVerificationValidity;
|
|
1189
|
+
exports.resolveWebflowResult = resolveWebflowResult;
|
|
771
1190
|
exports.shouldRetryJumio = shouldRetryJumio;
|
|
1191
|
+
exports.startWebflowSession = startWebflowSession;
|
|
772
1192
|
exports.stripDataUrlPrefix = stripDataUrlPrefix;
|
|
773
1193
|
exports.toLowerText = toLowerText;
|
|
774
1194
|
exports.toUpperText = toUpperText;
|