Skip to content

fix(oauth): parse RFC 8707 resource from request.url on authorize + consent paths#162

Merged
EsTharian merged 1 commit intomainfrom
fix/authorize-resource-from-url-v2
Apr 24, 2026
Merged

fix(oauth): parse RFC 8707 resource from request.url on authorize + consent paths#162
EsTharian merged 1 commit intomainfrom
fix/authorize-resource-from-url-v2

Conversation

@EsTharian
Copy link
Copy Markdown
Member

@EsTharian EsTharian commented Apr 24, 2026

Problem

fastify-type-provider-zod@6.1.0 does not write Zod-transformed fields back onto request.query for GET routes. This meant query.resource was always undefined even when the URL contained resource= params — so authorization codes were minted with an empty resource array, causing downstream /oauth/token to produce tokens with aud set to the client UUID instead of the requested resource URI. The resource param IS validated by Zod at schema time (invalid URIs still fail the request), but the parsed value is never surfaced on request.query.

The same bug affected both code-creation paths:

  1. authorize.ts — the consent-skip path (returning user, prior grant covers scopes), which creates the code directly in GET /oauth/authorize.
  2. consent.ts — the first-time browser flow, which creates the code in POST /ui/consent. This is the path taken by every new client authorization.

Fix

Parse resource indicators directly from request.url via URLSearchParams instead of relying on request.query.resource:

  • authorize.tsparseResourceFromUrl(request.url) on the authorizationCodes.create() call (consent-skip path)
  • consent.ts GET — parses resource URIs from the URL and renders one <input type="hidden" name="resource" value="..." /> per URI so values survive the POST
  • consent.ts POST — reads body.resource and passes it to authorizationCodes.create()

Tests

  • URL-parse regression: query.resource absent but URL carries resource= → code gets correct array
  • Multi-value resource= params parsed into array
  • Consent POST allow_forever path: resource field persisted onto the authorization code

🤖 Generated with Claude Code

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented Apr 24, 2026

View your CI Pipeline Execution ↗ for commit 455570a

Command Status Duration Result
nx affected -t lint test build ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-24 20:00:05 UTC

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request addresses an issue where the resource query parameter was being stripped from request.query by the Zod type provider in GET routes. The implementation now extracts the resource parameters directly from the raw request URL using URLSearchParams to ensure they are correctly captured. Corresponding tests have been updated and expanded to verify that both single and multiple resource parameters are correctly parsed even when absent from the validated query object. I have no feedback to provide.

…onsent paths

fastify-type-provider-zod@6.1.0 does not write Zod-transformed fields back
onto request.query for GET routes, so query.resource was always undefined even
when the URL contained resource= params.  Both code-creation paths now parse
resource indicators directly from request.url via URLSearchParams:

• authorize.ts (consent-skip path): parseResourceFromUrl(request.url)
• consent.ts GET: parses resource from URL → renders hidden <input> per URI
• consent.ts POST: reads body.resource → persists onto the authorization code

Tests cover the URL-parse regression, multi-value resource params, and the
full consent POST allow/allow_forever paths including resource passthrough.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@EsTharian EsTharian force-pushed the fix/authorize-resource-from-url-v2 branch from 0249fe5 to 455570a Compare April 24, 2026 19:59
@EsTharian EsTharian changed the title fix(oauth): parse authorize resource from request.url (follow-up to #161) fix(oauth): parse RFC 8707 resource from request.url on authorize + consent paths Apr 24, 2026
@EsTharian EsTharian merged commit 4008e0a into main Apr 24, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant