const express = require('express'); const cors = require('cors'); const app = express(); const PORT = process.env.PORT || 7860; const API_BASE = 'https://maylinejix-herxagg.hf.space'; app.use(cors()); app.use(express.json()); async function submitJob(code) { const response = await fetch(`${API_BASE}/api/s-playwright`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ code, lang: 'python' }) }); if (!response.ok) { throw new Error(`API error: ${response.status}`); } const result = await response.json(); if (!result.success) { throw new Error(result.error || 'Failed to submit job'); } return result.job_id; } async function pollJob(jobId, maxWaitTime = 120000) { const pollInterval = 3000; const start = Date.now(); while (Date.now() - start < maxWaitTime) { const statusResponse = await fetch(`${API_BASE}/job/${jobId}`); if (!statusResponse.ok) { throw new Error(`Status check failed: ${statusResponse.status}`); } const statusResult = await statusResponse.json(); if (!statusResult.success) { throw new Error(statusResult.error || 'Status check error'); } const job = statusResult.job; if (job.status === 'completed') { return job.result; } if (job.status === 'failed') { throw new Error(job.error || 'Job failed'); } await new Promise(resolve => setTimeout(resolve, pollInterval)); } throw new Error('Timeout waiting for job completion'); } app.post('/bycf', async (req, res) => { try { const { url, sitekey, action = null, cdata = null } = req.body; if (!url || !sitekey) { return res.status(400).json({ author: 'Herza', status: 400, data: { error: 'URL and SITEKEY are required' } }); } const t = Date.now(); const esc = (s) => s ? s.replace(/'/g, "\\'") : null; const a = esc(action); const c = esc(cdata); const code = `import random,time ctx=browser.new_context(viewport={'width':1920,'height':1080},ignore_https_errors=True) p=ctx.new_page() try: p.goto('${url}',wait_until='domcontentloaded',timeout=20000) time.sleep(0.5) p.evaluate("""(function(){const e=document.querySelector('.cf-turnstile');e&&e.remove();const d=document.createElement('div');d.className='cf-turnstile';d.setAttribute('data-sitekey','${sitekey}');${a ? `d.setAttribute('data-action','${a}');` : ''}${c ? `d.setAttribute('data-cdata','${c}');` : ''}d.style.cssText='position:fixed;top:50%;left:50%;transform:translate(-50%,-50%);z-index:999999';document.body.appendChild(d);const s=document.createElement('script');s.src='https://challenges.cloudflare.com/turnstile/v0/api.js';s.async=s.defer=1;document.head.appendChild(s)})()""") time.sleep(1.5) tk=None for i in range(40): try: inp=p.query_selector('input[name="cf-turnstile-response"]') if inp: v=inp.get_attribute('value') if v and len(v)>50: tk=v break if not v: div=p.query_selector('div.cf-turnstile') if div: b=div.bounding_box() if b: x=b['x']+b['width']/2 y=b['y']+b['height']/2 p.mouse.move(x+random.randint(-15,15),y+random.randint(-15,15)) time.sleep(0.2) p.mouse.click(x,y) time.sleep(0.3) except: pass time.sleep(0.3) if not tk:raise Exception('No token') ck={c['name']:c['value'] for c in p.context.cookies()} return_value={'success':True,'token':tk,'sitekey':'${sitekey}','url':'${url}','action':${a ? `'${a}'` : 'None'},'cdata':${c ? `'${c}'` : 'None'},'cookies':ck,'elapsed_ms':int((time.time()*1000)-${t})} except Exception as e: return_value={'success':False,'error':str(e)}`; const jobId = await submitJob(code); const result = await pollJob(jobId); if (!result.success) { return res.status(500).json({ author: 'Herza', status: 500, data: { error: result.error } }); } res.json({ author: 'Herza', status: 200, data: { token: result.token, sitekey: result.sitekey, url: result.url, action: result.action, cdata: result.cdata, cookies: result.cookies, elapsed_ms: result.elapsed_ms } }); } catch (error) { res.status(500).json({ author: 'Herza', status: 500, data: { error: error.message } }); } }); app.post('/wafsource', async (req, res) => { try { const { url } = req.body; if (!url) { return res.status(400).json({ author: 'Herza', status: 400, data: { error: 'URL is required' } }); } const startTime = Date.now(); const code = `import random,math,re ctx=browser.new_context(viewport={'width':1920,'height':1080},ignore_https_errors=True) p=ctx.new_page() p.set_viewport_size({'width':1920,'height':1080}) time.sleep(0.5) try: p.goto('${url}',wait_until='domcontentloaded',timeout=60000) p.evaluate('()=>{Object.defineProperty(window,"innerWidth",{value:1920,writable:false,configurable:false});Object.defineProperty(window,"innerHeight",{value:1080,writable:false,configurable:false})}') time.sleep(2) time.sleep(5) pg=p.content() has_cf='cloudflare' in pg.lower() or 'cf-wrapper' in pg.lower() if has_cf: for _ in range(random.randint(3,5)): p.evaluate(f'window.scrollTo(0,{random.randint(50,150)})') time.sleep(random.uniform(0.4,0.8)) p.evaluate('window.scrollTo(0,0)') time.sleep(random.uniform(1.0,2.0)) sx,sy=random.randint(100,300),random.randint(100,300) tx,ty=545,290 d=math.sqrt((tx-sx)**2+(ty-sy)**2) st=max(15,min(int(d/random.uniform(3,6)),40)) for i in range(st): t=(i+1)/st et=t*t*(3-2*t) bx=(sx+tx)/2+random.uniform(-30,30) by=(sy+ty)/2+random.uniform(-30,30) nx=(1-et)**2*sx+2*(1-et)*et*bx+et**2*tx ny=(1-et)**2*sy+2*(1-et)*et*by+et**2*ty p.mouse.move(nx,ny) time.sleep(random.uniform(0.015,0.040)) p.mouse.move(tx,ty) time.sleep(random.uniform(0.3,0.6)) p.mouse.down() time.sleep(random.uniform(0.12,0.18)) p.mouse.up() time.sleep(11) try:p.wait_for_load_state('networkidle',timeout=10000) except:pass time.sleep(5) fu=p.url html=p.content() title=p.title() ck={c['name']:c['value'] for c in p.context.cookies()} return_value={'success':True,'url':fu,'html':html,'title':title,'cookies':ck,'had_cloudflare':has_cf,'ms':int((time.time()*1000)-${startTime})} except Exception as e: return_value={'success':False,'error':str(e)}`; const jobId = await submitJob(code); const result = await pollJob(jobId, 300000); if (!result.success) { return res.status(500).json({ author: 'Herza', status: 500, data: { error: result.error } }); } res.json({ author: 'Herza', status: 200, data: { url: result.url, html: result.html, title: result.title, cookies: result.cookies, had_cloudflare: result.had_cloudflare, elapsed_ms: result.ms } }); } catch (error) { res.status(500).json({ author: 'Herza', status: 500, data: { error: error.message } }); } }); app.post('/wafsessions', async (req, res) => { try { const { url } = req.body; if (!url) { return res.status(400).json({ author: 'Herza', status: 400, data: { error: 'URL is required' } }); } const startTime = Date.now(); const code = `import random,math,re ctx=browser.new_context(viewport={'width':1920,'height':1080},ignore_https_errors=True) p=ctx.new_page() p.set_viewport_size({'width':1920,'height':1080}) time.sleep(0.5) try: p.goto('${url}',wait_until='domcontentloaded',timeout=60000) p.evaluate('()=>{Object.defineProperty(window,"innerWidth",{value:1920,writable:false,configurable:false});Object.defineProperty(window,"innerHeight",{value:1080,writable:false,configurable:false})}') time.sleep(2) time.sleep(5) pg=p.content() has_cf='cloudflare' in pg.lower() or 'cf-wrapper' in pg.lower() if has_cf: for _ in range(random.randint(3,5)): p.evaluate(f'window.scrollTo(0,{random.randint(50,150)})') time.sleep(random.uniform(0.4,0.8)) p.evaluate('window.scrollTo(0,0)') time.sleep(random.uniform(1.0,2.0)) sx,sy=random.randint(100,300),random.randint(100,300) tx,ty=545,290 d=math.sqrt((tx-sx)**2+(ty-sy)**2) st=max(15,min(int(d/random.uniform(3,6)),40)) for i in range(st): t=(i+1)/st et=t*t*(3-2*t) bx=(sx+tx)/2+random.uniform(-30,30) by=(sy+ty)/2+random.uniform(-30,30) nx=(1-et)**2*sx+2*(1-et)*et*bx+et**2*tx ny=(1-et)**2*sy+2*(1-et)*et*by+et**2*ty p.mouse.move(nx,ny) time.sleep(random.uniform(0.015,0.040)) p.mouse.move(tx,ty) time.sleep(random.uniform(0.3,0.6)) p.mouse.down() time.sleep(random.uniform(0.12,0.18)) p.mouse.up() time.sleep(11) try:p.wait_for_load_state('networkidle',timeout=10000) except:pass time.sleep(5) fu=p.url title=p.title() ck={c['name']:c['value'] for c in p.context.cookies()} return_value={'success':True,'url':fu,'title':title,'cookies':ck,'had_cloudflare':has_cf,'ms':int((time.time()*1000)-${startTime})} except Exception as e: return_value={'success':False,'error':str(e)}`; const jobId = await submitJob(code); const result = await pollJob(jobId, 300000); if (!result.success) { return res.json({ author: 'Herza', status: 500, data: { error: result.error } }); } res.json({ author: 'Herza', status: 200, data: { url: result.url, title: result.title, cookies: result.cookies, had_cloudflare: result.had_cloudflare, elapsed_ms: result.ms } }); } catch (error) { res.json({ author: 'Herza', status: 500, data: { error: error.message } }); } }); app.get('/', (req, res) => { res.json({ author: 'Herza', status: 200, data: { message: 'API is running', endpoints: { '/bycf': 'POST - Bypass Cloudflare Turnstile (requires: url, sitekey)', '/wafsource': 'POST - Get HTML with WAF bypass (requires: url)', '/wafsessions': 'POST - Get cookies only (requires: url)' } } }); }); app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); });