@supabase/auth-js 2.77.0 → 2.77.1-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/dist/main/GoTrueAdminApi.d.ts +7 -0
  2. package/dist/main/GoTrueAdminApi.d.ts.map +1 -1
  3. package/dist/main/GoTrueAdminApi.js +24 -0
  4. package/dist/main/GoTrueAdminApi.js.map +1 -1
  5. package/dist/main/GoTrueClient.d.ts +26 -1
  6. package/dist/main/GoTrueClient.d.ts.map +1 -1
  7. package/dist/main/GoTrueClient.js +120 -14
  8. package/dist/main/GoTrueClient.js.map +1 -1
  9. package/dist/main/lib/helpers.d.ts +11 -0
  10. package/dist/main/lib/helpers.d.ts.map +1 -1
  11. package/dist/main/lib/helpers.js +37 -0
  12. package/dist/main/lib/helpers.js.map +1 -1
  13. package/dist/main/lib/types.d.ts +117 -0
  14. package/dist/main/lib/types.d.ts.map +1 -1
  15. package/dist/main/lib/version.d.ts +1 -1
  16. package/dist/main/lib/version.d.ts.map +1 -1
  17. package/dist/main/lib/version.js +1 -1
  18. package/dist/main/lib/version.js.map +1 -1
  19. package/dist/module/GoTrueAdminApi.d.ts +7 -0
  20. package/dist/module/GoTrueAdminApi.d.ts.map +1 -1
  21. package/dist/module/GoTrueAdminApi.js +24 -0
  22. package/dist/module/GoTrueAdminApi.js.map +1 -1
  23. package/dist/module/GoTrueClient.d.ts +26 -1
  24. package/dist/module/GoTrueClient.d.ts.map +1 -1
  25. package/dist/module/GoTrueClient.js +121 -15
  26. package/dist/module/GoTrueClient.js.map +1 -1
  27. package/dist/module/lib/helpers.d.ts +11 -0
  28. package/dist/module/lib/helpers.d.ts.map +1 -1
  29. package/dist/module/lib/helpers.js +36 -0
  30. package/dist/module/lib/helpers.js.map +1 -1
  31. package/dist/module/lib/types.d.ts +117 -0
  32. package/dist/module/lib/types.d.ts.map +1 -1
  33. package/dist/module/lib/version.d.ts +1 -1
  34. package/dist/module/lib/version.d.ts.map +1 -1
  35. package/dist/module/lib/version.js +1 -1
  36. package/dist/module/lib/version.js.map +1 -1
  37. package/dist/tsconfig.module.tsbuildinfo +1 -1
  38. package/dist/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +1 -1
  40. package/src/GoTrueAdminApi.ts +34 -12
  41. package/src/GoTrueClient.ts +182 -16
  42. package/src/lib/helpers.ts +44 -0
  43. package/src/lib/types.ts +128 -0
  44. package/src/lib/version.ts +1 -1
