From 55194676238f92e2d37c57f47a92f2567138b471 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Mon, 9 Mar 2026 15:57:37 -0700 Subject: [PATCH 1/2] fix(web): handle duplicate resource query params in OAuth authorize endpoint RFC 8707 allows multiple resource parameters in authorization requests. Sourcebot only supports a single resource (the MCP endpoint), so deduplicate by taking the first value. Also improves error handling in the consent screen to show a toast when authorization fails. Co-Authored-By: Claude Sonnet 4.6 --- .../oauth/authorize/components/consentScreen.tsx | 16 ++++++++++++---- packages/web/src/app/oauth/authorize/page.tsx | 10 ++++++++-- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/packages/web/src/app/oauth/authorize/components/consentScreen.tsx b/packages/web/src/app/oauth/authorize/components/consentScreen.tsx index b5ef16c72..03ff1cce4 100644 --- a/packages/web/src/app/oauth/authorize/components/consentScreen.tsx +++ b/packages/web/src/app/oauth/authorize/components/consentScreen.tsx @@ -8,6 +8,7 @@ import Image from 'next/image'; import logo from '@/public/logo_512.png'; import { useEffect, useState } from 'react'; import useCaptureEvent from '@/hooks/useCaptureEvent'; +import { useToast } from '@/components/hooks/use-toast'; interface ConsentScreenProps { clientId: string; @@ -32,6 +33,7 @@ export function ConsentScreen({ }: ConsentScreenProps) { const [pending, setPending] = useState<'approve' | 'deny' | null>(null); const captureEvent = useCaptureEvent(); + const { toast } = useToast(); useEffect(() => { captureEvent('wa_oauth_consent_viewed', { clientId, clientName }); @@ -41,11 +43,17 @@ export function ConsentScreen({ captureEvent('wa_oauth_authorization_approved', { clientId, clientName }); setPending('approve'); const result = await approveAuthorization({ clientId, redirectUri, codeChallenge, resource, state }); - if (isServiceError(result)) { - setPending(null); - return; + if (!isServiceError(result)) { + window.location.href = result; + toast({ + description: `✅ Authorization approved successfully. Redirecting to ${result}...`, + }); + } else { + toast({ + description: `❌ Failed to approve authorization. ${result.message}`, + }); } - window.location.href = result; + setPending(null); }; const onDeny = async () => { diff --git a/packages/web/src/app/oauth/authorize/page.tsx b/packages/web/src/app/oauth/authorize/page.tsx index 0a62306da..bfbb5ac5a 100644 --- a/packages/web/src/app/oauth/authorize/page.tsx +++ b/packages/web/src/app/oauth/authorize/page.tsx @@ -15,7 +15,7 @@ interface AuthorizePageProps { code_challenge_method?: string; response_type?: string; state?: string; - resource?: string; + resource?: string | string[]; }>; } @@ -25,7 +25,13 @@ export default async function AuthorizePage({ searchParams }: AuthorizePageProps } const params = await searchParams; - const { client_id, redirect_uri, code_challenge, code_challenge_method, response_type, state, resource } = params; + const { client_id, redirect_uri, code_challenge, code_challenge_method, response_type, state, resource: _resource } = params; + + // RFC 8707 allows multiple resource parameters to indicate a token intended for multiple resources. + // Sourcebot only supports a single resource (the MCP endpoint), so we take the first value. + // + // @see: https://www.rfc-editor.org/rfc/rfc8707.html#section-2-2.2 + const resource = Array.isArray(_resource) ? _resource[0] : _resource; // Validate required parameters. Per spec, do NOT redirect on client errors — // show an error page instead to avoid open redirect vulnerabilities. From c532b5deb78524fae602864d8c74927115ccc821 Mon Sep 17 00:00:00 2001 From: Brendan Kellam Date: Mon, 9 Mar 2026 15:58:06 -0700 Subject: [PATCH 2/2] chore: update CHANGELOG for #987 Co-Authored-By: Claude Sonnet 4.6 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62dbd8d94..4e3222ea1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- [EE] Handle duplicate `resource` query parameters in the OAuth authorization endpoint. [#987](https://github.com/sourcebot-dev/sourcebot/pull/987) + ## [4.15.2] - 2026-03-06 ### Fixed