From 8e14434a1b358f82692c77cce1d8fe147f93e509 Mon Sep 17 00:00:00 2001 From: jubnl Date: Tue, 5 May 2026 13:48:43 +0200 Subject: [PATCH] fix: thread resource indicator through OAuth consent flow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The consent page extracted client_id, redirect_uri, scope, state, code_challenge from URL params but silently dropped `resource`. Without it the auth code had no resource binding, tokens were issued with audience=null, and the MCP handler's RFC 8707 audience check rejected every token — "There was a problem connecting TREK." Fix: extract `resource` from URLSearchParams and forward it through oauthApi.validate() and oauthApi.authorize(). Add the field to both API type signatures. --- client/src/api/client.ts | 2 ++ client/src/pages/OAuthAuthorizePage.tsx | 3 +++ 2 files changed, 5 insertions(+) diff --git a/client/src/api/client.ts b/client/src/api/client.ts index c8801411..3147e5c2 100644 --- a/client/src/api/client.ts +++ b/client/src/api/client.ts @@ -143,6 +143,7 @@ export const oauthApi = { state?: string code_challenge: string code_challenge_method: string + resource?: string }) => apiClient.get('/oauth/authorize/validate', { params }).then(r => r.data), /** Submit user consent (approve or deny) */ @@ -154,6 +155,7 @@ export const oauthApi = { code_challenge: string code_challenge_method: string approved: boolean + resource?: string }) => apiClient.post('/oauth/authorize', body).then(r => r.data), clients: { diff --git a/client/src/pages/OAuthAuthorizePage.tsx b/client/src/pages/OAuthAuthorizePage.tsx index f0a09df7..b1cd5b3e 100644 --- a/client/src/pages/OAuthAuthorizePage.tsx +++ b/client/src/pages/OAuthAuthorizePage.tsx @@ -34,6 +34,7 @@ export default function OAuthAuthorizePage(): React.ReactElement { const state = params.get('state') || '' const codeChallenge = params.get('code_challenge') || '' const ccMethod = params.get('code_challenge_method') || '' + const resource = params.get('resource') || undefined // Load auth state once, then validate useEffect(() => { @@ -57,6 +58,7 @@ export default function OAuthAuthorizePage(): React.ReactElement { code_challenge: codeChallenge, code_challenge_method: ccMethod, response_type: 'code', + resource, }) setValidation(result) @@ -99,6 +101,7 @@ export default function OAuthAuthorizePage(): React.ReactElement { code_challenge: codeChallenge, code_challenge_method: ccMethod, approved, + resource, }) setPageState('done') window.location.href = result.redirect