@@ -38,6 +38,7 @@ import {
38
38
  getAlgorithm,
39
39
  getCodeChallengeAndMethod,
40
40
  getItemAsync,
41
+ insecureUserWarningProxy,
41
42
  isBrowser,
42
43
  parseParametersFromURL,
43
44
  removeItemAsync,
@@ -105,6 +106,9 @@ import type {
105
106
  MFAVerifyWebauthnParamFields,
106
107
  MFAVerifyWebauthnParams,
107
108
  OAuthResponse,
109
+ AuthOAuthServerApi,
110
+ AuthOAuthAuthorizationDetailsResponse,
111
+ AuthOAuthConsentResponse,
108
112
  Prettify,
109
113
  Provider,
110
114
  ResendParams,
@@ -196,6 +200,12 @@ export default class GoTrueClient {
196
200
  * Namespace for the MFA methods.
197
201
  */
198
202
  mfa: GoTrueMFAApi
203
+ /**
204
+ * Namespace for the OAuth 2.1 authorization server methods.
205
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
206
+ * Used to implement the authorization code flow on the consent page.
207
+ */
208
+ oauth: AuthOAuthServerApi
199
209
  /**
200
210
  * The storage key used to identify the values saved in localStorage
201
211
  */
@@ -322,6 +332,12 @@ export default class GoTrueClient {
322
332
  webauthn: new WebAuthnApi(this),
323
333
  }
324
334
 
335
+ this.oauth = {
336
+ getAuthorizationDetails: this._getAuthorizationDetails.bind(this),
337
+ approveAuthorization: this._approveAuthorization.bind(this),
338
+ denyAuthorization: this._denyAuthorization.bind(this),
339
+ }
340
+
325
341
  if (this.persistSession) {
326
342
  if (settings.storage) {
327
343
  this.storage = settings.storage
@@ -1585,22 +1601,20 @@ export default class GoTrueClient {
1585
1601
  }
1586
1602
  }
1587
1603
 
1588
- if (this.storage.isServer && currentSession.user) {
1589
- let suppressWarning = this.suppressGetSessionWarning
1590
- const proxySession: Session = new Proxy(currentSession, {
1591
- get: (target: any, prop: string, receiver: any) => {
1592
- if (!suppressWarning && prop === 'user') {
1593
- // only show warning when the user object is being accessed from the server
1594
- console.warn(
1595
- 'Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server.'
1596
- )
1597
- suppressWarning = true // keeps this proxy instance from logging additional warnings
1598
- this.suppressGetSessionWarning = true // keeps this client's future proxy instances from warning
1599
- }
1600
- return Reflect.get(target, prop, receiver)
1601
- },
1602
- })
1603
- currentSession = proxySession
1604
+ // Wrap the user object with a warning proxy on the server
1605
+ // This warns when properties of the user are accessed, not when session.user itself is accessed
1606
+ if (
1607
+ this.storage.isServer &&
1608
+ currentSession.user &&
1609
+ !(currentSession.user as any).__isUserNotAvailableProxy
1610
+ ) {
1611
+ const suppressWarningRef = { value: this.suppressGetSessionWarning }
1612
+ currentSession.user = insecureUserWarningProxy(currentSession.user, suppressWarningRef)
1613
+
1614
+ // Update the client-level suppression flag when the proxy suppresses the warning
1615
+ if (suppressWarningRef.value) {
1616
+ this.suppressGetSessionWarning = true
1617
+ }
1604
1618
  }
1605
1619
 
1606
1620
  return { data: { session: currentSession }, error: null }
@@ -3344,6 +3358,158 @@ export default class GoTrueClient {
3344
3358
  })
3345
3359
  }
3346
3360
 
3361
+ /**
3362
+ * Retrieves details about an OAuth authorization request.
3363
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
3364
+ *
3365
+ * Returns authorization details including client info, scopes, and user information.
3366
+ * If the API returns a redirect_uri, it means consent was already given - the caller
3367
+ * should handle the redirect manually if needed.
3368
+ */
3369
+ private async _getAuthorizationDetails(
3370
+ authorizationId: string
3371
+ ): Promise<AuthOAuthAuthorizationDetailsResponse> {
3372
+ try {
3373
+ return await this._useSession(async (result) => {
3374
+ const {
3375
+ data: { session },
3376
+ error: sessionError,
3377
+ } = result
3378
+
3379
+ if (sessionError) {
3380
+ return { data: null, error: sessionError }
3381
+ }
3382
+
3383
+ if (!session) {
3384
+ return { data: null, error: new AuthSessionMissingError() }
3385
+ }
3386
+
3387
+ return await _request(
3388
+ this.fetch,
3389
+ 'GET',
3390
+ `${this.url}/oauth/authorizations/${authorizationId}`,
3391
+ {
3392
+ headers: this.headers,
3393
+ jwt: session.access_token,
3394
+ xform: (data: any) => ({ data, error: null }),
3395
+ }
3396
+ )
3397
+ })
3398
+ } catch (error) {
3399
+ if (isAuthError(error)) {
3400
+ return { data: null, error }
3401
+ }
3402
+
3403
+ throw error
3404
+ }
3405
+ }
3406
+
3407
+ /**
3408
+ * Approves an OAuth authorization request.
3409
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
3410
+ */
3411
+ private async _approveAuthorization(
3412
+ authorizationId: string,
3413
+ options?: { skipBrowserRedirect?: boolean }
3414
+ ): Promise<AuthOAuthConsentResponse> {
3415
+ try {
3416
+ return await this._useSession(async (result) => {
3417
+ const {
3418
+ data: { session },
3419
+ error: sessionError,
3420
+ } = result
3421
+
3422
+ if (sessionError) {
3423
+ return { data: null, error: sessionError }
3424
+ }
3425
+
3426
+ if (!session) {
3427
+ return { data: null, error: new AuthSessionMissingError() }
3428
+ }
3429
+
3430
+ const response = await _request(
3431
+ this.fetch,
3432
+ 'POST',
3433
+ `${this.url}/oauth/authorizations/${authorizationId}/consent`,
3434
+ {
3435
+ headers: this.headers,
3436
+ jwt: session.access_token,
3437
+ body: { action: 'approve' },
3438
+ xform: (data: any) => ({ data, error: null }),
3439
+ }
3440
+ )
3441
+
3442
+ if (response.data && response.data.redirect_url) {
3443
+ // Automatically redirect in browser unless skipBrowserRedirect is true
3444
+ if (isBrowser() && !options?.skipBrowserRedirect) {
3445
+ window.location.assign(response.data.redirect_url)
3446
+ }
3447
+ }
3448
+
3449
+ return response
3450
+ })
3451
+ } catch (error) {
3452
+ if (isAuthError(error)) {
3453
+ return { data: null, error }
3454
+ }
3455
+
3456
+ throw error
3457
+ }
3458
+ }
3459
+
3460
+ /**
3461
+ * Denies an OAuth authorization request.
3462
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
3463
+ */
3464
+ private async _denyAuthorization(
3465
+ authorizationId: string,
3466
+ options?: { skipBrowserRedirect?: boolean }
3467
+ ): Promise<AuthOAuthConsentResponse> {
3468
+ try {
3469
+ return await this._useSession(async (result) => {
3470
+ const {
3471
+ data: { session },
3472
+ error: sessionError,
3473
+ } = result
3474
+
3475
+ if (sessionError) {
3476
+ return { data: null, error: sessionError }
3477
+ }
3478
+
3479
+ if (!session) {
3480
+ return { data: null, error: new AuthSessionMissingError() }
3481
+ }
3482
+
3483
+ const response = await _request(
3484
+ this.fetch,
3485
+ 'POST',
3486
+ `${this.url}/oauth/authorizations/${authorizationId}/consent`,
3487
+ {
3488
+ headers: this.headers,
3489
+ jwt: session.access_token,
3490
+ body: { action: 'deny' },
3491
+ xform: (data: any) => ({ data, error: null }),
3492
+ }
3493
+ )
3494
+
3495
+ if (response.data && response.data.redirect_url) {
3496
+ // Automatically redirect in browser unless skipBrowserRedirect is true
3497
+ if (isBrowser() && !options?.skipBrowserRedirect) {
3498
+ window.location.assign(response.data.redirect_url)
3499
+ }
3500
+ }
3501
+
3502
+ return response
3503
+ })
3504
+ } catch (error) {
3505
+ if (isAuthError(error)) {
3506
+ return { data: null, error }
3507
+ }
3508
+
3509
+ throw error
3510
+ }
3511
+ }
3512
+
3347
3513
  private async fetchJwk(kid: string, jwks: { keys: JWK[] } = { keys: [] }): Promise<JWK | null> {
3348
3514
  // try fetching from the supplied jwks
3349
3515
  let jwk = jwks.keys.find((key) => key.kid === kid)
@@ -407,6 +407,50 @@ export function userNotAvailableProxy(): User {
407
407
  })
408
408
  }
409
409
 
410
+ /**
411
+ * Creates a proxy around a user object that warns when properties are accessed on the server.
412
+ * This is used to alert developers that using user data from getSession() on the server is insecure.
413
+ *
414
+ * @param user The actual user object to wrap
415
+ * @param suppressWarningRef An object with a 'value' property that controls warning suppression
416
+ * @returns A proxied user object that warns on property access
417
+ */
418
+ export function insecureUserWarningProxy(user: User, suppressWarningRef: { value: boolean }): User {
419
+ return new Proxy(user, {
420
+ get: (target: any, prop: string | symbol, receiver: any) => {
421
+ // Allow internal checks without warning
422
+ if (prop === '__isInsecureUserWarningProxy') {
423
+ return true
424
+ }
425
+
426
+ // Preventative check for common problematic symbols during cloning/inspection
427
+ // These symbols might be accessed by structuredClone or other internal mechanisms
428
+ if (typeof prop === 'symbol') {
429
+ const sProp = prop.toString()
430
+ if (
431
+ sProp === 'Symbol(Symbol.toPrimitive)' ||
432
+ sProp === 'Symbol(Symbol.toStringTag)' ||
433
+ sProp === 'Symbol(util.inspect.custom)' ||
434
+ sProp === 'Symbol(nodejs.util.inspect.custom)'
435
+ ) {
436
+ // Return the actual value for these symbols to allow proper inspection
437
+ return Reflect.get(target, prop, receiver)
438
+ }
439
+ }
440
+
441
+ // Emit warning on first property access
442
+ if (!suppressWarningRef.value && typeof prop === 'string') {
443
+ console.warn(
444
+ 'Using the user object as returned from supabase.auth.getSession() or from some supabase.auth.onAuthStateChange() events could be insecure! This value comes directly from the storage medium (usually cookies on the server) and may not be authentic. Use supabase.auth.getUser() instead which authenticates the data by contacting the Supabase Auth server.'
445
+ )
446
+ suppressWarningRef.value = true
447
+ }
448
+
449
+ return Reflect.get(target, prop, receiver)
450
+ },
451
+ })
452
+ }
453
+
410
454
  /**
411
455
  * Deep clones a JSON-serializable object using JSON.parse(JSON.stringify(obj)).
412
456
  * Note: Only works for JSON-safe data.
package/src/lib/types.ts CHANGED
@@ -1492,6 +1492,8 @@ export type OAuthClient = {
1492
1492
  registration_type: OAuthClientRegistrationType
1493
1493
  /** URI of the OAuth client */
1494
1494
  client_uri?: string
1495
+ /** URI of the OAuth client's logo */
1496
+ logo_uri?: string
1495
1497
  /** Array of allowed redirect URIs */
1496
1498
  redirect_uris: string[]
1497
1499
  /** Array of allowed grant types */
@@ -1525,6 +1527,24 @@ export type CreateOAuthClientParams = {
1525
1527
  scope?: string
1526
1528
  }
1527
1529
 
1530
+ /**
1531
+ * Parameters for updating an existing OAuth client.
1532
+ * All fields are optional. Only provided fields will be updated.
1533
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1534
+ */
1535
+ export type UpdateOAuthClientParams = {
1536
+ /** Human-readable name of the OAuth client */
1537
+ client_name?: string
1538
+ /** URI of the OAuth client */
1539
+ client_uri?: string
1540
+ /** URI of the OAuth client's logo */
1541
+ logo_uri?: string
1542
+ /** Array of allowed redirect URIs */
1543
+ redirect_uris?: string[]
1544
+ /** Array of allowed grant types */
1545
+ grant_types?: OAuthClientGrantType[]
1546
+ }
1547
+
1528
1548
  /**
1529
1549
  * Response type for OAuth client operations.
1530
1550
  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
@@ -1574,6 +1594,14 @@ export interface GoTrueAdminOAuthApi {
1574
1594
  */
1575
1595
  getClient(clientId: string): Promise<OAuthClientResponse>
1576
1596
 
1597
+ /**
1598
+ * Updates an existing OAuth client.
1599
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1600
+ *
1601
+ * This function should only be called on a server. Never expose your `service_role` key in the browser.
1602
+ */
1603
+ updateClient(clientId: string, params: UpdateOAuthClientParams): Promise<OAuthClientResponse>
1604
+
1577
1605
  /**
1578
1606
  * Deletes an OAuth client.
1579
1607
  * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
@@ -1590,3 +1618,103 @@ export interface GoTrueAdminOAuthApi {
1590
1618
  */
1591
1619
  regenerateClientSecret(clientId: string): Promise<OAuthClientResponse>
1592
1620
  }
1621
+
1622
+ /**
1623
+ * OAuth client details in an authorization request.
1624
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1625
+ */
1626
+ export type OAuthAuthorizationClient = {
1627
+ /** Unique identifier for the OAuth client (UUID) */
1628
+ client_id: string
1629
+ /** Human-readable name of the OAuth client */
1630
+ client_name: string
1631
+ /** URI of the OAuth client's website */
1632
+ client_uri: string
1633
+ /** URI of the OAuth client's logo */
1634
+ logo_uri: string
1635
+ }
1636
+
1637
+ /**
1638
+ * OAuth authorization details for the consent flow.
1639
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1640
+ */
1641
+ export type OAuthAuthorizationDetails = {
1642
+ /** The authorization ID */
1643
+ authorization_id: string
1644
+ /** Redirect URI - present if user already consented (can be used to trigger immediate redirect) */
1645
+ redirect_uri?: string
1646
+ /** OAuth client requesting authorization */
1647
+ client: OAuthAuthorizationClient
1648
+ /** User object associated with the authorization */
1649
+ user: {
1650
+ /** User ID (UUID) */
1651
+ id: string
1652
+ /** User email */
1653
+ email: string
1654
+ }
1655
+ /** Space-separated list of requested scopes */
1656
+ scope: string
1657
+ }
1658
+
1659
+ /**
1660
+ * Response type for getting OAuth authorization details.
1661
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1662
+ */
1663
+ export type AuthOAuthAuthorizationDetailsResponse = RequestResult<OAuthAuthorizationDetails>
1664
+
1665
+ /**
1666
+ * Response type for OAuth consent decision (approve/deny).
1667
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1668
+ */
1669
+ export type AuthOAuthConsentResponse = RequestResult<{
1670
+ /** URL to redirect the user back to the OAuth client */
1671
+ redirect_url: string
1672
+ }>
1673
+
1674
+ /**
1675
+ * Contains all OAuth 2.1 authorization server user-facing methods.
1676
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1677
+ *
1678
+ * These methods are used to implement the consent page.
1679
+ */
1680
+ export interface AuthOAuthServerApi {
1681
+ /**
1682
+ * Retrieves details about an OAuth authorization request.
1683
+ * Used to display consent information to the user.
1684
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1685
+ *
1686
+ * This method returns authorization details including client info, scopes, and user information.
1687
+ * If the response includes a redirect_uri, it means consent was already given - the caller
1688
+ * should handle the redirect manually if needed.
1689
+ *
1690
+ * @param authorizationId - The authorization ID from the authorization request
1691
+ * @returns Authorization details including client info and requested scopes
1692
+ */
1693
+ getAuthorizationDetails(authorizationId: string): Promise<AuthOAuthAuthorizationDetailsResponse>
1694
+
1695
+ /**
1696
+ * Approves an OAuth authorization request.
1697
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1698
+ *
1699
+ * @param authorizationId - The authorization ID to approve
1700
+ * @param options - Optional parameters including skipBrowserRedirect
1701
+ * @returns Redirect URL to send the user back to the OAuth client
1702
+ */
1703
+ approveAuthorization(
1704
+ authorizationId: string,
1705
+ options?: { skipBrowserRedirect?: boolean }
1706
+ ): Promise<AuthOAuthConsentResponse>
1707
+
1708
+ /**
1709
+ * Denies an OAuth authorization request.
1710
+ * Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
1711
+ *
1712
+ * @param authorizationId - The authorization ID to deny
1713
+ * @param options - Optional parameters including skipBrowserRedirect
1714
+ * @returns Redirect URL to send the user back to the OAuth client
1715
+ */
1716
+ denyAuthorization(
1717
+ authorizationId: string,
1718
+ options?: { skipBrowserRedirect?: boolean }
1719
+ ): Promise<AuthOAuthConsentResponse>
1720
+ }
@@ -4,4 +4,4 @@
4
4
  // - Debugging and support (identifying which version is running)
5
5
  // - Telemetry and logging (version reporting in errors/analytics)
6
6
  // - Ensuring build artifacts match the published package version
7
- export const version = '2.77.0'
7
+ export const version = '2.77.1-canary.1'