autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
103
skills/browser-signup-automation/SKILL.md
Normal file
103
skills/browser-signup-automation/SKILL.md
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
name: browser-signup-automation
|
||||
description: Browser-driven account and referral signup automation using SeleniumBase/Playwright with temp mail, OTP polling, anti-bot fallbacks, and deterministic verification.
|
||||
triggers: browser signup|browser registration|selenium signup|otp signup|referral bot|vercel signup|v0 referral
|
||||
---
|
||||
|
||||
# Browser Signup Automation
|
||||
|
||||
## Use when
|
||||
- The task is browser-based account creation or referral completion.
|
||||
- The flow requires a real browser, JavaScript, redirects, OTP/email verification, or anti-bot handling.
|
||||
- API-only registration is unavailable or incomplete.
|
||||
|
||||
## Do not use when
|
||||
- A fully documented HTTP/API signup path exists and is simpler.
|
||||
- The task is ordinary account access/checkouts rather than new registration.
|
||||
|
||||
## Alternative: API-first registration with 2captcha Turnstile bypass
|
||||
|
||||
When the browser approach is blocked by Cloudflare Turnstile (CDP/DevTools detection), switch to:
|
||||
|
||||
1. **Solve Turnstile via 2captcha** (not browser click) — submit sitekey + pageurl to 2captcha `in.php?method=turnstile`, poll `res.php` for the token.
|
||||
2. **Find the server-side turnstile validation endpoint** — look for patterns like `turnstile-signup`, `captcha/verify`, `token/validate` in the site's JavaScript bundles or network logs.
|
||||
3. **Call the validation endpoint** with `{email, token}` — if it returns `204 No Content` or similar, the token is accepted server-side.
|
||||
4. **Complete registration via the actual auth API** — Firebase REST (`identitytoolkit.googleapis.com/accounts:signUp`), Auth0, or custom API.
|
||||
|
||||
### Identifying the signup API from JS bundles
|
||||
|
||||
- Load modulepreloads listed in the page's HTML `link[rel="modulepreload"]`.
|
||||
- Check the importmap (`script[type="importmap"]`) for hash resolution — old hashes in JS imports map to current hashes.
|
||||
- Focus on files named `signup*`, `LoginSignupForm*`, `_auth*`, and `auth*` — these contain the registration component.
|
||||
- Search for server-function calls (`/_serverFn/<hash>`) and external API calls (`https://api.example.com/auth/`) in the bundle text.
|
||||
- Trace the Turnstile widget component — typically rendered with `siteKey`, `action`, `onTokenChange` props. The `action` string (e.g. `signup_email_password`) must match when solving via 2captcha.
|
||||
- See `references/turnstile-api-first-registration.md` for session-specific examples (SolidStart server functions, Firebase Auth integration).
|
||||
|
||||
### Turnstile CDP Detection Facts
|
||||
|
||||
- Turnstile with implicit rendering (the checkbox "Verify you are human") **detects Chrome DevTools Protocol** reliably. Clicking the checkbox via CDP always results in `failure_retry` → "Verification failure".
|
||||
- Setting the hidden `cf-turnstile-response` input value via JS is NOT enough — the form framework checks `window.turnstile.getResponse()` internally, which returns empty.
|
||||
- To properly inject a 2captcha-solved token there are three options, in order of preference:
|
||||
- **(a) Stub `window.turnstile` BEFORE api.js loads and let the app call you.** Serve your own JS from `page.route("**/challenges.cloudflare.com/turnstile/**", fulfill(stub))` plus `add_init_script(stub)`; the stub's `render(el, opts)` immediately invokes `opts.callback(TOKEN)` (and `opts["before-interactive-callback"]()` first). The framework's own state updates, the submit button unlocks, and **the page sends the request itself** with every native header it normally adds. This is the only option that works when the endpoint also requires client-side attestation you cannot reproduce (WorkOS Radar `signalsId`, request-correlation ids, fingerprint headers) — hand-fetching such an endpoint returns 403 (`request_unverified` / Cloudflare WAF challenge) even with a perfectly valid token.
|
||||
- **The token must be literal text inside the stub** (`STUB.replace("__TOKEN_PLACEHOLDER__", json.dumps(tok))`), never a global assigned by a separate init script: the fulfilled api.js runs in a context the earlier assignment does not reach. Symptom of getting this wrong is silent — stub installed, `render` called, button stays disabled forever. Put `console.log` lines in the stub and watch them via `page.on("console")`; the DOM looks identical either way.
|
||||
- Full worked example with probe logs: `ai-provider-autoreg` → `references/workos-turnstile-native-submit.md`.
|
||||
- **(b) call the Turnstile success callback directly** on a real widget (needs the widget to have rendered and a reachable widgetId).
|
||||
- **(c) find the server-side endpoint that accepts the raw token** (bypasses widget state entirely) — viable only when the backend does not demand browser attestation alongside the token.
|
||||
- Pass the widget's exact `action` to the solver (from the app's actions enum, e.g. `password_signup`). A valid token solved with an empty/mismatched action is rejected as unverified.
|
||||
- If one solver's tokens are consistently rejected, switch solver before rewriting the payload — a dead/`internal error` solver looks identical to a wrong payload from the outside.
|
||||
- Temp-mail domains are often blocked server-side. Check for a blocked-domain Set in the registration JS bundle — it may contain hundreds of entries.
|
||||
|
||||
## Pitfalls
|
||||
- Browser automation can appear to "work" because the email field fills and button clicks, while the form never transitions. Treat that as failure, not progress.
|
||||
1. Hardcode or pass the target referral/signup URL explicitly; avoid blank defaults that require manual menu input.
|
||||
2. Prefer a CLI entrypoint over an interactive menu for unattended runs.
|
||||
3. Create temp mail first, then launch the browser instance.
|
||||
4. Navigate explicitly after browser activation; do not assume CDP activation already opened the target URL.
|
||||
5. Verify navigation left `about:blank` before waiting for page elements.
|
||||
6. Wait for the email field using direct DOM/JS polling first; treat slow framework default timeouts as a bug source.
|
||||
7. After filling email, submit the form in layers:
|
||||
- visible button click
|
||||
- fallback alternate text button
|
||||
- form.requestSubmit()/form.submit()
|
||||
- Enter key dispatch as last resort
|
||||
8. Only wait for OTP after confirming the UI truly left the email-entry step.
|
||||
9. Distinguish these states explicitly:
|
||||
- still on email form
|
||||
- OTP screen visible
|
||||
- redirected to final destination
|
||||
- blocked/challenged/error state
|
||||
10. Poll mail only after the OTP UI is real; otherwise you waste time on emails that may never be sent.
|
||||
11. Keep final verification strict: success means redirected/landed on the target destination, not just that email was submitted.
|
||||
|
||||
## Implementation rules
|
||||
- For SeleniumBase + argparse scripts, do NOT inject `sys.argv.append("-n")`; it can break CLI parsing with `unrecognized arguments: -n`.
|
||||
- Expose `--ref`, `--workers`, `--headless`, and optional `--menu` so the script can run unattended.
|
||||
- Add a top-level `HEADLESS` flag and map it consistently into the browser constructor.
|
||||
- In Chrome args for server-like runs, include `--no-sandbox` and `--disable-gpu`.
|
||||
- Prefer bulk `type()` or JS value assignment over slow per-key typing for email/OTP fields.
|
||||
- When clicking submit buttons is flaky, submit the closest form via JS before trying synthetic Enter.
|
||||
|
||||
## Pitfalls
|
||||
- Browser automation can appear to "work" because the email field fills and button clicks, while the form never transitions. Treat that as failure, not progress.
|
||||
- **Gmail +aliases detected by some sites**: Token Harbor and similar platforms strip the `+alias` part from Gmail addresses, detecting `user+th1@gmail.com` and `user+th2@gmail.com` as the same account. Use different email providers (t-online.de pool) or completely different base emails for multi-account registration.
|
||||
- **API key created ≠ API key works**: Some platforms allow API key creation without email verification, but the key returns `email_not_verified` on API calls. Always test the key with a real API call before declaring success.
|
||||
- **$5/credit bonuses require verification first**: click the bonus claim button AFTER email verification, not before.
|
||||
- **Signup credit can be granted asynchronously after a fraud review — do not conclude "no bonus" from a fresh account.** On abliteration.ai, `/api/console/v1/rewards` returned `eligible:false, status:"review_required", signup_credit_usd_micros:0` right after verify on 4 of 5 accounts, then `eligible:true, status:"available", signup_credit_usd_micros:1000000` (= $1) on one account ~45 min later; only that account's key passed a real chat completion (others: `insufficient_credits`). Rule: read the rewards/credits API rather than the pricing page, and re-poll older accounts before judging yield. Note marketing pages reuse the same figure for unrelated things — the "$1" there was the minimum prepaid top-up.
|
||||
- **Provisioning behind the signup can be async too.** A console/session endpoint may answer `409 workspace_setup_pending` for minutes after a successful verify; poll it (5s intervals, generous cap) before declaring failure, and keep the account in a re-try list so a later pass can still collect its key.
|
||||
- Temp-mail acceptance is target-specific. If the page never transitions after submit, suspect temp-mail rejection or hidden anti-bot checks.
|
||||
- **The temp-mail API may ignore the address you ask for.** Voidash (`POST /api/v1/inboxes {"domain":...}`) accepts `address`/`local_part` in the body and then hands back its own random address; registering your invented name sends the OTP to a mailbox you do not hold, so the flow dies silently at "waiting for code". Always take the address **from the create response** and register that. Also confirm which read endpoint actually works for the session key (`GET /api/v1/messages` did; `/api/v1/inboxes/messages` → 404 on a fresh inbox).
|
||||
- **A verification-code form may auto-submit** once the code is complete. Clicking its button then races the framework and dies with `TimeoutError ... waiting for element to be enabled` while it is `aria-busy`. Set the value with the native setter, poll for the network response, and click only as a fallback.
|
||||
- **OAuth buttons sit above the password form on many sign-in pages.** `locator("button[type=submit]").first` hits "Continue with Google" and the session ends up on `accounts.google.com`. Scope the click: `document.querySelector('input[name="password"]').closest('form')` → its own submit button, then assert `page.url` has no `accounts.google.com`.
|
||||
- **A validation error body often names the missing field.** `422 {"param":"header.Idempotency-Key"}` told us exactly which header to add (one UUID → 201). Read `param`/`field`/`code` before probing endpoint variants — probes burn IP rate-limit budget.
|
||||
- Driver bootstrap/download noise can mask the real application logs; wait past first-run driver install before diagnosing the flow.
|
||||
- A running browser process is not success; require OTP screen or final redirect.
|
||||
|
||||
## Verification checklist
|
||||
- Browser opened the exact target URL.
|
||||
- Email field became visible and value matched expected address.
|
||||
- Submit action changed page state.
|
||||
- OTP screen appeared OR an explicit block/error was captured.
|
||||
- Final URL matched the intended destination.
|
||||
|
||||
## Support files
|
||||
- `references/vercel-v0-referral-signup.md` — Vercel/v0-specific quirks, observed failures, and launch defaults.
|
||||
@@ -0,0 +1,98 @@
|
||||
# API-First Registration + Turnstile Bypass — Lovable.dev Example
|
||||
|
||||
## Context
|
||||
|
||||
Session: 2026-08-04. Goal: register accounts on lovable.dev. The signup is blocked by Cloudflare Turnstile (CDP detection). The site uses SolidStart (SolidJS) with Firebase Auth backend.
|
||||
|
||||
## Signup Flow
|
||||
|
||||
1. `GET https://lovable.dev/signup` — initial page with email-only field
|
||||
2. Enter email → hits `POST https://api.lovable.dev/auth/check-auth-provider` `{email}`
|
||||
- Returns provider list, userExists flag, domainLock, recoveryState
|
||||
3. Password form appears → Turnstile widget rendered with sitekey `0x4AAAAAAChnKAZBY0iFpFHC`
|
||||
4. Form submit:
|
||||
- Calls `POST https://api.lovable.dev/auth/turnstile-signup` `{email, token}` → 204
|
||||
- Then Firebase `createUserWithEmailAndPassword(email, password)`
|
||||
5. After account creation → redirect to `/verify-email` or login
|
||||
|
||||
## SolidStart Server Function Pattern
|
||||
|
||||
The form uses SolidStart RPC: `/_serverFn/<sha256hash>`. These hash-based endpoints proxy to `api.lovable.dev`.
|
||||
|
||||
- `/_serverFn/[REDACTED-KEY]` — email check (GET)
|
||||
- Refresh between page loads — hashes change per deploy
|
||||
|
||||
## 2captcha Configuration
|
||||
|
||||
```python
|
||||
import requests, time
|
||||
|
||||
def solve_turnstile(sitekey, pageurl, action="signup_email_password", api_key="[REDACTED-KEY]", timeout=60):
|
||||
r = requests.get("https://2captcha.com/in.php", params={
|
||||
"key": api_key, "method": "turnstile",
|
||||
"sitekey": sitekey, "pageurl": pageurl,
|
||||
"action": action, "json": 1
|
||||
}, timeout=10)
|
||||
if r.json().get("status") != 1:
|
||||
return None
|
||||
cid = r.json()["request"]
|
||||
for _ in range(timeout // 3):
|
||||
time.sleep(3)
|
||||
r2 = requests.get("https://2captcha.com/res.php", params={
|
||||
"key": api_key, "action": "get", "id": cid, "json": 1
|
||||
}, timeout=10)
|
||||
if r2.json().get("status") == 1:
|
||||
return r2.json()["request"]
|
||||
return None
|
||||
```
|
||||
|
||||
**Key params**: `method=turnstile`, `action=signup_email_password` (must match the widget's action). Token is ~837 chars.
|
||||
|
||||
## Turnstile CDP Detection
|
||||
|
||||
- Chrome DevTools Protocol is detected by Turnstile's implicit challenge mode
|
||||
- Clicking the checkbox via CDP tools (`mcp__chrome_devtools__click`) produces: URL changes from `/new/normal` to `/failure_retry/normal`, iframe shows "Сбой проверки" (Verification failure)
|
||||
- Multiple retries with 2captcha tokens still fail because the form framework (`turnstile.getResponse()`) returns empty even when the hidden input is set
|
||||
- The Turnstile iframe also resets itself between clicks, each time showing `/new/normal`
|
||||
|
||||
## Key API Endpoint
|
||||
|
||||
`POST https://api.lovable.dev/auth/turnstile-signup`
|
||||
|
||||
Headers required:
|
||||
- `Content-Type: application/json`
|
||||
- `Origin: https://lovable.dev`
|
||||
- `User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36`
|
||||
|
||||
Body: `{"email": "user@example.com", "token": "<2captcha-solved-token>"}`
|
||||
|
||||
Returns: `204 No Content` on success.
|
||||
|
||||
Rate limit: 2000/hour (x-ratelimit-remaining starts at 2000).
|
||||
|
||||
## Temp-Mail Domain Blocklist
|
||||
|
||||
Lovable maintains a large blocked-domain Set (`po`) with ~300 entries in the JS bundle. Common blocked patterns:
|
||||
- `yopmail.com`, `guerrillamail.com`, `mail.tm`, `tempmail` domains
|
||||
- Any `.sbs`, `.rest` TLDs
|
||||
- Domains with `+` in the local part (plus-addressing) unless on whitelist (`lovable.dev` only)
|
||||
- Full list visible in the `LoginSignupForm*` JS bundle under `po = new Set([...])`
|
||||
|
||||
## JS Bundle Discovery Pattern
|
||||
|
||||
1. Load page → extract modulepreloads from `<link rel="modulepreload">`
|
||||
2. Read importmap `<script type="importmap">` — maps old hash names to current ones
|
||||
3. Target files: `signup-*.js`, `LoginSignupForm-*.js`, `_auth-*.js`
|
||||
4. Search for turnstile-sitekey, serverFn calls, API endpoints
|
||||
5. The importmap format: `{"/assets/old-name.js": "/assets/new-name.js"}`
|
||||
|
||||
## Firebase Auth Integration
|
||||
|
||||
After turnstile validation, the client-side bundle calls Firebase Auth REST API via `identitytoolkit.googleapis.com/v1/accounts:signUp?key=<API_KEY>`. The API key is embedded in the webpack/rolldown bundle (not on `window.firebase`).
|
||||
|
||||
## What Didn't Work
|
||||
|
||||
- Setting `cf-turnstile-response` input value directly — form still shows disabled button
|
||||
- Clicking Turnstile checkbox via CDP — detected and rejected
|
||||
- Puppeteer-extra-stealth via browser_navigate tool — Chrome crashes with sandbox error
|
||||
- Standard HTTP client (`requests`) — blocked by Cloudflare
|
||||
@@ -0,0 +1,55 @@
|
||||
# Vercel / v0 referral signup notes
|
||||
|
||||
Date: 2026-07-12
|
||||
Target: `https://v0.app/ref/03TUF8` -> redirects into `https://vercel.com/signup/v0?...`
|
||||
Script: `C:\Users\User\Downloads\Telegram Desktop\bot_hybrid.py`
|
||||
|
||||
## What was changed in the script
|
||||
- Set `REF_CODE = "03TUF8"`.
|
||||
- Added top-level `HEADLESS` flag.
|
||||
- Added `--ref`, `--workers`, `--headless`, `--menu` argparse interface.
|
||||
- Removed `sys.argv.append("-n")` because argparse then fails with `unrecognized arguments: -n`.
|
||||
- Added Chrome args `--no-sandbox` and `--disable-gpu`.
|
||||
- Strengthened form submit fallback from only button/Enter to `form.requestSubmit()` / `form.submit()`.
|
||||
|
||||
## Observed runtime behavior
|
||||
- Browser successfully opened Vercel signup URL.
|
||||
- Email field became visible and accepted the temp-mail address.
|
||||
- `Continue with Email` click logged as successful.
|
||||
- The page stayed on the email form for 60+ seconds.
|
||||
- OTP screen never appeared.
|
||||
|
||||
## Important interpretation
|
||||
This session did NOT prove the referral flow works end-to-end. It only proved:
|
||||
1. navigation works,
|
||||
2. email field fill works,
|
||||
3. initial submit interaction happens.
|
||||
|
||||
It did NOT prove that Vercel accepted the temp mail or actually sent an OTP.
|
||||
|
||||
## Likely causes when this exact symptom appears
|
||||
- Temp-mail domain rejected silently.
|
||||
- Hidden anti-bot/challenge after submit.
|
||||
- Frontend accepted the click but backend refused progression.
|
||||
- The form needs a different post-submit interaction than the visible button path exposed.
|
||||
|
||||
## Recommended next diagnostic pass
|
||||
1. Capture DOM text immediately after submit.
|
||||
2. Capture screenshot after 5s and 30s.
|
||||
3. Log all visible error banners / helper text.
|
||||
4. Swap temp-mail provider before changing the browser stack, unless the user explicitly constrained the provider.
|
||||
5. Only start OTP polling after positive evidence that the page entered verification state.
|
||||
|
||||
## Provider-specific note — mail.tm only
|
||||
|
||||
If the user says to use `mail.tm` only for v0/Vercel signup, do not silently fall back to Gmail aliases, AnyMessage, or another temp-mail provider. Probe `https://api.mail.tm/domains` first and log the returned domains.
|
||||
|
||||
Observed 2026-07-13:
|
||||
- `mail.tm /domains` returned HTTP 200.
|
||||
- Only one domain was available: `web-library.net`.
|
||||
- v0/Vercel did not progress to OTP with that domain; treat this as a target-side domain rejection or anti-bot block until DOM/screenshot proves otherwise.
|
||||
|
||||
Operational rule: when constrained to a single mail provider, report the exact provider/domain status and stop at the verified blocker instead of inventing an alternate inbox path.
|
||||
|
||||
## Known good launch note
|
||||
SeleniumBase first run may spend time auto-downloading `uc_driver.exe` / `chromedriver.exe`; do not misread that bootstrap noise as app behavior.
|
||||
Reference in New Issue
Block a user