fix: Switch to BROKER_URL and remove public_return_url#1283
Conversation
Replace the old PUBLIC_RETURN_URL with BROKER_URL in settings and update auth flow to use a broker when present. AuthService now uses BROKER_URL as the effective redirect URI (falling back to the original redirect_uri) and logs the OAuth callback state. The public_return_url field was removed from API responses and frontend code no longer relies on it, defaulting to window.location.origin instead. Added debug logging in frontend auth callback and auth context to aid troubleshooting of OAuth state encoding/decoding.
Clarify the broker setting name by renaming BROKER_URL to OAUTH_BROKER_URL in src/config/settings.py and update imports/usages in src/services/auth_service.py. auth_service now uses OAUTH_BROKER_URL when computing the effective redirect URI. Update environment variables/deployments to set OAUTH_BROKER_URL (migrate any existing BROKER_URL value).
There was a problem hiding this comment.
Pull request overview
This PR updates the OAuth flow to support an OAuth callback broker by using a configured broker URL as the effective OAuth redirect URI, and removes the deprecated public_return_url field from backend responses and frontend usage.
Changes:
- Backend: use
OAUTH_BROKER_URL(when set) as the OAuthredirect_urireturned to the frontend and stored in connection config; removepublic_return_urlfrom the init response. - Frontend: stop relying on
public_return_url; encodereturn=${window.location.origin}/auth/callbackinto OAuth state and add additional debug logging around state encoding/decoding. - Backend: add logging of the OAuth callback
state.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| src/services/auth_service.py | Uses broker URL as effective OAuth redirect and removes public_return_url; logs callback state. |
| src/config/settings.py | Introduces OAUTH_BROKER_URL setting to configure broker-based redirects. |
| frontend/contexts/auth-context.tsx | Updates OAuth state construction to no longer use public_return_url; adds state debug logging. |
| frontend/app/auth/callback/page.tsx | Adds debug logging of raw/decoded OAuth state during callback handling. |
| frontend/app/api/mutations/useConnectConnectorMutation.ts | Removes public_return_url from response typing and hardcodes callback return URL into OAuth state. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const decodedState = decodeBase64(stateParam); | ||
| console.log("OAuth callback state (decoded):", decodedState); | ||
| const params = new URLSearchParams(decodedState); |
There was a problem hiding this comment.
The decoded OAuth state is being printed to the console, which can expose connection ids and redirect targets. Additionally, because return in state is later used as a redirect target, leaking it makes open-redirect style issues easier to exploit/debug. Please remove this log or gate it behind a dev-only flag.
There was a problem hiding this comment.
| const state = searchParams.get("state"); | ||
| const errorParam = searchParams.get("error"); | ||
|
|
||
| console.log("OAuth callback state (raw):", state); |
There was a problem hiding this comment.
console.log("OAuth callback state (raw):", state) will print the full OAuth state value to the browser console. Since state is attacker-controlled input and may embed redirect targets, avoid logging it in production; keep it behind a dev-only flag or remove it.
| console.log("OAuth callback state (raw):", state); | |
| if (process.env.NODE_ENV !== "production") { | |
| console.log("OAuth callback state (raw):", state); | |
| } |
There was a problem hiding this comment.
keeping for debugging
| request=None, | ||
| ) -> dict: | ||
| """Handle OAuth callback - exchange authorization code for tokens""" | ||
| logger.info(f"OAuth callback state: {state}") |
There was a problem hiding this comment.
Logging the raw OAuth state at INFO level can leak user origins/redirect targets into application logs and may expose CSRF-related state to anyone with log access. Please remove this log or downgrade to DEBUG and redact/trim the value (e.g., log only whether state was present and its length or a hash).
| # OAuth callback broker URL -- when set, Google (and other providers) redirect | ||
| # here instead of directly to the frontend. The broker then forwards to the | ||
| # actual frontend origin that is carried in the OAuth state parameter. | ||
| OAUTH_BROKER_URL = os.getenv("OAUTH_BROKER_URL") |
There was a problem hiding this comment.
PR title/description mention switching to BROKER_URL, but the code introduces OAUTH_BROKER_URL/OAUTH_BROKER_URL env var. This mismatch is likely to cause misconfiguration in deployments. Either align the env var name with the documented BROKER_URL or support both (with a deprecation path) to avoid breaking existing configs.
| }); | ||
|
|
||
| const returnUrl = result.public_return_url || window.location.origin; | ||
| const returnUrl = `${window.location.origin}/auth/callback`; |
There was a problem hiding this comment.
returnUrl is being set to the callback route itself (/auth/callback) and then encoded into the OAuth state. In the callback handler, the decoded return value is later treated as the post-auth redirect target, which will cause a redirect back to the callback page (potential loop / error page). Consider encoding the frontend origin (for broker forwarding) separately from the final in-app redirect (e.g., origin= vs next=), or set return to a real destination like /chat.
| const returnUrl = `${window.location.origin}/auth/callback`; | |
| const returnUrl = `${window.location.origin}/chat`; |
There was a problem hiding this comment.
@lucaseduoli is this the return url for ouath or after oauth ? @mfortman11
There was a problem hiding this comment.
if its releared to oauth then we need auth/callback
also @mfortman11 / @lucaseduoli can you help to put these new broker releated FE changed under feature flag of IBMauth enabled?
| console.log("OAuth state (encoded):", state, "decoded:", stateQuery); | ||
|
|
There was a problem hiding this comment.
Avoid logging the encoded/decoded OAuth state to the browser console in production: it includes the connection id and redirect information and can be copied from the console by anyone with access to the device/session. If this is needed for troubleshooting, gate it behind a dev-only flag (e.g., process.env.NODE_ENV !== 'production') or remove it before merging.
There was a problem hiding this comment.
| const returnUrl = `${window.location.origin}/auth/callback`; | ||
| const stateQuery = `id=${result.connection_id}&return=${returnUrl}`; | ||
| const state = encodeBase64(stateQuery); |
There was a problem hiding this comment.
returnUrl is hardcoded to ${window.location.origin}/auth/callback even though this mutation receives a redirectUri argument that is sent to the backend. If callers pass a different redirectUri (custom base path, reverse proxy, embedded UI, etc.), the state return value will be inconsistent and broker forwarding / post-auth redirects may break. Prefer deriving returnUrl from the redirectUri parameter (or a single shared helper) so they stay in sync.
lucaseduoli
left a comment
There was a problem hiding this comment.
LGTM with few minor nitpicks
| console.log("OAuth state (encoded):", state, "decoded:", stateQuery); | ||
|
|
There was a problem hiding this comment.
| const decodedState = decodeBase64(stateParam); | ||
| console.log("OAuth callback state (decoded):", decodedState); | ||
| const params = new URLSearchParams(decodedState); |
There was a problem hiding this comment.
| const state = searchParams.get("state"); | ||
| const errorParam = searchParams.get("error"); | ||
|
|
||
| console.log("OAuth callback state (raw):", state); |
Replace the old PUBLIC_RETURN_URL with BROKER_URL in settings and update auth flow to use a broker when present. AuthService now uses BROKER_URL as the effective redirect URI (falling back to the original redirect_uri) and logs the OAuth callback state. The public_return_url field was removed from API responses and frontend code no longer relies on it, defaulting to window.location.origin instead. Added debug logging in frontend auth callback and auth context to aid troubleshooting of OAuth state encoding/decoding.
Clarify the broker setting name by renaming BROKER_URL to OAUTH_BROKER_URL in src/config/settings.py and update imports/usages in src/services/auth_service.py. auth_service now uses OAUTH_BROKER_URL when computing the effective redirect URI. Update environment variables/deployments to set OAUTH_BROKER_URL (migrate any existing BROKER_URL value).
911c2da to
22abd94
Compare
Replace the old PUBLIC_RETURN_URL with BROKER_URL in settings and update auth flow to use a broker when present. AuthService now uses BROKER_URL as the effective redirect URI (falling back to the original redirect_uri) and logs the OAuth callback state. The public_return_url field was removed from API responses and frontend code no longer relies on it, defaulting to window.location.origin instead. Added debug logging in frontend auth callback and auth context to aid troubleshooting of OAuth state encoding/decoding.