Files
autoreg-skills-max/skills/github-oauth-automation/references/github-checkup-dismissal.md

63 lines
2.2 KiB
Markdown

# GitHub 2FA Checkup Dismissal (2026-08-20)
After using recovery codes to bypass device verification, GitHub redirects logged-in users to `https://github.com/settings/two_factor_checkup` instead of the intended destination.
## Page Structure (from actual DOM dump)
```
Two-factor settings
Verify your recently configured two-factor authentication method.
[Enter the verification code input]
[Verify] ← btn-primary, do NOT click
[More options] ← btn-secondary, click FIRST
[Verify your 2FA setup tomorrow] ← hidden behind More options, click SECOND
[Reconfigure 2FA on this account] ← link to /settings/security
```
## Dismissal Code
```python
# After login with recovery code, check for checkup page
if "two_factor_checkup" in page.url:
# Click "More options" first
await page.locator("button:has-text('More options')").first.click()
await asyncio.sleep(2)
# Then click "tomorrow" (the skip/dismiss)
await page.locator("button:has-text('tomorrow')").first.click()
await asyncio.sleep(3)
```
## Why This Matters
Without this dismissal:
1. Login to GitHub with recovery code → device trusted
2. Navigate to platform (GoRouter) → click "Sign in with GitHub"
3. GitHub OAuth authorize page → click "Authorize"
4. Instead of redirecting back to platform → GitHub redirects to `two_factor_checkup`
5. Token is LOST
The checkup page MUST be dismissed BEFORE attempting any OAuth flow.
## Also Applies After OAuth Authorize
After clicking "Authorize" on the OAuth page, GitHub may redirect to `two_factor_checkup` instead of the callback URL. The same dismissal code works here too — dismiss it, then the OAuth callback should proceed.
## Debugging
To dump the checkup page content for debugging:
```python
buttons = await page.evaluate("""
() => [...document.querySelectorAll('button, a, input[type="submit"]')].map(el => ({
tag: el.tagName,
text: (el.textContent || '').trim().slice(0, 100),
id: el.id,
name: el.name,
className: (el.className || '').slice(0, 60),
}))
""")
```
## Recovery Code Usage
Each recovery code can be used ONCE. After use, it's burned. The account has 16 recovery codes total. When all are used, device verification can only be bypassed via email code.