@binance/fingerprint
Version:
binance web fingerprint
322 lines (321 loc) • 12.7 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _regeneratorRuntime = _interopRequireDefault(require("regenerator-runtime"));
var _uaParserUrl = require("@binance/ua-parser-url");
var _fingerprintjs2 = _interopRequireDefault(require("fingerprintjs2"));
var _store = require("./utils/store");
var _json = require("./utils/json");
var _constant = require("./constant");
var _is = require("./utils/is");
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
try {
var info = gen[key](arg);
var value = info.value;
} catch (error) {
reject(error);
return;
}
if (info.done) {
resolve(value);
} else {
Promise.resolve(value).then(_next, _throw);
}
}
function _asyncToGenerator(fn) {
return function() {
var self = this, args = arguments;
return new Promise(function(resolve, reject) {
var gen = fn.apply(self, args);
function _next(value) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
}
function _throw(err) {
asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
}
_next(undefined);
});
};
}
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true,
configurable: true,
writable: true
});
} else {
obj[key] = value;
}
return obj;
}
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : {
default: obj
};
}
function _objectSpread(target) {
for(var i = 1; i < arguments.length; i++){
var source = arguments[i] != null ? arguments[i] : {};
var ownKeys = Object.keys(source);
if (typeof Object.getOwnPropertySymbols === "function") {
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
}));
}
ownKeys.forEach(function(key) {
_defineProperty(target, key, source[key]);
});
}
return target;
}
var excludesFpOptions = {
colorDepth: true,
deviceMemory: true,
pixelRatio: true,
hardwareConcurrency: true,
sessionStorage: true,
localStorage: true,
indexedDb: true,
addBehavior: true,
openDatabase: true,
cpuClass: true,
doNotTrack: true,
adBlock: true,
hasLiedLanguages: true,
hasLiedResolution: true,
hasLiedOs: true,
hasLiedBrowser: true,
touchSupport: true,
fonts: true,
fontsFlash: true,
enumerateDevices: true
};
var defaultValue = _constant.DEFAULT_PLACEHOLDER;
var uaParseResult;
function getUAParseResult() {
uaParseResult = uaParseResult || new _uaParserUrl.UAParser().getResult();
return uaParseResult;
}
var getSystemAndVersion = function getSystemAndVersion() {
var os = getUAParseResult().os;
if (!os || !os.name) return defaultValue;
return "".concat(os.name, " ").concat(os.version);
};
var getBrandAndModal = function getBrandAndModal() {
var device = getUAParseResult().device;
if (!device || !device.model) return defaultValue;
return [
device.type,
device.vendor,
device.model,
""
].join(" ");
};
var getDeviceName = function getDeviceName() {
var _uaParseResult = getUAParseResult();
var browser = _uaParseResult.browser;
var os = _uaParseResult.os || {};
if (!browser || !browser.name) return defaultValue;
return "".concat(browser.name, " V").concat(browser.version, " (").concat(os.name || "", ")");
};
var getTimezone = function getTimezone(offset) {
var hours = Math.floor(Math.abs(offset) / 60);
var minutes = Math.abs(offset % 60);
var tz;
if (minutes === 0) {
tz = "".concat(hours.toString().padStart(2, "0"), ":00");
} else {
tz = "".concat(hours.toString().padStart(2, "0"), ":").concat(minutes.toString().padStart(2, "0"));
}
// If offset is positive, use negative timezone; if negative, use positive timezone
if (offset > 0) {
tz = "-".concat(tz);
} else {
tz = "+".concat(tz);
}
return "GMT".concat(tz);
};
var getCanvas = function getCanvas(canvasList) {
var baseStr = canvasList[1].replace("canvas fp:data:image/png;base64,", "");
var bin2hex = function bin2hex(s) {
var i;
var l;
var o = "";
var n;
s += "";
for(i = 0, l = s.length; i < l; i++){
n = s.charCodeAt(i).toString(16);
o += n.length < 2 ? "0".concat(n) : n;
}
return o;
};
try {
var bin = atob(baseStr);
var crc = bin2hex(bin.slice(-16, -12));
return crc;
} catch (error) {
console.warn("Failed to get canvas code: ", error);
return _constant.DEFAULT_PLACEHOLDER;
}
};
var getWebglVendorAndRenderer = function getWebglVendorAndRenderer(webgl) {
var result = {
vendor: _constant.DEFAULT_PLACEHOLDER,
renderer: _constant.DEFAULT_PLACEHOLDER
};
if (!webgl || !webgl.length) return result;
var len = webgl.length;
var cnt = 0;
for(var i = 0; i < len; i++){
var item = webgl[i] || "";
if (item.indexOf("webgl unmasked vendor:") > -1) {
result.vendor = item.split("webgl unmasked vendor:")[1] || _constant.DEFAULT_PLACEHOLDER;
cnt += 1;
} else if (item.indexOf("webgl unmasked renderer:") > -1) {
result.renderer = item.split("webgl unmasked renderer:")[1] || _constant.DEFAULT_PLACEHOLDER;
cnt += 1;
}
if (cnt === 2) break;
}
return result;
};
var getPlugins = function(data) {
var plugins = data.plugins || data.regular_plugins || data.ie_plugins;
if (!Array.isArray(plugins)) return _constant.DEFAULT_PLACEHOLDER;
var result = [];
plugins.forEach(function(plugin) {
result.push(plugin[0]);
});
if (result.length > 500) {
return result.slice(0, 500).join(",");
}
return result.join(",");
};
var getScreenResolution = function(data) {
var result = {
screenResolution: _constant.DEFAULT_PLACEHOLDER,
avaScreenResolution: _constant.DEFAULT_PLACEHOLDER
};
if (data.screenResolution && Array.isArray(data.availableScreenResolution)) {
result.screenResolution = data.screenResolution.join(",");
}
if (data.availableScreenResolution && Array.isArray(data.availableScreenResolution)) {
result.avaScreenResolution = data.availableScreenResolution.join(",");
}
return result;
};
var _getFpInfoCacheKey = function() {
return _constant.FINGERPRINT_INFO;
};
var getFpInfo = function() {
var _ref1 = _asyncToGenerator(_regeneratorRuntime.default.mark(function _callee1() {
var cacheKey, options, fpInfo, getData;
return _regeneratorRuntime.default.wrap(function _callee$(_ctx1) {
while(1)switch(_ctx1.prev = _ctx1.next){
case 0:
if (_is.isClient) {
_ctx1.next = 2;
break;
}
return _ctx1.abrupt("return", Promise.resolve({}));
case 2:
cacheKey = _getFpInfoCacheKey();
options = _objectSpread({}, excludesFpOptions);
fpInfo = (0, _json).safeJsonParse((0, _store).getLocalStorage(cacheKey));
if (!fpInfo) {
_ctx1.next = 7;
break;
}
return _ctx1.abrupt("return", fpInfo);
case 7:
getData = function() {
var _ref = _asyncToGenerator(_regeneratorRuntime.default.mark(function _callee() {
var result, resultObj, webgl, screen, res1, values;
return _regeneratorRuntime.default.wrap(function _callee$(_ctx) {
while(1)switch(_ctx.prev = _ctx.next){
case 0:
_ctx.next = 2;
return _fingerprintjs2.default.getPromise({
excludes: options
});
case 2:
result = _ctx.sent;
resultObj = result.reduce(function(res, cur) {
res[cur.key] = cur.value;
return res;
}, {});
webgl = getWebglVendorAndRenderer(resultObj.webgl);
screen = getScreenResolution(resultObj);
res1 = {
screen_resolution: screen.screenResolution,
available_screen_resolution: screen.avaScreenResolution,
system_version: getSystemAndVersion(),
brand_model: getBrandAndModal(),
system_lang: resultObj.language,
timezone: getTimezone(resultObj.timezoneOffset),
timezoneOffset: resultObj.timezoneOffset,
// web
user_agent: resultObj.userAgent,
list_plugin: getPlugins(resultObj),
canvas_code: getCanvas(resultObj.canvas),
webgl_vendor: webgl.vendor,
webgl_renderer: webgl.renderer,
audio: resultObj.audio,
platform: resultObj.platform,
web_timezone: resultObj.timezone,
device_name: getDeviceName()
};
values = Object.keys(res1).sort().map(function(k) {
return res1[k];
});
res1.fingerprint = _fingerprintjs2.default.x64hash128(values.join(""), 32);
// TODO: will remove it.
localStorage.removeItem("__BNC_FP_INFO__0093cf");
// expire time: 1 days
(0, _store).setLocalStorage(cacheKey, JSON.stringify(res1), {
ttl: 24 * 3600 * 1000
});
return _ctx.abrupt("return", res1);
case 12:
case "end":
return _ctx.stop();
}
}, _callee);
}));
return function getData() {
return _ref.apply(this, arguments);
};
}();
_ctx1.prev = 8;
_ctx1.next = 11;
return getData();
case 11:
return _ctx1.abrupt("return", _ctx1.sent);
case 14:
_ctx1.prev = 14;
_ctx1.t0 = _ctx1["catch"](8);
// eslint-disable-next-line no-console
console.error("Fingerprint error: ", _ctx1.t0);
case 17:
return _ctx1.abrupt("return", Promise.resolve({}));
case 18:
case "end":
return _ctx1.stop();
}
}, _callee1, null, [
[
8,
14
]
]);
}));
return function getFpInfo() {
return _ref1.apply(this, arguments);
};
}();
var _default = getFpInfo;
exports.default = _default;