Files
autoreg-skills-max/skills/github-autoreg/references/otp-and-provisioning.md

145 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OTP Entry & Post-Registration Provisioning
## OTP Entry: Multi-Strategy with Fallback
GitHub's verification page has changed over time. The current flow (2026-08-10) uses a **single numeric input**, NOT the old `launch_code[]` digit boxes. Use 3 strategies in order:
### Strategy 1: launch_code[] digit boxes (LEGACY — GitHub pre-2026-08)
```html
<input name="launch_code[]" type="number" maxlength="1"> × 8
```
If found (8 boxes), fill each individually and submit the form.
### Strategy 2: Single numeric input (CURRENT — works 2026-08-10)
```javascript
var e = document.querySelector('input[inputmode="numeric"]') ||
document.querySelector('input[aria-label*="code" i]') ||
document.querySelector('input[aria-label*="verif" i]') ||
document.querySelector('input[type="text"]:not([name="login"]):not([name="password"])');
e.value = code;
e.dispatchEvent(new Event('input', {bubbles: true}));
e.dispatchEvent(new Event('change', {bubbles: true}));
// Submit: form.requestSubmit() or click button[type="submit"]
```
### Strategy 3: Brute force (last resort)
Type code into ANY visible input and click any button matching verify/continue/submit/confirm.
### Wait for input to appear
The verification page may render inputs dynamically. Wait up to 10s:
```python
for _ in range(20):
any_input = document.querySelectorAll('input:not([type="hidden"]):not([type="submit"])').length
if any_input > 0: break
time.sleep(0.5)
```
## Post-OTP Result Detection
After OTP submission, GitHub can redirect to **multiple states**. Use **BOTH path and full URL** for matching:
| URL Pattern | Path | Meaning | Action |
|-------------|------|---------|--------|
| `/dashboard`, `/welcome`, `/` | match | Account created + auto-logged-in | Extract session cookies |
| `/login?return_to=...account_verifications` | `/login` | Still on verification page (OTP pending/failed) | Check for error messages after 10s |
| `/login` with flash "account was created successfully" | `/login` | Account created, needs login | Do post-signup login |
| `/login` without flash | `/login` | Registration failed or redirected | Abort |
**Critical: `/login?return_to=.../account_verifications` is the verification page.** The path is `/login`, but the full URL contains `account_verif`. Check BOTH:
```python
path = urlparse(url).path.rstrip("/")
url_lower = url.lower()
# still_on_verify: check BOTH path and full URL
still_on_verify = ("account_verif" in path and "launch" not in path) or \
("account_verif" in url_lower and "launch" not in url_lower)
```
**Time-limit the still_on_verify check:** in the post-OTP loop, only skip for first 10s of the 30s window. After that, evaluate other signals (has_session, dashboard, login, code error):
```python
deadline = time.time() + 30
while time.time() < deadline:
# ... get URL, path, cookies ...
if still_on_verify and time.time() < deadline - 20: # first 10s only
time.sleep(1)
continue
# ... check other signals ...
```
## Post-Signup Login
If GitHub shows "Your account was created successfully! Please sign in to continue":
1. Navigate to `https://github.com/login`
2. Fill `#login_field` (email) and `#password` (password)
3. Click submit button
4. Navigate to `https://github.com/settings/profile` to verify authenticated
5. Extract `user_session` cookie
## Session Verification
```python
page.goto("https://github.com/settings/profile")
# If redirected to /login → NOT authenticated
# If stays on /settings/profile → AUTHENTICATED
```
## 2FA + PAT via provision.py
After registration, use the `provision.py` from `авторег проект/backend/platforms/github/provision.py` for post-processing.
**WARNING: HTTP provisioning is rate-limited on the same IP.** If the browser registration used the local IP, the HTTP `requests`-based login to the fresh account triggers "login failed: rate". To avoid this:
- Use the SAME proxy for provisioning as registration, OR
- Extract cookies from the browser session and inject them into `requests.Session`, OR
- Do 2FA + PAT through the browser (CDP) instead of HTTP
### enable_2fa(email, password) → {totp_secret, recovery_codes}
Pure HTTP (requests + pyotp), no browser needed. Flow:
1. GET `/login` → extract CSRF
2. POST `/session` → authenticate
3. GET `/settings/two_factor_authentication/setup/intro` → extract scoped CSRF
4. POST `/settings/two_factor_authentication/setup/initiate` (type=app) → get secret + recovery codes
5. POST `/settings/two_factor_authentication/setup/verify` (type=app, otp=TOTP)
6. POST `/settings/two_factor_authentication/setup/enable`
### generate_token(email, password, totp_secret, scopes) → ghp_/github_pat_...
Creates a classic PAT. Flow:
1. Login with 2FA
2. Handle sudo re-auth if needed
3. GET `/settings/tokens/new` → extract CSRF
4. POST `/settings/tokens` with scopes
5. Extract `ghp_` or `github_pat_` from response
## Rate Limiting
GitHub applies a **secondary rate limit** after 2-3 fast signups. Symptoms:
- Form fields not found (all `querySelector` return null — `{"email":false,"password":false,"login":false}`)
- Page stays on `/signup` after submit
- HTTP login returns "login failed: rate"
**Mitigation:**
- Wait 10-15 minutes between batches
- Use proxy rotation (SOCKS5 from residential pool)
- Rate limit on same IP persists **1+ hour** — 15-minute wait is insufficient
- HTTP provisioning (requests) hits the SAME rate limit as browser — use same proxy or browser cookies
## Verified
- **2026-08-10**: `launch_code[]` boxes NO LONGER present on GitHub verification page. Single `input[inputmode="numeric"]` strategy works (S2).
- **2026-08-10**: Multi-strategy OTP entry (S1→S2→S3) with explicit logging confirmed working
- **2026-08-10**: Post-OTP `still_on_verify` check must be time-limited (10s max) — otherwise catches `/login?return_to=...account_verifications` indefinitely
- **2026-08-10**: Both path AND full URL needed for verification page detection (path alone misses `/login?return_to=...account_verifications`)
- **2026-08-10**: HTTP provisioning rate-limited on local IP (`login failed: rate`). Must use same proxy as browser or inject browser cookies.
- provision.py verified working (2026-08-06, from `авторег проект` backend)