fix: close stale oauth tabs before recovery
This commit is contained in:
@@ -50,6 +50,29 @@ def cdp(js, match='auth.openai.com', timeout=45):
|
||||
p = subprocess.run(['bash', '-lc', f"CDP_MATCH='{match}' python3 /tmp/cdp_async_eval.py"], input=js, text=True, capture_output=True, timeout=timeout)
|
||||
return (p.stdout or '') + (p.stderr or '')
|
||||
|
||||
def close_stale_oauth_tabs(reason='recover'):
|
||||
# Avoid tab pile-up and CDP target ambiguity before starting a fresh OAuth/add-phone recovery.
|
||||
try:
|
||||
tabs = json.loads(urllib.request.urlopen('http://127.0.0.1:9223/json/list', timeout=5).read().decode())
|
||||
except Exception as e:
|
||||
emit(phase='close_stale_oauth_tabs_failed', reason=reason, error=str(e))
|
||||
return 0
|
||||
patterns = ('auth.openai.com', 'chatgpt.com/auth', 'localhost', '127.0.0.1')
|
||||
closed = 0
|
||||
for t in tabs:
|
||||
url = t.get('url', '')
|
||||
tid = t.get('id')
|
||||
if tid and any(x in url for x in patterns):
|
||||
try:
|
||||
urllib.request.urlopen('http://127.0.0.1:9223/json/close/' + urllib.parse.quote(tid, safe=''), timeout=3).read()
|
||||
closed += 1
|
||||
time.sleep(0.05)
|
||||
except Exception:
|
||||
pass
|
||||
if closed:
|
||||
emit(phase='close_stale_oauth_tabs', reason=reason, closed_count=closed)
|
||||
return closed
|
||||
|
||||
def current_state():
|
||||
return cdp("""
|
||||
return {url: location.href, title: document.title,
|
||||
@@ -64,6 +87,7 @@ def restore_add_phone():
|
||||
if 'auth.openai.com/add-phone' in st:
|
||||
return True
|
||||
# Generate fresh OAuth URL and login with existing account. This account is already email-verified.
|
||||
close_stale_oauth_tabs('before_oauth_recover')
|
||||
raw = get('CODEX2API_URL')
|
||||
u = urllib.parse.urlsplit(raw)
|
||||
origin = f'{u.scheme}://{u.netloc}' if u.scheme and u.netloc else raw.rstrip('/')
|
||||
|
||||
@@ -50,6 +50,29 @@ def cdp(js, match='auth.openai.com', timeout=45):
|
||||
p = subprocess.run(['bash', '-lc', f"CDP_MATCH='{match}' python3 /tmp/cdp_async_eval.py"], input=js, text=True, capture_output=True, timeout=timeout)
|
||||
return (p.stdout or '') + (p.stderr or '')
|
||||
|
||||
def close_stale_oauth_tabs(reason='recover'):
|
||||
# Avoid tab pile-up and CDP target ambiguity before starting a fresh OAuth/add-phone recovery.
|
||||
try:
|
||||
tabs = json.loads(urllib.request.urlopen('http://127.0.0.1:9223/json/list', timeout=5).read().decode())
|
||||
except Exception as e:
|
||||
emit(phase='close_stale_oauth_tabs_failed', reason=reason, error=str(e))
|
||||
return 0
|
||||
patterns = ('auth.openai.com', 'chatgpt.com/auth', 'localhost', '127.0.0.1')
|
||||
closed = 0
|
||||
for t in tabs:
|
||||
url = t.get('url', '')
|
||||
tid = t.get('id')
|
||||
if tid and any(x in url for x in patterns):
|
||||
try:
|
||||
urllib.request.urlopen('http://127.0.0.1:9223/json/close/' + urllib.parse.quote(tid, safe=''), timeout=3).read()
|
||||
closed += 1
|
||||
time.sleep(0.05)
|
||||
except Exception:
|
||||
pass
|
||||
if closed:
|
||||
emit(phase='close_stale_oauth_tabs', reason=reason, closed_count=closed)
|
||||
return closed
|
||||
|
||||
def current_state():
|
||||
return cdp("""
|
||||
return {url: location.href, title: document.title,
|
||||
@@ -64,6 +87,7 @@ def restore_add_phone():
|
||||
if 'auth.openai.com/add-phone' in st:
|
||||
return True
|
||||
# Generate fresh OAuth URL and login with existing account. This account is already email-verified.
|
||||
close_stale_oauth_tabs('before_oauth_recover')
|
||||
raw = get('CODEX2API_URL')
|
||||
u = urllib.parse.urlsplit(raw)
|
||||
origin = f'{u.scheme}://{u.netloc}' if u.scheme and u.netloc else raw.rstrip('/')
|
||||
|
||||
@@ -47,6 +47,29 @@ def cdp(js, match='auth.openai.com', timeout=45):
|
||||
p = subprocess.run(['bash', '-lc', f"CDP_MATCH='{match}' python3 /tmp/cdp_async_eval.py"], input=js, text=True, capture_output=True, timeout=timeout)
|
||||
return (p.stdout or '') + (p.stderr or '')
|
||||
|
||||
def close_stale_oauth_tabs(reason='recover'):
|
||||
# Avoid tab pile-up and CDP target ambiguity before starting a fresh OAuth/add-phone recovery.
|
||||
try:
|
||||
tabs = json.loads(urllib.request.urlopen('http://127.0.0.1:9223/json/list', timeout=5).read().decode())
|
||||
except Exception as e:
|
||||
emit(phase='close_stale_oauth_tabs_failed', reason=reason, error=str(e))
|
||||
return 0
|
||||
patterns = ('auth.openai.com', 'chatgpt.com/auth', 'localhost', '127.0.0.1')
|
||||
closed = 0
|
||||
for t in tabs:
|
||||
url = t.get('url', '')
|
||||
tid = t.get('id')
|
||||
if tid and any(x in url for x in patterns):
|
||||
try:
|
||||
urllib.request.urlopen('http://127.0.0.1:9223/json/close/' + urllib.parse.quote(tid, safe=''), timeout=3).read()
|
||||
closed += 1
|
||||
time.sleep(0.05)
|
||||
except Exception:
|
||||
pass
|
||||
if closed:
|
||||
emit(phase='close_stale_oauth_tabs', reason=reason, closed_count=closed)
|
||||
return closed
|
||||
|
||||
def current_state():
|
||||
return cdp("""
|
||||
return {url: location.href, title: document.title,
|
||||
@@ -61,6 +84,7 @@ def restore_add_phone():
|
||||
if 'auth.openai.com/add-phone' in st:
|
||||
return True
|
||||
# Generate fresh OAuth URL and login with existing account. This account is already email-verified.
|
||||
close_stale_oauth_tabs('before_oauth_recover')
|
||||
raw = get('CODEX2API_URL')
|
||||
u = urllib.parse.urlsplit(raw)
|
||||
origin = f'{u.scheme}://{u.netloc}' if u.scheme and u.netloc else raw.rstrip('/')
|
||||
|
||||
@@ -48,7 +48,7 @@ These are confirmed operating rules for BOSS's environment:
|
||||
- ClawEmail creates a fresh mailbox for every run (`CLAWEMAIL_CREATE_PER_RUN=true`). Record every created mailbox locally with outcome classification: pending, success, failed. **Immediately after creation, actively set/verify the mailbox's communication settings before submitting it to OpenAI:** new sub-mailboxes can default to internal-only (`commLevel=1`, `extReceiveType=0`), which blocks OpenAI verification mail. The gate must pass with external receive enabled (`commLevel=2`, `extReceiveType=1`). Do not merely tell BOSS to do this manually: first try the logged-in ClawEmail Dashboard API `POST /api/v1/mailboxes/comm-settings?id=<mailboxId>` with `{commLevel:2, extReceiveType:1, extSendType:0}`. If the Dashboard is not logged in, open/login to it and ask BOSS only for the QQ master-mailbox 6-digit login code if the agent cannot read QQ mail. See `clawemail-operations` reference `references/clawemail-dashboard-comm-settings-openai-signup-2026-05-10.md` and this skill's `references/clawemail-external-receive-gate-openai-2026-05-10.md`.
|
||||
- Phone/SMS platform has no default. Keep `PHONE_VERIFICATION_ENABLED=false` and `PHONE_SMS_PROVIDER` empty unless BOSS configures one or approves enabling it after a phone verification appears.
|
||||
- If phone verification appears and BOSS has configured 5sim, use **SMS activation for `openai`**, not WhatsApp receive channels. The original extension's 5sim provider buys `/v1/user/buy/activation/{country}/{operator}/openai`, polls `/v1/user/check/{activationId}`, and finishes/cancels the activation. **Before buying any 5sim number, pass the identity gate:** the browser must already be confirmed on `auth.openai.com/add-phone` for a usable OpenAI account. If OpenAI returns `account_deactivated`, if ClawEmail cannot create a new sub-mailbox due to quota, or if reused sub-mailboxes only show password mismatch, stop and ask BOSS to free mailbox quota/provide the correct password/approve another mailbox provider. **Country selection priority is `FIVE_SIM_COUNTRY_ORDER` first** (comma-separated list such as `argentina,netherlands,indonesia`), then `FIVE_SIM_COUNTRY_ID`, then the original extension default `vietnam` only if both are empty. For each configured country, rotate numbers up to `PHONE_VERIFICATION_REPLACEMENT_LIMIT`; do **not** silently switch outside the configured order unless BOSS approves. Before buying/submitting a non-USA number, verify the OpenAI visible country selector is already the expected country (for example `阿根廷 (+54)`, `荷兰 (+31)`, `印度尼西亚 (+62)`, or `越南 (+84)`); if it reverted to `美国 (+1)`, fix the selector first or the number will be parsed as invalid. Use visible UI paste/click on `add-phone` when possible because CDP-only input mutation can desync React state and revert the country on submit. If a number is **not immediately rejected**, do not cancel it after one polling timeout: poll 5sim, click OpenAI `重新发送`, poll again, and retry resend at least once before canceling/rotating. If changing proxy (for example `1085` → `1083` or back), expect OpenAI auth session invalidation and restart from a fresh target OAuth URL. Codex2API env URLs may point at `/admin/accounts`; derive the API origin before calling `/api/admin/oauth/generate-auth-url`. If OpenAI returns `account_deactivated` after email verification, stop the current account and start with a new ClawEmail sub-mailbox instead of burning 5sim numbers. See `references/openai-add-phone-5sim-sms-activation-2026-05-10.md`, `references/openai-phone-verification-5sim-sms-2026-05-10.md`, `references/openai-phone-verification-proxy1083-resend-2026-05-10.md`, `references/codex-oauth-token-lite-automation-flow-2026-05-10.md`, and `references/clawemail-quota-identity-gate-before-phone-verify-2026-05-10.md` for observed behavior, resend strategy, proxy-switch recovery, identity-gate checks, and pitfalls.
|
||||
- If a phone-verification runner is stopped or interrupted, immediately inspect/cancel any active 5sim activation left in `RECEIVED`; killed scripts may not execute cleanup. For a UK `+44` run, use 5sim country slug `england`, OpenAI ISO `GB`, visible selector `英国 (+44)`, and dial prefix `44`. For a Europe broadened run requested as Italy/Poland/Spain/UK, use `italy -> IT -> 意大利 (+39)`, `poland -> PL -> 波兰 (+48)`, `spain -> ES -> 西班牙 (+34)`, and `england -> GB -> 英国 (+44)`. When BOSS says to run “10 次” across a country set, treat it as **10 total attempts across the ordered set**, not 10 per country, unless he explicitly says per-country; schedule countries **round-robin** so the first country cannot consume the whole budget. Before clicking OpenAI resend, **probe the resend channel without clicking** by reading button `value`/`aria-label`/`title`/text; if it says WhatsApp and BOSS's policy is SMS-only, cancel the SMS activation and rotate/stop instead of clicking. Classify `This page isn’t working` / `HTTP ERROR 500` / `500 Internal Server Error` after resend as `resend_server_error`, cancel the order, and recover to `add-phone`. See `references/openai-add-phone-strict-country-gate-2026-05-10.md`, `references/openai-add-phone-uk44-and-runner-cleanup-2026-05-10.md`, `references/openai-add-phone-eu4-roundrobin-correction-2026-05-10.md`, and `references/official-extension-phone-update-2026-05-10.md`.
|
||||
- If a phone-verification runner is stopped or interrupted, immediately inspect/cancel any active 5sim activation left in `RECEIVED`; killed scripts may not execute cleanup. For a UK `+44` run, use 5sim country slug `england`, OpenAI ISO `GB`, visible selector `英国 (+44)`, and dial prefix `44`. For a Europe broadened run requested as Italy/Poland/Spain/UK, use `italy -> IT -> 意大利 (+39)`, `poland -> PL -> 波兰 (+48)`, `spain -> ES -> 西班牙 (+34)`, and `england -> GB -> 英国 (+44)`. When BOSS says to run “10 次” across a country set, treat it as **10 total attempts across the ordered set**, not 10 per country, unless he explicitly says per-country; schedule countries **round-robin** so the first country cannot consume the whole budget. Before opening a fresh OAuth recovery tab, close stale `auth.openai.com` / `phone-verification` / localhost callback tabs unless the current tab is already a usable `add-phone` page; this prevents tab pile-up and CDP target ambiguity. Before clicking OpenAI resend, **probe the resend channel without clicking** by reading button `value`/`aria-label`/`title`/text; if it says WhatsApp and BOSS's policy is SMS-only, cancel the SMS activation and rotate/stop instead of clicking. Classify `This page isn’t working` / `HTTP ERROR 500` / `500 Internal Server Error` after resend as `resend_server_error`, cancel the order, and recover to `add-phone`. See `references/openai-add-phone-strict-country-gate-2026-05-10.md`, `references/openai-add-phone-uk44-and-runner-cleanup-2026-05-10.md`, `references/openai-add-phone-eu4-roundrobin-correction-2026-05-10.md`, `references/openai-oauth-tab-cleanup-before-recovery-2026-05-10.md`, and `references/official-extension-phone-update-2026-05-10.md`.
|
||||
- Plus mode uses `PLUS_PAYMENT_METHOD=gopay`. Any paid GoPay action still requires explicit confirmation immediately before payment/approval.
|
||||
- GoPay WhatsApp OTP uses **方案 A / manual checkpoint**: set `GOPAY_OTP_SOURCE=manual`. The extension detects OTP input and opens a side-panel prompt (`requestGoPayOtpInput` / “输入 GoPay 验证码”); BOSS pastes the WhatsApp code, then the extension fills OTP, fills `GOPAY_PIN`, and continues.
|
||||
- `GOPAY_OTP` should normally stay empty before the run. It is only a temporary prefill/cache for the current OTP dialog, not a durable secret.
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
# OAuth tab cleanup before recovery (2026-05-10)
|
||||
|
||||
## Problem
|
||||
|
||||
During repeated OpenAI phone-verification failures, the runner recovered by calling Chrome DevTools `/json/new?<oauth_url>` for each new Codex2API OAuth session. Failed `auth.openai.com/add-phone` and `auth.openai.com/phone-verification` tabs were not closed first.
|
||||
|
||||
Observed effect:
|
||||
|
||||
- Chrome accumulated many stale OpenAI auth tabs.
|
||||
- CDP target selection became ambiguous.
|
||||
- The visible browser became cluttered and harder for BOSS to inspect.
|
||||
|
||||
On inspection, 20 stale OAuth/OpenAI tabs were closed from CDP port `9223`.
|
||||
|
||||
## Fix
|
||||
|
||||
Before generating/opening a fresh OAuth recovery tab, close stale tabs matching:
|
||||
|
||||
```text
|
||||
auth.openai.com
|
||||
chatgpt.com/auth
|
||||
localhost
|
||||
127.0.0.1
|
||||
```
|
||||
|
||||
Do this only when the current page is not already a usable `https://auth.openai.com/add-phone` page. If the current page is already usable, do not close it.
|
||||
|
||||
## Runner implementation
|
||||
|
||||
Patched runners:
|
||||
|
||||
```text
|
||||
/tmp/phone_verify_eu4_roundrobin10_latest.py
|
||||
/tmp/phone_verify_strict_gate_10.py
|
||||
/tmp/phone_verify_eu4_total10_latest.py
|
||||
```
|
||||
|
||||
Helper:
|
||||
|
||||
```python
|
||||
def close_stale_oauth_tabs(reason='recover'):
|
||||
tabs = json.loads(urllib.request.urlopen('http://127.0.0.1:9223/json/list', timeout=5).read().decode())
|
||||
patterns = ('auth.openai.com', 'chatgpt.com/auth', 'localhost', '127.0.0.1')
|
||||
for t in tabs:
|
||||
url = t.get('url', '')
|
||||
tid = t.get('id')
|
||||
if tid and any(x in url for x in patterns):
|
||||
urllib.request.urlopen('http://127.0.0.1:9223/json/close/' + urllib.parse.quote(tid, safe=''), timeout=3).read()
|
||||
```
|
||||
|
||||
Call site:
|
||||
|
||||
```python
|
||||
if current page is not add-phone:
|
||||
close_stale_oauth_tabs('before_oauth_recover')
|
||||
open fresh Codex2API OAuth URL via /json/new
|
||||
```
|
||||
|
||||
## Workflow rule
|
||||
|
||||
Any recovery path that opens a fresh OAuth/OpenAI auth tab must first close stale OAuth/OpenAI tabs, unless it is deliberately keeping the current active `add-phone` tab. This avoids tab pile-up and CDP target ambiguity.
|
||||
Reference in New Issue
Block a user