[eric] fix OAuth redirect URI for Claude subscription connect

Problem: Our code sent http://localhost:20128/api/oauth/claude/callback
as redirect_uri, but Anthropic only accepts http://localhost:PORT/callback.

Fix: For authorization_code providers (Claude, Codex, Gemini), open
9Router's own dashboard page instead of trying to proxy the OAuth flow.
9Router handles the full popup + callback internally.

Flow: Click Connect → opens 9Router dashboard → user clicks Connect there →
OAuth popup → callback handled → poll from OpenSwarm until connected.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
ciregenz
2026-03-22 10:24:43 -07:00
co-authored by Claude Opus 4.6
parent a68f6cb750
commit 7430eae88a
2 changed files with 9 additions and 16 deletions
+5 -13
View File
@@ -123,20 +123,12 @@ async def start_oauth(provider: str) -> dict:
except Exception:
pass
# Fall back to authorization_code flow
callback_url = f"http://localhost:{NINE_ROUTER_PORT}/api/oauth/{provider}/callback"
r = await client.get(
f"{NINE_ROUTER_API}/oauth/{provider}/authorize",
params={"redirect_uri": callback_url},
)
r.raise_for_status()
data = r.json()
# For authorization_code providers (Claude, Codex, Gemini),
# open 9Router's own dashboard page where the user can connect.
# 9Router handles the full OAuth flow (popup + callback) internally.
return {
"flow": "authorization_code",
"auth_url": data.get("authUrl", ""),
"code_verifier": data.get("codeVerifier", ""),
"state": data.get("state", ""),
"redirect_uri": callback_url,
"flow": "dashboard_redirect",
"dashboard_url": f"http://localhost:{NINE_ROUTER_PORT}/dashboard/providers",
}
+4 -3
View File
@@ -251,9 +251,10 @@ const SubscriptionCards: React.FC = () => {
setPollTimer(timer);
setTimeout(() => { clearInterval(timer); setConnecting(null); setUserCode(''); }, 300000);
} else if (data.flow === 'authorization_code') {
// Auth code flow (Claude, Codex, Gemini) — open browser, poll for connection
if (data.auth_url) window.open(data.auth_url, '_blank');
} else if (data.flow === 'authorization_code' || data.flow === 'dashboard_redirect') {
// Auth code flow (Claude, Codex, Gemini) — open 9Router dashboard, poll for connection
const url = data.dashboard_url || data.auth_url;
if (url) window.open(url, '_blank');
// Poll the providers list until this provider appears as connected
const timer = setInterval(async () => {