Arrgcw6 commited on
Commit
ca7264e
·
verified ·
1 Parent(s): 17fda28

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +77 -131
index.js CHANGED
@@ -7,13 +7,13 @@ app.use(cors());
7
  app.use(express.json());
8
 
9
  const PORT = process.env.PORT || 7860;
10
- const MAX_CONCURRENT_BROWSERS = 3;
11
  let activeBrowsers = 0;
12
 
13
  async function createBrowser(proxy = null) {
14
  const options = {
15
- headless: false,
16
- turnstile: true,
17
  args: [
18
  '--no-sandbox',
19
  '--disable-setuid-sandbox',
@@ -43,119 +43,72 @@ async function createBrowser(proxy = null) {
43
  return { browser, page };
44
  }
45
 
46
- async function handleCloudflare(page, url) {
47
  return new Promise(async (resolve, reject) => {
48
- const timeout = setTimeout(() => reject(new Error("Timeout Cloudflare Bypass")), 120000);
 
 
 
49
 
50
  try {
51
- console.log(`[Cloudflare] Navigating to ${url}`);
52
-
53
- let cookieFoundTime = 0;
54
- let finalCookieValue = "";
55
- let hasForcedNavigated = false;
56
-
57
- page.on('response', async resp => {
58
- try {
59
- const headers = resp.headers();
60
- const setCookie = headers['set-cookie'] || headers['Set-Cookie'] || headers['set-cookie'.toLowerCase()];
61
-
62
- if (setCookie) {
63
- const cookieStr = Array.isArray(setCookie) ? setCookie.join(' ') : setCookie;
64
- if (cookieStr.includes('cf_clearance')) {
65
- if (cookieFoundTime === 0) {
66
- cookieFoundTime = Date.now();
67
- console.log(`[Cloudflare] 🔥 FAST DETECT: cf_clearance found via Listener!`);
68
- const match = cookieStr.match(/cf_clearance=([^;]+)/);
69
- if (match) finalCookieValue = match[1];
70
- }
71
- }
72
  }
73
- } catch(e){}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  });
75
 
76
- await page.bringToFront();
 
77
  await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 });
78
 
79
- const loop = setInterval(async () => {
 
80
  try {
81
- const title = await page.title();
82
- const content = await page.content();
83
- const currentTime = Date.now();
84
- const cookies = await page.cookies();
85
-
86
- const cfCookie = cookies.find(c => c.name === 'cf_clearance');
87
- if (cfCookie) {
88
- if (cookieFoundTime === 0) console.log(`[Cloudflare] Cookie found in storage.`);
89
- cookieFoundTime = cookieFoundTime || Date.now();
90
- finalCookieValue = cfCookie.value;
91
- }
92
-
93
- const isChallengePage = title.includes("Just a moment") ||
94
- content.includes("challenge-platform") ||
95
- title.includes("Cloudflare");
96
-
97
- if (!isChallengePage && title.trim().length > 0) {
98
- clearInterval(loop);
99
- clearTimeout(timeout);
100
- const ua = await page.evaluate(() => navigator.userAgent);
101
- console.log(`[Cloudflare] Success! Page Title: ${title}`);
102
- resolve({
103
- status: "success",
104
- userAgent: ua,
105
- cookies_full: cookies,
106
- cookie: finalCookieValue,
107
- title: title
108
- });
109
- return;
110
- }
111
-
112
- if (cookieFoundTime > 0 && (currentTime - cookieFoundTime) > 5000 && !hasForcedNavigated) {
113
- console.log("[Cloudflare] Cookie found but stuck. Performing FORCE NAVIGATION...");
114
- hasForcedNavigated = true;
115
- await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 }).catch(()=>{});
116
- return;
117
- }
118
-
119
- if (hasForcedNavigated && (currentTime - cookieFoundTime) > 20000) {
120
- clearInterval(loop);
121
  clearTimeout(timeout);
122
- console.log("[Cloudflare] Giving up waiting for title change. Returning valid cookie.");
123
- const ua = await page.evaluate(() => navigator.userAgent);
124
- resolve({
125
- status: "success",
126
- userAgent: ua,
127
- cookies_full: cookies,
128
- cookie: finalCookieValue,
129
- title: title
130
- });
131
- return;
132
- }
133
-
134
- const frames = page.frames();
135
- const challengeFrame = frames.find(f => f.url().includes("challenges.cloudflare.com") || f.url().includes("turnstile"));
136
-
137
- if (challengeFrame) {
138
- try {
139
- const checkbox = await challengeFrame.$("input[type='checkbox']");
140
- if (checkbox) {
141
- const isChecked = await challengeFrame.evaluate(el => el.checked, checkbox);
142
- if (!isChecked) {
143
- console.log("[Cloudflare] Checkbox found & clicked!");
144
- await checkbox.click();
145
- }
146
- } else {
147
- await challengeFrame.click('body').catch(()=>{});
148
- }
149
- } catch(e) {}
150
  }
151
-
152
- try {
153
- await page.mouse.move(Math.floor(Math.random() * 500), Math.floor(Math.random() * 500));
154
- if (Math.random() > 0.95) await page.click('body').catch(()=>{});
155
- } catch (err) {}
156
-
157
  } catch (e) {}
158
- }, 1000);
159
 
160
  } catch (e) {
161
  clearTimeout(timeout);
@@ -164,50 +117,43 @@ async function handleCloudflare(page, url) {
164
  });
165
  }
166
 
167
- async function handleTurnstile(page, url, siteKey) {
168
- return new Promise(async (resolve, reject) => {
169
- const timeout = setTimeout(() => reject(new Error("Timeout Turnstile")), 60000);
170
- try {
171
- const htmlContent = `<!DOCTYPE html><html lang="en"><body><div class="cf-turnstile" data-sitekey="${siteKey}" data-callback="turnstileCallback"></div><script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script><script>function turnstileCallback(token) { window.cf_token = token; }</script></body></html>`;
172
- await page.setRequestInterception(true);
173
- page.once('request', request => request.respond({ status: 200, contentType: 'text/html', body: htmlContent }));
174
- page.on('request', req => { if (req.isInterceptResolutionHandled()) return; req.continue(); });
175
- await page.goto(url, { waitUntil: "domcontentloaded" });
176
- const checkToken = setInterval(async () => {
177
- try {
178
- const token = await page.evaluate(() => window.cf_token);
179
- if (token) { clearInterval(checkToken); clearTimeout(timeout); resolve({ token: token }); }
180
- } catch (e) {}
181
- }, 1000);
182
- } catch (e) { clearTimeout(timeout); reject(e); }
183
- });
184
- }
185
-
186
  app.post('/bypass', async (req, res) => {
187
  const { url, mode, siteKey, proxy } = req.body;
 
188
  if (!url || !mode) return res.status(400).json({ status: "error", message: "Missing url or mode" });
189
- if (activeBrowsers >= MAX_CONCURRENT_BROWSERS) return res.status(429).json({ status: "busy", message: "Server busy" });
 
 
 
190
 
191
  activeBrowsers++;
192
  let browserInstance = null;
 
193
  try {
194
  console.log(`[REQ] Processing: ${url} | Mode: ${mode}`);
195
  const { browser, page } = await createBrowser(proxy);
196
  browserInstance = browser;
 
197
  let result;
198
- if (mode === 'turnstile') result = await handleTurnstile(page, url, siteKey);
199
- else if (mode === 'cloudflare') result = await handleCloudflare(page, url);
200
- else throw new Error("Invalid mode");
201
- console.log(`[SUCCESS] Operation completed for ${mode}`);
 
 
 
202
  res.json({ status: "success", ...result });
 
203
  } catch (error) {
204
  console.error(`[ERROR] ${error.message}`);
205
  res.status(500).json({ status: "error", message: error.message });
206
  } finally {
207
- if (browserInstance) try { await browserInstance.close(); } catch {}
 
 
208
  activeBrowsers--;
209
  }
210
  });
211
 
212
- app.get('/', (req, res) => res.send("Server Running"));
213
- app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));
 
