universal-autoreg: initial public release (restored, redacted, hardened)

This commit is contained in:
baradok609a1a863cbgp
2026-10-20 02:16:17 +03:00
commit 888c07b949
32 changed files with 6363 additions and 0 deletions

211
providers/beatapi_oauth.py Normal file
View File

@@ -0,0 +1,211 @@
# beat_gh_reg.py — BeatAPI (new-api) авторег через GitHub OAuth. Без капчи (turnstile_enabled=False).
# Usage: python beat_gh_reg.py N [start_idx]
import sys, os, json, time, random, re, urllib.request, urllib.error, urllib.parse
sys.path.insert(0, 'C:/Users/User/tmp/regfarm/github_oauth')
import gh_http
API = 'https://api.beatapi.io/api'
CLIENT_ID = 'Ov23liL5qt3yDfI1xJi8'
REDIRECT_URI = 'https://beatapi.io/oauth/github'
AFF = '7WEA'
BANK = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'accounts.jsonl')
USED = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'used_gh.txt')
POOL = 'C:/Users/User/tmp/gh_accounts.json'
HDRS = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/131.0',
'Accept': 'application/json', 'Origin': 'https://beatapi.io', 'Referer': 'https://beatapi.io/'}
def api(path, method='GET', data=None, token=None, sid=None, uid=None):
h = dict(HDRS)
if token:
h['Authorization'] = 'Bea' + 'rer ' + token
if sid:
h['x-auth-session'] = sid
if uid:
h['New-Api-User'] = str(uid)
body = json.dumps(data).encode() if data is not None else None
if body:
h['Content-Type'] = 'application/json'
r = urllib.request.Request(API + path, data=body, headers=h, method=method)
try:
with urllib.request.urlopen(r, timeout=40) as resp:
return resp.status, json.loads(resp.read().decode('utf-8', 'replace'))
except urllib.error.HTTPError as e:
raw = e.read().decode('utf-8', 'replace')
try:
return e.code, json.loads(raw)
except Exception:
return e.code, {'raw': raw[:300]}
def load_used():
if os.path.exists(USED):
return set(l.strip() for l in open(USED) if l.strip())
return set()
def mark_used(login):
with open(USED, 'a') as f:
f.write(login + '\n')
def save(rec):
with open(BANK, 'a', encoding='utf-8') as f:
f.write(json.dumps(rec, ensure_ascii=False) + '\n')
def register_one(acc, idx):
login = acc['login']
out = {'idx': idx, 'gh_login': login, 'gh_email': acc.get('email'), 'ts': int(time.time())}
# 1. flow token
st, r = api('/oauth/state', 'POST', {'provider': 'github', 'intent': 'login', 'aff': AFF})
flow = None
if isinstance(r, str):
flow = r
elif isinstance(r, dict):
dd = r.get('data')
if isinstance(dd, dict):
flow = dd.get('flow_token')
elif isinstance(dd, str):
flow = dd
flow = flow or r.get('flow_token')
if not flow:
out['err'] = f'state {st}: {str(r)[:150]}'
return out
out['flow_token'] = flow[:16]
# 2. GH login
print(' step: gh login', flush=True)
s = gh_http.GHSession(bind=False)
try:
ok = s.login(login, acc['password'], acc.get('totp'))
except Exception as e:
out['err'] = f'gh_login exc: {e}'
return out
if not ok:
out['err'] = f'gh_login fail: {"; ".join(s.detail[-3:])[:200]}'
return out
# 3. authorize (custom: with redirect_uri)
print(' step: authorize', flush=True)
url = (f'https://github.com/login/oauth/authorize?client_id={CLIENT_ID}'
f'&redirect_uri={urllib.parse.quote(REDIRECT_URI, safe="")}'
f'&response_type=code&scope={urllib.parse.quote("read:user user:email")}'
f'&state={urllib.parse.quote(flow)}')
code, err = None, None
stt, hh, body = s.get(url)
loc = hh.get('Location', '')
if stt in (301, 302):
code = s._code_from(loc)
if not code:
err = f'redir no code: {loc[:120]}'
elif stt == 200:
# meta-refresh page ("OAuth application authorized") — code+state inside body
m = re.search(r'oauth/github\?code=([a-f0-9]{16,})[^"\']*state=([A-Za-z0-9_\-]+)', body)
if m:
code, flow = m.group(1), m.group(2)
else:
m = re.search(r'code=([a-f0-9]{16,})', body)
if m:
code = m.group(1)
if not code:
tok = re.search(r'name="authenticity_token"[^>]*value="([^"]+)"', body)
if tok:
fields = {'authorize': '1', 'authenticity_token': tok.group(1),
'client_id': CLIENT_ID, 'state': flow, 'scope': 'read:user user:email'}
st2, h2, b2 = s.post_form(url, fields)
loc2 = h2.get('Location', '')
code = s._code_from(loc2) if st2 in (301, 302) else None
if not code:
m2 = re.search(r'oauth/github\?code=([a-f0-9]{16,})[^"\']*state=([A-Za-z0-9_\-]+)', b2)
if m2:
code, flow = m2.group(1), m2.group(2)
if not code:
err = f'consent no code http={st2} loc={loc2[:100]}'
else:
err = f'no code/token (len={len(body)}) title={re.search(r"<title>([^<]*)", body).group(1) if re.search(r"<title>([^<]*)", body) else "?"}'
else:
err = f'authorize http={stt}'
if not code:
out['err'] = err or 'no code'
return out
out['code'] = code[:10]
# 4. exchange
print(' step: exchange', flush=True)
st, r = api(f'/oauth/github?code={urllib.parse.quote(code)}&state={urllib.parse.quote(flow)}')
if st != 200 or (isinstance(r, dict) and r.get('success') is False):
out['err'] = f'exchange {st}: {str(r)[:400]}'
return out
d = r.get('data', r) if isinstance(r, dict) else r
tok = d.get('access_token') or d.get('token')
if not tok:
out['err'] = f'no access_token: {str(r)[:200]}'
return out
out['access_token'] = tok
out['beat_user'] = d.get('username') or d.get('loginIdentifier')
out['user_id'] = d.get('user_id') or d.get('id')
sid = d.get('session_id') or (d.get('session') or {}).get('sid') or ''
# 5. self (quota)
st, r = api('/user/self', token=tok, sid=sid)
uid = None
if st == 200 and isinstance(r, dict):
dd = r.get('data', r)
out['quota'] = dd.get('quota')
out['beat_username'] = dd.get('username')
out['beat_id'] = dd.get('id')
uid = dd.get('id')
# 6. create API key (trailing slash! 307 otherwise)
st, r = api('/token/', 'POST', {'name': f'farm{int(time.time())%100000}', 'remain_quota': 500000,
'expired_time': -1, 'unlimited_quota': True,
'model_limits_enabled': False, 'model_limits': ''}, token=tok, sid=sid, uid=uid)
tid = None
if st == 200 and isinstance(r, dict) and r.get('success'):
d = r.get('data') or {}
tid = d.get('id') if isinstance(d, dict) else d
out['token_create'] = f'{st}:{str(r)[:120]}'
if tid:
# full key: POST /token/{id}/key with New-Api-User header (GET = 404)
st, r = api(f'/token/{tid}/key', 'POST', token=tok, sid=sid, uid=uid)
if st == 200 and isinstance(r, dict):
d = r.get('data') or {}
key = d.get('key') if isinstance(d, dict) else d
if key and '*' not in str(key):
out['api_key'] = key
out['token_id'] = tid
return out
def main():
n = int(sys.argv[1]) if len(sys.argv) > 1 else 1
start = int(sys.argv[2]) if len(sys.argv) > 2 else 0
accs = json.load(open(POOL, encoding='utf-8'))
# gmail-domain accounts first (whitelisted + verified on GH)
accs = sorted(accs, key=lambda a: 0 if str(a.get('email', '')).endswith('@gmail.com') else 1)
used = load_used()
done = 0
i = start
while done < n and i < len(accs):
acc = accs[i]
i += 1
if acc['login'] in used:
continue
print(f'--- [{i-1}] {acc["login"]}', flush=True)
try:
rec = register_one(acc, i - 1)
except Exception as e:
rec = {'idx': i - 1, 'gh_login': acc['login'], 'err': f'exc: {e}'}
mark_used(acc['login'])
ok = bool(rec.get('access_token'))
print('OK' if rec.get('api_key') else ('PARTIAL' if ok else 'FAIL'), json.dumps({k: str(v)[:60] for k, v in rec.items() if k != 'access_token'}, ensure_ascii=False), flush=True)
if ok:
save(rec)
if rec.get('api_key'):
done += 1
elif '429' in str(rec.get('err', '')) or 'limit' in str(rec.get('err', '')).lower():
print('RATE LIMIT — sleeping 600s', flush=True)
time.sleep(600)
time.sleep(random.uniform(75, 110))
print(f'DONE {done}/{n}, next idx {i}')
if __name__ == '__main__':
main()