Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update v1.2.0 #102

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
test
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ You must first fetch a token using getToken
```js
const token = await fun.getToken({
pkey: "476068BF-9607-4799-B53D-966BE98E2B81", // The public key
surl: "https://roblox-api.arkoselabs.com", // OPTIONAL: Some websites can have a custom service URL
surl: "https://arkoselabs.roblox.com", // OPTIONAL: Some websites can have a custom service URL
data: { // OPTIONAL
blob: "blob" // Some websites can have custom data passed: here it is data[blob]
},
Expand All @@ -24,7 +24,13 @@ const token = await fun.getToken({
// in mind to pass a user agent when doing that
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
},
site: "https://www.roblox.com/login", // The site which contains the funcaptcha
bda: { // OPTIONAL
"window__ancestor_origins": ["https://www.roblox.com", "https://www.roblox.com"],
"client_config__sitedata_location_href": "https://www.roblox.com/arkose/iframe",
"window__tree_structure": "[[[]]]",
'window__tree_index': [0, 0]
},
site: "https://www.roblox.com", // The site which contains the funcaptcha
proxy: "http://127.0.0.1:8888" // OPTIONAL: A proxy to fetch the token, usually not required
// NOTE: The proxy will only be used for fetching the token, and not future requests such as getting images and answering captchas
})
Expand Down Expand Up @@ -57,6 +63,7 @@ console.log(challenge.variant) // The game variant, eg: apple, rotated, maze, di
console.log(challenge.instruction) // Self explanatory
console.log(challenge.waves) // Wave count
console.log(challenge.wave) // Current wave number
console.log(challenge.difficulty) // Challenge difficulty || Img width / 200

// You can then use these functions
await challenge.getImage()
Expand Down Expand Up @@ -93,7 +100,7 @@ function ask(question) {
}

fun.getToken({
pkey: "69A21A01-CC7B-B9C6-0F9A-E7FA06677FFC",
pkey: "DF58DD3B-DFCC-4502-91FA-EDC0DC385CFF",
}).then(async token => {
let session = new fun.Session(token)
let challenge = await session.getChallenge()
Expand Down
15 changes: 14 additions & 1 deletion lib/api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@ export interface GetTokenOptions {
location?: string;
proxy?: string;
language?: string;
capi?: string;
hash?: string;
bda?: Record<'window__ancestor_origins' | 'client_config__sitedata_location_href' | 'window__tree_structure' | 'window__tree_index', any>;
}
export interface GetTokenResult {
challenge_url: string;
challenge_url_cdn: string;
challenge_url_cdn_sri: string;
compatibility_mode_enabled: boolean;
disable_default_styling: boolean | null;
iframe_height: number | null;
iframe_width: number | null;
Expand All @@ -24,5 +28,14 @@ export interface GetTokenResult {
noscript: string;
tbio: boolean;
token: string;
pow: boolean;
cookie: string;
capi: string;
hash: string;
}
export declare function getToken(options: GetTokenOptions): Promise<GetTokenResult>;
interface ErrorResponse {
error?: boolean;
message?: string;
}
export declare function getToken(options: GetTokenOptions): Promise<GetTokenResult | ErrorResponse>;
export {};
111 changes: 92 additions & 19 deletions lib/api.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,69 @@
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getToken = void 0;
const http_1 = require("./http");
const util_1 = require("./util");
const http_1 = __importDefault(require("./http"));
const util_1 = __importDefault(require("./util"));
async function getToken(options) {
let xheaders = { ...options.headers };
delete options.headers;
options = {
surl: "https://client-api.arkoselabs.com",
data: {},
...options,
headers: {
// ':authority': 'client-api.arkoselabs.com',
// ':method': 'POST',
// ':path': '/fc/gt2/public_key/{key}',
// ':scheme': 'https',
'Accept': '*/*',
'Accept-Encoding': '',
'Accept-Language': 'en-GB,en-US;q=0.9,en;q=0.8,ar;q=0.7',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'Origin': '{surl}',
'Priority': 'u=1, i',
'Referer': '{surl}/v2/{capi}/enforcement.{hash}.html',
'Sec-Ch-Ua': '"Google Chrome";v="131", "Chromium";v="131", "Not_A_Brand";v="24"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
...xheaders
// 'X-Ark-Esync-Value': '1734588000'
},
...options
};
if (!options.headers)
options.headers = { "User-Agent": util_1.default.DEFAULT_USER_AGENT };
else if (!Object.keys(options.headers).map(v => v.toLowerCase()).includes("user-agent"))
// options.headers[':authority'] = new URL(options.surl).host;
// options.headers[':path'] = options.headers[':path'].replace('{key}', options.pkey);
if (!Object.keys(options.headers).map(v => v.toLowerCase()).includes("user-agent"))
options.headers["User-Agent"] = util_1.default.DEFAULT_USER_AGENT;
options.headers["Accept-Language"] = "en-US,en;q=0.9";
options.headers["Sec-Fetch-Site"] = "same-origin";
options.headers["Accept"] = "*/*";
options.headers["Content-Type"] = "application/x-www-form-urlencoded; charset=UTF-8";
options.headers["sec-fetch-mode"] = "cors";
options.surl = new URL(options.surl).origin;
let surl = options.surl;
let ua = options.headers[Object.keys(options.headers).find(v => v.toLowerCase() == "user-agent")];
let { capi, hash, cookie } = await getkeyInfo(surl, options.pkey, options.proxy);
options.capi = capi;
options.hash = hash;
if (options.site) {
options.headers["Origin"] = options.surl;
options.headers["Referer"] = `${options.surl}/v2/${options.pkey}/1.5.5/enforcement.fbfc14b0d793c6ef8359e0e4b4a91f67.html`;
options.headers["Origin"] = surl;
options.headers["Referer"] = options.headers["Referer"].replace('{surl}', surl).replace('{capi}', capi).replace('{hash}', hash);
}
let ua = options.headers[Object.keys(options.headers).find(v => v.toLowerCase() == "user-agent")];
let res = await (0, http_1.default)(options.surl, {
method: "POST",
path: "/fc/gt2/public_key/" + options.pkey,
if (cookie) {
options.headers["Cookie"] = cookie;
}
let time = new Date().getTime() / 1000;
let key = Math.round(time - (time % 21600));
options.headers['X-Ark-Esync-Value'] = key.toString();
let res = await (0, http_1.default)(surl, {
path: `/fc/gt2/public_key/${options.pkey}`,
method: 'POST',
body: util_1.default.constructFormData({
bda: util_1.default.getBda(ua, options),
public_key: options.pkey,
site: options.site ? new URL(options.site).origin : undefined,
userbrowser: ua,
capi_version: "1.5.5",
capi_version: capi,
capi_mode: "inline",
style_theme: "default",
rnd: Math.random().toString(),
Expand All @@ -40,6 +72,47 @@ async function getToken(options) {
}),
headers: options.headers,
}, options.proxy);
return JSON.parse(res.body.toString());
try {
const x = JSON.parse(res.body);
x.cookie = cookie;
x.capi = capi;
x.hash = hash;
return x;
}
catch {
return { error: true, message: res.body };
}
}
exports.getToken = getToken;
async function getkeyInfo(surl, key, proxy) {
var _a, _b;
let res = await (0, http_1.default)(surl, {
method: 'GET',
"path": `/v2/${key}/api.js`,
headers: {
// ":authority": new URL(surl).host,
// ":method": "GET",
// ":path": `/v2/${key}/api.js`,
// ":scheme": "https",
"Accept": "*/*",
'Accept-Encoding': '',
"Accept-Language": "en-GB,en-US;q=0.9,en;q=0.8,ar;q=0.7",
"Referer": "https://demo.arkoselabs.com/",
"Sec-Ch-Ua": "\"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
"Sec-Ch-Ua-Mobile": "?0",
"Sec-Ch-Ua-Platform": "\"Windows\"",
"Sec-Fetch-Dest": "script",
"Sec-Fetch-Mode": "no-cors",
"Sec-Fetch-Site": "same-site",
"User-Agent": util_1.default.DEFAULT_USER_AGENT
}
}, proxy);
const data = res.body;
const capi = (_a = data.match(/u="([\d.]+)"/)) === null || _a === void 0 ? void 0 : _a[1];
const hash = (_b = data.match(/enforcement\.([a-f0-9]+)\.html/)) === null || _b === void 0 ? void 0 : _b[1];
return {
cookie: typeof res.headers['set-cookie'] == 'string' && res.headers['set-cookie'].split(';')[0].concat(';'),
capi,
hash
};
}
1 change: 1 addition & 0 deletions lib/bio.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function getBio(): string;
Loading