autoreg-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
# gh-regkit-prime: Camoufox multi-stage GitHub runner — pitfalls & ops
|
||||
|
||||
Stack: Camoufox (Firefox anti-detect) + mail.cx (mailcx provider) + multi-stage runner
|
||||
(reg → email verify → auto-login → repo → 2FA TOTP → PAT → profile). Project:
|
||||
`Desktop/_PROJECTS/gh-regkit-prime`, repo `gbonnet65923/gh-regkit-prime`.
|
||||
Account line format: `email----password----username----totp_secret----has_recovery----pat`.
|
||||
|
||||
## Batch operations (CRITICAL)
|
||||
|
||||
- NEVER run two registration batches concurrently — they share the exit IP, GitHub
|
||||
DataDome bans it fast and accounts come out `suspended`. Before launching, enumerate
|
||||
and kill leftovers.
|
||||
- Filter processes by `main.py` substring ONLY, not by project path — the CommandLine
|
||||
of a batch started with a relative path (`cd project && python main.py`) does not
|
||||
contain the project directory, so a `path in CommandLine` filter silently misses it
|
||||
and duplicate batches keep running.
|
||||
- Enumerate/kill on Windows (wmic is unreliable here):
|
||||
`powershell Get-CimInstance Win32_Process -Filter "Name='python.exe'" | ConvertTo-Json`,
|
||||
parse JSON in Python, `taskkill /F /T /PID`.
|
||||
- Run batches with `background=true` + heartbeat; report OK/FAIL from the heartbeat log,
|
||||
verify saves by `wc -l accounts/github_accounts_*.txt` (a successful log line without
|
||||
a saved row means the crash happened before persistence — see salvage below).
|
||||
|
||||
## Signup form
|
||||
|
||||
- mail.cx issues short local-parts (4 chars) → derived usernames collide constantly.
|
||||
Pad any local-part shorter than ~10 chars with random alnum BEFORE the first attempt.
|
||||
- "Create account stayed disabled after validation wait" is AMBIGUOUS: it can mean
|
||||
octocaptcha pending OR username taken (a taken name keeps the button disabled
|
||||
forever). Probe the username-error element first and raise a distinct
|
||||
"username taken" error → caller retries with a fresh random suffix in-place.
|
||||
Treating it as transient and reloading the page WITH THE SAME DATA burns all
|
||||
page-reload attempts for nothing.
|
||||
|
||||
## 2FA (TOTP) stage
|
||||
|
||||
- The wizard keeps hidden twin otp inputs in the DOM; `locator(...).first` resolves to
|
||||
an INVISIBLE one and `fill()` hangs "element is not visible" until timeout → stage
|
||||
fails. Iterate candidates checking `is_visible() and is_editable()`; last-resort
|
||||
fill via JS `el.value=code` + dispatch `input`/`change` on the `offsetParent!==null`
|
||||
element.
|
||||
- TOTP secret is frequently absent from innerText (dialog closed / rendered as QR).
|
||||
Parse it from `page.content()`: look for `otpauth://totp/...secret=[REDACTED] in BOTH
|
||||
percent-encoded (`secret%3D`) and plain form, then fall back to a bare
|
||||
`[A-Z2-7]{16,32}` scan.
|
||||
- Recovery codes: scrape from the DOM first. SKIP the file download entirely when the
|
||||
DOM scrape succeeded — Firefox/Camoufox download handling intermittently hangs the
|
||||
whole 2FA wizard (user-visible symptom: hang at the backup-download step).
|
||||
- GitHub regenerates the TOTP secret on every load of the setup page — read the secret
|
||||
only from the page you actually submit the code on.
|
||||
|
||||
## PAT stage
|
||||
|
||||
- The `ghp_...` token often lives in HTML attributes (`<code>`, clipboard-value), not
|
||||
in innerText. Search `_page_text(page)` first, then `page.content()`, then wait ~5s
|
||||
and retry both — a single innerText search reports "token not found" on success.
|
||||
- Any helper called from the PAT function needs its own local import (`import re as _re`
|
||||
inside the function) — module-level `re` may not be imported in this codebase shape;
|
||||
a NameError here kills the stage after the token was already generated.
|
||||
|
||||
## Crash salvage (account-saving checkpoint)
|
||||
|
||||
- The browser/driver can crash ("Connection closed while reading from the driver",
|
||||
WebGL out-of-memory) AFTER the account is verified and logged in. If credentials are
|
||||
only persisted at the very end, the account is lost. Set a checkpoint dict
|
||||
(`pending["active"]=True`, `pending["username"]`, email) at the start of the finalize
|
||||
stage, and in the outer exception handler salvage a record line from it when the
|
||||
checkpoint is set. Thread the `pending` dict through the post-form flow function.
|
||||
|
||||
## Proxies / DataDome
|
||||
|
||||
- Free HTTP pool (~125 live) gives roughly 30-60% yield; failures are DataDome
|
||||
challenge pages and dead-proxy connect timeouts. When the home IP itself gets
|
||||
DataDome-banned ("email form did not appear (DataDome challenge page); IP is
|
||||
blocked"), only IP rotation helps — residential proxies.
|
||||
- 1024proxy.com residential: the marketing/pricing site is Cloudflare-blocked from a
|
||||
banned/flagged home IP — open it through Camoufox routed via one of the free pool
|
||||
proxies to read prices. Wallet balance alone does NOT enable the gateways: the white
|
||||
API (`white.1024proxy.com/white/api?region=US&num=N&time=M&format=0&type=json`,
|
||||
cookie `zero_sid` auth, navigate not fetch — CORS) returns "Insufficient traffic"
|
||||
until a traffic package is purchased; gateways answer raw CONNECT with 407.
|
||||
Purchase only via the dashboard UI (Buy button); raw api.1024proxy.com calls from
|
||||
Python return "re-login" errors — they need the browser session context.
|
||||
|
||||
## Config knobs that silently disable stages
|
||||
|
||||
- `create_repo`, `set_profile_status`, `complete_profile` can be False in config.json
|
||||
even when the dataclass defaults are True — a warmed-up account (profile + first
|
||||
repo) requires flipping them explicitly in config.json AND restarting the batch (a
|
||||
running process holds the old code/config in memory).
|
||||
Reference in New Issue
Block a user