7
  app.use(express.json());
8
 
9
  const PORT = process.env.PORT || 7860;
10
+ const MAX_CONCURRENT_BROWSERS = 2; // Limit 2 Browser agar RAM aman
11
  let activeBrowsers = 0;
12
 
13
  async function createBrowser(proxy = null) {
14
  const options = {
15
+ headless: false, // Wajib false
16
+ turnstile: true, // Auto-click turnstile bawaan library
17
  args: [
18
  '--no-sandbox',
19
  '--disable-setuid-sandbox',
 
43
  return { browser, page };
44
  }
45
 
46
+ async function handleTurnstile(page, url, siteKey) {
47
  return new Promise(async (resolve, reject) => {
48
+ // PERBAIKAN 1: Timeout diperpanjang jadi 120 detik (2 menit)
49
+ const timeout = setTimeout(() => {
50
+ reject(new Error("Timeout Turnstile (120s limit reached)"));
51
+ }, 120000);
52
 
53
  try {
54
+ console.log(`[Turnstile] Preparing Injection for ${url}`);
55
+
56
+ // Template HTML minimalis untuk memancing Turnstile keluar
57
+ const htmlContent = `
58
+ <!DOCTYPE html>
59
+ <html lang="en">
60
+ <head>
61
+ <meta charset="UTF-8">
62
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
63
+ <title>Turnstile Solver</title>
64
+ </head>
65
+ <body>
66
+ <div class="cf-turnstile" data-sitekey="${siteKey}" data-callback="turnstileCallback"></div>
67
+
68
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
69
+
70
+ <script>
71
+ console.log("Widget rendered...");
72
+ function turnstileCallback(token) {
73
+ console.log("Token received in browser!");
74
+ window.cf_token = token;
75
  }
76
+ </script>
77
+ </body>
78
+ </html>`;
79
+
80
+ // Intercept request ke URL target dan ganti isinya dengan HTML di atas
81
+ await page.setRequestInterception(true);
82
+ page.once('request', request => {
83
+ request.respond({
84
+ status: 200,
85
+ contentType: 'text/html',
86
+ body: htmlContent
87
+ });
88
+ });
89
+
90
+ // Handle request lain (gambar/css) agar tidak error
91
+ page.on('request', req => {
92
+ if (req.isInterceptResolutionHandled()) return;
93
+ req.continue();
94
  });
95
 
96
+ // Buka URL (ini akan memicu intercept di atas)
97
+ console.log(`[Turnstile] Navigating...`);
98
  await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 });
99
 
100
+ // Polling Token
101
+ const checkToken = setInterval(async () => {
102
  try {
103
+ const token = await page.evaluate(() => window.cf_token);
104
+ if (token) {
105
+ clearInterval(checkToken);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
106
  clearTimeout(timeout);
107
+ console.log(`[Turnstile] Token found: ${token.substring(0, 15)}...`);
108
+ resolve({ token: token });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  }
 
 
 
 
 
 
110
  } catch (e) {}
111
+ }, 1000);
112
 
113
  } catch (e) {
114
  clearTimeout(timeout);
 
117
  });
118
  }
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  app.post('/bypass', async (req, res) => {
121
  const { url, mode, siteKey, proxy } = req.body;
122
+
123
  if (!url || !mode) return res.status(400).json({ status: "error", message: "Missing url or mode" });
124
+
125
+ if (activeBrowsers >= MAX_CONCURRENT_BROWSERS) {
126
+ return res.status(429).json({ status: "busy", message: "Server busy, try again in a few seconds" });
127
+ }
128
 
129
  activeBrowsers++;
130
  let browserInstance = null;
131
+
132
  try {
133
  console.log(`[REQ] Processing: ${url} | Mode: ${mode}`);
134
  const { browser, page } = await createBrowser(proxy);
135
  browserInstance = browser;
136
+
137
  let result;
138
+ if (mode === 'turnstile') {
139
+ result = await handleTurnstile(page, url, siteKey);
140
+ } else {
141
+ throw new Error("Invalid mode (only turnstile supported in this version)");
142
+ }
143
+
144
+ console.log(`[SUCCESS] Operation completed.`);
145
  res.json({ status: "success", ...result });
146
+
147
  } catch (error) {
148
  console.error(`[ERROR] ${error.message}`);
149
  res.status(500).json({ status: "error", message: error.message });
150
  } finally {
151
+ if (browserInstance) {
152
+ try { await browserInstance.close(); } catch {}
153
+ }
154
  activeBrowsers--;
155
  }
156
  });
157
 
158
+ app.get('/', (req, res) => res.send("Turnstile Solver Ready (v3 - 120s Timeout)"));
159
+ app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));