UNPKG

@sumsub/fisherman

Version:

The Sumsub Fisherman is a powerful tool that helps developers integrate fraud detection capabilities into their applications. With Fisherman, you can easily identify and prevent fraudulent activities within your system, providing a safer and more secure e

754 lines (753 loc) 20.8 kB
import j from "fingerprintjs2"; import Ie from "detectincognitojs"; function Z() { return Date.now(); } function Te() { return (/* @__PURE__ */ new Date()).toISOString(); } const xe = "crypto" in window && "randomUUID" in window.crypto; function De() { return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => { const n = Math.random() * 16 | 0; return (e === "x" ? n : n & 3 | 8).toString(16); }); } function Se() { return xe ? crypto.randomUUID() : De(); } const Re = { type: "InvalidToken", message: "Token is invalid, make sure you generate a new one each time, because the old ones are invalidated upon usage" }; async function Ae(e, n, t, r, i) { const a = await fetch(`${t}${r}`, { method: "POST", body: JSON.stringify(e), headers: { "Content-Type": "application/json", "X-Access-Token": n, "X-Client-Id": "fisherman" } }); i(a.status, e); } async function Ue({ payload: e, token: n, baseUrl: t, path: r }) { return fetch(`${t}${r}`, { method: "POST", body: JSON.stringify(e), headers: { "Content-Type": "application/json", "X-Access-Token": n, "X-Client-Id": "fisherman" } }); } const Oe = 2e3, Ne = atob("aHR0cHM6Ly9jb2NrcGl0LnN1bXN1Yi5jb20="), Pe = Math.random().toString(36).substring(0, 8), ee = `/resources/bhv/evts/${Pe}`, ne = "/resources/di/req"; let b, M, te, U, y, F, $, C = ee, V = ne; function ke(e) { b = e, N(b.token); } function Le(e) { e && (C = e); } function _e(e) { e && (V = e); } function je() { re(), te = void 0, N(void 0), M = void 0, C = ee, V = ne; } async function O(e, n) { return await Me( Fe( e, { fpRequestId: n == null ? void 0 : n.fpRequestId, fpVisitorId: n == null ? void 0 : n.fpVisitorId, fpSimulation: n == null ? void 0 : n.fpSimulation }, n == null ? void 0 : n.behavioralDataEnabled ) ); } function Fe(e, n = {}, t = !0) { e.capturedAt = Te(); const r = Se(), i = "deviceFingerprint" in e || !t, a = { id: r, predecessorEventId: M, deviceSessionId: te, ...n, [i ? "initData" : "interactionData"]: e }; return M = r, a; } async function Me(e, n) { y === void 0 && (y = []), !F && e.initData ? (F = !0, y.unshift(e)) : y.push(e), F && ($ || ($ = setTimeout(ie, Oe))); } function re() { y = void 0, $ = void 0; } async function ie() { if (y != null && y.length && U) { const e = [...y]; re(), await Ae(e, U, H(), C, qe); } } function H() { return b.baseUrl !== void 0 ? b.baseUrl : Ne; } async function $e() { if (b.accessTokenUpdateHandler) { const e = await b.accessTokenUpdateHandler(); N(e); } } async function Be(e) { await $e(), y === void 0 && (y = []), y.unshift(...e), await ie(); } async function qe(e, n) { e === 401 && (b.accessTokenUpdateHandler ? await Be(n) : N(void 0), b.onError && b.onError(Re)); } async function oe(e) { if (U) return Ue({ payload: e, token: U, baseUrl: H(), path: V }); } function N(e) { U = e; } const ae = "focus"; let k, z = 0; function Ke() { k = () => { z++, O({ event: "focus", count: z }); }, window.addEventListener(ae, k); } function Ce() { k && window.removeEventListener(ae, k); } function Ve(e) { if (e.target instanceof Element) { const n = e.target, t = n.getAttribute("type"), r = t ? `[${t}]` : "", i = n.id ? `#${n.id}` : ""; return `${n.tagName}${r}${i}`; } } const He = [ // Modifier keys "Alt", "Control", "Meta", "Shift", // Whitespace keys "Enter", "Tab", // Navigation keys "ArrowDown", "ArrowLeft", "ArrowRight", "ArrowUp", "End", "Home", // Editing keys "Backspace", "Delete", // UI keys "Escape" ]; function Ge(e) { if (He.includes(e)) return e; } function ce(e) { return e instanceof Element; } const Xe = typeof window.WeakMap == "function", D = Xe ? /* @__PURE__ */ new WeakMap() : void 0; function We(e) { return D == null ? void 0 : D.get(e); } function ze(e, n) { D == null || D.set(e, n); } const Je = ["type", "autocomplete", "autofocus", "placeholder", "aria-label"]; function Ye(e) { const n = e.parentNode, t = e.tagName; if (n) { const r = Array.from(n.childNodes).filter( (i) => ce(i) && t === i.tagName ); if (r.length > 1) { const i = r.indexOf(e); if (i > -1) return `:nth-of-type(${i + 1})`; } } return ""; } function Qe(e) { const n = e.id ? `#${e.id}` : "", t = Ye(e), r = Je.map((i) => { if (e.hasAttribute(i)) { const a = e.getAttribute(i); return `[${a ? `${i}="${a}"` : i}]`; } }).filter(Boolean).join(""); return ( // INPUT e.tagName + // #id n + // :nth-of-type(2) t + // [type="email"][autocomplete="email"][autofocus][aria-label="Email or username"] r ); } function Ze(e) { const n = [e]; let t = e; for (; t.parentElement; ) { const i = t.parentElement; n.push(i), t = i; } const r = n.reverse().map(Qe).join(" > "); return j.x64hash128(r, 31); } function en(e) { if (ce(e.target)) { const n = e.target; let t = We(n); return t || (t = Ze(n), ze(n, t)), t; } } const se = ["keydown", "keyup"], ue = ["mousemove", "mousedown"], de = ["paste", "focusin", "change", ...ue, ...se]; let w, m; function fe() { w = /* @__PURE__ */ new Map(), m = []; } function nn(e) { let n; return e.type === "change" && (m && (m == null ? void 0 : m.length) > 0 && (n = m), fe()), n; } function tn({ key: e }) { w && w.get(e) === void 0 && w.set(e, Z()); } function rn({ key: e }) { const n = w == null ? void 0 : w.get(e); if (w && n) { m === void 0 && (m = []), w.delete(e); const t = { start: n, end: Z() }, r = Ge(e); r && (t.key = r), m.push(t); } } function G(e) { const n = e.type; if (n === "keydown" ? tn(e) : n === "keyup" && rn(e), !se.includes(n)) { const t = { event: n, trusted: e.isTrusted, el: Ve(e), elUid: en(e), cadence: nn(e) }; O(t); } ue.includes(n) && document.removeEventListener(n, G); } function on() { fe(), de.forEach((e) => document.addEventListener(e, G)); } function an() { de.forEach((e) => document.removeEventListener(e, G)), w = void 0, m = void 0; } const le = "deviceorientation"; let S; function cn(e) { const n = e.alpha !== null ? e.alpha : 0, t = e.beta !== null ? e.beta : 0, r = e.gamma !== null ? e.gamma : 0, i = Math.abs(t) > Math.abs(r) ? "portrait" : "landscape"; return { alpha: n, beta: t, gamma: r, orientation: i }; } async function sn() { if (!S) { const e = "DeviceOrientationEvent" in window; return e && (S = (n) => { O({ event: "orientation", orientation: cn(n) }), pe(); }, window.addEventListener(le, S)), { supported: e }; } } function pe() { S && (window.removeEventListener(le, S), S = void 0); } const un = "not available", dn = [ "userAgent", "webdriver", "language", "colorDepth", "deviceMemory", "pixelRatio", "hardwareConcurrency", "timezoneOffset", "timezone", "sessionStorage", "localStorage", "indexedDb", "openDatabase", "platform", "doNotTrack", "plugins", "canvas", "webgl", "webglVendorAndRenderer", "adBlock", "hasLiedOs", "hasLiedBrowser", "touchSupport", "fonts", "audio" ], B = 200, fn = (e, n) => { switch (e) { case "touchSupport": return hn(n); case "plugins": return gn(n); case "webgl": case "canvas": return yn(n); default: return ln(n); } }, ln = (e) => typeof e == "string" ? ge(e) : Array.isArray(e) ? pn(e) : e, ge = (e) => e.length > B ? he(e) : e, pn = (e) => ((e == null ? void 0 : e.length) > B && e.splice(0, B), e.map((n) => typeof n == "string" ? ge(n) : n)), gn = (e) => { if (Array.isArray(e) && e.length > 0) return e.map((n) => Array.isArray(n) ? n[0] : ""); }, hn = (e) => { if ((e == null ? void 0 : e.length) === 3) try { return { maxTouchPoints: Number(e[0]), touchEvent: !!e[1], touchStart: !!e[2] }; } catch { return; } }, he = (e) => j.x64hash128(e, 31), yn = (e) => { if (e) return he(e.toString()); }, wn = 500; async function J(e) { const n = await vn(), t = []; n.forEach(({ key: r, value: i }) => { if (t.push(i), dn.includes(r) && i !== un) { const a = fn(r, i); a !== void 0 && (e[r] = a); } }), e.deviceFingerprint = j.x64hash128(t.join(""), 31); } async function mn(e) { return new Promise((n, t) => { typeof window.requestIdleCallback == "function" ? requestIdleCallback(async () => { n(await J(e)); }) : setTimeout(async () => { n(await J(e)); }, wn); }); } function vn() { return new Promise((e) => j.get(e)); } function P() { return navigator instanceof window.Navigator; } async function bn(e) { var n; return !!(P() && typeof ((n = navigator.permissions) == null ? void 0 : n.query) == "function" && (await navigator.permissions.query({ name: e })).state === "granted"); } async function En() { return new Promise((e) => { navigator.geolocation.getCurrentPosition( (n) => { const t = n.coords.latitude, r = n.coords.longitude; e(`${t}:${r}`); }, () => { e("unknown"); } ); }); } async function In() { const e = await bn("geolocation"), n = { permissionGranted: e }; return P() && e && navigator.geolocation && (n.location = await En()), n; } async function Tn() { if (P() && "getBattery" in navigator && typeof navigator.getBattery == "function") { const e = await navigator.getBattery(); if (e) return { level: e.level, charging: e.charging }; } } async function xn() { var e; if (P() && typeof ((e = navigator.mediaDevices) == null ? void 0 : e.enumerateDevices) == "function") return (await navigator.mediaDevices.enumerateDevices()).map(({ kind: t, label: r, deviceId: i, groupId: a }) => ({ kind: t, // "|| undefined" to eliminate empty strings label: r || void 0, deviceId: i || void 0, groupId: a || void 0 })); } function Dn() { let e; try { throw "a"; } catch (n) { try { n.toSource(), e = !0; } catch { e = !1; } } return e; } const Sn = "notDetected"; async function Rn() { try { return await Ie(); } catch { return { browserName: Sn }; } } async function An() { var f; const e = {}, { width: n, height: t, availWidth: r, availHeight: i } = window.screen; e.width = n, e.height = t, e.availableWidth = r, e.availableHeight = i, await mn(e); const a = await Rn(); if (e.browser = a.browserName, e.incognito = a.isPrivate, P() && "userAgentData" in navigator) { const c = navigator.userAgentData; e.mobile = c == null ? void 0 : c.mobile; } (f = navigator.languages) != null && f.length && (e.languages = [...navigator.languages]), e.geolocation = await In(); const o = await Tn(); o && (e.battery = o); const u = await xn(); u && (e.mediaDevices = u); const d = await sn(); d && (e.orientation = d), e.oscpu = navigator.oscpu, e.productSub = navigator.productSub, e.evalLength = eval.toString().length, e.errFirefox = Dn(), O(e); } const ye = "navigate"; let A, q; var Q; const Un = typeof ((Q = window.navigation) == null ? void 0 : Q.addEventListener) == "function"; function On() { var e; Un && (A = () => { const n = Pn(); n !== q && (q = n, O({ event: "urlchanged" })); }, (e = window.navigation) == null || e.addEventListener(ye, A)); } function Nn() { var e; A && ((e = window.navigation) == null || e.removeEventListener(ye, A), A = void 0, q = void 0); } function Pn() { return window.location.href; } var L = function() { return L = Object.assign || function(n) { for (var t, r = 1, i = arguments.length; r < i; r++) { t = arguments[r]; for (var a in t) Object.prototype.hasOwnProperty.call(t, a) && (n[a] = t[a]); } return n; }, L.apply(this, arguments); }; function kn(e, n) { var t = {}; for (var r in e) Object.prototype.hasOwnProperty.call(e, r) && n.indexOf(r) < 0 && (t[r] = e[r]); if (e != null && typeof Object.getOwnPropertySymbols == "function") for (var i = 0, r = Object.getOwnPropertySymbols(e); i < r.length; i++) n.indexOf(r[i]) < 0 && Object.prototype.propertyIsEnumerable.call(e, r[i]) && (t[r[i]] = e[r[i]]); return t; } function Ln(e, n, t) { if (t || arguments.length === 2) for (var r = 0, i = n.length, a; r < i; r++) (a || !(r in n)) && (a || (a = Array.prototype.slice.call(n, 0, r)), a[r] = n[r]); return e.concat(a || Array.prototype.slice.call(n)); } function _n(e, n) { return function(t, r) { return Object.prototype.hasOwnProperty.call(t, r); }(e, n) ? e[n] : void 0; } function jn(e, n, t, r) { var i, a = document, o = "securitypolicyviolation", u = function(f) { var c = new URL(e, location.href), s = f.blockedURI; s !== c.href && s !== c.protocol.slice(0, -1) && s !== c.origin || (i = f, d()); }; a.addEventListener(o, u); var d = function() { return a.removeEventListener(o, u); }; return Promise.resolve().then(n).then(function(f) { return d(), f; }, function(f) { return new Promise(function(c) { var s = new MessageChannel(); s.port1.onmessage = function() { return c(); }, s.port2.postMessage(null); }).then(function() { if (d(), i) return t(i); throw f; }); }); } var we = "Blocked by CSP", me = "The endpoint parameter is not a valid URL", Fn = "API key required", Mn = "3.11.8", X = "Failed to load the JS script of the agent", W = "9319"; function $n(e, n) { var t, r, i, a, o, u, d, f = [], c = (t = function(g) { var p = Ln([], g, !0); return { current: function() { return p[0]; }, postpone: function() { var l = p.shift(); l !== void 0 && p.push(l); }, exclude: function() { p.shift(); } }; }(e), a = 100, o = 3e3, u = 0, r = function() { return Math.random() * Math.min(o, a * Math.pow(2, u++)); }, i = /* @__PURE__ */ new Set(), [t.current(), function(g, p) { var l, h = p instanceof Error ? p.message : ""; if (h === we || h === me) t.exclude(), l = 0; else if (h === W) t.exclude(); else if (h === X) { var x = Date.now() - g.getTime() < 50, T = t.current(); T && x && !i.has(T) && (i.add(T), l = 0), t.postpone(); } else t.postpone(); var R = t.current(); return R === void 0 ? void 0 : [R, l ?? g.getTime() + r() - Date.now()]; }]), s = c[0], E = c[1]; if (s === void 0) return Promise.reject(new TypeError("The list of script URL patterns is empty")); var I = function(g) { var p = /* @__PURE__ */ new Date(), l = function(x) { return f.push({ url: g, startedAt: p, finishedAt: /* @__PURE__ */ new Date(), error: x }); }, h = n(g); return h.then(function() { return l(); }, l), h.catch(function(x) { if (d != null || (d = x), f.length >= 5) throw d; var T = E(p, x); if (!T) throw d; var R, ve = T[0], be = T[1]; return (R = be, new Promise(function(Ee) { return setTimeout(Ee, R); })).then(function() { return I(ve); }); }); }; return I(s).then(function(g) { return [g, f]; }); } var Bn = "https://fpnpmcdn.net/v<version>/<apiKey>/loader_v<loaderVersion>.js"; function qn(e) { var n; e.scriptUrlPattern; var t = e.token, r = e.apiKey, i = r === void 0 ? t : r, a = kn(e, ["scriptUrlPattern", "token", "apiKey"]), o = (n = _n(e, "scriptUrlPattern")) !== null && n !== void 0 ? n : Bn, u = function() { var c = [], s = function() { c.push({ time: /* @__PURE__ */ new Date(), state: document.visibilityState }); }, E = function(I, g, p, l) { return I.addEventListener(g, p, l), function() { return I.removeEventListener(g, p, l); }; }(document, "visibilitychange", s); return s(), [c, E]; }(), d = u[0], f = u[1]; return Promise.resolve().then(function() { if (!i || typeof i != "string") throw new Error(Fn); var c = function(s, E) { return (Array.isArray(s) ? s : [s]).map(function(I) { return function(g, p) { var l = encodeURIComponent; return g.replace(/<[^<>]+>/g, function(h) { return h === "<version>" ? "3" : h === "<apiKey>" ? l(p) : h === "<loaderVersion>" ? l(Mn) : h; }); }(String(I), E); }); }(o, i); return $n(c, Kn); }).catch(function(c) { throw f(), function(s) { return s instanceof Error && s.message === W ? new Error(X) : s; }(c); }).then(function(c) { var s = c[0], E = c[1]; return f(), s.load(L(L({}, a), { ldi: { attempts: E, visibilityStates: d } })); }); } function Kn(e) { return jn(e, function() { return function(n) { return new Promise(function(t, r) { if (function(u) { if (URL.prototype) try { return new URL(u, location.href), !1; } catch (d) { if (d instanceof Error && d.name === "TypeError") return !0; throw d; } }(n)) throw new Error(me); var i = document.createElement("script"), a = function() { var u; return (u = i.parentNode) === null || u === void 0 ? void 0 : u.removeChild(i); }, o = document.head || document.getElementsByTagName("head")[0]; i.onload = function() { a(), t(); }, i.onerror = function() { a(), r(new Error(X)); }, i.async = !0, i.src = n, o.appendChild(i); }); }(e); }, function() { throw new Error(we); }).then(Cn); } function Cn() { var e = window, n = "__fpjs_p_l_b", t = e[n]; if (function(r, i) { var a, o = (a = Object.getOwnPropertyDescriptor) === null || a === void 0 ? void 0 : a.call(Object, r, i); o != null && o.configurable ? delete r[i] : o && !o.writable || (r[i] = void 0); }(e, n), typeof (t == null ? void 0 : t.load) != "function") throw new Error(W); return t; } var Vn = { load: qn }; async function Hn(e, n) { const t = `${n}/resources/di/info`; return fetch(t, { headers: { "Content-Type": "application/json", "X-Access-Token": e, "X-Client-Id": "fisherman" } }).then((r) => { if (r.status !== 204) return r.json(); }); } const Gn = "https://fpmetrics.sumsub.com"; let _, v; async function Xn(e, n) { let t = !1, r = !1, i, a; try { const o = await Hn(e, H()), u = (o == null ? void 0 : o.fpUrl) || Gn; r = !!(o != null && o.bhvEnabled), i = o == null ? void 0 : o.evRelUrl, a = o == null ? void 0 : o.fpReqRelUrl, o != null && o.fpKey && (_ = await Vn.load({ apiKey: o.fpKey, scriptUrlPattern: `${u}/web/v<version>/<apiKey>/loader_v<loaderVersion>.js`, endpoint: u, region: "eu", remoteControlDetection: !0 })), n ? v = { enabled: !0, conf: n } : o != null && o.simulation && (v = o.simulation), t = !!(o != null && o.fpKey || v); } catch (o) { console.log(o.message); } return { isDeviceIntelligenceEnabled: t, behavioralDataEnabled: r, eventsRelUrl: i, fpReqRelUrl: a }; } async function Wn(e) { if (v) return await zn(); let n, t; try { if (!_) throw new Error("Device Intelligence feature is not enabled"); const r = await _.get({ timeout: 3e4, linkedId: e == null ? void 0 : e.linkedId }); n = r.visitorId, t = r.requestId, await oe({ fpVisitorId: n, fpRequestId: t }); } catch { console.log("Device Intelligence feature is not enabled"); } return { visitorId: n }; } async function zn() { var t, r; const e = { visitorId: (t = v == null ? void 0 : v.conf) == null ? void 0 : t.visitorId }; if (!v) return e; const n = { ...v }; if (!((r = n.conf) != null && r.requestId)) { const i = `simulated-${Math.random().toString(36).substring(2, 10)}`; n.conf = { ...n.conf, requestId: i }; } try { await oe({ fpSimulation: n }); } catch { console.error("Simulation error"); } return e; } const Jn = () => { _ = void 0, v = void 0; }; let K, Y = !1; async function Zn(e) { let n = !1; if (!K) { K = !0, ke(e); const t = await Xn(e.token, e.simulationConfig); n = t.isDeviceIntelligenceEnabled, Y = t.behavioralDataEnabled, Le(t.eventsRelUrl), _e(t.fpReqRelUrl), Y && (await An(), Ke(), On(), on()); } return { isDeviceIntelligenceEnabled: n, async fingerprint(t) { return Wn(t); } }; } function et() { pe(), Ce(), Nn(), an(), je(), Jn(), K = !1; } function nt(e) { N(e); } export { et as destroy, Zn as init, nt as updateAccessToken };