-
Notifications
You must be signed in to change notification settings - Fork 25
/
index.js
96 lines (83 loc) · 2.95 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
const request = require("request-promise-native");
const Solver = require("./src/solver");
const HumanoidReqHandler = require("./src/humanoidReqHandler");
class Humanoid extends HumanoidReqHandler {
constructor(autoBypass=true, maxRetries=3) {
super();
this._getRandomTimeout = () => Math.floor(Math.random() * (7000 - 5000 + 1)) + 5000;
this.autoBypass = autoBypass;
this.maxRetries = maxRetries;
this.currMaxRetries = maxRetries;
this._resetCurrMaxRetries = () => this.currMaxRetries = this.maxRetries;
}
async _asyncTimeout(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
rotateUA() {
super.UA = super._getRandomUA();
}
clearCookies() {
super.cookieJar = request.jar();
}
_buildAnswerObject(values) {
let [vc, pass, answer] = [...values];
return {
jschl_vc: vc,
pass: pass,
jschl_answer: answer
}
}
async get(url, queryString=undefined, headers=undefined) {
return await this.sendRequest(url, "GET", queryString, headers)
}
async post(url, postBody=undefined, headers=undefined, dataType=undefined) {
return await this.sendRequest(url, "POST", postBody, headers, dataType)
}
async sendRequest(url, method=undefined, data=undefined, headers=undefined, dataType=undefined) {
let response = await super.sendRequest(url, method, data, headers, dataType);
if (response.isSessionChallenged) {
if (this.autoBypass) {
if (--this.currMaxRetries <= 0) {
this._resetCurrMaxRetries();
throw Error(
`Max retries limit reached. Cannot Solve JavaScript challenge from response:
${JSON.stringify(response)}`
)
} else {
let challengeResponse = await this.bypassJSChallenge(response);
// If we got a 200, mark challenge and solved and return
challengeResponse.isChallengeSolved = challengeResponse.statusCode === 200;
this._resetCurrMaxRetries();
return challengeResponse;
}
}
}
this._resetCurrMaxRetries()
return response;
}
async bypassJSChallenge(response) {
let {...solution} = Solver.solveChallenge(response);
let timeout = Solver._extractTimeoutFromScript(response.body) || this._getRandomTimeout();
if (![solution.vc, solution.pass, solution.answer, solution.origin].every(elem => !!elem)) {
throw Error(`Failed to Extract one or more necessary values.
Values obtained:
vc: ${solution.vc}
pass: ${solution.pass}
answer${solution.answer}`)
} else {
// Wait the desired time;
await this._asyncTimeout(timeout);
let answerUrl = `${solution.origin}/cdn-cgi/l/chk_jschl`;
let answerObj = this._buildAnswerObject([solution.vc, solution.pass, solution.answer]);
let headers = super._getRequestHeaders(answerUrl);
headers["Referer"] = response.origin;
let solvedChallengeRes = await this.get(answerUrl, answerObj, headers);
// All requests that reached here were from a challenged session
solvedChallengeRes.isSessionChallenged = true;
return solvedChallengeRes;
}
}
}
module.exports = Humanoid;