@flonkid/kyc 1.8.1 → 1.9.0
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 +108 -2
- package/dist/index.cjs +330 -87
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +128 -4
- package/dist/index.d.ts +128 -4
- package/dist/index.js +325 -88
- package/dist/index.js.map +1 -1
- package/dist/server.cjs +102 -32
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +938 -36
- package/dist/server.d.ts +938 -36
- package/dist/server.js +103 -33
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +950 -34
- package/package.json +78 -49
package/dist/index.js
CHANGED
|
@@ -2,14 +2,31 @@ import { useRef, useMemo, useEffect } from 'react';
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
|
|
4
4
|
// src/shared/constants.ts
|
|
5
|
-
var SDK_VERSION = "1.
|
|
5
|
+
var SDK_VERSION = "1.9.0";
|
|
6
6
|
var DEFAULT_WIDGET_URL = "https://widget.flonk.id";
|
|
7
7
|
var DEFAULT_API_BASE = "https://api.flonk.id/v1";
|
|
8
|
+
var API_VERSION = "2026-06-01";
|
|
9
|
+
var PROTOCOL_VERSION = 1;
|
|
8
10
|
var WIDGET_EVENTS = {
|
|
9
11
|
READY: "KYC_WIDGET_READY",
|
|
10
12
|
COMPLETE: "KYC_COMPLETE",
|
|
11
13
|
CANCEL: "KYC_CANCEL",
|
|
12
|
-
ERROR: "KYC_ERROR"
|
|
14
|
+
ERROR: "KYC_ERROR",
|
|
15
|
+
CONFIG: "KYC_WIDGET_CONFIG"
|
|
16
|
+
};
|
|
17
|
+
var WIDGET_PARAMS = {
|
|
18
|
+
PROTOCOL_VERSION: "pv",
|
|
19
|
+
SESSION_ID: "sessionId",
|
|
20
|
+
EMBED_TOKEN: "embedToken",
|
|
21
|
+
TOKEN: "token",
|
|
22
|
+
PUBLISHABLE_KEY: "publishableKey",
|
|
23
|
+
CLIENT_ID: "clientId",
|
|
24
|
+
CLIENT_METADATA: "clientMetadata",
|
|
25
|
+
DESIGN_TOKENS: "designTokens",
|
|
26
|
+
ALLOW_MANUAL_UPLOAD: "allowManualUpload",
|
|
27
|
+
LANG: "lang",
|
|
28
|
+
OVERLAY_COLOR: "overlayColor",
|
|
29
|
+
MODE: "mode"
|
|
13
30
|
};
|
|
14
31
|
|
|
15
32
|
// src/shared/errors.ts
|
|
@@ -197,24 +214,6 @@ async function fetchSessionFromServer(serverUrl, clientMetadata, requestHeaders)
|
|
|
197
214
|
sessionCreateInflight.set(key, promise);
|
|
198
215
|
return promise;
|
|
199
216
|
}
|
|
200
|
-
async function fetchPublicSession(apiBase, sessionId, embedToken) {
|
|
201
|
-
const res = await fetchWithTimeout(`${apiBase}/public/session/${sessionId}`, {
|
|
202
|
-
headers: {
|
|
203
|
-
"Content-Type": "application/json",
|
|
204
|
-
"Authorization": `Bearer ${embedToken}`
|
|
205
|
-
}
|
|
206
|
-
});
|
|
207
|
-
if (!res.ok) {
|
|
208
|
-
let message = `Failed to fetch session (${res.status})`;
|
|
209
|
-
try {
|
|
210
|
-
const b = await res.json();
|
|
211
|
-
message = b.error || b.message || message;
|
|
212
|
-
} catch {
|
|
213
|
-
}
|
|
214
|
-
throw new Error(message);
|
|
215
|
-
}
|
|
216
|
-
return res.json();
|
|
217
|
-
}
|
|
218
217
|
async function exchangeSessionForToken(apiBase, sessionId) {
|
|
219
218
|
const res = await fetchWithTimeout(`${apiBase}/public/session/${sessionId}/token`, {
|
|
220
219
|
method: "POST",
|
|
@@ -245,10 +244,14 @@ function createIframe(src) {
|
|
|
245
244
|
top: "0",
|
|
246
245
|
left: "0",
|
|
247
246
|
zIndex: "9999",
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
// Hidden until reveal so the loader overlay doesn't show the iframe's own
|
|
248
|
+
// loading state through its translucent backdrop (double loader). Reveal
|
|
249
|
+
// is gated on READY-OR-a-timeout (see index.ts), so a missing READY can't
|
|
250
|
+
// leave it permanently hidden — that timeout is what removed the deadlock.
|
|
250
251
|
opacity: "0",
|
|
251
252
|
visibility: "hidden",
|
|
253
|
+
background: "transparent",
|
|
254
|
+
backgroundColor: "transparent",
|
|
252
255
|
borderRadius: d ? "0" : "",
|
|
253
256
|
boxShadow: d ? "none" : "",
|
|
254
257
|
colorScheme: "normal"
|
|
@@ -283,15 +286,15 @@ function adjustZIndex(loader, iframe) {
|
|
|
283
286
|
function transitionLoaderToIframe(loader, iframe, onDone) {
|
|
284
287
|
const d = isDesktop();
|
|
285
288
|
const dur = d ? 300 : 500;
|
|
286
|
-
setStyles(iframe, { opacity: "0", visibility: "hidden" });
|
|
287
289
|
const card = loader.querySelector("div");
|
|
288
290
|
if (card) {
|
|
289
291
|
setStyles(card, {
|
|
292
|
+
transition: "transform 300ms ease-out, opacity 300ms ease-out",
|
|
290
293
|
transform: d ? "translateY(-10px) scale(0.98)" : "translateY(-15px) scale(0.96)",
|
|
291
294
|
opacity: "0"
|
|
292
295
|
});
|
|
293
296
|
}
|
|
294
|
-
loader
|
|
297
|
+
setStyles(loader, { transition: "opacity 300ms ease-out", opacity: "0" });
|
|
295
298
|
setTimeout(() => {
|
|
296
299
|
onDone();
|
|
297
300
|
setStyles(iframe, {
|
|
@@ -302,6 +305,160 @@ function transitionLoaderToIframe(loader, iframe, onDone) {
|
|
|
302
305
|
}, dur);
|
|
303
306
|
}
|
|
304
307
|
|
|
308
|
+
// src/browser/diagnostics.ts
|
|
309
|
+
var handlers = /* @__PURE__ */ new Set();
|
|
310
|
+
function addDiagnosticHandler(handler) {
|
|
311
|
+
handlers.add(handler);
|
|
312
|
+
return () => {
|
|
313
|
+
handlers.delete(handler);
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
function debugEnabled() {
|
|
317
|
+
try {
|
|
318
|
+
return Boolean(globalThis.__FLONK_DEBUG__);
|
|
319
|
+
} catch {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function emitDiagnostic(code, level, message, detail) {
|
|
324
|
+
const event = { code, level, message, detail };
|
|
325
|
+
if (debugEnabled()) {
|
|
326
|
+
try {
|
|
327
|
+
const fn = level === "error" ? console.error : level === "warn" ? console.warn : console.log;
|
|
328
|
+
fn(`[flonk:${code}] ${message}`, detail ?? "");
|
|
329
|
+
} catch {
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
for (const handler of handlers) {
|
|
333
|
+
try {
|
|
334
|
+
handler(event);
|
|
335
|
+
} catch {
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// src/browser/prewarm.ts
|
|
341
|
+
var noop = () => {
|
|
342
|
+
};
|
|
343
|
+
function originOf(url) {
|
|
344
|
+
try {
|
|
345
|
+
return new URL(url).origin;
|
|
346
|
+
} catch {
|
|
347
|
+
return url.replace(/\/+$/, "");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
function addLinkHint(doc, rel, href, attrs) {
|
|
351
|
+
try {
|
|
352
|
+
const existing = doc.querySelector(`link[rel="${rel}"][href="${href}"]`);
|
|
353
|
+
if (existing) return;
|
|
354
|
+
const link = doc.createElement("link");
|
|
355
|
+
link.rel = rel;
|
|
356
|
+
link.href = href;
|
|
357
|
+
if (attrs) for (const k of Object.keys(attrs)) link.setAttribute(k, attrs[k]);
|
|
358
|
+
(doc.head || doc.documentElement).appendChild(link);
|
|
359
|
+
} catch {
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
function preconnect(widgetUrl, doc = document) {
|
|
363
|
+
const origin = originOf(widgetUrl);
|
|
364
|
+
addLinkHint(doc, "preconnect", origin, { crossorigin: "" });
|
|
365
|
+
addLinkHint(doc, "dns-prefetch", origin);
|
|
366
|
+
}
|
|
367
|
+
function defaultScheduleIdle(fn) {
|
|
368
|
+
if (typeof window === "undefined") {
|
|
369
|
+
fn();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
const w = window;
|
|
373
|
+
const run = () => {
|
|
374
|
+
if (typeof w.requestIdleCallback === "function") {
|
|
375
|
+
w.requestIdleCallback(fn, { timeout: 2e3 });
|
|
376
|
+
} else {
|
|
377
|
+
setTimeout(fn, 200);
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
if (document.readyState === "complete") run();
|
|
381
|
+
else window.addEventListener("load", run, { once: true });
|
|
382
|
+
}
|
|
383
|
+
function prewarm(options) {
|
|
384
|
+
const level = options.level ?? "connect";
|
|
385
|
+
const doc = options.doc ?? (typeof document !== "undefined" ? document : void 0);
|
|
386
|
+
if (level === "none" || !doc) {
|
|
387
|
+
emitDiagnostic("PREWARM_SKIPPED", "info", `Prewarm skipped (level=${level}${doc ? "" : ", no document"}).`);
|
|
388
|
+
return noop;
|
|
389
|
+
}
|
|
390
|
+
const scheduleIdle = options.scheduleIdle ?? defaultScheduleIdle;
|
|
391
|
+
const origin = originOf(options.widgetUrl);
|
|
392
|
+
preconnect(options.widgetUrl, doc);
|
|
393
|
+
const warmAssets = () => {
|
|
394
|
+
if (options.apiBase) {
|
|
395
|
+
const q = options.publishableKey ? `pk=${encodeURIComponent(options.publishableKey)}` : options.sessionId ? `sessionId=${encodeURIComponent(options.sessionId)}` : "";
|
|
396
|
+
addLinkHint(doc, "prefetch", `${options.apiBase}/v1/public/design-tokens${q ? `?${q}` : ""}`);
|
|
397
|
+
}
|
|
398
|
+
addLinkHint(doc, "prefetch", `${origin}/`, { as: "document" });
|
|
399
|
+
};
|
|
400
|
+
if (level === "intent") {
|
|
401
|
+
return attachIntent(doc, options.trigger ?? null, () => {
|
|
402
|
+
warmAssets();
|
|
403
|
+
mountHiddenIframe(doc, origin);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
scheduleIdle(() => {
|
|
407
|
+
warmAssets();
|
|
408
|
+
if (level === "eager") mountHiddenIframe(doc, origin);
|
|
409
|
+
});
|
|
410
|
+
return noop;
|
|
411
|
+
}
|
|
412
|
+
function attachIntent(doc, trigger, warm) {
|
|
413
|
+
let fired = false;
|
|
414
|
+
const fire = () => {
|
|
415
|
+
if (fired) return;
|
|
416
|
+
fired = true;
|
|
417
|
+
cleanup();
|
|
418
|
+
warm();
|
|
419
|
+
};
|
|
420
|
+
const events = [
|
|
421
|
+
["mouseenter", fire],
|
|
422
|
+
["focusin", fire],
|
|
423
|
+
["touchstart", fire]
|
|
424
|
+
];
|
|
425
|
+
let io = null;
|
|
426
|
+
const cleanup = () => {
|
|
427
|
+
if (trigger) for (const [type, fn] of events) trigger.removeEventListener(type, fn);
|
|
428
|
+
if (io) {
|
|
429
|
+
io.disconnect();
|
|
430
|
+
io = null;
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
if (trigger) {
|
|
434
|
+
for (const [type, fn] of events) trigger.addEventListener(type, fn, { passive: true });
|
|
435
|
+
const w = doc.defaultView || (typeof window !== "undefined" ? window : void 0);
|
|
436
|
+
if (w && typeof w.IntersectionObserver === "function") {
|
|
437
|
+
const observer = new w.IntersectionObserver((entries) => {
|
|
438
|
+
if (entries.some((e) => e.isIntersecting)) fire();
|
|
439
|
+
});
|
|
440
|
+
observer.observe(trigger);
|
|
441
|
+
io = observer;
|
|
442
|
+
}
|
|
443
|
+
} else {
|
|
444
|
+
defaultScheduleIdle(fire);
|
|
445
|
+
}
|
|
446
|
+
return cleanup;
|
|
447
|
+
}
|
|
448
|
+
function mountHiddenIframe(doc, origin) {
|
|
449
|
+
try {
|
|
450
|
+
if (doc.querySelector("iframe[data-flonk-prewarm]")) return;
|
|
451
|
+
const iframe = doc.createElement("iframe");
|
|
452
|
+
iframe.src = `${origin}/?prewarm=1`;
|
|
453
|
+
iframe.setAttribute("data-flonk-prewarm", "1");
|
|
454
|
+
iframe.setAttribute("aria-hidden", "true");
|
|
455
|
+
iframe.tabIndex = -1;
|
|
456
|
+
iframe.style.cssText = "position:absolute;width:1px;height:1px;left:-9999px;top:-9999px;border:0;opacity:0;pointer-events:none";
|
|
457
|
+
(doc.body || doc.documentElement).appendChild(iframe);
|
|
458
|
+
} catch {
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
305
462
|
// src/browser/loader.ts
|
|
306
463
|
var LOADER_I18N = {
|
|
307
464
|
en: { title: "Initializing...", subtitle: "Loading KYC widget", errorTitle: "Something went wrong", close: "Close" },
|
|
@@ -551,8 +708,81 @@ var Loader = class {
|
|
|
551
708
|
this.cleanup = null;
|
|
552
709
|
}
|
|
553
710
|
};
|
|
711
|
+
function isServerLoaderReady() {
|
|
712
|
+
return typeof window !== "undefined" && !!window.FlonkWidgetLoader?.show;
|
|
713
|
+
}
|
|
714
|
+
var serverScriptRequested = false;
|
|
715
|
+
function loadServerLoaderScript(apiBase, pk, sessionId) {
|
|
716
|
+
if (typeof document === "undefined" || serverScriptRequested || isServerLoaderReady()) return;
|
|
717
|
+
serverScriptRequested = true;
|
|
718
|
+
try {
|
|
719
|
+
const q = pk ? `?publishableKey=${encodeURIComponent(pk)}` : sessionId ? `?sessionId=${encodeURIComponent(sessionId)}` : "";
|
|
720
|
+
const s = document.createElement("script");
|
|
721
|
+
s.src = `${apiBase}/public/loader.js${q}`;
|
|
722
|
+
s.async = true;
|
|
723
|
+
s.onerror = () => {
|
|
724
|
+
serverScriptRequested = false;
|
|
725
|
+
emitDiagnostic(
|
|
726
|
+
"LOADER_SCRIPT_BLOCKED",
|
|
727
|
+
"warn",
|
|
728
|
+
`Failed to load the server loader (${s.src}). Likely a CSP script-src or CORP block \u2014 allow the API origin in script-src. Falling back to the bundled loader.`,
|
|
729
|
+
{ src: s.src }
|
|
730
|
+
);
|
|
731
|
+
};
|
|
732
|
+
(document.head || document.documentElement).appendChild(s);
|
|
733
|
+
} catch {
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
var ServerLoader = class {
|
|
737
|
+
constructor() {
|
|
738
|
+
this.overlay = null;
|
|
739
|
+
}
|
|
740
|
+
show(primaryColor, lang) {
|
|
741
|
+
this.overlay = window.FlonkWidgetLoader.show({ primaryColor, lang });
|
|
742
|
+
return this.overlay;
|
|
743
|
+
}
|
|
744
|
+
get element() {
|
|
745
|
+
return this.overlay;
|
|
746
|
+
}
|
|
747
|
+
updateColor(primaryColor) {
|
|
748
|
+
this.overlay?.updateColor?.(primaryColor);
|
|
749
|
+
}
|
|
750
|
+
showError(message, lang) {
|
|
751
|
+
this.overlay?.showError?.(message, lang);
|
|
752
|
+
}
|
|
753
|
+
fadeOut() {
|
|
754
|
+
this.overlay?.fadeOut?.();
|
|
755
|
+
}
|
|
756
|
+
destroy() {
|
|
757
|
+
try {
|
|
758
|
+
this.overlay?.remove();
|
|
759
|
+
} catch {
|
|
760
|
+
}
|
|
761
|
+
this.overlay = null;
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
function makeLoader() {
|
|
765
|
+
if (isServerLoaderReady()) return new ServerLoader();
|
|
766
|
+
emitDiagnostic(
|
|
767
|
+
"LOADER_FALLBACK_BUNDLED",
|
|
768
|
+
"info",
|
|
769
|
+
"Server loader not ready at show time \u2014 using the bundled loader."
|
|
770
|
+
);
|
|
771
|
+
return new Loader();
|
|
772
|
+
}
|
|
554
773
|
|
|
555
774
|
// src/browser/message-handler.ts
|
|
775
|
+
function checkProtocol(data) {
|
|
776
|
+
const remote = data.protocolVersion;
|
|
777
|
+
if (typeof remote === "number" && remote !== PROTOCOL_VERSION) {
|
|
778
|
+
emitDiagnostic(
|
|
779
|
+
"PROTOCOL_VERSION_MISMATCH",
|
|
780
|
+
"warn",
|
|
781
|
+
`SDK speaks protocol ${PROTOCOL_VERSION}, iframe speaks ${remote}. Additive-compatible, but check for a stale-cached widget if behavior is off.`,
|
|
782
|
+
{ sdk: PROTOCOL_VERSION, iframe: remote }
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
}
|
|
556
786
|
var MessageHandler = class {
|
|
557
787
|
constructor(iframeSrc, iframe, callbacks) {
|
|
558
788
|
this.iframeSrc = iframeSrc;
|
|
@@ -585,6 +815,7 @@ var MessageHandler = class {
|
|
|
585
815
|
this.completionHandled = true;
|
|
586
816
|
this.callbacks.onError?.(data.error || "Unknown error");
|
|
587
817
|
} else if (type === WIDGET_EVENTS.READY) {
|
|
818
|
+
checkProtocol(data);
|
|
588
819
|
this.callbacks.onReady?.();
|
|
589
820
|
}
|
|
590
821
|
};
|
|
@@ -736,14 +967,55 @@ async function showLoaderWithEarlyColor(tokensPromise, lang) {
|
|
|
736
967
|
new Promise((resolve) => setTimeout(() => resolve(null), EARLY_COLOR_BUDGET_MS))
|
|
737
968
|
]);
|
|
738
969
|
const primaryColor = primaryFrom(earlyTokens);
|
|
739
|
-
const loader =
|
|
970
|
+
const loader = makeLoader();
|
|
740
971
|
loader.show(primaryColor, lang);
|
|
741
972
|
return { loader, primaryColor };
|
|
742
973
|
}
|
|
743
974
|
var FlonkKYC = class {
|
|
744
975
|
constructor(options = {}) {
|
|
976
|
+
this.disposeDiagnostics = null;
|
|
745
977
|
this.widgetUrl = (options.widgetUrl || DEFAULT_WIDGET_URL).replace(/\/$/, "");
|
|
746
978
|
this.apiBase = (options.apiBase || DEFAULT_API_BASE).replace(/\/$/, "");
|
|
979
|
+
if (options.onDiagnostic) this.disposeDiagnostics = addDiagnosticHandler(options.onDiagnostic);
|
|
980
|
+
if (typeof document !== "undefined") {
|
|
981
|
+
try {
|
|
982
|
+
preconnect(this.widgetUrl);
|
|
983
|
+
} catch {
|
|
984
|
+
}
|
|
985
|
+
try {
|
|
986
|
+
loadServerLoaderScript(this.apiBase);
|
|
987
|
+
} catch {
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
/** Unregister this instance's `onDiagnostic` handler. */
|
|
992
|
+
dispose() {
|
|
993
|
+
this.disposeDiagnostics?.();
|
|
994
|
+
this.disposeDiagnostics = null;
|
|
995
|
+
}
|
|
996
|
+
/**
|
|
997
|
+
* Prewarm the widget ahead of the user's click — preconnect + idle prefetch
|
|
998
|
+
* of branding/assets, and (with `level:'eager'`) a hidden background iframe so
|
|
999
|
+
* the full bundle is loaded before the click. Call on page mount / route
|
|
1000
|
+
* enter. Returns a cleanup (removes `intent` listeners). Never pre-creates a
|
|
1001
|
+
* session. SSR-safe.
|
|
1002
|
+
*
|
|
1003
|
+
* @example
|
|
1004
|
+
* FlonkKYC.prewarm({ publishableKey: 'pk_live_…', level: 'eager' });
|
|
1005
|
+
* // or, warm only when the user shows intent:
|
|
1006
|
+
* FlonkKYC.prewarm({ publishableKey: 'pk_live_…', level: 'intent', trigger: btn });
|
|
1007
|
+
*/
|
|
1008
|
+
static prewarm(opts = {}) {
|
|
1009
|
+
if (typeof document === "undefined") return () => {
|
|
1010
|
+
};
|
|
1011
|
+
return prewarm({
|
|
1012
|
+
widgetUrl: (opts.widgetUrl || DEFAULT_WIDGET_URL).replace(/\/$/, ""),
|
|
1013
|
+
apiBase: (opts.apiBase || DEFAULT_API_BASE).replace(/\/$/, ""),
|
|
1014
|
+
publishableKey: opts.publishableKey,
|
|
1015
|
+
sessionId: opts.sessionId,
|
|
1016
|
+
level: opts.level,
|
|
1017
|
+
trigger: opts.trigger ?? null
|
|
1018
|
+
});
|
|
747
1019
|
}
|
|
748
1020
|
/**
|
|
749
1021
|
* Warm the project's branding (colors) ahead of time so the widget paints the
|
|
@@ -894,20 +1166,7 @@ var FlonkKYC = class {
|
|
|
894
1166
|
const finalTokens = designTokens ?? await fetchDesignTokens(this.apiBase, { sessionId });
|
|
895
1167
|
const finalColor = primaryFrom(finalTokens);
|
|
896
1168
|
if (finalColor !== primaryColor) loader.updateColor(finalColor);
|
|
897
|
-
|
|
898
|
-
const session = {
|
|
899
|
-
id: sessionData.id,
|
|
900
|
-
allowManualUpload: sessionData.allowManualUpload ?? config.allowManualUpload ?? true,
|
|
901
|
-
clientMetadata: sessionData.clientMetadata || config.clientMetadata,
|
|
902
|
-
qrCodeUrl: sessionData.qrCodeUrl,
|
|
903
|
-
testMode: sessionData.testMode || false,
|
|
904
|
-
poaEnabled: sessionData.poaEnabled || false,
|
|
905
|
-
poaRequired: sessionData.poaRequired || false,
|
|
906
|
-
mlAutoCaptureEnabled: sessionData.mlAutoCaptureEnabled || false,
|
|
907
|
-
mlCropEnabled: sessionData.mlCropEnabled ?? true,
|
|
908
|
-
mlVerifyEnabled: sessionData.mlVerifyEnabled || false
|
|
909
|
-
};
|
|
910
|
-
return this.buildWidget(embedToken, session, config, loader, finalTokens);
|
|
1169
|
+
return this.buildWidget(embedToken, sessionId, config, loader, finalTokens);
|
|
911
1170
|
} catch (err) {
|
|
912
1171
|
const msg = err.message || "Failed to create session";
|
|
913
1172
|
loader.showError(msg, config.lang);
|
|
@@ -921,32 +1180,12 @@ var FlonkKYC = class {
|
|
|
921
1180
|
async initWithEmbedToken(config) {
|
|
922
1181
|
const pk = config.publishableKey;
|
|
923
1182
|
const designTokensPromise = pk ? fetchDesignTokens(this.apiBase, { pk }) : fetchDesignTokens(this.apiBase, { sessionId: config.sessionId });
|
|
924
|
-
const sessionPromise = fetchPublicSession(
|
|
925
|
-
this.apiBase,
|
|
926
|
-
config.sessionId,
|
|
927
|
-
config.embedToken
|
|
928
|
-
);
|
|
929
1183
|
const { loader, primaryColor } = await showLoaderWithEarlyColor(designTokensPromise, config.lang);
|
|
930
1184
|
try {
|
|
931
|
-
const
|
|
932
|
-
sessionPromise,
|
|
933
|
-
designTokensPromise
|
|
934
|
-
]);
|
|
1185
|
+
const designTokens = await designTokensPromise;
|
|
935
1186
|
const finalColor = primaryFrom(designTokens);
|
|
936
1187
|
if (finalColor !== primaryColor) loader.updateColor(finalColor);
|
|
937
|
-
|
|
938
|
-
id: sessionData.id,
|
|
939
|
-
allowManualUpload: sessionData.allowManualUpload ?? config.allowManualUpload ?? true,
|
|
940
|
-
clientMetadata: sessionData.clientMetadata || config.clientMetadata,
|
|
941
|
-
qrCodeUrl: sessionData.qrCodeUrl,
|
|
942
|
-
testMode: sessionData.testMode || false,
|
|
943
|
-
poaEnabled: sessionData.poaEnabled || false,
|
|
944
|
-
poaRequired: sessionData.poaRequired || false,
|
|
945
|
-
mlAutoCaptureEnabled: sessionData.mlAutoCaptureEnabled || false,
|
|
946
|
-
mlCropEnabled: sessionData.mlCropEnabled ?? true,
|
|
947
|
-
mlVerifyEnabled: sessionData.mlVerifyEnabled || false
|
|
948
|
-
};
|
|
949
|
-
return this.buildWidget(config.embedToken, session, config, loader, designTokens);
|
|
1188
|
+
return this.buildWidget(config.embedToken, config.sessionId, config, loader, designTokens);
|
|
950
1189
|
} catch (err) {
|
|
951
1190
|
const msg = err.message || "Failed to initialize verification";
|
|
952
1191
|
loader.showError(msg, config.lang);
|
|
@@ -972,7 +1211,7 @@ var FlonkKYC = class {
|
|
|
972
1211
|
exchangePromise,
|
|
973
1212
|
designTokensPromise
|
|
974
1213
|
]);
|
|
975
|
-
return this.buildWidget(embedToken, session, config, loader, designTokens);
|
|
1214
|
+
return this.buildWidget(embedToken, config.sessionId || session.id, config, loader, designTokens);
|
|
976
1215
|
} catch (err) {
|
|
977
1216
|
const msg = err.message || "Failed to initialize verification";
|
|
978
1217
|
loader.showError(msg, config.lang);
|
|
@@ -1019,32 +1258,21 @@ var FlonkKYC = class {
|
|
|
1019
1258
|
}
|
|
1020
1259
|
}
|
|
1021
1260
|
// ── Core widget builder ──────────────────────────────
|
|
1022
|
-
buildWidget(token,
|
|
1261
|
+
buildWidget(token, sessionId, config, loader, designTokens) {
|
|
1023
1262
|
const params = {
|
|
1024
1263
|
mode: "embedded",
|
|
1025
|
-
sessionId
|
|
1026
|
-
token
|
|
1027
|
-
allowManualUpload: String(session.allowManualUpload !== false)
|
|
1264
|
+
sessionId,
|
|
1265
|
+
token
|
|
1028
1266
|
};
|
|
1029
|
-
if (
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
if (session.mlAutoCaptureEnabled) params.mlAutoCaptureEnabled = "true";
|
|
1033
|
-
if (session.mlCropEnabled !== false) params.mlCropEnabled = "true";
|
|
1034
|
-
if (session.mlVerifyEnabled) params.mlVerifyEnabled = "true";
|
|
1035
|
-
if (session.vaultReuseEnabled) params.vaultReuseEnabled = "true";
|
|
1036
|
-
if (session.vaultReuseChallenge) params.vaultReuseChallenge = session.vaultReuseChallenge;
|
|
1037
|
-
if (session.faceAutoCapture) params.faceAutoCapture = JSON.stringify(session.faceAutoCapture);
|
|
1038
|
-
if (session.project) params.project = JSON.stringify(session.project);
|
|
1039
|
-
params.policyReady = "1";
|
|
1267
|
+
if (config.allowManualUpload !== void 0) {
|
|
1268
|
+
params.allowManualUpload = String(config.allowManualUpload !== false);
|
|
1269
|
+
}
|
|
1040
1270
|
if (designTokens?.colors) {
|
|
1041
1271
|
params.designTokens = JSON.stringify(designTokens);
|
|
1042
1272
|
}
|
|
1043
1273
|
if (config.embedToken) params.embedToken = config.embedToken;
|
|
1044
|
-
if (
|
|
1045
|
-
|
|
1046
|
-
if (clientMetadata) {
|
|
1047
|
-
params.clientMetadata = JSON.stringify(clientMetadata);
|
|
1274
|
+
if (config.clientMetadata) {
|
|
1275
|
+
params.clientMetadata = JSON.stringify(config.clientMetadata);
|
|
1048
1276
|
}
|
|
1049
1277
|
if (config.lang) params.lang = config.lang;
|
|
1050
1278
|
if (config.overlayColor) params.overlayColor = config.overlayColor;
|
|
@@ -1066,12 +1294,14 @@ var FlonkKYC = class {
|
|
|
1066
1294
|
const filtered = Object.fromEntries(
|
|
1067
1295
|
Object.entries(params).filter(([, v]) => v != null)
|
|
1068
1296
|
);
|
|
1297
|
+
filtered[WIDGET_PARAMS.PROTOCOL_VERSION] = String(PROTOCOL_VERSION);
|
|
1069
1298
|
const search = new URLSearchParams(filtered);
|
|
1070
1299
|
const src = `${this.widgetUrl}/?${search.toString()}`;
|
|
1071
1300
|
const iframe = createIframe(src);
|
|
1301
|
+
emitDiagnostic("IFRAME_FRESH", "info", "Built a fresh widget iframe");
|
|
1072
1302
|
const mountTarget = opts.mount || document.body;
|
|
1073
1303
|
const loader = opts.loader ?? (() => {
|
|
1074
|
-
const l =
|
|
1304
|
+
const l = makeLoader();
|
|
1075
1305
|
l.show(opts.primaryColor, opts.lang);
|
|
1076
1306
|
return l;
|
|
1077
1307
|
})();
|
|
@@ -1107,11 +1337,18 @@ var FlonkKYC = class {
|
|
|
1107
1337
|
onReady: opts.onReady
|
|
1108
1338
|
});
|
|
1109
1339
|
handler.listen();
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1340
|
+
let revealed = false;
|
|
1341
|
+
const revealOnce = () => {
|
|
1342
|
+
if (revealed) return;
|
|
1343
|
+
revealed = true;
|
|
1344
|
+
clearTimeout(revealTimer);
|
|
1345
|
+
if (loader.element) transitionLoaderToIframe(loader.element, iframe, () => loader.destroy());
|
|
1346
|
+
};
|
|
1347
|
+
const revealTimer = setTimeout(() => {
|
|
1348
|
+
emitDiagnostic("READY_TIMEOUT_REVEAL", "warn", "Widget did not signal READY in time; revealing anyway");
|
|
1349
|
+
revealOnce();
|
|
1350
|
+
}, 4e3);
|
|
1351
|
+
handler.onReadyOnce(revealOnce);
|
|
1115
1352
|
return {
|
|
1116
1353
|
iframe,
|
|
1117
1354
|
destroy: cleanupAll
|
|
@@ -1199,6 +1436,6 @@ function FlonkKYCBrandingPreloader({
|
|
|
1199
1436
|
return null;
|
|
1200
1437
|
}
|
|
1201
1438
|
|
|
1202
|
-
export { FlonkError, FlonkKYC, FlonkKYCBrandingPreloader, FlonkKYCWidget, FlonkValidationError };
|
|
1439
|
+
export { API_VERSION, FlonkError, FlonkKYC, FlonkKYCBrandingPreloader, FlonkKYCWidget, FlonkValidationError, PROTOCOL_VERSION, SDK_VERSION, WIDGET_EVENTS, WIDGET_PARAMS, addDiagnosticHandler };
|
|
1203
1440
|
//# sourceMappingURL=index.js.map
|
|
1204
1441
|
//# sourceMappingURL=index.js.map
|