fix(gotrue): handle already-consented OAuth authorization responses#1536
Merged
Conversation
getAuthorizationDetails crashed with a FormatException when the OAuth
2.1 server short-circuited the consent flow. This happens when a user
who already approved a client starts a new authorization for it: the
server returns a redirect-only body
({"redirect_url": "...?code=..."}) with no user or client, which the
parser rejected because it required a user object.
Model the two possible outcomes as a sealed OAuthAuthorizationResponse:
- OAuthAuthorizationDetailsResponse when consent is still required
- OAuthAuthorizationRedirectResponse carrying the redirect URL when the
user already consented
Callers now switch on the result and forward the redirect instead of
losing it to an exception. Genuinely malformed detail bodies (no
redirect_url and no user) still throw, so validation isn't weakened.
BREAKING CHANGE: getAuthorizationDetails now returns the sealed
OAuthAuthorizationResponse instead of OAuthAuthorizationDetailsResponse.
Callers must switch/cast to access client, user, scope and redirectUri.
Contributor
Author
Contributor
spydon
approved these changes
Jul 6, 2026
spydon
left a comment
Contributor
There was a problem hiding this comment.
Generally we shouldn't pull in breaking changes now, but since this fixes a bug it's fine.
Contributor
Author
|
Ah I see, I can still make some changes if you prefer? I don't see how I would be able to keep out the breaking change though. |
Contributor
|
@Pieter-JanRobrechtCronos can you turn on so that maintainers can modify the PR? Then I can fix up the compliance matrix |
`sdk-compliance.yaml` only tracked didn't yet track the new `OAuthAuthorizationResponse` and `OAuthAuthorizationRedirectResponse` models.
Contributor
Author
|
I've checked, and I don't see any checkmarks that I can toggle to give you the necessary access... Is that something that I would need to toggle in my fork or a setting in this PR? In the meantime I've made the necessary changes to the compliance matrix. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Bug fix
What is the current behavior?
getAuthorizationDetailscrashed with aFormatExceptionwhen the OAuth 2.1 server short-circuited the consent flow. This happens when a user who already approved a client starts a new authorization for it: the server returns a redirect-only body ({"redirect_url": "...?code=..."}) with no user or client, which the parser rejected because it required a user object.What is the new behavior?
getAuthorizationDetailsnow checks whether aredirect_urlis present returningOAuthAuthorizationRedirectResponsewhen it is present. When the key isn't present the oldOAuthAuthorizationDetailsResponseobject is returned.Callers now switch on the result and forward the redirect instead of losing it to an exception. Genuinely malformed detail bodies (no redirect_url and no user) still throw, so validation isn't weakened.
Additional context
BREAKING CHANGE:
getAuthorizationDetailsnow returns the sealedOAuthAuthorizationResponseinstead ofOAuthAuthorizationDetailsResponse. Callers must switch/cast to access client, user, scope and redirectUri.