fourmovie commited on
Commit
fdf376b
·
1 Parent(s): d384356
Files changed (4) hide show
  1. endpoints/cloudflare-cookies.js +124 -0
  2. endpoints/recaptchav2.js +0 -82
  3. index.js +222 -38
  4. package.json +13 -9
endpoints/cloudflare-cookies.js ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ async function cloudflareCookies({ domain, cookies = [], proxy = null, mobile = false }, page) {
2
+ if (!domain) throw new Error("Missing domain parameter");
3
+
4
+ const timeout = global.timeOut || 60000;
5
+ let isResolved = false;
6
+
7
+ const cl = setTimeout(async () => {
8
+ if (!isResolved) {
9
+ throw new Error("Timeout Error");
10
+ }
11
+ }, timeout);
12
+
13
+ try {
14
+ // Proxy authentication
15
+ if (proxy?.username && proxy?.password) {
16
+ await page.authenticate({
17
+ username: proxy.username,
18
+ password: proxy.password,
19
+ });
20
+ }
21
+
22
+ // Set cookies jika ada
23
+ if (cookies && cookies.length > 0) {
24
+ console.log('Setting cookies:', cookies.length);
25
+
26
+ const cookieObjects = cookies.map(cookie => {
27
+ if (typeof cookie === 'string') {
28
+ // Parse string cookie format: "name=value"
29
+ const [name, value] = cookie.split('=');
30
+ return {
31
+ name: name.trim(),
32
+ value: value.trim(),
33
+ domain: new URL(domain).hostname,
34
+ path: '/'
35
+ };
36
+ } else {
37
+ // Object cookie format
38
+ return {
39
+ name: cookie.name,
40
+ value: cookie.value,
41
+ domain: cookie.domain || new URL(domain).hostname,
42
+ path: cookie.path || '/'
43
+ };
44
+ }
45
+ });
46
+
47
+ await page.setCookie(...cookieObjects);
48
+ console.log('Cookies set successfully');
49
+ }
50
+
51
+ // Navigate to the page
52
+ console.log('Navigating to:', domain);
53
+ await page.goto(domain, {
54
+ waitUntil: 'networkidle0',
55
+ timeout: timeout
56
+ });
57
+
58
+ // Wait a bit for any challenge to process
59
+ await page.waitForTimeout(5000);
60
+
61
+ // Check if we're still on challenge page
62
+ const isChallenge = await page.evaluate(() => {
63
+ return document.title.includes('Just a moment') ||
64
+ document.body.innerHTML.includes('challenge-form') ||
65
+ document.body.innerHTML.includes('cloudflare');
66
+ });
67
+
68
+ if (isChallenge) {
69
+ console.log('Cloudflare challenge detected, waiting...');
70
+ // Wait for challenge to complete (max 45 seconds)
71
+ try {
72
+ await page.waitForFunction(() => {
73
+ return !document.title.includes('Just a moment') &&
74
+ !document.body.innerHTML.includes('challenge-form');
75
+ }, { timeout: 45000 });
76
+ console.log('Challenge completed!');
77
+ } catch (error) {
78
+ console.log('Challenge might still be processing...');
79
+ }
80
+ }
81
+
82
+ // Get current URL and cookies
83
+ const finalUrl = page.url();
84
+ const allCookies = await page.cookies();
85
+
86
+ // Filter important Cloudflare cookies
87
+ const cfCookies = allCookies.filter(cookie =>
88
+ cookie.name.includes('cf_') ||
89
+ cookie.name.includes('__cf') ||
90
+ cookie.name.toLowerCase().includes('cloudflare')
91
+ );
92
+
93
+ // Get page content info
94
+ const pageInfo = await page.evaluate(() => {
95
+ return {
96
+ title: document.title,
97
+ url: window.location.href,
98
+ hasChallenge: document.title.includes('Just a moment') ||
99
+ document.body.innerHTML.includes('challenge'),
100
+ hasFaucet: document.body.innerHTML.includes('faucet') ||
101
+ document.body.innerHTML.includes('claim'),
102
+ hasForm: document.querySelector('form') !== null,
103
+ contentLength: document.body.innerHTML.length
104
+ };
105
+ });
106
+
107
+ isResolved = true;
108
+ clearTimeout(cl);
109
+
110
+ return {
111
+ success: !pageInfo.hasChallenge,
112
+ url: finalUrl,
113
+ cookies: cfCookies,
114
+ pageInfo: pageInfo,
115
+ allCookies: allCookies // Optional: include all cookies if needed
116
+ };
117
+
118
+ } catch (e) {
119
+ clearTimeout(cl);
120
+ throw e;
121
+ }
122
+ }
123
+
124
+ module.exports = cloudflareCookies;
endpoints/recaptchav2.js DELETED
@@ -1,82 +0,0 @@
1
- async function recaptchav2({ domain, siteKey, proxy }, page) {
2
- if (!domain) throw new Error("Missing domain parameter");
3
- if (!siteKey) throw new Error("Missing siteKey parameter");
4
-
5
- const timeout = global.timeOut || 60000;
6
-
7
- try {
8
- if (proxy?.username && proxy?.password) {
9
- await page.authenticate({
10
- username: proxy.username,
11
- password: proxy.password,
12
- });
13
- }
14
-
15
- // Inject HTML dengan recaptcha
16
- const htmlContent = `
17
- <!DOCTYPE html>
18
- <html>
19
- <head>
20
- <script src="https://www.google.com/recaptcha/api.js" async defer></script>
21
- </head>
22
- <body>
23
- <div class="g-recaptcha" data-sitekey="${siteKey}" data-callback="onSuccess"></div>
24
- <script>
25
- window.onSuccess = function(token) {
26
- document.getElementById('token-result').value = token;
27
- };
28
- </script>
29
- <input type="hidden" id="token-result">
30
- </body>
31
- </html>
32
- `;
33
-
34
- await page.setRequestInterception(true);
35
- page.on('request', async (request) => {
36
- if (request.url() === domain && request.resourceType() === 'document') {
37
- await request.respond({
38
- status: 200,
39
- contentType: 'text/html',
40
- body: htmlContent
41
- });
42
- } else {
43
- await request.continue();
44
- }
45
- });
46
-
47
- await page.goto(domain, { waitUntil: "networkidle0", timeout: timeout });
48
-
49
- // Tunggu recaptcha load
50
- await page.waitForSelector('.g-recaptcha', { timeout: timeout });
51
-
52
- // Cari frame recaptcha
53
- const frameElement = await page.$('.g-recaptcha iframe');
54
- if (!frameElement) throw new Error("Recaptcha iframe not found");
55
-
56
- const frame = await frameElement.contentFrame();
57
- if (!frame) throw new Error("Could not get recaptcha frame");
58
-
59
- // Klik checkbox
60
- await frame.waitForSelector('#recaptcha-anchor', { timeout: timeout });
61
- await frame.click('#recaptcha-anchor');
62
-
63
- // Tunggu token
64
- await page.waitForFunction(() => {
65
- const tokenInput = document.getElementById('token-result');
66
- return tokenInput && tokenInput.value && tokenInput.value.length > 10;
67
- }, { timeout: timeout });
68
-
69
- const token = await page.evaluate(() => {
70
- return document.getElementById('token-result').value;
71
- });
72
-
73
- if (!token || token.length < 10) throw new Error("Failed to get recaptcha v2 token");
74
-
75
- return token;
76
-
77
- } catch (e) {
78
- throw e;
79
- }
80
- }
81
-
82
- module.exports = recaptchav2;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
index.js CHANGED
@@ -6,7 +6,7 @@ const path = require("path")
6
  const app = express()
7
  const port = process.env.PORT || 7860
8
  const authToken = process.env.authToken || null
9
- const DOMAIN = 'https://rezaharis-captcha.hf.space'
10
 
11
  global.browserLimit = Number(process.env.browserLimit) || 20
12
  global.timeOut = Number(process.env.timeOut) || 60000
@@ -52,24 +52,33 @@ app.use(express.urlencoded({ extended: true }))
52
  app.get('/', (req, res) => {
53
  res.json({
54
  status: "active",
55
- message: "Server is running"
 
 
 
 
 
 
 
56
  })
57
  })
58
 
59
- if (process.env.NODE_ENV !== 'development') {
60
- let server = app.listen(port, () => {
61
- console.log(`Server running on port ${port}`)
62
- })
63
- try {
64
- server.timeout = global.timeOut
65
- } catch {}
66
- }
67
-
68
  async function createBrowser(proxyServer = null) {
69
  const connectOptions = {
70
- headless: false,
71
  turnstile: true,
72
- connectOption: { defaultViewport: null },
 
 
 
 
 
 
 
 
 
 
 
73
  disableXvfb: false,
74
  }
75
 
@@ -82,8 +91,6 @@ async function createBrowser(proxyServer = null) {
82
  const pages = await browser.pages()
83
  const page = pages[0]
84
 
85
- await page.goto('about:blank')
86
-
87
  await page.setRequestInterception(true)
88
  page.on('request', (req) => {
89
  const type = req.resourceType()
@@ -97,8 +104,94 @@ async function createBrowser(proxyServer = null) {
97
  return { browser, page }
98
  }
99
 
100
- const recaptchav2 = require('./endpoints/recaptchav2')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
 
 
102
  app.post('/cloudflare', async (req, res) => {
103
  const data = req.body
104
 
@@ -130,25 +223,34 @@ app.post('/cloudflare', async (req, res) => {
130
  })
131
  }
132
 
133
- global.browserLimit--
134
- let result
135
- let browser, page
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
  try {
138
- const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null
139
- const ctx = await createBrowser(proxyServer)
140
- browser = ctx.browser
141
- page = ctx.page
142
 
143
- await page.goto('about:blank')
144
 
145
  switch (data.mode) {
146
- case "recaptchav2":
147
- result = await recaptchav2({
148
- domain: data.domain,
149
- siteKey: data.siteKey,
150
- proxy: data.proxy
151
- }, page)
152
  .then(token => ({
153
  token,
154
  status: "success"
@@ -157,39 +259,121 @@ app.post('/cloudflare', async (req, res) => {
157
  code: 500,
158
  message: err.message,
159
  status: "failed"
 
 
 
 
 
 
 
 
160
  }))
161
- break
 
 
 
 
162
 
 
 
 
 
 
163
  default:
164
  result = {
165
  code: 400,
166
  message: 'Invalid mode',
167
  status: "failed"
168
- }
169
  }
170
  } catch (err) {
171
  result = {
172
  code: 500,
173
  message: err.message,
174
  status: "failed"
 
 
 
 
175
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  } finally {
177
  if (browser) {
178
  try { await browser.close() } catch {}
179
  }
180
- global.browserLimit++
181
  }
182
 
183
- res.status(result.code ?? 200).json(result)
184
- })
185
 
186
  app.use((req, res) => {
187
  res.status(404).json({
188
  message: "Not Found",
189
  status: "failed"
190
- })
191
- })
 
 
 
 
 
 
 
 
 
 
192
 
193
  if (process.env.NODE_ENV === 'development') {
194
- module.exports = app
195
  }
 
6
  const app = express()
7
  const port = process.env.PORT || 7860
8
  const authToken = process.env.authToken || null
9
+ const DOMAIN = process.env.DOMAIN || 'https://rezaharis-captcha.hf.space'
10
 
11
  global.browserLimit = Number(process.env.browserLimit) || 20
12
  global.timeOut = Number(process.env.timeOut) || 60000
 
52
  app.get('/', (req, res) => {
53
  res.json({
54
  status: "active",
55
+ message: "Cloudflare Bypass API is running",
56
+ endpoints: {
57
+ "/cloudflare": "Solve Cloudflare challenges (turnstile/iuam)",
58
+ "/cloudflare-cookies": "Bypass Cloudflare with cookies",
59
+ "/turnstile": "Solve Turnstile captcha",
60
+ "/recaptchav3": "Solve reCAPTCHA v3"
61
+ },
62
+ usage: "curl -X POST https://your-app.hf.space/cloudflare-cookies -H 'Content-Type: application/json' -d '{\"domain\":\"https://example.com\",\"cookies\":[\"cookie1=value1\"]}'"
63
  })
64
  })
65
 
 
 
 
 
 
 
 
 
 
66
  async function createBrowser(proxyServer = null) {
67
  const connectOptions = {
68
+ headless: true,
69
  turnstile: true,
70
+ connectOption: {
71
+ defaultViewport: { width: 1920, height: 1080 },
72
+ args: [
73
+ '--no-sandbox',
74
+ '--disable-setuid-sandbox',
75
+ '--disable-dev-shm-usage',
76
+ '--disable-accelerated-2d-canvas',
77
+ '--no-first-run',
78
+ '--no-zygote',
79
+ '--disable-gpu'
80
+ ]
81
+ },
82
  disableXvfb: false,
83
  }
84
 
 
91
  const pages = await browser.pages()
92
  const page = pages[0]
93
 
 
 
94
  await page.setRequestInterception(true)
95
  page.on('request', (req) => {
96
  const type = req.resourceType()
 
104
  return { browser, page }
105
  }
106
 
107
+ // Import endpoints
108
+ const turnstile = require('./endpoints/turnstile')
109
+ const cloudflare = require('./endpoints/cloudflare')
110
+ const cloudflareCookies = require('./endpoints/cloudflare-cookies')
111
+
112
+ // Cloudflare Challenge dengan Cookies
113
+ app.post('/cloudflare-cookies', async (req, res) => {
114
+ const data = req.body;
115
+
116
+ if (!data || !data.domain) {
117
+ return res.status(400).json({
118
+ message: "Parameter 'domain' diperlukan",
119
+ status: "failed"
120
+ });
121
+ }
122
+
123
+ if (authToken && data.authToken !== authToken) {
124
+ return res.status(401).json({
125
+ message: "Unauthorized",
126
+ status: "failed"
127
+ });
128
+ }
129
+
130
+ if (global.browserLimit <= 0) {
131
+ return res.status(429).json({
132
+ message: "Too Many Requests",
133
+ status: "failed"
134
+ });
135
+ }
136
+
137
+ const cacheKey = JSON.stringify(data);
138
+ const cached = readCache(cacheKey);
139
+ if (cached) {
140
+ return res.status(200).json({
141
+ ...cached,
142
+ cached: true,
143
+ status: "success"
144
+ });
145
+ }
146
+
147
+ global.browserLimit--;
148
+ let result;
149
+ let browser, page;
150
+
151
+ try {
152
+ const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null;
153
+ const ctx = await createBrowser(proxyServer);
154
+ browser = ctx.browser;
155
+ page = ctx.page;
156
+
157
+ // Set user agent mobile jika diperlukan
158
+ if (data.mobile) {
159
+ await page.setUserAgent('Mozilla/5.0 (Linux; Android 14; CPH2641 Build/UP1A.231005.007) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.7390.97 Mobile Safari/537.36');
160
+ await page.setViewport({ width: 980, height: 1743 });
161
+ }
162
+
163
+ result = await cloudflareCookies(data, page)
164
+ .then(r => ({
165
+ ...r,
166
+ status: "success"
167
+ }))
168
+ .catch(err => ({
169
+ code: 500,
170
+ message: err.message,
171
+ status: "failed"
172
+ }));
173
+
174
+ if (result.status === "success") {
175
+ writeCache(cacheKey, result);
176
+ }
177
+
178
+ } catch (err) {
179
+ result = {
180
+ code: 500,
181
+ message: err.message,
182
+ status: "failed"
183
+ };
184
+ } finally {
185
+ if (browser) {
186
+ try { await browser.close() } catch {}
187
+ }
188
+ global.browserLimit++;
189
+ }
190
+
191
+ res.status(result.code ?? 200).json(result);
192
+ });
193
 
194
+ // Endpoint Cloudflare yang sudah ada
195
  app.post('/cloudflare', async (req, res) => {
196
  const data = req.body
197
 
 
223
  })
224
  }
225
 
226
+ let cacheKey, cached;
227
+ if (data.mode === "iuam") {
228
+ cacheKey = JSON.stringify(data);
229
+ cached = readCache(cacheKey);
230
+ if (cached) {
231
+ return res.status(200).json({
232
+ ...cached,
233
+ cached: true,
234
+ status: "success"
235
+ });
236
+ }
237
+ }
238
+
239
+ global.browserLimit--;
240
+ let result;
241
+ let browser, page;
242
 
243
  try {
244
+ const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null;
245
+ const ctx = await createBrowser(proxyServer);
246
+ browser = ctx.browser;
247
+ page = ctx.page;
248
 
249
+ await page.goto('about:blank');
250
 
251
  switch (data.mode) {
252
+ case "turnstile":
253
+ result = await turnstile(data, page)
 
 
 
 
254
  .then(token => ({
255
  token,
256
  status: "success"
 
259
  code: 500,
260
  message: err.message,
261
  status: "failed"
262
+ }));
263
+ break;
264
+
265
+ case "iuam":
266
+ result = await cloudflare(data, page)
267
+ .then(r => ({
268
+ ...r,
269
+ status: "success"
270
  }))
271
+ .catch(err => ({
272
+ code: 500,
273
+ message: err.message,
274
+ status: "failed"
275
+ }));
276
 
277
+ if (!result.code || result.code === 200) {
278
+ writeCache(cacheKey, result);
279
+ }
280
+ break;
281
+
282
  default:
283
  result = {
284
  code: 400,
285
  message: 'Invalid mode',
286
  status: "failed"
287
+ };
288
  }
289
  } catch (err) {
290
  result = {
291
  code: 500,
292
  message: err.message,
293
  status: "failed"
294
+ };
295
+ } finally {
296
+ if (browser) {
297
+ try { await browser.close() } catch {}
298
  }
299
+ global.browserLimit++;
300
+ }
301
+
302
+ res.status(result.code ?? 200).json(result);
303
+ });
304
+
305
+ // Endpoint khusus Turnstile
306
+ app.post('/turnstile', async (req, res) => {
307
+ const data = req.body;
308
+
309
+ if (!data || !data.siteKey || !data.domain) {
310
+ return res.status(400).json({
311
+ message: "Parameter 'siteKey' dan 'domain' diperlukan",
312
+ status: "failed"
313
+ });
314
+ }
315
+
316
+ if (authToken && data.authToken !== authToken) {
317
+ return res.status(401).json({
318
+ message: "Unauthorized",
319
+ status: "failed"
320
+ });
321
+ }
322
+
323
+ global.browserLimit--;
324
+ let result;
325
+ let browser, page;
326
+
327
+ try {
328
+ const proxyServer = data.proxy ? `${data.proxy.hostname}:${data.proxy.port}` : null;
329
+ const ctx = await createBrowser(proxyServer);
330
+ browser = ctx.browser;
331
+ page = ctx.page;
332
+
333
+ result = await turnstile(data, page)
334
+ .then(token => ({
335
+ token,
336
+ status: "success"
337
+ }))
338
+ .catch(err => ({
339
+ code: 500,
340
+ message: err.message,
341
+ status: "failed"
342
+ }));
343
+
344
+ } catch (err) {
345
+ result = {
346
+ code: 500,
347
+ message: err.message,
348
+ status: "failed"
349
+ };
350
  } finally {
351
  if (browser) {
352
  try { await browser.close() } catch {}
353
  }
354
+ global.browserLimit++;
355
  }
356
 
357
+ res.status(result.code ?? 200).json(result);
358
+ });
359
 
360
  app.use((req, res) => {
361
  res.status(404).json({
362
  message: "Not Found",
363
  status: "failed"
364
+ });
365
+ });
366
+
367
+ if (process.env.NODE_ENV !== 'development') {
368
+ let server = app.listen(port, () => {
369
+ console.log(`Server running on port ${port}`);
370
+ console.log(`Domain: ${DOMAIN}`);
371
+ });
372
+ try {
373
+ server.timeout = global.timeOut;
374
+ } catch {}
375
+ }
376
 
377
  if (process.env.NODE_ENV === 'development') {
378
+ module.exports = app;
379
  }
package.json CHANGED
@@ -1,16 +1,20 @@
1
  {
2
- "name": "cf-bypass",
3
- "version": "1.0",
4
- "description": "get the cf_clearance cookie from any website",
 
5
  "scripts": {
6
  "start": "node index.js",
7
- "dev": "nodemon index.js"
8
  },
9
  "dependencies": {
10
- "express": "^5.1.0",
11
- "puppeteer-real-browser": "^1.4.0"
 
 
 
12
  },
13
- "devDependencies": {
14
- "nodemon": "^3.1.10"
15
  }
16
- }
 
1
  {
2
+ "name": "cloudflare-bypass-api",
3
+ "version": "1.0.0",
4
+ "description": "API untuk bypass Cloudflare challenge dengan cookies",
5
+ "main": "index.js",
6
  "scripts": {
7
  "start": "node index.js",
8
+ "dev": "node index.js"
9
  },
10
  "dependencies": {
11
+ "express": "^4.18.2",
12
+ "puppeteer": "^21.5.2",
13
+ "puppeteer-extra": "^3.3.6",
14
+ "puppeteer-extra-plugin-stealth": "^2.11.2",
15
+ "puppeteer-real-browser": "^0.0.9"
16
  },
17
+ "engines": {
18
+ "node": ">=18.0.0"
19
  }
20
+ }