refactor(tui_gateway): parse the loopback redirect with the shared helper

The gateway loopback handler re-inlined tools.mcp_oauth._parse_redirect_query;
that copy is exactly how the gateway relay lost `iss` while the CLI path
kept it. Use the helper so the four callback keys have one owner, and
point the docstring at it instead of repeating the RFC 9207 rationale.
This commit is contained in:
kshitijk4poor
2026-09-15 12:21:13 +05:30
committed by kshitij
parent 1c243f86de
commit 4a164a8073
2 changed files with 5 additions and 7 deletions

View File

@@ -75,9 +75,7 @@ class DashboardOAuthFlow:
) -> None:
"""Hand the browser redirect to the waiting flow; ``state`` must match exactly.
``iss`` (RFC 9207) is carried through: mcp 2.x rejects an authorization response that omits
it when the server advertised ``authorization_response_iss_parameter_supported``, which
Cloudflare and Resend both do. Dropping it breaks login against those providers.
``iss`` (RFC 9207) is carried through — see ``tools.mcp_oauth._parse_redirect_query``.
"""
with self._lock:
if self._callback_ready.is_set():

View File

@@ -14,7 +14,7 @@ import time
from contextlib import suppress
from pathlib import Path
from typing import Any, Dict, Optional
from urllib.parse import parse_qs, urlparse
from urllib.parse import urlparse
# session_id -> record wrapping the shared DashboardOAuthFlow bridge plus bookkeeping.
_sessions: Dict[str, Dict[str, Any]] = {}
@@ -56,12 +56,12 @@ def _start_loopback_listener(flow) -> "http.server.HTTPServer":
self.send_response(404)
self.end_headers()
return
qs = parse_qs(parsed.query)
from tools.mcp_oauth import _parse_redirect_query
body = b"<h1>Authorization received</h1><p>You can close this tab and return to Hermes.</p>"
status = 200
try:
flow.deliver_callback(
**{k: (qs.get(k) or [None])[0] for k in ("code", "state", "error", "iss")})
flow.deliver_callback(**_parse_redirect_query(parsed.query))
except Exception:
body = b"<h1>OAuth callback rejected</h1><p>The callback was invalid or already used.</p>"
status = 400