Files
autoreg-skills-max/skills/ai-provider-autoreg/references/provider-auth-recon.md

109 lines
8.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.

# Provider Auth Recon — Before Building Autoreg
## Rule
**Probe auth mechanism FIRST** — before writing a single line of registration code. Many providers look like email signup in marketing copy but actually require Web3 wallets, Google-only login, or invite codes. A `curl` recon costs 30 seconds; a full Playwright probe costs 2-3 minutes. Both are cheaper than building autoreg for the wrong auth type.
## Fast HTTP probe (10-30s, no browser)
```bash
# NextAuth-based providers (common for AI gateways)
curl -s "https://<host>/api/auth/providers" | jq 'keys'
# Returns provider IDs: google, email, github, credentials, tronlink, bybit...
# If you see ONLY wallet providers (tronlink/bybit/okx/binance) → STOP, autoreg impossible
# If 'email' is present → probe /api/auth/signin/email for 302 vs form
# Check if email endpoint returns actual form or just redirect
curl -s -w '\n%{http_code}' "https://<host>/api/auth/signin/email" -A "Mozilla/5.0"
# 200+form → email magic code works; 302 → redirects elsewhere, email not available
# Check invite-code endpoint (B.AI pattern)
curl -s "https://api.b.ai/api/activity/campaigns/<campaign>/codes/<CODE>/validate"
```
## Playwright headless probe (1-3 min, full form analysis)
```python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
br = p.chromium.launch(headless=True)
ctx = br.new_context(ua="Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/126.0")
pg = ctx.new_page()
reqs = []
pg.on("request", lambda r: reqs.append(r.url[:200]) if any(k in r.url for k in ["auth","clerk","sign","api"]) else None)
pg.goto("https://<target>/login", timeout=60000)
pg.wait_for_timeout(5000)
# Dump ALL inputs (type + name + placeholder) — reveals hidden Turnstile/csrf
inputs = pg.eval_on_selector_all(
"input",
"els => els.map(e => ({type:e.type, name:e.name, ph:e.placeholder}))"
)
# Dump ALL buttons
btns = pg.eval_on_selector_all(
"button",
"els => [...new Set(els.map(e=>e.innerText.trim()).filter(t=>t))]"
)
print("INPUTS:", inputs)
print("BUTTONS:", btns)
print("AUTH REQUESTS:", [u for u in set(reqs)])
```
## Classify Auth Type
| Signal | Auth Type | Autoreg Feasibility |
|--------|-----------|---------------------|
| `type=email, name=email` + hidden `cf-turnstile-response` | Email OTP + Turnstile | Yes (YesCaptcha) |
| `name=password` + email input | Email + password | Yes (no captcha = easy) |
| Clerk `pk_live_*` in JS + sign-up page with email | Clerk email code | Yes (max 1 per IP before rate-limit) |
| `pk_live_*` + Turnstile iframe | Clerk + Turnstile | Yes if residential proxy |
| Google-only button, no email input | Google OAuth only | No (needs real Google accounts) |
| GitHub-only button, no email | GitHub OAuth only | Yes if GH account pool exists |
| TronLink/Bybit/OKX/Binance in `/api/auth/providers` | Web3 wallet only | No (needs wallet + signature) |
| No inputs, just "Log in" button → modal | Clerk modal (lazy load) | Probe with eval: `window.Clerk?.publishableKey` |
| `/api/v1/settings/public`: `registration_enabled=false` + `linuxdo_oauth_enabled=true` | LINUX DO Connect only | No (linux.do invite-only; needs owner's LDC account) |
## Clerk-specific recon
```python
# Extract publishable key at runtime
pk = pg.evaluate("""
const clerk = window.Clerk;
if (clerk) return clerk.publishableKey;
for (const k of Object.getOwnPropertyNames(window)) {
const v = window[k];
if (typeof v === 'object' && v?.publishableKey) return v.publishableKey;
}
return null;
""")
```
## Pitfalls
- **Overlay intercepts click** — Next.js modals/popups catch pointer events over login buttons. Use `pg.evaluate("() => btn.click()")` (JS click) instead of Playwright `.click()` (coordinates).
- **`/api/auth/providers` returns only Web3 wallets** — email login might still exist via Clerk (separate frontend). Probe the rendered page with Playwright, not just the API.
- **Login page shows Email/Google buttons but neither works** — some sites (Grokified) show "Email me a code" as a Next.js Server Action, not a REST endpoint. The form contains `$ACTION_ID_*` hidden inputs. This is still automatable via browser fill.
- **Clerk pk never appears in HTML source** — it's injected at runtime. Use browser eval, not grep.
- **Headless Chromium blocks Clerk modals** — Clerk uses iframes with X-Frame-Options; in headless mode the modal may silently fail to load. Probe inputs BEFORE clicking login — the email field may already be on the page.
- **Registration success ≠ usable artifact** — some providers complete signup + email verification but disable API-key creation on the Free plan (key button disabled, no issuance endpoint; e.g. Mistral console). Walk ONE throwaway account all the way to key creation BEFORE building an autoreg flow; if key issuance is plan-gated, the provider is unfarmable no matter how easy signup is.
- **OAuth walls across MULTIPLE unrelated providers from the same environment = suspect exit-IP/account flag, not the providers** — symptoms: magic-link/IdP token errors (stytch-style), `OAuthCallbackError`, GitHub «cannot authorize a third party application» on pool accounts. Test one flow from a clean residential IP with an aged account before declaring each provider unfarmable or building per-provider workarounds.
- **Phone-gated and DNS-blocked providers: skip fast** — +86-only phone verification (SiliconFlow-class) and unresolvable domains from the current network are instant skips; do not burn browser sessions on them.
## Panel-stack recon: «AI API Gateway» Vue SPA (не new-api)
Часть relay/公益-панелей — Vue SPA с титулом `<name> - AI API Gateway` и API под `/api/v1`. Эвристика стека: new-api `GET /api/status` → 404, но `GET /api/v1/auth/me` → 401 JSON `{"code":"UNAUTHORIZED"}`.
**Fast feasibility probe (без браузера, решает всё):**
```bash
curl -s https://<host>/api/v1/settings/public
```
В `data` лежат: `registration_enabled` (false = email-рег закрыта), `email_verify_enabled`, `registration_email_suffix_whitelist` (какие почтовые домены вообще принимает), `invitation_code_enabled`, `turnstile_enabled`/`aliyun_captcha_enabled`/`tencent_captcha_enabled`, все OAuth-флаги (`linuxdo_oauth_enabled`, `github/google/wechat/dingtalk/oidc_oauth_enabled`), `payment_enabled`, `affiliate_enabled`, `version`.
Reg-эндпоинты стека: `POST /api/v1/auth/send-verify-code` `{email, purpose:"register"}` и `POST /api/v1/auth/register`. При закрытой регистрации оба отдают явный `403 {"reason":"REGISTRATION_DISABLED"}` — окончательный вердикт без единого браузерного запуска. `POST /api/v1/auth/validate-invitation-code` `{code}` отвечает `valid:false / INVITATION_CODE_NOT_FOUND` — брутфорс инвайтов не окупается.
**Добыча эндпоинтов, когда пути неизвестны:** скачать главный бандл (`grep -o 'src="/assets/[^"]*"' index.html`), из JS вытянуть пути регексом `["'`](/auth/[a-z0-9/_-]+)["'`]`; имя settings-эндпоинта найти grep'ом `.get("` рядом со словами `settings`/`config`. В бандле же зашит дефолтный объект конфига — его поля = ключи `/settings/public`.
**LINUX DO Connect-only панели** (`registration_enabled=false` + `linuxdo_oauth_enabled=true`; кейс mazal.lol — 公益-пул free-ChatGPT акков, $0.5 на баланс, rate 0.001): единственный вход = аккаунт linux.do. linux.do сам по себе invite-only и за Cloudflare-челленджем с резидентных IP, массово фармить LDC-акки нереально. Вердикт «нефармируемо», если только у Влада нет личного linux.do аккаунта — тогда он логинится сам и передаёт post-OAuth cookie `_t` с домена панели, дальше ключ забирается по API. Не жечь время на браузерные обходы OAuth-стены.