Download app.js from kavion/cf: direct link, hf CLI and curl.
- Browser
- Download file 2.99 kB
-
https://huggingface.co/spaces/kavion/cf/resolve/main/app.js
- Command line
-
hf download hf://spaces/kavion/cf/app.js
-
curl -L -o app.js https://huggingface.co/spaces/kavion/cf/resolve/main/app.js
2.99 kB
| ; | |
| const express = require('express'); | |
| const TurnstileSolver = require('./turnstile-solver'); | |
| const app = express(); | |
| const PORT = process.env.PORT || 7860; | |
| app.use(express.json()); | |
| // Singleton solver — browser tetap hidup selama server berjalan | |
| const solver = new TurnstileSolver({ | |
| timeout: 25000, | |
| record: false, | |
| width: 1280, | |
| height: 720, | |
| }); | |
| // Inisialisasi browser saat startup | |
| let ready = false; | |
| (async () => { | |
| try { | |
| await solver.initialize(); | |
| ready = true; | |
| console.log('[API] Solver ready.'); | |
| } catch (e) { | |
| console.error('[API] Solver init failed:', e.message); | |
| } | |
| })(); | |
| /** | |
| * GET /bypass/turnstile-min | |
| * Query params: | |
| * - url : URL target (wajib) | |
| * - siteKey : Sitekey Turnstile (opsional, kalau tidak ada pakai mode page) | |
| * - apikey : API key sederhana untuk proteksi (opsional, cek env API_KEY) | |
| * | |
| * Response (sukses): | |
| * { status: true, token: "...", time: 3.2 } | |
| * | |
| * Response (gagal): | |
| * { status: false, message: "..." } | |
| */ | |
| app.get('/bypass/turnstile-min', async (req, res) => { | |
| // Cek API key kalau dikonfigurasi | |
| const apiKey = process.env.API_KEY; | |
| if (apiKey && req.query.apikey !== apiKey) { | |
| return res.status(401).json({ status: false, message: 'Invalid API key.' }); | |
| } | |
| const { url, siteKey } = req.query; | |
| if (!url) { | |
| return res.status(400).json({ status: false, message: 'Parameter "url" wajib diisi.' }); | |
| } | |
| if (!ready) { | |
| return res.status(503).json({ status: false, message: 'Solver belum siap, coba lagi sebentar.' }); | |
| } | |
| try { | |
| const result = await solver.solve(url, siteKey || null); | |
| if (!result.success) { | |
| return res.status(500).json({ | |
| status: false, | |
| message: result.error || 'Gagal mendapatkan token Turnstile.', | |
| time: result.time, | |
| }); | |
| } | |
| return res.json({ | |
| status: true, | |
| creator: 'XAi Community', | |
| token: result.token, | |
| time: result.time, | |
| }); | |
| } catch (e) { | |
| return res.status(500).json({ status: false, message: e.message }); | |
| } | |
| }); | |
| // Health check | |
| app.get('/', (req, res) => { | |
| res.json({ | |
| status: 'ok', | |
| ready, | |
| endpoints: [ | |
| 'GET /bypass/turnstile-min?url=<URL>&siteKey=<SITEKEY>&apikey=<KEY>', | |
| 'GET /debug/screenshot — lihat screenshot terakhir saat solving gagal', | |
| ], | |
| }); | |
| }); | |
| // Debug: lihat screenshot terakhir | |
| const fs = require('fs'); | |
| app.get('/debug/screenshot', (req, res) => { | |
| const p = '/tmp/debug_turnstile.png'; | |
| if (!fs.existsSync(p)) return res.status(404).json({ error: 'Belum ada screenshot.' }); | |
| res.sendFile(p); | |
| }); | |
| app.listen(PORT, '0.0.0.0', () => { | |
| console.log(`[API] Server jalan di port ${PORT}`); | |
| }); | |
| // Cleanup saat proses mati | |
| process.on('SIGTERM', async () => { | |
| await solver.cleanup(); | |
| process.exit(0); | |
| }); | |