Arrgcw6 commited on
Commit
aacb46d
·
verified ·
1 Parent(s): 8ab5c20

Update index.js

Browse files
Files changed (1) hide show
  1. index.js +69 -75
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',
@@ -23,8 +23,8 @@ async function createBrowser(proxy = null) {
23
  '--no-zygote',
24
  '--disable-gpu',
25
  '--window-size=1920,1080',
26
- '--disable-blink-features=AutomationControlled'
27
  ],
 
28
  executablePath: process.env.CHROME_PATH || "/usr/bin/google-chrome-stable",
29
  customConfig: {},
30
  connectOption: { defaultViewport: null }
@@ -34,6 +34,7 @@ async function createBrowser(proxy = null) {
34
  options.args.push(`--proxy-server=${proxy.hostname}:${proxy.port}`);
35
  }
36
 
 
37
  const { browser, page } = await connect(options);
38
 
39
  if (proxy && proxy.username && proxy.password) {
@@ -43,81 +44,71 @@ async function createBrowser(proxy = null) {
43
  return { browser, page };
44
  }
45
 
46
- async function handleTurnstile(page, url, siteKey) {
 
47
  return new Promise(async (resolve, reject) => {
 
48
  const timeout = setTimeout(() => reject(new Error("Timeout waiting for Turnstile token")), 60000);
49
 
50
  try {
51
- const htmlContent = `
52
- <!DOCTYPE html>
53
- <html lang="en">
54
- <body>
55
- <div class="cf-turnstile" data-sitekey="${siteKey}" data-callback="turnstileCallback"></div>
56
- <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
57
- <script>function turnstileCallback(token) { window.cf_token = token; }</script>
58
- </body>
59
- </html>
60
- `;
61
-
62
- await page.setRequestInterception(true);
63
- page.once('request', request => {
64
- request.respond({ status: 200, contentType: 'text/html', body: htmlContent });
65
- });
66
- page.on('request', req => { if (req.isInterceptResolutionHandled()) return; req.continue(); });
67
-
68
- console.log(`[Turnstile] Navigating to ${url}`);
69
- await page.goto(url, { waitUntil: "domcontentloaded" });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
 
 
71
  const checkToken = setInterval(async () => {
72
  try {
73
- const token = await page.evaluate(() => window.cf_token);
74
  if (token) {
75
  clearInterval(checkToken);
76
  clearTimeout(timeout);
77
  resolve({ token: token });
78
  }
79
- } catch (e) {}
80
- }, 1000);
81
-
82
- } catch (e) {
83
- clearTimeout(timeout);
84
- reject(e);
85
- }
86
- });
87
- }
88
-
89
- async function handleCloudflare(page, url) {
90
- return new Promise(async (resolve, reject) => {
91
- const timeout = setTimeout(() => reject(new Error("Timeout waiting for Cloudflare clearance")), 60000);
92
-
93
- try {
94
- console.log(`[Cloudflare] Navigating to ${url}`);
95
-
96
- const response = await page.goto(url, { waitUntil: "domcontentloaded", timeout: 60000 });
97
- const httpCode = response ? response.status() : 0;
98
-
99
- const checkSuccess = setInterval(async () => {
100
- try {
101
- const title = await page.title();
102
- const content = await page.content();
103
 
104
- if (!title.includes("Just a moment") && !content.includes("challenge-platform")) {
105
-
106
- clearInterval(checkSuccess);
107
- clearTimeout(timeout);
108
-
109
- const cookies = await page.cookies();
110
- const cfCookie = cookies.find(c => c.name === 'cf_clearance');
111
- const userAgent = await page.evaluate(() => navigator.userAgent);
112
-
113
- resolve({
114
- status_code: httpCode,
115
- cookie: cfCookie ? cfCookie.value : "",
116
- userAgent: userAgent,
117
- html: content,
118
- title: title
119
- });
120
- }
121
  } catch (e) {}
122
  }, 1000);
123
 
@@ -128,12 +119,15 @@ async function handleCloudflare(page, url) {
128
  });
129
  }
130
 
 
131
  app.post('/bypass', async (req, res) => {
132
- const { url, mode, siteKey, proxy } = req.body;
 
133
 
134
  if (!url || !mode) return res.status(400).json({ status: "error", message: "Missing url or mode" });
135
  if (mode === 'turnstile' && !siteKey) return res.status(400).json({ status: "error", message: "siteKey required for turnstile" });
136
 
 
137
  if (activeBrowsers >= MAX_CONCURRENT_BROWSERS) {
138
  return res.status(429).json({ status: "busy", message: "Server busy, try again later" });
139
  }
@@ -142,20 +136,20 @@ app.post('/bypass', async (req, res) => {
142
  let browserInstance = null;
143
 
144
  try {
145
- console.log(`[REQ] Processing: ${url} | Mode: ${mode}`);
 
146
  const { browser, page } = await createBrowser(proxy);
147
  browserInstance = browser;
148
 
149
  let result;
150
  if (mode === 'turnstile') {
151
- result = await handleTurnstile(page, url, siteKey);
152
- } else if (mode === 'cloudflare') {
153
- result = await handleCloudflare(page, url);
154
  } else {
155
- throw new Error("Invalid mode. Use 'turnstile' or 'cloudflare'");
156
  }
157
 
158
- console.log(`[SUCCESS] Operation completed for ${mode}`);
159
  res.json({ status: "success", ...result });
160
 
161
  } catch (error) {
@@ -169,5 +163,5 @@ app.post('/bypass', async (req, res) => {
169
  }
170
  });
171
 
172
- app.get('/', (req, res) => res.send("Server Running"));
173
- 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 = 3; // Batasi agar RAM HF tidak jebol
11
  let activeBrowsers = 0;
12
 
13
  async function createBrowser(proxy = null) {
14
  const options = {
15
+ headless: false, // Wajib false agar Turnstile mengira ini user asli
16
+ turnstile: true, // Fitur auto-solve bawaan library (opsional, tapi kita pakai manual logic)
17
  args: [
18
  '--no-sandbox',
19
  '--disable-setuid-sandbox',
 
23
  '--no-zygote',
24
  '--disable-gpu',
25
  '--window-size=1920,1080',
 
26
  ],
27
+ // Menggunakan Chrome yang sudah diinstall Dockerfile
28
  executablePath: process.env.CHROME_PATH || "/usr/bin/google-chrome-stable",
29
  customConfig: {},
30
  connectOption: { defaultViewport: null }
 
34
  options.args.push(`--proxy-server=${proxy.hostname}:${proxy.port}`);
35
  }
36
 
37
+ // Connect ke browser
38
  const { browser, page } = await connect(options);
39
 
40
  if (proxy && proxy.username && proxy.password) {
 
44
  return { browser, page };
45
  }
46
 
47
+ // FUNGSI UTAMA: Handle Turnstile dengan cData
48
+ async function handleTurnstile(page, url, siteKey, cData = null, action = null) {
49
  return new Promise(async (resolve, reject) => {
50
+ // Timeout 60 detik
51
  const timeout = setTimeout(() => reject(new Error("Timeout waiting for Turnstile token")), 60000);
52
 
53
  try {
54
+ console.log(`[Turnstile] Navigating to Real URL: ${url}`);
55
+
56
+ // 1. Buka URL Asli (PENTING: Jangan pakai konten palsu)
57
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 30000 });
58
+
59
+ // 2. Inject Logika Render Widget
60
+ // Kita menyuntikkan script ke browser untuk merender widget sesuai request bot
61
+ await page.evaluate((key, data, act) => {
62
+ // Hapus widget yang mungkin sudah ada agar tidak bentrok
63
+ document.querySelectorAll('.cf-turnstile').forEach(e => e.remove());
64
+ document.querySelectorAll('iframe[src*="challenges.cloudflare.com"]').forEach(e => e.remove());
65
+
66
+ // Buat wadah baru
67
+ const div = document.createElement('div');
68
+ div.id = 'custom-turnstile-container';
69
+ div.style.position = 'fixed';
70
+ div.style.top = '10px';
71
+ div.style.left = '10px';
72
+ div.style.zIndex = '99999';
73
+ document.body.appendChild(div);
74
+
75
+ // Pastikan library Turnstile ada
76
+ if (typeof window.turnstile === 'undefined') {
77
+ const script = document.createElement('script');
78
+ script.src = "https://challenges.cloudflare.com/turnstile/v0/api.js";
79
+ document.body.appendChild(script);
80
+ }
81
+
82
+ // Fungsi Callback
83
+ window.cf_solved_token = null; // Reset token
84
+
85
+ // Tunggu sebentar lalu render
86
+ setTimeout(() => {
87
+ if (window.turnstile) {
88
+ window.turnstile.render('#custom-turnstile-container', {
89
+ sitekey: key,
90
+ cData: data, // Masukkan cData di sini
91
+ action: act, // Masukkan Action di sini
92
+ callback: function(token) {
93
+ window.cf_solved_token = token;
94
+ }
95
+ });
96
+ }
97
+ }, 1000);
98
+ }, siteKey, cData, action);
99
 
100
+ // 3. Polling: Cek apakah token sudah muncul di variabel window.cf_solved_token
101
  const checkToken = setInterval(async () => {
102
  try {
103
+ const token = await page.evaluate(() => window.cf_solved_token);
104
  if (token) {
105
  clearInterval(checkToken);
106
  clearTimeout(timeout);
107
  resolve({ token: token });
108
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
 
110
+ // Cek error box (opsional)
111
+ // const error = await page.evaluate(() => document.querySelector('...error...'));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  } catch (e) {}
113
  }, 1000);
114
 
 
119
  });
120
  }
121
 
122
+ // Endpoint API
123
  app.post('/bypass', async (req, res) => {
124
+ // Tambahkan parameter cdata dan action
125
+ const { url, mode, siteKey, cdata, action, proxy } = req.body;
126
 
127
  if (!url || !mode) return res.status(400).json({ status: "error", message: "Missing url or mode" });
128
  if (mode === 'turnstile' && !siteKey) return res.status(400).json({ status: "error", message: "siteKey required for turnstile" });
129
 
130
+ // Cek Slot Browser
131
  if (activeBrowsers >= MAX_CONCURRENT_BROWSERS) {
132
  return res.status(429).json({ status: "busy", message: "Server busy, try again later" });
133
  }
 
136
  let browserInstance = null;
137
 
138
  try {
139
+ console.log(`[REQ] Processing: ${url} | Mode: ${mode} | cData: ${cdata ? "YES" : "NO"}`);
140
+
141
  const { browser, page } = await createBrowser(proxy);
142
  browserInstance = browser;
143
 
144
  let result;
145
  if (mode === 'turnstile') {
146
+ // Panggil fungsi handleTurnstile dengan parameter baru
147
+ result = await handleTurnstile(page, url, siteKey, cdata, action);
 
148
  } else {
149
+ throw new Error("Invalid mode. Only 'turnstile' supported in this fix.");
150
  }
151
 
152
+ console.log(`[SUCCESS] Token: ${result.token.substring(0, 15)}...`);
153
  res.json({ status: "success", ...result });
154
 
155
  } catch (error) {
 
163
  }
164
  });
165
 
166
+ app.get('/', (req, res) => res.send("Turnstile cData Solver Ready"));
167
+ app.listen(PORT, () => console.log(`Server listening on port ${PORT}`));