New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

ebic

Package Overview
Dependencies
Maintainers
1
Versions
7
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ebic - npm Package Compare versions

Comparing version
1.0.5
to
1.0.7
+0
-0
.github/workflows/main.yml

@@ -0,0 +0,0 @@ name: CI

@@ -0,0 +0,0 @@ export interface GetTokenOptions {

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -0,0 +0,0 @@ "use strict";

+18
-14
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const crypto_1 = require("crypto");
const alphabet = "abcdefghijklmnopqrstuvwxyz";
let md5 = (0, crypto_1.createHash)("md5");
function encrypt(data, key) {

@@ -8,10 +10,11 @@ let salt = "";

let dx = Buffer.alloc(0);
// Generate salt, as 8 random lowercase letters
salt = String.fromCharCode(...Array(8).fill(0).map(_ => Math.floor(Math.random() * 26) + 97));
// Our final key and iv come from the key and salt being repeatedly hashed
// dx = md5(md5(md5(key + salt) + key + salt) + key + salt)
// For each round of hashing, we append the result to salted, resulting in a 96 character string
// The first 64 characters are the key, and the last 32 are the iv
salt = Array(8)
.fill(0)
.map((v) => alphabet[Math.floor(Math.random() * alphabet.length)])
.join(""); // 8 random letters
data =
data +
Array(17 - (data.length % 16)).join(String.fromCharCode(16 - (data.length % 16))); // Padding (pkcs7?)
for (let x = 0; x < 3; x++) {
dx = (0, crypto_1.createHash)("md5")
dx = md5
.update(Buffer.concat([

@@ -24,6 +27,6 @@ Buffer.from(dx),

salted += dx.toString("hex");
md5 = (0, crypto_1.createHash)("md5");
}
let aes = (0, crypto_1.createCipheriv)("aes-256-cbc", Buffer.from(salted.substring(0, 64), "hex"), // Key
Buffer.from(salted.substring(64, 64 + 32), "hex") // IV
);
let aes = (0, crypto_1.createCipheriv)("aes-256-cbc", Buffer.from(salted, "hex").slice(0, 32), Buffer.from(salted, "hex").slice(32, 32 + 16));
aes.setAutoPadding(false);
return JSON.stringify({

@@ -37,8 +40,9 @@ ct: aes.update(data, null, "base64") + aes.final("base64"),

let data = JSON.parse(rawData);
// We get our decryption key by doing the inverse of the encryption process
let dk = Buffer.concat([Buffer.from(key), Buffer.from(data.s, "hex")]);
let arr = [Buffer.from((0, crypto_1.createHash)("md5").update(dk).digest()).toString("hex")];
let md5 = (0, crypto_1.createHash)("md5");
let arr = [Buffer.from(md5.update(dk).digest()).toString("hex")];
let result = arr[0];
for (let x = 1; x < 3; x++) {
arr.push(Buffer.from((0, crypto_1.createHash)("md5")
md5 = (0, crypto_1.createHash)("md5");
arr.push(Buffer.from(md5
.update(Buffer.concat([Buffer.from(arr[x - 1], "hex"), dk]))

@@ -48,3 +52,3 @@ .digest()).toString("hex"));

}
let aes = (0, crypto_1.createDecipheriv)("aes-256-cbc", Buffer.from(result.substring(0, 64), "hex"), Buffer.from(data.iv, "hex"));
let aes = (0, crypto_1.createDecipheriv)("aes-256-cbc", Buffer.from(result, "hex").slice(0, 32), Buffer.from(data.iv, "hex"));
return aes.update(data.ct, "base64", "utf8") + aes.final("utf8");

@@ -51,0 +55,0 @@ }

@@ -1,2 +0,2 @@

declare const baseFingerprint: {
declare function getFingerprint(canvasFp?: string, randomCanvasFp?: boolean): {
DNT: string;

@@ -16,3 +16,3 @@ L: string;

PK: string;
CFP: string;
CFP: string | boolean;
FR: boolean;

@@ -27,33 +27,4 @@ FOS: boolean;

};
declare function getFingerprint(): {
DNT: string;
L: string;
D: number;
PR: number;
S: number[];
AS: number[];
TO: number;
SS: boolean;
LS: boolean;
IDB: boolean;
B: boolean;
ODB: boolean;
CPUC: string;
PK: string;
CFP: string;
FR: boolean;
FOS: boolean;
FB: boolean;
JSF: string[];
P: string[];
T: (number | boolean)[];
H: number;
SWF: boolean;
};
declare function prepareF(fingerprint: any): string;
declare function prepareFe(fingerprint: any): any[];
declare function getEnhancedFingerprint(fp: typeof baseFingerprint, ua: string, opts: any): {
key: string;
value: any;
}[];
declare const _default: {

@@ -63,4 +34,3 @@ getFingerprint: typeof getFingerprint;

prepareFe: typeof prepareFe;
getEnhancedFingerprint: typeof getEnhancedFingerprint;
};
export default _default;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const murmur_1 = require("./murmur");
const crypto_1 = require("crypto");
const pngjs_1 = require("pngjs");
const baseFingerprint = {

@@ -92,5 +91,7 @@ DNT: "unknown",

P: [
"Chrome PDF Plugin::Portable Document Format::application/x-google-chrome-pdf~pdf",
"Chrome PDF Viewer::::application/pdf~pdf",
"Native Client::::application/x-nacl~,application/x-pnacl~",
'Chrome PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'Chromium PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'Microsoft Edge PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'WebKit built-in PDF::Portable Document Format::application/pdf~pdf,text/pdf~pdf'
],

@@ -102,17 +103,241 @@ T: [0, false, false],

const languages = [
"af", "af-ZA", "ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA",
"ar-SY", "ar-TN", "ar-YE", "az", "az-AZ", "az-AZ", "be", "be-BY", "bg", "bg-BG", "bs-BA", "ca", "ca-ES", "cs", "cs-CZ", "cy",
"cy-GB", "da", "da-DK", "de", "de-AT", "de-CH", "de-DE", "de-LI", "de-LU", "dv", "dv-MV", "el", "el-GR", "en", "en-AU", "en-BZ",
"en-CA", "en-CB", "en-GB", "en-IE", "en-JM", "en-NZ", "en-PH", "en-TT", "en-US", "en-ZA", "en-ZW", "eo", "es", "es-AR", "es-BO", "es-CL",
"es-CO", "es-CR", "es-DO", "es-EC", "es-ES", "es-ES", "es-GT", "es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PR", "es-PY", "es-SV", "es-UY",
"es-VE", "et", "et-EE", "eu", "eu-ES", "fa", "fa-IR", "fi", "fi-FI", "fo", "fo-FO", "fr", "fr-BE", "fr-CA", "fr-CH", "fr-FR",
"fr-LU", "fr-MC", "gl", "gl-ES", "gu", "gu-IN", "he", "he-IL", "hi", "hi-IN", "hr", "hr-BA", "hr-HR", "hu", "hu-HU", "hy",
"hy-AM", "id", "id-ID", "is", "is-IS", "it", "it-CH", "it-IT", "ja", "ja-JP", "ka", "ka-GE", "kk", "kk-KZ", "kn", "kn-IN",
"ko", "ko-KR", "kok", "kok-IN", "ky", "ky-KG", "lt", "lt-LT", "lv", "lv-LV", "mi", "mi-NZ", "mk", "mk-MK", "mn", "mn-MN",
"mr", "mr-IN", "ms", "ms-BN", "ms-MY", "mt", "mt-MT", "nb", "nb-NO", "nl", "nl-BE", "nl-NL", "nn-NO", "ns", "ns-ZA", "pa",
"pa-IN", "pl", "pl-PL", "ps", "ps-AR", "pt", "pt-BR", "pt-PT", "qu", "qu-BO", "qu-EC", "qu-PE", "ro", "ro-RO", "ru", "ru-RU",
"sa", "sa-IN", "se", "se-FI", "se-FI", "se-FI", "se-NO", "se-NO", "se-NO", "se-SE", "se-SE", "se-SE", "sk", "sk-SK", "sl", "sl-SI",
"sq", "sq-AL", "sr-BA", "sr-BA", "sr-SP", "sr-SP", "sv", "sv-FI", "sv-SE", "sw", "sw-KE", "syr", "syr-SY", "ta", "ta-IN", "te",
"te-IN", "th", "th-TH", "tl", "tl-PH", "tn", "tn-ZA", "tr", "tr-TR", "tt", "tt-RU", "ts", "uk", "uk-UA", "ur", "ur-PK",
"uz", "uz-UZ", "uz-UZ", "vi", "vi-VN", "xh", "xh-ZA", "zh", "zh-CN", "zh-HK", "zh-MO", "zh-SG", "zh-TW", "zu", "zu-ZA"
"af",
"af-ZA",
"ar",
"ar-AE",
"ar-BH",
"ar-DZ",
"ar-EG",
"ar-IQ",
"ar-JO",
"ar-KW",
"ar-LB",
"ar-LY",
"ar-MA",
"ar-OM",
"ar-QA",
"ar-SA",
"ar-SY",
"ar-TN",
"ar-YE",
"az",
"az-AZ",
"az-AZ",
"be",
"be-BY",
"bg",
"bg-BG",
"bs-BA",
"ca",
"ca-ES",
"cs",
"cs-CZ",
"cy",
"cy-GB",
"da",
"da-DK",
"de",
"de-AT",
"de-CH",
"de-DE",
"de-LI",
"de-LU",
"dv",
"dv-MV",
"el",
"el-GR",
"en",
"en-AU",
"en-BZ",
"en-CA",
"en-CB",
"en-GB",
"en-IE",
"en-JM",
"en-NZ",
"en-PH",
"en-TT",
"en-US",
"en-ZA",
"en-ZW",
"eo",
"es",
"es-AR",
"es-BO",
"es-CL",
"es-CO",
"es-CR",
"es-DO",
"es-EC",
"es-ES",
"es-ES",
"es-GT",
"es-HN",
"es-MX",
"es-NI",
"es-PA",
"es-PE",
"es-PR",
"es-PY",
"es-SV",
"es-UY",
"es-VE",
"et",
"et-EE",
"eu",
"eu-ES",
"fa",
"fa-IR",
"fi",
"fi-FI",
"fo",
"fo-FO",
"fr",
"fr-BE",
"fr-CA",
"fr-CH",
"fr-FR",
"fr-LU",
"fr-MC",
"gl",
"gl-ES",
"gu",
"gu-IN",
"he",
"he-IL",
"hi",
"hi-IN",
"hr",
"hr-BA",
"hr-HR",
"hu",
"hu-HU",
"hy",
"hy-AM",
"id",
"id-ID",
"is",
"is-IS",
"it",
"it-CH",
"it-IT",
"ja",
"ja-JP",
"ka",
"ka-GE",
"kk",
"kk-KZ",
"kn",
"kn-IN",
"ko",
"ko-KR",
"kok",
"kok-IN",
"ky",
"ky-KG",
"lt",
"lt-LT",
"lv",
"lv-LV",
"mi",
"mi-NZ",
"mk",
"mk-MK",
"mn",
"mn-MN",
"mr",
"mr-IN",
"ms",
"ms-BN",
"ms-MY",
"mt",
"mt-MT",
"nb",
"nb-NO",
"nl",
"nl-BE",
"nl-NL",
"nn-NO",
"ns",
"ns-ZA",
"pa",
"pa-IN",
"pl",
"pl-PL",
"ps",
"ps-AR",
"pt",
"pt-BR",
"pt-PT",
"qu",
"qu-BO",
"qu-EC",
"qu-PE",
"ro",
"ro-RO",
"ru",
"ru-RU",
"sa",
"sa-IN",
"se",
"se-FI",
"se-FI",
"se-FI",
"se-NO",
"se-NO",
"se-NO",
"se-SE",
"se-SE",
"se-SE",
"sk",
"sk-SK",
"sl",
"sl-SI",
"sq",
"sq-AL",
"sr-BA",
"sr-BA",
"sr-SP",
"sr-SP",
"sv",
"sv-FI",
"sv-SE",
"sw",
"sw-KE",
"syr",
"syr-SY",
"ta",
"ta-IN",
"te",
"te-IN",
"th",
"th-TH",
"tl",
"tl-PH",
"tn",
"tn-ZA",
"tr",
"tr-TR",
"tt",
"tt-RU",
"ts",
"uk",
"uk-UA",
"ur",
"ur-PK",
"uz",
"uz-UZ",
"uz-UZ",
"vi",
"vi-VN",
"xh",
"xh-ZA",
"zh",
"zh-CN",
"zh-HK",
"zh-MO",
"zh-SG",
"zh-TW",
"zu",
"zu-ZA",
];

@@ -138,31 +363,70 @@ let screenRes = [

// Get fingerprint
function getFingerprint() {
let fingerprint = { ...baseFingerprint }; // Create a copy of the base fingerprint
function getFingerprint(canvasFp, randomCanvasFp) {
var _a;
let fingerprint = Object.assign({}, baseFingerprint); // Create a copy of the base fingerprint
// Randomization time!
fingerprint["DNT"] = "unknown";
fingerprint["DNT"] = "unknown"; //Math.round(Math.random());
fingerprint["L"] = languages[Math.floor(Math.random() * languages.length)];
fingerprint["D"] = [8, 24][Math.floor(Math.random() * 2)];
fingerprint["PR"] = Math.round(Math.random() * 100) / 100 * 2 + 0.5;
fingerprint["S"] = randomScreenRes();
fingerprint["AS"] = fingerprint.S;
fingerprint["TO"] = (Math.floor(Math.random() * 24) - 12) * 60;
fingerprint["SS"] = Math.random() > 0.5;
fingerprint["LS"] = Math.random() > 0.5;
fingerprint["IDB"] = Math.random() > 0.5;
fingerprint["B"] = Math.random() > 0.5;
fingerprint["ODB"] = Math.random() > 0.5;
fingerprint["CPUC"] = "unknown";
fingerprint["PK"] = "Win32";
fingerprint["CFP"] = "canvas winding:yes~canvas fp:data:image/png;base64," + (0, crypto_1.randomBytes)(128).toString("base64");
fingerprint["D"] = [24, 32][Math.floor(Math.random() * 2)]; // common value only: 24bit/32bit
fingerprint["PR"] = [1, 1.25, 1.5, 1.75][Math.floor(Math.random() * 4)]; // common value only: 1, 1.25, 1.5, 1.75
fingerprint["S"] = randomScreenRes().map(x => x / fingerprint["PR"]); // change screen res to match pixel ratio
fingerprint["AS"] = fingerprint["S"]; //[fingerprint["S"][0], fingerprint["S"][1] - 40]
fingerprint["TO"] = (Math.floor(Math.random() * 24) - 12) * 60; // timezone SHOULD be based on current IP
fingerprint["SS"] = true; //Math.random() > 0.5;
fingerprint["LS"] = true; //Math.random() > 0.5;
fingerprint["IDB"] = true; //Math.random() > 0.5;
fingerprint["B"] = false; // IE-only signature, SHOULD NOT EXIST //Math.random() > 0.5;
fingerprint["ODB"] = true; // WebSQL, MUST be disabled after November 7, 2023 (Chromium 119). Might TODO base on UA. //Math.random() > 0.5;
fingerprint["CPUC"] = "unknown"; /*["68K", "Alpha", "PPC", "x86", "Other", "unknown"][
Math.floor(Math.random() * 5)
];*/
fingerprint["PK"] = "Win32"; // This SHOULD be based on User Agent.
/*[
"HP-UX",
"Mac68K",
"MacPPC",
"SunOS",
"Win16",
"Win32",
"WinCE",
][Math.floor(Math.random() * 7)];*/
let rdCanvas;
if (typeof randomCanvasFp === "undefined" || randomCanvasFp) {
// attempt to randomize canvas fingerprint by generating a random 300x150 PNG image
let png = new pngjs_1.PNG({
height: 150,
width: 300,
});
for (let y = 0; y < png.height; y++) {
for (let x = 0; x < png.width; x++) {
let idx = (png.width * y + x) << 2;
png.data[idx] = Math.floor(Math.random() * 256);
png.data[idx + 1] = Math.floor(Math.random() * 256);
png.data[idx + 2] = Math.floor(Math.random() * 256);
png.data[idx + 3] = 0xFF;
}
}
var buffer = pngjs_1.PNG.sync.write(png, {
colorType: 6,
bitDepth: 8
});
rdCanvas = `data:image/png;base64,${buffer.toString("base64")}`;
}
fingerprint["CFP"] = (_a = canvasFp !== null && canvasFp !== void 0 ? canvasFp : rdCanvas) !== null && _a !== void 0 ? _a : false; // We CAN randomize data, block canvas fingerprinting, or BYOP
/*`canvas winding:yes~canvas fp:data:image/png;base64,${Buffer.from(
Math.random().toString()
).toString("base64")}`;*/ //canvasFp || ''; // Canvas Fingerprint
fingerprint["FR"] = false; // Fake Resolution
fingerprint["FOS"] = false; // Fake Operating System
fingerprint["FB"] = false; // Fake Browser
fingerprint["JSF"] = fingerprint["JSF"].filter(() => Math.random() > 0.5);
fingerprint["P"] = fingerprint["P"].filter(() => Math.random() > 0.5);
fingerprint["T"] = [
// Standard Windows fonts
fingerprint["JSF"] = ['Arial', 'Arial Black', 'Arial Narrow', 'Book Antiqua', 'Bookman Old Style', 'Calibri', 'Cambria', 'Cambria Math', 'Century', 'Century Gothic', 'Century Schoolbook', 'Comic Sans MS', 'Consolas', 'Courier', 'Courier New', 'Garamond', 'Georgia', 'Helvetica', 'Impact', 'Lucida Bright', 'Lucida Calligraphy', 'Lucida Console', 'Lucida Fax', 'Lucida Handwriting', 'Lucida Sans', 'Lucida Sans Typewriter', 'Lucida Sans Unicode', 'Microsoft Sans Serif', 'Monotype Corsiva', 'MS Gothic', 'MS PGothic', 'MS Reference Sans Serif', 'MS Sans Serif', 'MS Serif', 'Palatino Linotype', 'Segoe Print', 'Segoe Script', 'Segoe UI', 'Segoe UI Light', 'Segoe UI Semibold', 'Segoe UI Symbol', 'Tahoma', 'Times', 'Times New Roman', 'Trebuchet MS', 'Verdana', 'Wingdings', 'Wingdings 2', 'Wingdings 3']; //fingerprint["JSF"].filter(() => Math.random() > 0.5);
//fingerprint["P"] = fingerprint["P"].filter(() => Math.random() > 0.5);
let randomizeTouch = Math.random() > 0.5;
fingerprint["T"] = randomizeTouch ? [
Math.floor(Math.random() * 8),
Math.random() > 0.5,
Math.random() > 0.5,
];
fingerprint["H"] = 2 ** Math.floor(Math.random() * 6);
false,
false //Math.random() > 0.5,
] : [0, false, false]; // Touch Support [maxTouchPoints, touchEvent emit support, is touchStart listened]
fingerprint["H"] = Math.pow(2, Math.floor(Math.random() * 3));
fingerprint["SWF"] = fingerprint["SWF"]; // RIP Flash

@@ -219,84 +483,2 @@ return fingerprint;

}
let baseEnhancedFingerprint = {
"webgl_extensions": "ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_multi_draw",
"webgl_extensions_hash": "58a5a04a5bef1a78fa88d5c5098bd237",
"webgl_renderer": "WebKit WebGL",
"webgl_vendor": "WebKit",
"webgl_version": "WebGL 1.0 (OpenGL ES 2.0 Chromium)",
"webgl_shading_language_version": "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)",
"webgl_aliased_line_width_range": "[1, 1]",
"webgl_aliased_point_size_range": "[0.125, 8192]",
"webgl_antialiasing": "yes",
"webgl_bits": "8,8,24,8,8,0",
"webgl_max_params": "16,32,8192,261,8192,16,8192,32,32,16,256",
"webgl_max_viewport_dims": "[8192, 8192]",
"webgl_unmasked_vendor": "Google Inc.",
"webgl_unmasked_renderer": "Google SwiftShader",
"webgl_vsf_params": "23,127,127,23,127,127,23,127,127",
"webgl_vsi_params": "0,31,30,0,31,30,0,31,30",
"webgl_fsf_params": "23,127,127,23,127,127,23,127,127",
"webgl_fsi_params": "0,31,30,0,31,30,0,31,30",
"webgl_hash_webgl": null,
"user_agent_data_brands": "Not/A)Brand,Google Chrome,Chromium",
"user_agent_data_mobile": null,
"navigator_connection_downlink": null,
"navigator_connection_downlink_max": null,
"network_info_rtt": null,
"network_info_save_data": false,
"network_info_rtt_type": null,
"screen_pixel_depth": 24,
"navigator_device_memory": 0.5,
"navigator_languages": "en-US,fr-BE,fr,en-BE,en",
"window_inner_width": 0,
"window_inner_height": 0,
"window_outer_width": 2195,
"window_outer_height": 1195,
"browser_detection_firefox": false,
"browser_detection_brave": false,
"audio_codecs": "{\"ogg\":\"probably\",\"mp3\":\"probably\",\"wav\":\"probably\",\"m4a\":\"maybe\",\"aac\":\"probably\"}",
"video_codecs": "{\"ogg\":\"probably\",\"h264\":\"probably\",\"webm\":\"probably\",\"mpeg4v\":\"\",\"mpeg4a\":\"\",\"theora\":\"\"}",
"media_query_dark_mode": true,
"headless_browser_phantom": false,
"headless_browser_selenium": false,
"headless_browser_nightmare_js": false,
"document__referrer": "https://www.roblox.com/",
"window__ancestor_origins": [
"https://www.roblox.com",
],
"window__tree_index": [
0
],
"window__tree_structure": "[[]]",
"window__location_href": "https://roblox-api.arkoselabs.com/v2/1.5.4/enforcement.cd12da708fe6cbe6e068918c38de2ad9.html#476068BF-9607-4799-B53D-966BE98E2B81",
"client_config__sitedata_location_href": "https://www.roblox.com/arkose/iframe",
"client_config__surl": "https://roblox-api.arkoselabs.com",
"client_config__language": null,
"navigator_battery_charging": true,
"audio_fingerprint": (124.04347527516074 + Math.random() * 0.001 - 0.0005).toString(),
};
function getEnhancedFingerprint(fp, ua, opts) {
let fingerprint = { ...baseEnhancedFingerprint };
fingerprint.webgl_extensions = fingerprint.webgl_extensions.split(";").filter(_ => Math.random() > 0.5).join(";");
fingerprint.webgl_extensions_hash = (0, murmur_1.default)(fingerprint.webgl_extensions, 0);
fingerprint.screen_pixel_depth = fp.D;
fingerprint.navigator_languages = fp.L;
fingerprint.window_outer_height = fp.S[0];
fingerprint.window_outer_width = fp.S[1];
fingerprint.window_inner_height = fp.S[0];
fingerprint.window_inner_width = fp.S[1];
fingerprint.screen_pixel_depth = fp.D;
fingerprint.browser_detection_firefox = !!ua.match(/Firefox\/\d+/);
fingerprint.browser_detection_brave = !!ua.match(/Brave\/\d+/);
fingerprint.media_query_dark_mode = Math.random() > 0.9;
fingerprint.webgl_hash_webgl = (0, murmur_1.default)(Object.entries(fingerprint).filter(([k, v]) => k.startsWith("webgl_") && k != "webgl_hash_webgl").map(([k, v]) => v).join(","), 0);
fingerprint.client_config__language = opts.language || null;
fingerprint.window__location_href = `${opts.surl}/v2/${opts.pkey}/1.5.4/enforcement.${(0, crypto_1.randomBytes)(16).toString("hex")}.html`;
if (opts.site) {
fingerprint.document__referrer = opts.site;
fingerprint.window__ancestor_origins = [opts.site];
fingerprint.client_config__sitedata_location_href = opts.site;
}
fingerprint.client_config__surl = opts.surl || "https://client-api.arkoselabs.com";
return Object.entries(fingerprint).map(([k, v]) => ({ key: k, value: v }));
}
exports.default = {

@@ -306,3 +488,2 @@ getFingerprint,

prepareFe,
getEnhancedFingerprint,
};

@@ -0,0 +0,0 @@ /// <reference types="node" />

@@ -0,0 +0,0 @@ "use strict";

export * from "./api";
export * from "./session";

@@ -0,0 +0,0 @@ "use strict";

declare var x64hash128: (t: any, r: any) => string;
export default x64hash128;

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ import { GetTokenResult } from "./api";

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ interface TimestampData {

@@ -0,0 +0,0 @@ "use strict";

@@ -0,0 +0,0 @@ Copyright (c) 2023 noahcoolboy

{
"name": "ebic",
"version": "1.0.5",
"description": "Ebic Condos packages",
"author": "Diego Miguel",
"license": "MIT",
"keywords": [
"condo captcha"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build": "rimraf lib && tsc",
"test": "node test/test.js",
"benchmark": "node test/benchmark.js",
"roblox": "node test/roblox.js"
},
"devDependencies": {
"@types/node": "^17.0.42",
"@types/pngjs": "^6.0.1",
"rimraf": "^3.0.2",
"typescript": "^4.7.4"
},
"repository": {
"type": "git",
"url": "git+https://github.com/badaimweeb/funcaptcha.git"
},
"dependencies": {
"http2-wrapper": "^2.2.0",
"pngjs": "^7.0.0",
"socks": "^2.7.1",
"undici": "^5.22.1",
"windmouse": "^1.0.5"
},
"bugs": {
"url": "https://github.com/badaimweeb/funcaptcha/issues"
},
"homepage": "https://github.com/badaimweeb/funcaptcha#readme",
"directories": {
"lib": "lib",
"test": "test"
}
"name": "ebic",
"version": "1.0.7",
"description": "A library used to interact with funcaptchas.",
"author": "noahcoolboy",
"license": "MIT",
"keywords": [
"funcaptcha"
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"scripts": {
"build": "rimraf lib && tsc",
"test": "node test/test.js",
"benchmark": "node test/benchmark.js",
"roblox": "node test/roblox.js"
},
"devDependencies": {
"@types/node": "^17.0.42",
"@types/pngjs": "^6.0.1",
"rimraf": "^3.0.2",
"typescript": "^4.7.4"
},
"repository": "github:badaimweeb/funcaptcha",
"dependencies": {
"http2-wrapper": "^2.2.0",
"pngjs": "^7.0.0",
"socks": "^2.7.1",
"undici": "^5.22.1",
"windmouse": "^1.0.5"
}
}

@@ -0,0 +0,0 @@ # funcaptcha

@@ -0,0 +0,0 @@ import request from "./http";

@@ -0,0 +0,0 @@ import request from "./http";

@@ -9,2 +9,5 @@ import { createHash, createCipheriv, createDecipheriv } from "crypto";

const alphabet = "abcdefghijklmnopqrstuvwxyz";
let md5 = createHash("md5");
function encrypt(data: string, key: string): string {

@@ -15,11 +18,14 @@ let salt = "";

// Generate salt, as 8 random lowercase letters
salt = String.fromCharCode(...Array(8).fill(0).map(_ => Math.floor(Math.random() * 26) + 97))
salt = Array(8)
.fill(0)
.map((v) => alphabet[Math.floor(Math.random() * alphabet.length)])
.join(""); // 8 random letters
data =
data +
Array(17 - (data.length % 16)).join(
String.fromCharCode(16 - (data.length % 16))
); // Padding (pkcs7?)
// Our final key and iv come from the key and salt being repeatedly hashed
// dx = md5(md5(md5(key + salt) + key + salt) + key + salt)
// For each round of hashing, we append the result to salted, resulting in a 96 character string
// The first 64 characters are the key, and the last 32 are the iv
for (let x = 0; x < 3; x++) {
dx = createHash("md5")
dx = md5
.update(

@@ -35,2 +41,3 @@ Buffer.concat([

salted += dx.toString("hex");
md5 = createHash("md5");
}

@@ -40,5 +47,6 @@

"aes-256-cbc",
Buffer.from(salted.substring(0, 64), "hex"), // Key
Buffer.from(salted.substring(64, 64 + 32), "hex") // IV
Buffer.from(salted, "hex").slice(0, 32),
Buffer.from(salted, "hex").slice(32, 32 + 16)
);
aes.setAutoPadding(false);

@@ -55,11 +63,13 @@ return JSON.stringify({

// We get our decryption key by doing the inverse of the encryption process
let dk = Buffer.concat([Buffer.from(key), Buffer.from(data.s, "hex")]);
let arr = [Buffer.from(createHash("md5").update(dk).digest()).toString("hex")];
let md5 = createHash("md5");
let arr = [Buffer.from(md5.update(dk).digest()).toString("hex")];
let result = arr[0];
for (let x = 1; x < 3; x++) {
md5 = createHash("md5");
arr.push(
Buffer.from(
createHash("md5")
md5
.update(Buffer.concat([Buffer.from(arr[x - 1], "hex"), dk]))

@@ -74,3 +84,3 @@ .digest()

"aes-256-cbc",
Buffer.from(result.substring(0, 64), "hex"),
Buffer.from(result, "hex").slice(0, 32),
Buffer.from(data.iv, "hex")

@@ -77,0 +87,0 @@ );

@@ -1,5 +0,28 @@

import x64hash128 from "./murmur";
import { randomBytes } from "crypto";
import { PNG } from "pngjs";
const baseFingerprint = {
const baseFingerprint: {
DNT: string;
L: string;
D: number;
PR: number;
S: number[];
AS: number[];
TO: number;
SS: boolean;
LS: boolean;
IDB: boolean;
B: boolean;
ODB: boolean;
CPUC: string;
PK: string;
CFP: string | boolean;
FR: boolean;
FOS: boolean;
FB: boolean;
JSF: string[];
P: string[];
T: (number | boolean)[];
H: number;
SWF: boolean;
} = {
DNT: "unknown", // Do not track On/Off | Previous Value: 1

@@ -91,8 +114,10 @@ L: "en-US", // Browser language

"Wingdings 3",
], // Available fonts
], // Checked fonts
P: [
"Chrome PDF Plugin::Portable Document Format::application/x-google-chrome-pdf~pdf",
"Chrome PDF Viewer::::application/pdf~pdf",
"Native Client::::application/x-nacl~,application/x-pnacl~",
], // Plugins
'Chrome PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'Chromium PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'Microsoft Edge PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'PDF Viewer::Portable Document Format::application/pdf~pdf,text/pdf~pdf',
'WebKit built-in PDF::Portable Document Format::application/pdf~pdf,text/pdf~pdf'
], // Plugins (standard and CONSTANT)
T: [0, false, false], // Touch screen (maxTouchPoints, TouchEvent event listener support, ontouchstart support)

@@ -104,17 +129,241 @@ H: 24, // Cpu threads

const languages = [
"af", "af-ZA", "ar", "ar-AE", "ar-BH", "ar-DZ", "ar-EG", "ar-IQ", "ar-JO", "ar-KW", "ar-LB", "ar-LY", "ar-MA", "ar-OM", "ar-QA", "ar-SA",
"ar-SY", "ar-TN", "ar-YE", "az", "az-AZ", "az-AZ", "be", "be-BY", "bg", "bg-BG", "bs-BA", "ca", "ca-ES", "cs", "cs-CZ", "cy",
"cy-GB", "da", "da-DK", "de", "de-AT", "de-CH", "de-DE", "de-LI", "de-LU", "dv", "dv-MV", "el", "el-GR", "en", "en-AU", "en-BZ",
"en-CA", "en-CB", "en-GB", "en-IE", "en-JM", "en-NZ", "en-PH", "en-TT", "en-US", "en-ZA", "en-ZW", "eo", "es", "es-AR", "es-BO", "es-CL",
"es-CO", "es-CR", "es-DO", "es-EC", "es-ES", "es-ES", "es-GT", "es-HN", "es-MX", "es-NI", "es-PA", "es-PE", "es-PR", "es-PY", "es-SV", "es-UY",
"es-VE", "et", "et-EE", "eu", "eu-ES", "fa", "fa-IR", "fi", "fi-FI", "fo", "fo-FO", "fr", "fr-BE", "fr-CA", "fr-CH", "fr-FR",
"fr-LU", "fr-MC", "gl", "gl-ES", "gu", "gu-IN", "he", "he-IL", "hi", "hi-IN", "hr", "hr-BA", "hr-HR", "hu", "hu-HU", "hy",
"hy-AM", "id", "id-ID", "is", "is-IS", "it", "it-CH", "it-IT", "ja", "ja-JP", "ka", "ka-GE", "kk", "kk-KZ", "kn", "kn-IN",
"ko", "ko-KR", "kok", "kok-IN", "ky", "ky-KG", "lt", "lt-LT", "lv", "lv-LV", "mi", "mi-NZ", "mk", "mk-MK", "mn", "mn-MN",
"mr", "mr-IN", "ms", "ms-BN", "ms-MY", "mt", "mt-MT", "nb", "nb-NO", "nl", "nl-BE", "nl-NL", "nn-NO", "ns", "ns-ZA", "pa",
"pa-IN", "pl", "pl-PL", "ps", "ps-AR", "pt", "pt-BR", "pt-PT", "qu", "qu-BO", "qu-EC", "qu-PE", "ro", "ro-RO", "ru", "ru-RU",
"sa", "sa-IN", "se", "se-FI", "se-FI", "se-FI", "se-NO", "se-NO", "se-NO", "se-SE", "se-SE", "se-SE", "sk", "sk-SK", "sl", "sl-SI",
"sq", "sq-AL", "sr-BA", "sr-BA", "sr-SP", "sr-SP", "sv", "sv-FI", "sv-SE", "sw", "sw-KE", "syr", "syr-SY", "ta", "ta-IN", "te",
"te-IN", "th", "th-TH", "tl", "tl-PH", "tn", "tn-ZA", "tr", "tr-TR", "tt", "tt-RU", "ts", "uk", "uk-UA", "ur", "ur-PK",
"uz", "uz-UZ", "uz-UZ", "vi", "vi-VN", "xh", "xh-ZA", "zh", "zh-CN", "zh-HK", "zh-MO", "zh-SG", "zh-TW", "zu", "zu-ZA"
"af",
"af-ZA",
"ar",
"ar-AE",
"ar-BH",
"ar-DZ",
"ar-EG",
"ar-IQ",
"ar-JO",
"ar-KW",
"ar-LB",
"ar-LY",
"ar-MA",
"ar-OM",
"ar-QA",
"ar-SA",
"ar-SY",
"ar-TN",
"ar-YE",
"az",
"az-AZ",
"az-AZ",
"be",
"be-BY",
"bg",
"bg-BG",
"bs-BA",
"ca",
"ca-ES",
"cs",
"cs-CZ",
"cy",
"cy-GB",
"da",
"da-DK",
"de",
"de-AT",
"de-CH",
"de-DE",
"de-LI",
"de-LU",
"dv",
"dv-MV",
"el",
"el-GR",
"en",
"en-AU",
"en-BZ",
"en-CA",
"en-CB",
"en-GB",
"en-IE",
"en-JM",
"en-NZ",
"en-PH",
"en-TT",
"en-US",
"en-ZA",
"en-ZW",
"eo",
"es",
"es-AR",
"es-BO",
"es-CL",
"es-CO",
"es-CR",
"es-DO",
"es-EC",
"es-ES",
"es-ES",
"es-GT",
"es-HN",
"es-MX",
"es-NI",
"es-PA",
"es-PE",
"es-PR",
"es-PY",
"es-SV",
"es-UY",
"es-VE",
"et",
"et-EE",
"eu",
"eu-ES",
"fa",
"fa-IR",
"fi",
"fi-FI",
"fo",
"fo-FO",
"fr",
"fr-BE",
"fr-CA",
"fr-CH",
"fr-FR",
"fr-LU",
"fr-MC",
"gl",
"gl-ES",
"gu",
"gu-IN",
"he",
"he-IL",
"hi",
"hi-IN",
"hr",
"hr-BA",
"hr-HR",
"hu",
"hu-HU",
"hy",
"hy-AM",
"id",
"id-ID",
"is",
"is-IS",
"it",
"it-CH",
"it-IT",
"ja",
"ja-JP",
"ka",
"ka-GE",
"kk",
"kk-KZ",
"kn",
"kn-IN",
"ko",
"ko-KR",
"kok",
"kok-IN",
"ky",
"ky-KG",
"lt",
"lt-LT",
"lv",
"lv-LV",
"mi",
"mi-NZ",
"mk",
"mk-MK",
"mn",
"mn-MN",
"mr",
"mr-IN",
"ms",
"ms-BN",
"ms-MY",
"mt",
"mt-MT",
"nb",
"nb-NO",
"nl",
"nl-BE",
"nl-NL",
"nn-NO",
"ns",
"ns-ZA",
"pa",
"pa-IN",
"pl",
"pl-PL",
"ps",
"ps-AR",
"pt",
"pt-BR",
"pt-PT",
"qu",
"qu-BO",
"qu-EC",
"qu-PE",
"ro",
"ro-RO",
"ru",
"ru-RU",
"sa",
"sa-IN",
"se",
"se-FI",
"se-FI",
"se-FI",
"se-NO",
"se-NO",
"se-NO",
"se-SE",
"se-SE",
"se-SE",
"sk",
"sk-SK",
"sl",
"sl-SI",
"sq",
"sq-AL",
"sr-BA",
"sr-BA",
"sr-SP",
"sr-SP",
"sv",
"sv-FI",
"sv-SE",
"sw",
"sw-KE",
"syr",
"syr-SY",
"ta",
"ta-IN",
"te",
"te-IN",
"th",
"th-TH",
"tl",
"tl-PH",
"tn",
"tn-ZA",
"tr",
"tr-TR",
"tt",
"tt-RU",
"ts",
"uk",
"uk-UA",
"ur",
"ur-PK",
"uz",
"uz-UZ",
"uz-UZ",
"vi",
"vi-VN",
"xh",
"xh-ZA",
"zh",
"zh-CN",
"zh-HK",
"zh-MO",
"zh-SG",
"zh-TW",
"zu",
"zu-ZA",
];

@@ -142,34 +391,82 @@

// Get fingerprint
function getFingerprint() {
function getFingerprint(canvasFp?: string, randomCanvasFp?: boolean) {
let fingerprint = { ...baseFingerprint }; // Create a copy of the base fingerprint
// Randomization time!
fingerprint["DNT"] = "unknown";
fingerprint["DNT"] = "unknown"; //Math.round(Math.random());
fingerprint["L"] = languages[Math.floor(Math.random() * languages.length)];
fingerprint["D"] = [8, 24][
fingerprint["D"] = [24, 32][
Math.floor(Math.random() * 2)
];
fingerprint["PR"] = Math.round(Math.random() * 100) / 100 * 2 + 0.5;
fingerprint["S"] = randomScreenRes();
fingerprint["AS"] = fingerprint.S;
fingerprint["TO"] = (Math.floor(Math.random() * 24) - 12) * 60;
fingerprint["SS"] = Math.random() > 0.5;
fingerprint["LS"] = Math.random() > 0.5;
fingerprint["IDB"] = Math.random() > 0.5;
fingerprint["B"] = Math.random() > 0.5;
fingerprint["ODB"] = Math.random() > 0.5;
fingerprint["CPUC"] = "unknown";
fingerprint["PK"] = "Win32"
fingerprint["CFP"] = "canvas winding:yes~canvas fp:data:image/png;base64," + randomBytes(128).toString("base64");
]; // common value only: 24bit/32bit
fingerprint["PR"] = [1, 1.25, 1.5, 1.75][
Math.floor(Math.random() * 4)
]; // common value only: 1, 1.25, 1.5, 1.75
fingerprint["S"] = randomScreenRes().map(x => x / fingerprint["PR"]); // change screen res to match pixel ratio
fingerprint["AS"] = fingerprint["S"]; //[fingerprint["S"][0], fingerprint["S"][1] - 40]
fingerprint["TO"] = (Math.floor(Math.random() * 24) - 12) * 60; // timezone SHOULD be based on current IP
fingerprint["SS"] = true; //Math.random() > 0.5;
fingerprint["LS"] = true; //Math.random() > 0.5;
fingerprint["IDB"] = true; //Math.random() > 0.5;
fingerprint["B"] = false; // IE-only signature, SHOULD NOT EXIST //Math.random() > 0.5;
fingerprint["ODB"] = true; // WebSQL, MUST be disabled after November 7, 2023 (Chromium 119). Might TODO base on UA. //Math.random() > 0.5;
fingerprint["CPUC"] = "unknown"; /*["68K", "Alpha", "PPC", "x86", "Other", "unknown"][
Math.floor(Math.random() * 5)
];*/
fingerprint["PK"] = "Win32" // This SHOULD be based on User Agent.
/*[
"HP-UX",
"Mac68K",
"MacPPC",
"SunOS",
"Win16",
"Win32",
"WinCE",
][Math.floor(Math.random() * 7)];*/
let rdCanvas: string;
if (typeof randomCanvasFp === "undefined" || randomCanvasFp) {
// attempt to randomize canvas fingerprint by generating a random 300x150 PNG image
let png = new PNG({
height: 150,
width: 300,
});
for (let y = 0; y < png.height; y++) {
for (let x = 0; x < png.width; x++) {
let idx = (png.width * y + x) << 2;
png.data[idx] = Math.floor(Math.random() * 256);
png.data[idx + 1] = Math.floor(Math.random() * 256);
png.data[idx + 2] = Math.floor(Math.random() * 256);
png.data[idx + 3] = 0xFF;
}
}
var buffer = PNG.sync.write(png, {
colorType: 6,
bitDepth: 8
});
rdCanvas = `data:image/png;base64,${buffer.toString("base64")}`;
}
fingerprint["CFP"] = canvasFp ?? rdCanvas ?? false; // We CAN randomize data, block canvas fingerprinting, or BYOP
/*`canvas winding:yes~canvas fp:data:image/png;base64,${Buffer.from(
Math.random().toString()
).toString("base64")}`;*/ //canvasFp || ''; // Canvas Fingerprint
fingerprint["FR"] = false; // Fake Resolution
fingerprint["FOS"] = false; // Fake Operating System
fingerprint["FB"] = false; // Fake Browser
fingerprint["JSF"] = fingerprint["JSF"].filter(() => Math.random() > 0.5);
fingerprint["P"] = fingerprint["P"].filter(() => Math.random() > 0.5);
fingerprint["T"] = [
// Standard Windows fonts
fingerprint["JSF"] = ['Arial', 'Arial Black', 'Arial Narrow', 'Book Antiqua', 'Bookman Old Style', 'Calibri', 'Cambria', 'Cambria Math', 'Century', 'Century Gothic', 'Century Schoolbook', 'Comic Sans MS', 'Consolas', 'Courier', 'Courier New', 'Garamond', 'Georgia', 'Helvetica', 'Impact', 'Lucida Bright', 'Lucida Calligraphy', 'Lucida Console', 'Lucida Fax', 'Lucida Handwriting', 'Lucida Sans', 'Lucida Sans Typewriter', 'Lucida Sans Unicode', 'Microsoft Sans Serif', 'Monotype Corsiva', 'MS Gothic', 'MS PGothic', 'MS Reference Sans Serif', 'MS Sans Serif', 'MS Serif', 'Palatino Linotype', 'Segoe Print', 'Segoe Script', 'Segoe UI', 'Segoe UI Light', 'Segoe UI Semibold', 'Segoe UI Symbol', 'Tahoma', 'Times', 'Times New Roman', 'Trebuchet MS', 'Verdana', 'Wingdings', 'Wingdings 2', 'Wingdings 3']; //fingerprint["JSF"].filter(() => Math.random() > 0.5);
//fingerprint["P"] = fingerprint["P"].filter(() => Math.random() > 0.5);
let randomizeTouch = Math.random() > 0.5;
fingerprint["T"] = randomizeTouch ? [
Math.floor(Math.random() * 8),
Math.random() > 0.5,
Math.random() > 0.5,
];
fingerprint["H"] = 2 ** Math.floor(Math.random() * 6);
false, //Math.random() > 0.5,
false //Math.random() > 0.5,
] : [0, false, false]; // Touch Support [maxTouchPoints, touchEvent emit support, is touchStart listened]
fingerprint["H"] = 2 ** Math.floor(Math.random() * 3);
fingerprint["SWF"] = fingerprint["SWF"]; // RIP Flash

@@ -210,2 +507,3 @@

}
return fe;

@@ -232,89 +530,2 @@ }

let baseEnhancedFingerprint = {
"webgl_extensions": "ANGLE_instanced_arrays;EXT_blend_minmax;EXT_color_buffer_half_float;EXT_disjoint_timer_query;EXT_float_blend;EXT_frag_depth;EXT_shader_texture_lod;EXT_texture_compression_bptc;EXT_texture_compression_rgtc;EXT_texture_filter_anisotropic;EXT_sRGB;KHR_parallel_shader_compile;OES_element_index_uint;OES_fbo_render_mipmap;OES_standard_derivatives;OES_texture_float;OES_texture_float_linear;OES_texture_half_float;OES_texture_half_float_linear;OES_vertex_array_object;WEBGL_color_buffer_float;WEBGL_compressed_texture_s3tc;WEBGL_compressed_texture_s3tc_srgb;WEBGL_debug_renderer_info;WEBGL_debug_shaders;WEBGL_depth_texture;WEBGL_draw_buffers;WEBGL_lose_context;WEBGL_multi_draw",
"webgl_extensions_hash": "58a5a04a5bef1a78fa88d5c5098bd237",
"webgl_renderer": "WebKit WebGL",
"webgl_vendor": "WebKit",
"webgl_version": "WebGL 1.0 (OpenGL ES 2.0 Chromium)",
"webgl_shading_language_version": "WebGL GLSL ES 1.0 (OpenGL ES GLSL ES 1.0 Chromium)",
"webgl_aliased_line_width_range": "[1, 1]",
"webgl_aliased_point_size_range": "[0.125, 8192]",
"webgl_antialiasing": "yes",
"webgl_bits": "8,8,24,8,8,0",
"webgl_max_params": "16,32,8192,261,8192,16,8192,32,32,16,256",
"webgl_max_viewport_dims": "[8192, 8192]",
"webgl_unmasked_vendor": "Google Inc.",
"webgl_unmasked_renderer": "Google SwiftShader",
"webgl_vsf_params": "23,127,127,23,127,127,23,127,127",
"webgl_vsi_params": "0,31,30,0,31,30,0,31,30",
"webgl_fsf_params": "23,127,127,23,127,127,23,127,127",
"webgl_fsi_params": "0,31,30,0,31,30,0,31,30",
"webgl_hash_webgl": null, // TODO
"user_agent_data_brands": "Not/A)Brand,Google Chrome,Chromium",
"user_agent_data_mobile": null,
"navigator_connection_downlink": null,
"navigator_connection_downlink_max": null,
"network_info_rtt": null,
"network_info_save_data": false,
"network_info_rtt_type": null,
"screen_pixel_depth": 24,
"navigator_device_memory": 0.5,
"navigator_languages": "en-US,fr-BE,fr,en-BE,en",
"window_inner_width": 0,
"window_inner_height": 0,
"window_outer_width": 2195,
"window_outer_height": 1195,
"browser_detection_firefox": false,
"browser_detection_brave": false,
"audio_codecs": "{\"ogg\":\"probably\",\"mp3\":\"probably\",\"wav\":\"probably\",\"m4a\":\"maybe\",\"aac\":\"probably\"}",
"video_codecs": "{\"ogg\":\"probably\",\"h264\":\"probably\",\"webm\":\"probably\",\"mpeg4v\":\"\",\"mpeg4a\":\"\",\"theora\":\"\"}",
"media_query_dark_mode": true,
"headless_browser_phantom": false,
"headless_browser_selenium": false,
"headless_browser_nightmare_js": false,
"document__referrer": "https://www.roblox.com/",
"window__ancestor_origins": [
"https://www.roblox.com",
],
"window__tree_index": [
0
],
"window__tree_structure": "[[]]",
"window__location_href": "https://roblox-api.arkoselabs.com/v2/1.5.4/enforcement.cd12da708fe6cbe6e068918c38de2ad9.html#476068BF-9607-4799-B53D-966BE98E2B81",
"client_config__sitedata_location_href": "https://www.roblox.com/arkose/iframe",
"client_config__surl": "https://roblox-api.arkoselabs.com",
"client_config__language": null,
"navigator_battery_charging": true,
"audio_fingerprint": (124.04347527516074 + Math.random() * 0.001 - 0.0005).toString(),
}
function getEnhancedFingerprint(fp: typeof baseFingerprint, ua: string, opts: any) {
let fingerprint = { ...baseEnhancedFingerprint };
fingerprint.webgl_extensions = fingerprint.webgl_extensions.split(";").filter(_ => Math.random() > 0.5).join(";");
fingerprint.webgl_extensions_hash = x64hash128(fingerprint.webgl_extensions, 0);
fingerprint.screen_pixel_depth = fp.D;
fingerprint.navigator_languages = fp.L;
fingerprint.window_outer_height = fp.S[0];
fingerprint.window_outer_width = fp.S[1];
fingerprint.window_inner_height = fp.S[0];
fingerprint.window_inner_width = fp.S[1];
fingerprint.screen_pixel_depth = fp.D;
fingerprint.browser_detection_firefox = !!ua.match(/Firefox\/\d+/)
fingerprint.browser_detection_brave = !!ua.match(/Brave\/\d+/)
fingerprint.media_query_dark_mode = Math.random() > 0.9;
fingerprint.webgl_hash_webgl = x64hash128(Object.entries(fingerprint).filter(([k, v]) => k.startsWith("webgl_") && k != "webgl_hash_webgl").map(([k, v]) => v).join(","), 0);
fingerprint.client_config__language = opts.language || null;
fingerprint.window__location_href = `${opts.surl}/v2/${opts.pkey}/1.5.4/enforcement.${randomBytes(16).toString("hex")}.html`
if (opts.site) {
fingerprint.document__referrer = opts.site;
fingerprint.window__ancestor_origins = [opts.site];
fingerprint.client_config__sitedata_location_href = opts.site;
}
fingerprint.client_config__surl = opts.surl || "https://client-api.arkoselabs.com";
return Object.entries(fingerprint).map(([k, v]) => ({ key: k, value: v }));
}
export default {

@@ -324,3 +535,2 @@ getFingerprint,

prepareFe,
getEnhancedFingerprint,
};

@@ -0,0 +0,0 @@ import * as http2 from "http2-wrapper";

export * from "./api";
export * from "./session";

@@ -0,0 +0,0 @@ // MurmurHash3 related functions

@@ -154,7 +154,30 @@ import { GetTokenResult } from "./api";

getEmbedUrl(): string {
// infer game version from rawToken
let gameVersion = "1.12.1";
if (this.tokenRaw) {
gameVersion = this.tokenRaw.challenge_url_cdn.match(/ec-game-core\/bootstrap\/(.*)\/standard/)?.[1] ?? gameVersion;
}
let ti = this.tokenInfo;
let newQuery = {
session: ti.token,
r: ti.r,
meta: ti.meta,
metabgclr: ti.metabgclr,
metaiconclr: ti.metaiconclr,
maintxtclr: ti.maintxtclr,
guitextcolor: ti.guitextcolor,
pk: ti.pk,
at: ti.at,
ag: ti.ag,
cdn_url: ti.cdn_url,
lurl: ti.lurl,
surl: ti.surl,
smurl: ti.smurl,
theme: "default"
}
//https://client-api.arkoselabs.com/fc/assets/ec-game-core/game-core/1.12.0/standard/index.html
return `${this.tokenInfo.surl}/fc/assets/ec-game-core/game-core/1.12.0/standard/index.html?${util.constructFormData(
this.tokenInfo
)}`;
return `${this.tokenInfo.surl}/fc/assets/ec-game-core/game-core/${gameVersion}/standard/index.html?${util.constructFormData(newQuery)}`;
}
}

@@ -0,0 +0,0 @@ import fingerprint from "./fingerprint";

@@ -0,0 +0,0 @@ let fun = require("../lib");

@@ -0,0 +0,0 @@ // Optional test for roblox detection

@@ -0,0 +0,0 @@ const fun = require("../lib");

@@ -0,0 +0,0 @@ {