Skip to content

Instantly share code, notes, and snippets.

@ultrafunkamsterdam
Created February 5, 2023 14:06
Show Gist options
  • Save ultrafunkamsterdam/d13ab70f5fc571fe61a17f894b1c1189 to your computer and use it in GitHub Desktop.
Save ultrafunkamsterdam/d13ab70f5fc571fe61a17f894b1c1189 to your computer and use it in GitHub Desktop.
fingerprint.com bot detection source
function _construct(Parent, args, Class) {
if (isNativeReflectConstruct()) {
_construct = Reflect.construct.bind();
} else {
_construct = function _construct(Parent, args, Class) {
var a = [null];
a.push.apply(a, args);
var Constructor = Function.bind.apply(Parent, a);
var instance = new Constructor();
if (Class) setPrototypeOf(instance, Class.prototype);
return instance;
};
}
return _construct.apply(null, arguments);
}
function _isNativeReflectConstruct() {
if (typeof Reflect === "undefined" || !Reflect.construct) return false;
if (Reflect.construct.sham) return false;
if (typeof Proxy === "function") return true;
try {
Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {}));
return true;
} catch (e) {
return false;
}
}
function _isNativeFunction(fn) {
return Function.toString.call(fn).indexOf("[native code]") !== -1;
}
function _getPrototypeOf(o) {
_getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) {
return o.__proto__ || Object.getPrototypeOf(o);
};
return _getPrototypeOf(o);
}
function _setPrototypeOf(o, p) {
module.exports = _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
o.__proto__ = p;
return o;
}, module.exports.__esModule = true, module.exports["default"] = module.exports;
return _setPrototypeOf(o, p);
}
function _wrapNativeSuper(Class) {
var _cache = typeof Map === "function" ? new Map() : undefined;
_wrapNativeSuper = function _wrapNativeSuper(Class) {
if (Class === null || !isNativeFunction(Class)) return Class;
if (typeof Class !== "function") {
throw new TypeError("Super expression must either be null or a function");
}
if (typeof _cache !== "undefined") {
if (_cache.has(Class)) return _cache.get(Class);
_cache.set(Class, Wrapper);
}
function Wrapper() {
return construct(Class, arguments, getPrototypeOf(this).constructor);
}
Wrapper.prototype = Object.create(Class.prototype, {
constructor: {
value: Wrapper,
enumerable: false,
writable: true,
configurable: true
}
});
return setPrototypeOf(Wrapper, Class);
};
return _wrapNativeSuper(Class);
}
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
import _regeneratorRuntime from "/vercel/path0/node_modules/gatsby/node_modules/@babel/runtime/regenerator";
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
/**
* FingerprintJS Challenge Framework v0.0.7 - Copyright (c) FingerprintJS, Inc, 2022 (https://fingerprintjs.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter$1(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
/**
* Represents the challenge framework error.
*/
var TuringError = /*#__PURE__*/function (_Error) {
_inherits(TuringError, _Error);
var _super = _createSuper(TuringError);
/**
* Creates a new TuringError.
*
* @class
*/
function TuringError(state, message) {
var _this;
_classCallCheck(this, TuringError);
_this = _super.call(this, message);
_this.state = state;
_this.name = 'TuringError';
return _this;
}
return TuringError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
function errorNoSiteKey(msg) {
return new TuringError(101
/* NoSiteKey */
, msg);
}
function errorManyForms(msg) {
return new TuringError(102
/* ManyForms */
, msg);
}
function errorNoTuringSpot(msg) {
return new TuringError(106
/* NoTuringSpot */
, msg);
}
function errorManyTuringSpots(msg) {
return new TuringError(103
/* ManyTuringSpot */
, msg);
}
function errorNeedInit(msg) {
return new TuringError(104
/* NeedInit */
, msg);
}
function errorUnexpected(msg) {
return new TuringError(-100
/* Unexpected */
, msg);
}
function getAttrValue(attr) {
var elWithAttr = document.querySelector("[".concat(attr, "]"));
if (elWithAttr == null) {
return undefined;
}
var attrValue = elWithAttr.getAttribute(attr);
if (attrValue == null) {
return undefined;
}
return attrValue;
}
function getElementWithAttr(attr) {
return document.querySelector("[".concat(attr, "]"));
}
function getAllElementsWithAttr(attr) {
return document.querySelectorAll("[".concat(attr, "]"));
}
function setStyleAttribute(element, attrs) {
Object.keys(attrs).forEach(function (k) {
element.style.setProperty(k, attrs[k]);
});
}
function setElementAttribute(element, attrs) {
Object.keys(attrs).forEach(function (k) {
element.setAttribute(k, attrs[k]);
});
}
function initURL(endpoint) {
var url = new URL(endpoint);
url.pathname += 'api/v1/init';
return url.href;
}
function iframeURL(endpoint, challengeType) {
var url = new URL(endpoint);
url.pathname += "static/".concat(challengeType, "/");
return url.href;
}
var ModalWindow = /*#__PURE__*/function () {
function ModalWindow() {
var _this2 = this;
_classCallCheck(this, ModalWindow);
this.wrapper = document.createElement('div');
this.hide();
this.background = document.createElement('div');
this.window = document.createElement('div');
this.closeButton = document.createElement('button');
setStyleAttribute(this.window, {
position: 'fixed',
width: '500px',
height: '280px',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
'background-color': 'white',
opacity: '1'
});
setStyleAttribute(this.background, {
position: 'fixed',
top: '0',
left: '0',
width: '100%',
height: '100%',
'background-color': 'black',
opacity: '0.5'
});
setStyleAttribute(this.closeButton, {
float: 'right',
height: '20px',
'min-height': '20px',
width: '20px',
'min-width': '20px',
padding: '0',
border: 'none',
margin: '10px',
// Close icon in svg
background: 'url("data:image/svg+xml,%3Csvg%20fill%3D%22%23000000%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20%20viewBox%3D%220%200%2050%2050%22%20width%3D%2250px%22%20height%3D%2250px%22%3E%3Cpath%20d%3D%22M%207.71875%206.28125%20L%206.28125%207.71875%20L%2023.5625%2025%20L%206.28125%2042.28125%20L%207.71875%2043.71875%20L%2025%2026.4375%20L%2042.28125%2043.71875%20L%2043.71875%2042.28125%20L%2026.4375%2025%20L%2043.71875%207.71875%20L%2042.28125%206.28125%20L%2025%2023.5625%20Z%22%2F%3E%3C%2Fsvg%3E")',
'background-size': 'contain',
opacity: '0.5'
});
this.closeButton.addEventListener('click', function () {
return _this2.hide();
});
this.closeButton.addEventListener('mouseenter', function () {
return _this2.closeButton.style.opacity = '1';
});
this.closeButton.addEventListener('mouseout', function () {
return _this2.closeButton.style.opacity = '0.5';
});
this.window.appendChild(this.closeButton);
this.wrapper.appendChild(this.background);
this.wrapper.appendChild(this.window);
}
_createClass(ModalWindow, [{
key: "hide",
value: function hide() {
setStyleAttribute(this.wrapper, {
display: 'none'
});
}
}, {
key: "show",
value: function show() {
setStyleAttribute(this.wrapper, {
display: 'block'
});
}
}, {
key: "remove",
value: function remove() {
this.window.remove();
this.background.remove();
this.wrapper.remove();
}
}]);
return ModalWindow;
}();
var CHALLENGE_FRAME_ID = 'challengeFrame';
function createIFrame(url, publicKey, sessionId) {
var iframeElement = document.createElement('iframe');
setElementAttribute(iframeElement, {
src: url,
name: CHALLENGE_FRAME_ID,
id: CHALLENGE_FRAME_ID
});
setStyleAttribute(iframeElement, {
width: '500px',
height: '200px',
border: 'none'
});
iframeElement.addEventListener('load', function () {
var _a;
var frame = document.getElementById(CHALLENGE_FRAME_ID);
if (frame !== null) {
// TODO: Update targetOrigin
(_a = frame.contentWindow) === null || _a === void 0 ? void 0 : _a.postMessage({
publicKey: publicKey,
sessionId: sessionId
}, '*');
}
});
return iframeElement;
}
var View = /*#__PURE__*/function () {
function View() {
_classCallCheck(this, View);
this.modalWindow = new ModalWindow();
this.mode = View.detectMode();
this.iframeElement = null;
if (this.mode === "modal"
/* Modal */
) {
this.wrapperElement = document.body.appendChild(this.modalWindow.wrapper);
this.turingSpot = this.modalWindow.window;
} else {
var turingSpot = getElementWithAttr("turing-spot"
/* Spot */
);
if (turingSpot === null) {
throw errorNoTuringSpot("cannot find element with '".concat("turing-spot"
/* Spot */
, "' attribute"));
}
this.turingSpot = turingSpot;
this.wrapperElement = turingSpot;
}
}
_createClass(View, [{
key: "show",
value: function show(endpoint, challengeType, publicKey, sessionId) {
if (this.mode == "modal"
/* Modal */
) {
this.modalWindow.show();
}
if (this.iframeElement === null) {
this.iframeElement = createIFrame(iframeURL(endpoint, challengeType), publicKey, sessionId);
this.turingSpot.appendChild(this.iframeElement);
}
}
}, {
key: "hide",
value: function hide() {
if (this.mode === "modal"
/* Modal */
) {
this.modalWindow.hide();
} else {
setStyleAttribute(this.wrapperElement, {
display: 'none'
});
}
}
}, {
key: "clear",
value: function clear() {
this.modalWindow.remove();
if (this.iframeElement !== null) {
this.iframeElement.remove();
}
}
}], [{
key: "detectMode",
value: function detectMode() {
var turingSpot = getAllElementsWithAttr("turing-spot"
/* Spot */
);
if (turingSpot.length === 0) {
// Modal mode, should be only single form
if (document.forms.length > 1) {
throw errorManyForms('too many forms on the page');
}
return "modal"
/* Modal */
;
} else {
if (turingSpot.length > 1) {
throw errorManyTuringSpots("multiple elements with '".concat("turing-spot"
/* Spot */
, "' attribute"));
}
return "withHandler"
/* WithHandler */
;
}
}
}]);
return View;
}();
/**
* FingerprintJS Botd v0.1.23 - Copyright (c) FingerprintJS, Inc, 2021 (https://fingerprintjs.com)
* Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
*/
/*! *****************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P ? value : new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
/**
* Represents the bot detection error.
*/
var BotdError = /*#__PURE__*/function (_Error2) {
_inherits(BotdError, _Error2);
var _super2 = _createSuper(BotdError);
/**
* Creates a new BotdError.
*
* @class
*/
function BotdError(state, message) {
var _this3;
_classCallCheck(this, BotdError);
_this3 = _super2.call(this, message);
_this3.state = state;
_this3.name = 'BotdError';
return _this3;
}
return BotdError;
}( /*#__PURE__*/_wrapNativeSuper(Error));
function getUserAgent() {
return navigator.userAgent;
}
function hasUserAgentData() {
return navigator.userAgentData !== undefined;
}
function getAppVersion() {
return navigator.appVersion;
}
function getRTT() {
if (navigator.connection === undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.connection is undefined');
}
return navigator.connection.rtt;
}
function getWindowOuterSize() {
return [window.outerWidth, window.outerHeight];
}
function arePermissionsInconsistent() {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var _navigator, permissions, permissionStatus;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!(window.Notification === undefined)) {
_context.next = 2;
break;
}
throw new BotdError(-1
/* Undefined */
, 'window.Notification is undefined');
case 2:
if (!(navigator.permissions === undefined)) {
_context.next = 4;
break;
}
throw new BotdError(-1
/* Undefined */
, 'navigator.permissions is undefined');
case 4:
_navigator = navigator, permissions = _navigator.permissions;
if (!(typeof permissions.query !== 'function')) {
_context.next = 7;
break;
}
throw new BotdError(104
/* NotFunction */
, 'navigator.permissions.query is not a function');
case 7:
_context.next = 9;
return permissions.query({
name: 'notifications'
});
case 9:
permissionStatus = _context.sent;
return _context.abrupt("return", window.Notification.permission === 'denied' && permissionStatus.state === 'prompt');
case 11:
case "end":
return _context.stop();
}
}
}, _callee);
}));
}
function getInstallTrigger() {
return window.InstallTrigger !== undefined;
}
function getWebGL() {
var canvasElement = document.createElement('canvas');
if (typeof canvasElement.getContext !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'HTMLCanvasElement.getContext is not a function');
}
var webGLContext = canvasElement.getContext('webgl');
if (webGLContext == null) {
throw new BotdError(101
/* Null */
, 'WebGLRenderingContext is null');
} else {
if (typeof webGLContext.getParameter !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'WebGLRenderingContext.getParameter is not a function');
}
var vendor = webGLContext.getParameter(webGLContext.VENDOR);
var renderer = webGLContext.getParameter(webGLContext.RENDERER);
var _version = webGLContext.getParameter(webGLContext.VERSION);
if (getInstallTrigger()) {
return [vendor, renderer, _version];
} else {
var webGLDebugInfo = webGLContext.getExtension('WEBGL_debug_renderer_info');
if (webGLDebugInfo == null) {
throw new BotdError(101
/* Null */
, 'WEBGL_debug_renderer_info extension is null');
} else {
var unmaskedVendor = webGLContext.getParameter(webGLDebugInfo.UNMASKED_VENDOR_WEBGL);
var unmaskedRenderer = webGLContext.getParameter(webGLDebugInfo.UNMASKED_RENDERER_WEBGL);
return [unmaskedVendor, unmaskedRenderer, vendor, renderer, _version];
}
}
}
}
function getScreen() {
return [screen.width, screen.height];
}
function getDeviceMemory() {
if (navigator.deviceMemory === undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.deviceMemory is undefined');
}
return navigator.deviceMemory;
}
function isBigEndian() {
var buf = new ArrayBuffer(4);
new Uint32Array(buf)[0] = 0xaa000000;
return new Uint8Array(buf)[0] === 0xaa;
}
function getHardwareConcurrency() {
try {
var concurrency = navigator.hardwareConcurrency;
if (typeof concurrency === 'string') {
var concurrencyInt = parseInt(concurrency);
return isNaN(concurrencyInt) ? 1 : concurrencyInt;
}
return concurrency;
} catch (e) {
throw new BotdError(103
/* WrongType */
, 'navigator.hardwareConcurrency wrong type');
}
}
function getEvalLength() {
return eval.toString().length;
}
function getPluginsLength() {
if (navigator.plugins === undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.plugins is undefined');
}
return navigator.plugins.length;
}
function arePluginsConsistent() {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
var _navigator2, plugins, isConsistent, i;
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
if (!(navigator.plugins === undefined)) {
_context2.next = 2;
break;
}
return _context2.abrupt("return", false);
case 2:
_navigator2 = navigator, plugins = _navigator2.plugins;
isConsistent = Object.getPrototypeOf(plugins) === PluginArray.prototype;
for (i = 0; i < plugins.length; i++) {
isConsistent && (isConsistent = Object.getPrototypeOf(plugins[i]) === Plugin.prototype);
}
return _context2.abrupt("return", isConsistent);
case 6:
case "end":
return _context2.stop();
}
}
}, _callee2);
}));
}
function getErrorTrace() {
try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
null[0]();
} catch (error) {
return error.stack.toString();
}
throw new BotdError(102
/* UnexpectedBehaviour */
, 'errorTrace signal unexpected behaviour');
}
function getErrorFF() {
try {
throw 'a';
} catch (e) {
try {
e.toSource();
return true;
} catch (e2) {
return false;
}
}
}
function getOSCPU() {
if (navigator.oscpu === undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.oscpu is undefined');
}
return navigator.oscpu;
}
function getPlatform() {
return navigator.platform;
}
function getProductSub() {
return navigator.productSub;
}
function getVendor() {
return navigator.vendor;
}
function getWebDriver() {
if (navigator.webdriver == undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.webdriver is undefined');
}
return navigator.webdriver;
}
function getFrequency() {
function now() {
return performance.now() / 1000;
}
function gcd(a, b) {
if (a < 0.00000001) {
return b;
}
if (a < b) {
return gcd(b - Math.floor(b / a) * a, a);
} else if (a === b) {
return a;
} else {
return gcd(b, a);
}
}
var x = now();
var g = now() - x;
for (var i = 0; i < 10; i++) {
g = gcd(g, now() - x);
}
return Math.round(1 / g);
}
function getProperties(object) {
var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
if (Object.getPrototypeOf(object) == null) {
return properties;
}
return getProperties(Object.getPrototypeOf(object), properties.concat(Object.getOwnPropertyNames(object)));
}
function getWindowProperties() {
return getProperties(window);
}
function getDocumentProperties() {
return getProperties(window.document);
}
function getNavigatorProperties() {
return getProperties(window.navigator);
}
function getTouchPoints() {
return [navigator.maxTouchPoints, navigator.msMaxTouchPoints];
}
function getSourceBufferType() {
return [typeof SourceBuffer, typeof SourceBufferList];
}
function getDocumentElementKeys() {
if (document.documentElement === undefined) {
throw new BotdError(-1
/* Undefined */
, 'document.documentElement is undefined');
}
var _document = document,
documentElement = _document.documentElement;
if (typeof documentElement.getAttributeNames !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'document.documentElement.getAttributeNames is not a function');
}
return documentElement.getAttributeNames();
}
function getWindowClose() {
if (window.close === undefined) {
throw new BotdError(-1
/* Undefined */
, 'window.close is undefined');
}
return window.close.toString();
}
function getWindowExternal() {
if (window.external === undefined) {
throw new BotdError(-1
/* Undefined */
, 'window.external is undefined');
}
var _window = window,
external = _window.external;
if (typeof external.toString !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'window.external.toString is not a function');
}
return external.toString();
}
function getLanguages() {
return Object.assign([], navigator.languages);
}
function getMimeTypesLength() {
if (navigator.mimeTypes === undefined) {
throw new BotdError(-1
/* Undefined */
, 'navigator.mimeTypes is undefined');
}
return navigator.mimeTypes.length;
}
function areMimeTypesConsistent() {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
var _navigator3, mimeTypes, isConsistent, i;
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
if (!(navigator.mimeTypes === undefined)) {
_context3.next = 2;
break;
}
return _context3.abrupt("return", false);
case 2:
_navigator3 = navigator, mimeTypes = _navigator3.mimeTypes;
isConsistent = Object.getPrototypeOf(mimeTypes) === MimeTypeArray.prototype;
for (i = 0; i < mimeTypes.length; i++) {
isConsistent && (isConsistent = Object.getPrototypeOf(mimeTypes[i]) === MimeType.prototype);
}
return _context3.abrupt("return", isConsistent);
case 6:
case "end":
return _context3.stop();
}
}
}, _callee3);
}));
}
function requiredAccelerometerPermission() {
return typeof DeviceMotionEvent !== 'undefined' && typeof DeviceMotionEvent.requestPermission === 'function';
}
function getTimestamp() {
return Date.now();
}
function getBackdropFilter() {
return CSS.supports('backdrop-filter', 'blur(2px)');
}
function getASTCProfiles() {
var canvasElement = document.createElement('canvas');
if (typeof canvasElement.getContext !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'HTMLCanvasElement.getContext is not a function');
}
var webGLContext = canvasElement.getContext('webgl');
if (webGLContext == null) {
throw new BotdError(101
/* Null */
, 'WebGLRenderingContext is null');
} else {
var astcExtension = webGLContext.getExtension('WEBGL_compressed_texture_astc');
if (astcExtension == null) return '';
if (typeof astcExtension.getSupportedProfiles !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'WEBGL_compressed_texture_astc.getSupportedProfiles is not a function');
}
return astcExtension.getSupportedProfiles().toString();
}
}
function getHairlines() {
if (window.devicePixelRatio === undefined) {
throw new BotdError(-1
/* Undefined */
, 'window.devicePixelRatio is undefined');
}
var el = document.createElement('div');
el.style.border = '.5px dotted transparent';
document.body.appendChild(el);
var offsetHeight = el.offsetHeight;
document.body.removeChild(el);
return [window.devicePixelRatio, offsetHeight];
}
function isHiDPI() {
if (typeof window.matchMedia !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'window.matchMedia is not a function');
}
var query = '(-webkit-min-device-pixel-ratio: 2), (min-device-pixel-ratio: 2), (min-resolution: 192dpi)';
var mql = window.matchMedia(query);
if (mql.matches === undefined) {
throw new BotdError(-1
/* Undefined */
, 'MediaQueryList.matches is undefined');
}
return mql.matches;
}
function isDarkTheme() {
if (typeof window.matchMedia !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'window.matchMedia is not a function');
}
var query = '(prefers-color-scheme: dark)';
var mql = window.matchMedia(query);
if (mql.matches === undefined) {
throw new BotdError(-1
/* Undefined */
, 'MediaQueryList.matches is undefined');
}
return mql.matches;
}
function getSABByteLength() {
if (typeof window.SharedArrayBuffer !== 'function') {
throw new BotdError(104
/* NotFunction */
, 'window.SharedArrayBuffer is not a function');
}
var singleElementSAB = new window.SharedArrayBuffer(1);
if (singleElementSAB.byteLength === undefined) {
throw new BotdError(-1
/* Undefined */
, 'SharedArrayBuffer.byteLength is undefined');
}
return singleElementSAB.byteLength;
}
function handleSource(sourceFunction) {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_context4.prev = 0;
_context4.next = 3;
return sourceFunction();
case 3:
_context4.t0 = _context4.sent;
return _context4.abrupt("return", {
state: 1,
value: _context4.t0
});
case 7:
_context4.prev = 7;
_context4.t1 = _context4["catch"](0);
if (!(_context4.t1 instanceof BotdError)) {
_context4.next = 13;
break;
}
return _context4.abrupt("return", {
state: _context4.t1.state,
value: _context4.t1.toString()
});
case 13:
return _context4.abrupt("return", {
state: -100
/* Unexpected */
,
value: _context4.t1.toString()
});
case 14:
case "end":
return _context4.stop();
}
}
}, _callee4, null, [[0, 7]]);
}));
}
function handleAll(sources) {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee5() {
var components, _iterator, _step, value, _index, name;
return _regeneratorRuntime.wrap(function _callee5$(_context5) {
while (1) {
switch (_context5.prev = _context5.next) {
case 0:
components = {};
_iterator = _createForOfIteratorHelper(sources);
_context5.prev = 2;
_iterator.s();
case 4:
if ((_step = _iterator.n()).done) {
_context5.next = 13;
break;
}
value = _step.value;
_index = sources.indexOf(value);
name = "s".concat(_index + 1);
_context5.next = 10;
return handleSource(value);
case 10:
components[name] = _context5.sent;
case 11:
_context5.next = 4;
break;
case 13:
_context5.next = 18;
break;
case 15:
_context5.prev = 15;
_context5.t0 = _context5["catch"](2);
_iterator.e(_context5.t0);
case 18:
_context5.prev = 18;
_iterator.f();
return _context5.finish(18);
case 21:
return _context5.abrupt("return", components);
case 22:
case "end":
return _context5.stop();
}
}
}, _callee5, null, [[2, 15, 18, 21]]);
}));
}
/**
* Collects all the components from the browser.
*
* @returns {Promise<ComponentDict>} A promise to the collected components.
*/
function _collect() {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee6() {
return _regeneratorRuntime.wrap(function _callee6$(_context6) {
while (1) {
switch (_context6.prev = _context6.next) {
case 0:
return _context6.abrupt("return", handleAll([getUserAgent, hasUserAgentData, getAppVersion, getRTT, getWindowOuterSize, arePermissionsInconsistent, getWebGL, getScreen, getDeviceMemory, isBigEndian, getHardwareConcurrency, getInstallTrigger, getWebDriver, getEvalLength, getPluginsLength, arePluginsConsistent, getErrorTrace, getErrorFF, getOSCPU, getPlatform, getProductSub, getVendor, getFrequency, getWindowProperties, getDocumentProperties, getNavigatorProperties, getTouchPoints, getSourceBufferType, getDocumentElementKeys, getWindowClose, getWindowExternal, getLanguages, getMimeTypesLength, areMimeTypesConsistent, requiredAccelerometerPermission, getTimestamp, getBackdropFilter, getASTCProfiles, getHairlines, isHiDPI, isDarkTheme, getSABByteLength // s42
]));
case 1:
case "end":
return _context6.stop();
}
}
}, _callee6);
}));
}
var version = "0.1.23";
function getUTF8Bytes(text) {
// Benchmark: https://jsbench.me/b6klaaxgwq/1
// If you want to just count bytes, see solutions at https://jsbench.me/ehklab415e/1
if (typeof TextEncoder === 'function') {
return new TextEncoder().encode(text); // From https://stackoverflow.com/a/11411402/1118709
} // From https://stackoverflow.com/a/18722848/1118709
var binaryText = unescape(encodeURI(text));
var bytes = new Uint8Array(binaryText.length);
for (var i = 0; i < binaryText.length; ++i) {
bytes[i] = binaryText.charCodeAt(i);
}
return bytes;
}
function parseUTF8Bytes(data) {
if (typeof TextDecoder === 'function') {
var decoded = new TextDecoder().decode(data); // From https://stackoverflow.com/a/11411402/1118709
if (decoded) {
return decoded; // The decoder always returns empty string in old Blink (e.g. Android 5.1 Browser)
}
} // From https://stackoverflow.com/a/18722848/111870
var bytes = bufferSourceToBytes(data);
return decodeURIComponent(escape(String.fromCharCode.apply(null, bytes)));
}
function bufferSourceToBytes(source) {
if (source instanceof ArrayBuffer) {
return new Uint8Array(source);
}
return new Uint8Array(source.buffer, source.byteOffset, source.byteLength);
}
var XorWithIndexObfuscation = /*#__PURE__*/function () {
function XorWithIndexObfuscation() {
_classCallCheck(this, XorWithIndexObfuscation);
this.type = 1
/* XorWithIndex */
;
this.paddingSize = 0;
}
_createClass(XorWithIndexObfuscation, [{
key: "obfuscate",
value: function obfuscate(payload) {
var payloadBytes = getUTF8Bytes(JSON.stringify(payload));
var resultSize = 2 + payloadBytes.length; // Type + padding size + padding + payload
var result = new ArrayBuffer(resultSize);
var resultBytes = new Uint8Array(result);
var resultOffset = 0;
resultBytes[resultOffset++] = this.type;
resultBytes[resultOffset++] = this.paddingSize; // No padding
for (var i = 0; i < payloadBytes.length; ++i) {
resultBytes[resultOffset++] = payloadBytes[i] ^ i;
}
return resultBytes;
}
}, {
key: "deobfuscate",
value: function deobfuscate(encoded) {
var encodedBytes = bufferSourceToBytes(encoded);
var type = encodedBytes[0];
var paddingSize = encodedBytes[1];
if (type != this.type || paddingSize != this.paddingSize) {
throw new BotdError(105
/* ObfuscationError */
, 'Wrong type or padding size');
}
var headerOffset = 2; // Type and padding size
var payloadBytes = new Uint8Array(encodedBytes.length - headerOffset);
for (var i = 0; i < payloadBytes.length; ++i) {
payloadBytes[i] = encodedBytes[i + headerOffset] ^ i;
}
return JSON.parse(parseUTF8Bytes(payloadBytes));
}
}]);
return XorWithIndexObfuscation;
}();
function setCookie(name, value) {
value = encodeURIComponent(value);
document.cookie = "".concat(name, "=").concat(value, ";SameSite=None;Secure");
}
/**
* Class representing a bot detector.
*
* @class
* @implements {BotDetectorInterface}
*/
var BotDetector = /*#__PURE__*/function () {
function BotDetector(options) {
_classCallCheck(this, BotDetector);
this.tag = '';
this.endpoint = options.endpoint == undefined ? 'https://botd.fpapi.io/api/v1/' : options.endpoint;
this.endpoint += this.endpoint.endsWith('/') ? '' : '/';
if (this.endpoint.indexOf('://') === -1) {
this.endpoint = new URL(this.endpoint, document.baseURI).href;
} // TODO: Get rid of token
var token = options.token == undefined ? '' : options.token;
var publicKey = options.publicKey == undefined ? '' : options.publicKey;
if (publicKey == '' && token == '') {
throw BotDetector.createError("publicKeyRequired"
/* PublicKeyRequired */
, 'publicKey required');
}
this.publicKey = publicKey == '' ? token : publicKey;
this.integration = options.mode == 'integration';
this.mode = options.mode == undefined ? 'requestId' : this.integration ? 'requestId' : options.mode;
this.obfuscator = new XorWithIndexObfuscation();
this.obfuscationMode = options.obfuscationMode == undefined ? this.integration ? 'requestOnly' : 'all' : options.obfuscationMode;
}
/**
* @inheritdoc
*/
_createClass(BotDetector, [{
key: "collect",
value: function collect() {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee7() {
var timestamp;
return _regeneratorRuntime.wrap(function _callee7$(_context7) {
while (1) {
switch (_context7.prev = _context7.next) {
case 0:
timestamp = Date.now();
_context7.next = 3;
return _collect();
case 3:
this.components = _context7.sent;
this.performance = Date.now() - timestamp;
return _context7.abrupt("return", this.components);
case 6:
case "end":
return _context7.stop();
}
}
}, _callee7, this);
}));
}
}, {
key: "createRequestBody",
value: function createRequestBody() {
return {
mode: this.mode,
performance: this.performance,
signals: this.components,
publicKey: this.publicKey,
tag: this.tag
};
}
/**
* @inheritdoc
*/
}, {
key: "detect",
value: function detect() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
tag: ''
};
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
var credentials, url, body, response, responseJSON;
return _regeneratorRuntime.wrap(function _callee8$(_context8) {
while (1) {
switch (_context8.prev = _context8.next) {
case 0:
this.tag = options.tag;
_context8.prev = 1;
credentials = this.integration ? 'include' : undefined;
url = new URL(this.endpoint);
url.pathname += 'detect';
url.searchParams.append('version', version);
url.search += this.obfuscationMode != 'all' ? '&deobfuscate' : '';
body = this.obfuscationMode == 'none' ? JSON.stringify(this.createRequestBody()) : this.obfuscator.obfuscate(this.createRequestBody());
_context8.next = 10;
return fetch(url.href, {
method: 'POST',
headers: {
'Content-Type': 'text/plain'
},
body: body,
credentials: credentials
});
case 10:
response = _context8.sent;
if (!(this.obfuscationMode != 'all')) {
_context8.next = 17;
break;
}
_context8.next = 14;
return response.json();
case 14:
_context8.t0 = _context8.sent;
_context8.next = 22;
break;
case 17:
_context8.t1 = this.obfuscator;
_context8.next = 20;
return response.arrayBuffer();
case 20:
_context8.t2 = _context8.sent;
_context8.t0 = _context8.t1.deobfuscate.call(_context8.t1, _context8.t2);
case 22:
responseJSON = _context8.t0;
BotDetector.throwIfError(responseJSON);
if ('requestId' in responseJSON && !this.integration) {
setCookie('botd-request-id', responseJSON['requestId']);
}
return _context8.abrupt("return", responseJSON);
case 28:
_context8.prev = 28;
_context8.t3 = _context8["catch"](1);
BotDetector.throwIfError(_context8.t3);
throw BotDetector.createError("botdFailed"
/* BotdFailed */
, _context8.t3.toString());
case 32:
case "end":
return _context8.stop();
}
}
}, _callee8, this, [[1, 28]]);
}));
}
}], [{
key: "throwIfError",
value: function throwIfError(response) {
if ('error' in response) {
throw response;
}
}
}, {
key: "createError",
value: function createError(code, msg) {
return {
error: {
code: code,
message: msg
}
};
}
}]);
return BotDetector;
}();
/**
* Builds an instance of the BotDetector. It's recommended to call it as early as possible, ideally during application startup.
*
* @param {InitOptions} options Configuration options.
* @returns {Promise<BotDetectorInterface>} A promise to the instance of the bot detector.
*/
function load(options) {
return __awaiter(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee9() {
var detector;
return _regeneratorRuntime.wrap(function _callee9$(_context9) {
while (1) {
switch (_context9.prev = _context9.next) {
case 0:
detector = new BotDetector(options);
_context9.next = 3;
return detector.collect();
case 3:
return _context9.abrupt("return", detector);
case 4:
case "end":
return _context9.stop();
}
}
}, _callee9);
}));
}
var index = {
load: load
};
var Challenge = /*#__PURE__*/function () {
function Challenge() {
_classCallCheck(this, Challenge);
var endpoint = getAttrValue("turing-server-url"
/* ServerUrl */
);
this.endpoint = endpoint === undefined ? 'https://turing.fpapi.io' : endpoint;
this.debug = getAttrValue("turing-debug"
/* Debug */
) !== undefined;
var siteKey = getAttrValue("data-sitekey"
/* DataSiteKey */
);
if (siteKey === undefined) {
throw errorNoSiteKey("cannot find ".concat("data-sitekey"
/* DataSiteKey */
, " attribute"));
}
this.siteKey = siteKey;
this.enableBotD = getAttrValue("disable-botd"
/* DisableBotD */
) === undefined;
this.promise = this.createPromise();
if (this.debug) {
// eslint-disable-next-line no-console
console.log("[Turing] constructor - endpoint: ".concat(this.endpoint, ", sitekey: ").concat(this.siteKey, ", BotD: ").concat(this.enableBotD));
}
}
_createClass(Challenge, [{
key: "initialize",
value: function initialize() {
return __awaiter$1(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
var _this4 = this;
var botdRequestId, botdPromise, botd, result, body, resp, respJSON, type, sessionId;
return _regeneratorRuntime.wrap(function _callee10$(_context10) {
while (1) {
switch (_context10.prev = _context10.next) {
case 0:
_context10.prev = 0;
botdRequestId = '';
if (!this.enableBotD) {
_context10.next = 11;
break;
}
botdPromise = index.load({
publicKey: this.siteKey
});
_context10.next = 6;
return botdPromise;
case 6:
botd = _context10.sent;
_context10.next = 9;
return botd.detect();
case 9:
result = _context10.sent;
if ('requestId' in result) {
botdRequestId = result.requestId;
}
case 11:
body = JSON.stringify({
public_key: this.siteKey,
botd_request_id: botdRequestId
});
_context10.next = 14;
return fetch(initURL(this.endpoint), {
method: 'POST',
headers: {
'Content-Type': 'text/plain'
},
body: body
});
case 14:
resp = _context10.sent;
_context10.next = 17;
return resp.json();
case 17:
respJSON = _context10.sent;
type = respJSON.challenge_type;
sessionId = respJSON.session_id;
this.challengeType = type;
this.sessionId = sessionId;
this.isBot = type !== 'none'; // TODO: more accurate check
if (this.debug) {
// eslint-disable-next-line no-console
console.log("[Turing] initialize - is bot: ".concat(this.isBot, ", challenge type: ").concat(this.challengeType, ", session: ").concat(this.sessionId));
}
this.clientForm = this.getClientFormWithSessionId(this.sessionId);
if (this.isBot) {
this.view = new View();
if (this.clientForm !== undefined) {
this.clientForm.addEventListener('submit', function (e) {
var _a;
e.preventDefault();
(_a = _this4.view) === null || _a === void 0 ? void 0 : _a.show(_this4.endpoint, type, _this4.siteKey, sessionId);
}, false);
}
}
_context10.next = 31;
break;
case 28:
_context10.prev = 28;
_context10.t0 = _context10["catch"](0);
throw errorUnexpected(_context10.t0);
case 31:
case "end":
return _context10.stop();
}
}
}, _callee10, this, [[0, 28]]);
}));
}
}, {
key: "getClientFormWithSessionId",
value: function getClientFormWithSessionId(sessionId) {
if (document.forms[0] === undefined) {
return undefined;
} // TODO: if there are many forms on the page, should we take a form with 'turing-spot' attr?
var formElement = document.forms[0];
var hiddenInputElement = document.createElement('input');
setElementAttribute(hiddenInputElement, {
type: 'hidden',
name: 'turing-session-id',
value: sessionId,
id: 'session-id'
});
formElement.appendChild(hiddenInputElement);
return formElement;
}
}, {
key: "createPromise",
value: function createPromise() {
var _this5 = this;
return new Promise(function (resolve, reject) {
var messageListener = function messageListener(e) {
if (e.data.solved) {
if (_this5.sessionId !== undefined) {
resolve(_this5.sessionId);
} else {
reject('session id undefined');
}
window.removeEventListener('message', messageListener);
if (_this5.view !== undefined) {
_this5.view.hide();
}
if (_this5.clientForm) {
_this5.clientForm.submit();
}
}
};
window.addEventListener('message', messageListener);
});
}
}, {
key: "getPromise",
value: function getPromise() {
var _this6 = this;
if (this.isBot !== undefined && !this.isBot) {
return new Promise(function (resolve, reject) {
if (_this6.sessionId !== undefined) {
resolve(_this6.sessionId);
} else {
reject('sessionId undefined');
}
});
} else {
return this.promise;
}
}
}, {
key: "render",
value: function render() {
if (this.debug) {
// eslint-disable-next-line no-console
console.log("[Turing] render - is bot: ".concat(this.isBot, ", challenge type: ").concat(this.challengeType, ", session: ").concat(this.sessionId));
}
if (this.challengeType === undefined || this.sessionId === undefined || this.isBot === undefined) {
throw errorNeedInit('Initialize framework before call');
}
if (this.isBot) if (this.view === undefined) {
throw errorNeedInit('Initialize framework before call');
} else {
this.view.show(this.endpoint, this.challengeType, this.siteKey, this.sessionId);
}
}
}]);
return Challenge;
}();
var cf = undefined;
if (typeof document !== 'undefined') {
// document is inherently client-side so document will be undefined on build on server-side render sites
document.addEventListener('DOMContentLoaded', createChallenge);
}
function ready(callback) {
return __awaiter$1(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
return _regeneratorRuntime.wrap(function _callee11$(_context11) {
while (1) {
switch (_context11.prev = _context11.next) {
case 0:
_context11.next = 2;
return createChallenge();
case 2:
if (cf !== undefined) {
callback();
}
case 3:
case "end":
return _context11.stop();
}
}
}, _callee11);
}));
}
function execute() {
return __awaiter$1(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
return _regeneratorRuntime.wrap(function _callee12$(_context12) {
while (1) {
switch (_context12.prev = _context12.next) {
case 0:
_context12.next = 2;
return render();
case 2:
if (!(cf !== undefined)) {
_context12.next = 4;
break;
}
return _context12.abrupt("return", cf.getPromise());
case 4:
case "end":
return _context12.stop();
}
}
}, _callee12);
}));
}
function render() {
return __awaiter$1(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
return _regeneratorRuntime.wrap(function _callee13$(_context13) {
while (1) {
switch (_context13.prev = _context13.next) {
case 0:
_context13.next = 2;
return createChallenge();
case 2:
if (cf !== undefined) {
cf.render();
}
case 3:
case "end":
return _context13.stop();
}
}
}, _callee13);
}));
}
function createChallenge() {
return __awaiter$1(this, void 0, void 0, /*#__PURE__*/_regeneratorRuntime.mark(function _callee14() {
return _regeneratorRuntime.wrap(function _callee14$(_context14) {
while (1) {
switch (_context14.prev = _context14.next) {
case 0:
if (!(cf === undefined)) {
_context14.next = 4;
break;
}
cf = new Challenge();
_context14.next = 4;
return cf.initialize();
case 4:
case "end":
return _context14.stop();
}
}
}, _callee14);
}));
}
export { execute, ready };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment