ken4 commited on
Commit
05b690a
·
verified ·
1 Parent(s): f65426f

Upload 3 files

Browse files
Files changed (3) hide show
  1. Dockerfile +29 -0
  2. app.js +104 -0
  3. package.json +15 -0
Dockerfile ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM node:18-slim
2
+
3
+ # Install dependencies for Puppeteer/Chrome
4
+ RUN apt-get update && apt-get install -y \
5
+ chromium \
6
+ fonts-ipafont-gothic \
7
+ fonts-wqy-zenhei \
8
+ fonts-thai-tlwg \
9
+ fonts-kacst \
10
+ fonts-freefont-ttf \
11
+ libxss1 \
12
+ --no-install-recommends \
13
+ && rm -rf /var/lib/apt/lists/*
14
+
15
+ # Set environment variables for Puppeteer
16
+ ENV PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true \
17
+ PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
18
+
19
+ WORKDIR /app
20
+
21
+ COPY package*.json ./
22
+ RUN npm install
23
+
24
+ COPY . .
25
+
26
+ # Hugging Face Spaces default port
27
+ EXPOSE 7860
28
+
29
+ CMD ["node", "app.js"]
app.js ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const express = require('express');
2
+ const puppeteer = require('puppeteer-extra');
3
+ puppeteer.use(require('puppeteer-extra-plugin-stealth')());
4
+ const path = require('path');
5
+
6
+ const app = express();
7
+ const port = process.env.PORT || 7860;
8
+
9
+ const HTML_TEMPLATE = `<!DOCTYPE html>
10
+ <html lang="en">
11
+ <head>
12
+ <meta charset="UTF-8">
13
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
14
+ <title>Turnstile Solver</title>
15
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async></script>
16
+ <script>
17
+ function checkToken(){
18
+ const el=document.querySelector("[name='cf-turnstile-response']");
19
+ if(el && el.value) {
20
+ window.capturedToken = el.value;
21
+ }
22
+ }
23
+ window.onload=function(){setInterval(checkToken, 500);}
24
+ </script>
25
+ </head>
26
+ <body>
27
+ <div class="cf-turnstile" id="turnstile-widget"></div>
28
+ </body>
29
+ </html>`;
30
+
31
+ const sleep = (ms) => new Promise(r => setTimeout(r, ms));
32
+
33
+ async function solveTurnstile(url, sitekey) {
34
+ const browser = await puppeteer.launch({
35
+ headless: "new",
36
+ executablePath: process.env.PUPPETEER_EXECUTABLE_PATH || null,
37
+ args: [
38
+ "--no-sandbox",
39
+ "--disable-setuid-sandbox",
40
+ "--disable-dev-shm-usage",
41
+ "--disable-blink-features=AutomationControlled"
42
+ ]
43
+ });
44
+
45
+ try {
46
+ const page = await browser.newPage();
47
+ const urlFixed = url.endsWith("/") ? url : url + "/";
48
+
49
+ await page.setRequestInterception(true);
50
+ page.on('request', (req) => {
51
+ if (req.url() === urlFixed && req.resourceType() === 'document') {
52
+ const html = HTML_TEMPLATE.replace('id="turnstile-widget"', `id="turnstile-widget" data-sitekey="${sitekey}"`);
53
+ req.respond({ status: 200, contentType: 'text/html', body: html });
54
+ } else {
55
+ req.continue();
56
+ }
57
+ });
58
+
59
+ await page.goto(urlFixed, { waitUntil: 'domcontentloaded' });
60
+
61
+ // Tunggu iframe muncul dan klik jika perlu
62
+ await page.waitForSelector('.cf-turnstile', { timeout: 10000 });
63
+ await sleep(2000);
64
+
65
+ // Polling token
66
+ for (let i = 0; i < 30; i++) {
67
+ const token = await page.evaluate(() => window.capturedToken || null);
68
+ if (token) {
69
+ await browser.close();
70
+ return token;
71
+ }
72
+ await sleep(1000);
73
+ }
74
+ throw new Error("Timeout: Gagal mendapatkan token Turnstile");
75
+ } catch (err) {
76
+ await browser.close();
77
+ throw err;
78
+ }
79
+ }
80
+
81
+ app.get('/solve', async (req, res) => {
82
+ const { url, siteKey } = req.query;
83
+
84
+ if (!url || !siteKey) {
85
+ return res.status(400).json({ error: "Parameter 'url' dan 'siteKey' diperlukan" });
86
+ }
87
+
88
+ try {
89
+ console.log(`Menyelesaikan Turnstile untuk: ${url}`);
90
+ const token = await solveTurnstile(url, siteKey);
91
+ res.json({ result: token });
92
+ } catch (error) {
93
+ console.error(error);
94
+ res.status(500).json({ error: error.message });
95
+ }
96
+ });
97
+
98
+ app.get('/', (req, res) => {
99
+ res.send('Turnstile Solver API sedang berjalan. Gunakan endpoint /solve');
100
+ });
101
+
102
+ app.listen(port, () => {
103
+ console.log(`Server berjalan di port ${port}`);
104
+ });
package.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "turnstile-solver-api",
3
+ "version": "1.0.0",
4
+ "description": "API to solve Cloudflare Turnstile",
5
+ "main": "app.js",
6
+ "scripts": {
7
+ "start": "node app.js"
8
+ },
9
+ "dependencies": {
10
+ "express": "^4.18.2",
11
+ "puppeteer": "^21.5.0",
12
+ "puppeteer-extra": "^3.3.6",
13
+ "puppeteer-extra-plugin-stealth": "^2.11.2"
14
+ }
15
+ }