UNPKG

vk-captcha-bypass

Version:

Обход VK Captcha

116 lines 4.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.VKCaptchaBypasser = exports.APIError = exports.VKCaptchaBypasserError = void 0; const utils_1 = require("./utils"); class VKCaptchaBypasserError extends Error { constructor(message) { super(message); } } exports.VKCaptchaBypasserError = VKCaptchaBypasserError; class APIError extends Error { error; constructor(error) { super(`${error.error_msg} (Code: ${error.error_code})`); this.error = error; } get code() { return this.error.error_code; } get params() { return this.error.request_params; } } exports.APIError = APIError; class VKCaptchaBypasser { version; baseApiUrl; maxSensorsDataSizeKb; constructor(options) { this.version = options?.version || '5.199'; this.baseApiUrl = options?.baseApiUrl || 'https://api.vk.ru/'; this.maxSensorsDataSizeKb = options?.maxSensorsDataSizeKb || 900; } async bypass(redirectUri, mouseTraceParams) { const pow = await this.loadPoWChallengeParams(redirectUri); const hash = await (0, utils_1.generatePoW)(pow.input, pow.difficulty); const queryParams = new URLSearchParams(redirectUri.replace(/(.*)\?/, '')); const { session_token, domain } = Object.fromEntries(queryParams.entries()); const initialParams = { session_token, domain }; const { bridge_sensors_list: sensorsList } = await this.request('captchaNotRobot.settings', initialParams); await this.request('captchaNotRobot.componentDone', initialParams); const sensorsData = this.buildSensorsData(sensorsList, mouseTraceParams); const captcha = await this.request('captchaNotRobot.check', { ...initialParams, ...sensorsData, hash, answer: 'e30=', }); await this.request('captchaNotRobot.endSession', initialParams); return captcha; } async request(method, params) { const entries = Object.entries({ ...params, v: this.version }); const encoded = entries.map(([key, value]) => { if (typeof value === 'object' && value !== null) return [key, JSON.stringify(value)]; return [key, String(value)]; }); const body = new URLSearchParams(Object.fromEntries(encoded)); const contentLength = Buffer.from(body.toString()).byteLength; const url = new URL(`/method/${method}`, this.baseApiUrl); const fetchResponse = await fetch(url.toString(), { headers: { 'content-type': 'application/x-www-form-urlencoded', 'content-length': contentLength.toString(), }, body, method: 'POST', }); const response = (await fetchResponse.json()); if ('error' in response) throw new APIError(response.error); if ('status' in response && response.status === 'ERROR') throw new APIError({ error_code: 0, error_msg: `APIError: ${JSON.stringify(response)}`, request_params: [ ...body .entries() .map(([key, value]) => ({ key, value })) .toArray(), ], }); return response.response; } async loadPoWChallengeParams(redirectUri) { const fetchResponse = await fetch(redirectUri); const html = await fetchResponse.text(); const [, input] = html.match(/const powInput\s*=\s*"([^']+)";/i) || []; if (typeof input !== 'string') { throw new VKCaptchaBypasserError(`No "powInput" value`); } const [, rawDifficulty] = html.match(/const difficulty\s*=\s*(\d+);/) || []; if (typeof rawDifficulty !== 'string') { throw new VKCaptchaBypasserError(`No "difficulty" value`); } const difficulty = Number(rawDifficulty); return { difficulty, input }; } buildSensorsData(sensorsList, mouseTraceParams) { let cursor = (0, utils_1.generateMouseTrace)(mouseTraceParams); const maxBytes = this.maxSensorsDataSizeKb * 1024; const avgBytesPerPoint = 20; let maxPoints = Math.floor(maxBytes / avgBytesPerPoint); if (cursor.length > maxPoints) { cursor = cursor.slice(0, maxPoints); } let sensors = {}; for (const sensor of sensorsList) { sensors[sensor] = sensor === 'cursor' ? cursor : []; } return sensors; } } exports.VKCaptchaBypasser = VKCaptchaBypasser; //# sourceMappingURL=bypasser.js.map