Skip to content

Conversation

@cemalkilic
Copy link
Contributor

Summary

Adds user-facing OAuth authorization methods to @supabase/auth-js for building consent pages when Supabase Auth acts as an OAuth 2.1 authorization server.

Implements the consent flow where users approve/deny OAuth client authorization requests.

New API

Namespace: auth.oauth.*

Three new methods for managing OAuth authorization consent:

// Get authorization details (client info, scopes, user)
const { data, error } = await supabase.auth.oauth.getAuthorizationDetails(
  authorizationId,
  { skipBrowserRedirect?: boolean }
)

// Approve authorization request
const { data, error } = await supabase.auth.oauth.approveAuthorization(
  authorizationId,
  { skipBrowserRedirect?: boolean }
)

// Deny authorization request
const { data, error } = await supabase.auth.oauth.denyAuthorization(
  authorizationId,
  { skipBrowserRedirect?: boolean }
)

Use Case

Enables developers to build custom OAuth consent pages for their Supabase projects when acting as an OAuth 2.1 authorization server. Example flow:

  1. User is redirected to consent page with authorization_id in URL
  2. App calls getAuthorizationDetails(authorizationId) to fetch client and scope info
  3. User reviews and clicks "Approve" or "Deny"
  4. App calls approveAuthorization() or denyAuthorization()
  5. SDK auto-redirects back to OAuth client with authorization code/error

What's NOT Included

Third-party OAuth client integration (calling /oauth/authorize and /oauth/token from external apps) is intentionally not included in this PR.

Rationale:

  • Standard OAuth 2.1 client libraries already handle this well
  • Would require full OAuth client lifecycle (refresh tokens, expiration, storage)
  • Better served by documentation + existing OAuth libraries
  • This PR focuses on the unique Supabase-specific consent management API, utilizing the existing Supabase session

Third-party integration will be addressed through comprehensive documentation showing how to use standard OAuth client libraries with Supabase Auth endpoints.

Breaking Changes

None. This is a purely additive change with zero breaking changes to existing APIs

@cemalkilic cemalkilic requested review from a team as code owners October 21, 2025 07:24
@github-actions github-actions bot added the auth-js Related to the auth-js library. label Oct 21, 2025
@coveralls
Copy link

Coverage Status

coverage: 95.455% (-0.5%) from 95.986%
when pulling 0d7a77a on cemal/feat-auth-add-oauth-endpoints
into c5ad2f4 on master.

Comment on lines +1619 to +1628
client: OAuthAuthorizationClient
/** User object associated with the authorization */
user: {
/** User ID (UUID) */
id: string
/** User email */
email: string
}
/** Space-separated list of requested scopes */
scope: string

Choose a reason for hiding this comment

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

Can these values be optional/undefined? I ask because I see them tagged with omitempty but I can't seem to find a case they would be

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point and yeah ideally they should always exists. The context on why we have omitempty is: supabase/auth#2107 (comment)

Comment on lines +3394 to +3399
if (data.redirect_uri) {
// Automatically redirect in browser unless skipBrowserRedirect is true
if (isBrowser() && !options?.skipBrowserRedirect) {
window.location.assign(data.redirect_uri)
}
}

Choose a reason for hiding this comment

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

I'm a bit on the fence about this: it feels like the default should be that we return the redirect URL to the caller and let them handle the redirect given that these APIs are slightly lower level (as opposed to having some hosted consent page).

Copy link
Contributor Author

@cemalkilic cemalkilic Oct 23, 2025

Choose a reason for hiding this comment

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

Completely get you, wanted to stick with the existing conventions for skipBrowserRedirect

// try to open on the browser
if (isBrowser() && !options.skipBrowserRedirect) {
window.location.assign(url)
}

Choose a reason for hiding this comment

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

I guess I would expect the SDK to redirect me when calling a method signInWithOAuth but as a user you might find it unexpected to be redirected when calling getAuthorizationDetails (personally I'd expect an object to be returned).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

auth-js Related to the auth-js library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants