@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
JavaScript
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
};