@@ -105,6 +105,9 @@ import type {
105105 MFAVerifyWebauthnParamFields , 
106106 MFAVerifyWebauthnParams , 
107107 OAuthResponse , 
108+  AuthOAuthServerApi , 
109+  AuthOAuthAuthorizationDetailsResponse , 
110+  AuthOAuthConsentResponse , 
108111 Prettify , 
109112 Provider , 
110113 ResendParams , 
@@ -196,6 +199,12 @@ export default class GoTrueClient {
196199 * Namespace for the MFA methods. 
197200 */ 
198201 mfa : GoTrueMFAApi 
202+  /** 
203+  * Namespace for the OAuth 2.1 authorization server methods. 
204+  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. 
205+  * Used to implement the authorization code flow on the consent page. 
206+  */ 
207+  oauth : AuthOAuthServerApi 
199208 /** 
200209 * The storage key used to identify the values saved in localStorage 
201210 */ 
@@ -322,6 +331,12 @@ export default class GoTrueClient {
322331 webauthn : new  WebAuthnApi ( this ) , 
323332 } 
324333
334+  this . oauth  =  { 
335+  getAuthorizationDetails : this . _getAuthorizationDetails . bind ( this ) , 
336+  approveAuthorization : this . _approveAuthorization . bind ( this ) , 
337+  denyAuthorization : this . _denyAuthorization . bind ( this ) , 
338+  } 
339+ 
325340 if  ( this . persistSession )  { 
326341 if  ( settings . storage )  { 
327342 this . storage  =  settings . storage 
@@ -3344,6 +3359,165 @@ export default class GoTrueClient {
33443359 } ) 
33453360 } 
33463361
3362+  /** 
3363+  * Retrieves details about an OAuth authorization request. 
3364+  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. 
3365+  */ 
3366+  private  async  _getAuthorizationDetails ( 
3367+  authorizationId : string , 
3368+  options ?: {  skipBrowserRedirect ?: boolean  } 
3369+  ) : Promise < AuthOAuthAuthorizationDetailsResponse >  { 
3370+  try  { 
3371+  return  await  this . _useSession ( async  ( result )  =>  { 
3372+  const  { 
3373+  data : {  session } , 
3374+  error : sessionError , 
3375+  }  =  result 
3376+ 
3377+  if  ( sessionError )  { 
3378+  return  {  data : null ,  error : sessionError  } 
3379+  } 
3380+ 
3381+  if  ( ! session )  { 
3382+  return  {  data : null ,  error : new  AuthSessionMissingError ( )  } 
3383+  } 
3384+ 
3385+  return  await  _request ( 
3386+  this . fetch , 
3387+  'GET' , 
3388+  `${ this . url } ${ authorizationId }  , 
3389+  { 
3390+  headers : this . headers , 
3391+  jwt : session . access_token , 
3392+  xform : ( data : any )  =>  { 
3393+  // If the API returns redirect_uri, it means consent was already given 
3394+  if  ( data . redirect_uri )  { 
3395+  // Automatically redirect in browser unless skipBrowserRedirect is true 
3396+  if  ( isBrowser ( )  &&  ! options ?. skipBrowserRedirect )  { 
3397+  window . location . assign ( data . redirect_uri ) 
3398+  } 
3399+  } 
3400+ 
3401+  return  {  data,  error : null  } 
3402+  } , 
3403+  } 
3404+  ) 
3405+  } ) 
3406+  }  catch  ( error )  { 
3407+  if  ( isAuthError ( error ) )  { 
3408+  return  {  data : null ,  error } 
3409+  } 
3410+ 
3411+  throw  error 
3412+  } 
3413+  } 
3414+ 
3415+  /** 
3416+  * Approves an OAuth authorization request. 
3417+  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. 
3418+  */ 
3419+  private  async  _approveAuthorization ( 
3420+  authorizationId : string , 
3421+  options ?: {  skipBrowserRedirect ?: boolean  } 
3422+  ) : Promise < AuthOAuthConsentResponse >  { 
3423+  try  { 
3424+  return  await  this . _useSession ( async  ( result )  =>  { 
3425+  const  { 
3426+  data : {  session } , 
3427+  error : sessionError , 
3428+  }  =  result 
3429+ 
3430+  if  ( sessionError )  { 
3431+  return  {  data : null ,  error : sessionError  } 
3432+  } 
3433+ 
3434+  if  ( ! session )  { 
3435+  return  {  data : null ,  error : new  AuthSessionMissingError ( )  } 
3436+  } 
3437+ 
3438+  const  response  =  await  _request ( 
3439+  this . fetch , 
3440+  'POST' , 
3441+  `${ this . url } ${ authorizationId }  , 
3442+  { 
3443+  headers : this . headers , 
3444+  jwt : session . access_token , 
3445+  body : {  action : 'approve'  } , 
3446+  xform : ( data : any )  =>  ( {  data,  error : null  } ) , 
3447+  } 
3448+  ) 
3449+ 
3450+  if  ( response . data  &&  response . data . redirect_url )  { 
3451+  // Automatically redirect in browser unless skipBrowserRedirect is true 
3452+  if  ( isBrowser ( )  &&  ! options ?. skipBrowserRedirect )  { 
3453+  window . location . assign ( response . data . redirect_url ) 
3454+  } 
3455+  } 
3456+ 
3457+  return  response 
3458+  } ) 
3459+  }  catch  ( error )  { 
3460+  if  ( isAuthError ( error ) )  { 
3461+  return  {  data : null ,  error } 
3462+  } 
3463+ 
3464+  throw  error 
3465+  } 
3466+  } 
3467+ 
3468+  /** 
3469+  * Denies an OAuth authorization request. 
3470+  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth. 
3471+  */ 
3472+  private  async  _denyAuthorization ( 
3473+  authorizationId : string , 
3474+  options ?: {  skipBrowserRedirect ?: boolean  } 
3475+  ) : Promise < AuthOAuthConsentResponse >  { 
3476+  try  { 
3477+  return  await  this . _useSession ( async  ( result )  =>  { 
3478+  const  { 
3479+  data : {  session } , 
3480+  error : sessionError , 
3481+  }  =  result 
3482+ 
3483+  if  ( sessionError )  { 
3484+  return  {  data : null ,  error : sessionError  } 
3485+  } 
3486+ 
3487+  if  ( ! session )  { 
3488+  return  {  data : null ,  error : new  AuthSessionMissingError ( )  } 
3489+  } 
3490+ 
3491+  const  response  =  await  _request ( 
3492+  this . fetch , 
3493+  'POST' , 
3494+  `${ this . url } ${ authorizationId }  , 
3495+  { 
3496+  headers : this . headers , 
3497+  jwt : session . access_token , 
3498+  body : {  action : 'deny'  } , 
3499+  xform : ( data : any )  =>  ( {  data,  error : null  } ) , 
3500+  } 
3501+  ) 
3502+ 
3503+  if  ( response . data  &&  response . data . redirect_url )  { 
3504+  // Automatically redirect in browser unless skipBrowserRedirect is true 
3505+  if  ( isBrowser ( )  &&  ! options ?. skipBrowserRedirect )  { 
3506+  window . location . assign ( response . data . redirect_url ) 
3507+  } 
3508+  } 
3509+ 
3510+  return  response 
3511+  } ) 
3512+  }  catch  ( error )  { 
3513+  if  ( isAuthError ( error ) )  { 
3514+  return  {  data : null ,  error } 
3515+  } 
3516+ 
3517+  throw  error 
3518+  } 
3519+  } 
3520+ 
33473521 private  async  fetchJwk ( kid : string ,  jwks : {  keys : JWK [ ]  }  =  {  keys : [ ]  } ) : Promise < JWK  |  null >  { 
33483522 // try fetching from the supplied jwks 
33493523 let  jwk  =  jwks . keys . find ( ( key )  =>  key . kid  ===  kid ) 
0 commit comments