Spaces:
Runtime error
Runtime error
| const puppeteer = require('puppeteer-core'); | |
| const axios = require('axios'); | |
| const path = require('path'); | |
| const CHROMIUM_PATH = process.env.CHROMIUM_PATH || process.env.PUPPETEER_EXECUTABLE_PATH || '/nix/store/khk7xpgsm5insk81azy9d560yq4npf77-chromium-131.0.6778.204/bin/chromium'; | |
| const CF_SOLVER_URL = 'https://samleuma-cf-solver.hf.space/solver'; | |
| const TURNSTILE_SITEKEY = '0x4AAAAAAAfqMU3EtZs0r_nN'; | |
| const ONBOARDING_URL = 'https://autz.org/onboarding/qinw2ix?callback_url=https%3A%2F%2Fmy.zone.id%2F'; | |
| const SCREENSHOTS_DIR = path.join(__dirname, '..', 'screenshots'); | |
| async function saveScreenshot(page, name) { | |
| try { | |
| const timestamp = Date.now(); | |
| const filePath = path.join(SCREENSHOTS_DIR, `${name}_${timestamp}.png`); | |
| await page.screenshot({ path: filePath, fullPage: true }); | |
| console.log(`[Screenshot] Saved: ${filePath}`); | |
| return filePath; | |
| } catch (err) { | |
| console.error(`[Screenshot] Failed to save ${name}:`, err.message); | |
| return null; | |
| } | |
| } | |
| async function solveTurnstile() { | |
| const response = await axios.post(CF_SOLVER_URL, { | |
| mode: 'turnstile-max', | |
| url: ONBOARDING_URL, | |
| siteKey: TURNSTILE_SITEKEY | |
| }, { timeout: 180000 }); | |
| if (response.data.code === 200 && response.data.token) { | |
| return response.data.token; | |
| } | |
| throw new Error('Failed to solve Turnstile: ' + JSON.stringify(response.data)); | |
| } | |
| async function createAutzAccountWithBrowser(email, password, name, phone) { | |
| const turnstileToken = await solveTurnstile(); | |
| const browser = await puppeteer.launch({ | |
| executablePath: CHROMIUM_PATH, | |
| headless: true, | |
| args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage', '--disable-gpu'] | |
| }); | |
| let userTokenId = null; | |
| try { | |
| const page = await browser.newPage(); | |
| await page.setViewport({ width: 1280, height: 800 }); | |
| page.on('response', async (response) => { | |
| const url = response.url(); | |
| if (url.includes('/api/register') && response.status() === 200) { | |
| try { | |
| const data = await response.json(); | |
| userTokenId = data.user_token_id; | |
| console.log('[Autz] Captured userTokenId:', userTokenId); | |
| } catch (e) {} | |
| } | |
| }); | |
| await page.evaluateOnNewDocument((token) => { | |
| window.turnstile = { | |
| render: (container, params) => { | |
| if (params.callback) setTimeout(() => params.callback(token), 500); | |
| return 'widget-id'; | |
| }, | |
| getResponse: () => token, | |
| reset: () => {} | |
| }; | |
| }, turnstileToken); | |
| await page.goto(ONBOARDING_URL, { waitUntil: 'networkidle2', timeout: 60000 }); | |
| await page.waitForSelector('#login-modal', { visible: true, timeout: 30000 }); | |
| await saveScreenshot(page, '01_login_modal'); | |
| await page.type('input[type="email"]', email, { delay: 20 }); | |
| await page.evaluate((token) => { | |
| if (window.onVerifiedCaptcha) window.onVerifiedCaptcha(token); | |
| const btn = document.querySelector('button.btn-primary'); | |
| if (btn) btn.disabled = false; | |
| }, turnstileToken); | |
| await new Promise(r => setTimeout(r, 1000)); | |
| await page.click('button.btn-primary'); | |
| await new Promise(r => setTimeout(r, 3000)); | |
| const inputs = await page.$$('#login-modal input.form-control'); | |
| if (inputs.length >= 4) { | |
| await inputs[1].type(password, { delay: 15 }); | |
| await inputs[2].type(name, { delay: 15 }); | |
| await inputs[3].type(phone, { delay: 15 }); | |
| await saveScreenshot(page, '02_registration_form_filled'); | |
| await page.click('button.btn-primary'); | |
| await new Promise(r => setTimeout(r, 5000)); | |
| await saveScreenshot(page, '03_after_registration_submit'); | |
| } | |
| console.log('[Autz] Registration completed, clicking Activate Now...'); | |
| await Promise.all([ | |
| page.waitForNavigation({ waitUntil: 'networkidle2', timeout: 30000 }).catch(() => {}), | |
| page.evaluate(() => { | |
| document.querySelectorAll('a, span, button').forEach(el => { | |
| if (el.textContent?.toLowerCase().includes('activate')) el.click(); | |
| }); | |
| }) | |
| ]); | |
| await new Promise(r => setTimeout(r, 2000)); | |
| let pages = await browser.pages(); | |
| let activePage = page; | |
| if (pages.length > 1) { | |
| activePage = pages[pages.length - 1]; | |
| } | |
| let pageText = await activePage.evaluate(() => document.body.innerText); | |
| console.log('[Autz] Current page:', pageText.substring(0, 120).replace(/\n/g, ' ')); | |
| await saveScreenshot(activePage, '04_after_activate_click'); | |
| if (pageText.toLowerCase().includes('send otp')) { | |
| console.log('[Autz] Found Send OTP page - clicking Send OTP button...'); | |
| await activePage.evaluate(() => { | |
| document.querySelectorAll('button').forEach(btn => { | |
| if (btn.textContent?.toLowerCase().includes('send otp')) { | |
| btn.click(); | |
| } | |
| }); | |
| }); | |
| await new Promise(r => setTimeout(r, 3000)); | |
| await saveScreenshot(activePage, '05_after_send_otp_click'); | |
| console.log('[Autz] Send OTP clicked - email should be sent now'); | |
| } else { | |
| console.log('[Autz] Send OTP page not found, checking for other activation methods...'); | |
| } | |
| return { | |
| success: true, | |
| email, | |
| userTokenId, | |
| browser, | |
| activePage | |
| }; | |
| } catch (err) { | |
| await browser.close(); | |
| throw err; | |
| } | |
| } | |
| async function enterOtpAndActivate(activePage, otp) { | |
| console.log(`[Autz] Entering OTP: ${otp}`); | |
| const otpInput = await activePage.$('input'); | |
| if (!otpInput) { | |
| throw new Error('OTP input field not found'); | |
| } | |
| await otpInput.click({ clickCount: 3 }); | |
| await otpInput.type(otp, { delay: 50 }); | |
| await saveScreenshot(activePage, '06_otp_entered'); | |
| await activePage.evaluate(() => { | |
| document.querySelectorAll('button').forEach(btn => { | |
| if (btn.textContent?.toLowerCase().includes('submit') || | |
| btn.textContent?.toLowerCase().includes('verify') || | |
| btn.textContent?.toLowerCase().includes('activate')) { | |
| btn.click(); | |
| } | |
| }); | |
| }); | |
| console.log('[Autz] OTP submitted, waiting for activation...'); | |
| await new Promise(r => setTimeout(r, 5000)); | |
| await saveScreenshot(activePage, '07_after_otp_submit'); | |
| const pageText = await activePage.evaluate(() => document.body.innerText); | |
| console.log('[Autz] Page after OTP submit:', pageText.substring(0, 200).replace(/\n/g, ' ')); | |
| if (pageText.toLowerCase().includes('error') || pageText.toLowerCase().includes('invalid')) { | |
| throw new Error('OTP activation failed: ' + pageText.substring(0, 100)); | |
| } | |
| return true; | |
| } | |
| module.exports = { createAutzAccountWithBrowser, enterOtpAndActivate, solveTurnstile, saveScreenshot }; | |