@binance/fingerprint
Version:
binance web fingerprint
256 lines (255 loc) • 10.6 kB
JavaScript
import _async_to_generator from "@swc/helpers/src/_async_to_generator.mjs";
import _object_spread from "@swc/helpers/src/_object_spread.mjs";
import regeneratorRuntime from "regenerator-runtime";
import { UAParser } from "@binance/ua-parser-url";
import FP from "fingerprintjs2";
import { setLocalStorage, getLocalStorage } from "./utils/store";
import { safeJsonParse } from "./utils/json";
import { DEFAULT_PLACEHOLDER, FINGERPRINT_INFO } from "./constant";
import { isClient } from "./utils/is";
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 = DEFAULT_PLACEHOLDER;
var uaParseResult;
function getUAParseResult() {
uaParseResult = uaParseResult || new 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 DEFAULT_PLACEHOLDER;
}
};
var getWebglVendorAndRenderer = function getWebglVendorAndRenderer(webgl) {
var result = {
vendor: DEFAULT_PLACEHOLDER,
renderer: 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] || DEFAULT_PLACEHOLDER;
cnt += 1;
} else if (item.indexOf("webgl unmasked renderer:") > -1) {
result.renderer = item.split("webgl unmasked renderer:")[1] || 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 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: DEFAULT_PLACEHOLDER,
avaScreenResolution: 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 FINGERPRINT_INFO;
};
var getFpInfo = function() {
var _ref1 = _async_to_generator(regeneratorRuntime.mark(function _callee1() {
var cacheKey, options, fpInfo, getData;
return regeneratorRuntime.wrap(function _callee$(_ctx1) {
while(1)switch(_ctx1.prev = _ctx1.next){
case 0:
if (isClient) {
_ctx1.next = 2;
break;
}
return _ctx1.abrupt("return", Promise.resolve({}));
case 2:
cacheKey = _getFpInfoCacheKey();
options = _object_spread({}, excludesFpOptions);
fpInfo = safeJsonParse(getLocalStorage(cacheKey));
if (!fpInfo) {
_ctx1.next = 7;
break;
}
return _ctx1.abrupt("return", fpInfo);
case 7:
getData = function() {
var _ref = _async_to_generator(regeneratorRuntime.mark(function _callee() {
var result, resultObj, webgl, screen, res1, values;
return regeneratorRuntime.wrap(function _callee$(_ctx) {
while(1)switch(_ctx.prev = _ctx.next){
case 0:
_ctx.next = 2;
return FP.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 = FP.x64hash128(values.join(""), 32);
// TODO: will remove it.
localStorage.removeItem("__BNC_FP_INFO__0093cf");
// expire time: 1 days
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);
};
}();
export default getFpInfo;