@supabase/gotrue-js 2.40.0 → 2.41.0

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.
@@ -29,6 +29,8 @@ import {
29
29
  generatePKCEVerifier,
30
30
  generatePKCEChallenge,
31
31
  supportsLocalStorage,
32
+ stackGuard,
33
+ isInStackGuard,
32
34
  } from './lib/helpers'
33
35
  import localStorageAdapter from './lib/local-storage'
34
36
  import { polyfillGlobalThis } from './lib/polyfills'
@@ -279,8 +281,6 @@ export default class GoTrueClient {
279
281
  redirectType
280
282
  )
281
283
 
282
- await this._saveSession(session)
283
-
284
284
  setTimeout(async () => {
285
285
  if (redirectType === 'recovery') {
286
286
  await this._notifyAllSubscribers('PASSWORD_RECOVERY', session)
@@ -291,7 +291,6 @@ export default class GoTrueClient {
291
291
 
292
292
  return { error: null }
293
293
  }
294
-
295
294
  // no login attempt via callback url try to recover session from storage
296
295
  await this._recoverAndRefresh()
297
296
  return { error: null }
@@ -699,18 +698,20 @@ export default class GoTrueClient {
699
698
  */
700
699
  async reauthenticate(): Promise<AuthResponse> {
701
700
  try {
702
- const {
703
- data: { session },
704
- error: sessionError,
705
- } = await this.getSession()
706
- if (sessionError) throw sessionError
707
- if (!session) throw new AuthSessionMissingError()
701
+ return await this._useSession(async (result) => {
702
+ const {
703
+ data: { session },
704
+ error: sessionError,
705
+ } = result
706
+ if (sessionError) throw sessionError
707
+ if (!session) throw new AuthSessionMissingError()
708
708
 
709
- const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
710
- headers: this.headers,
711
- jwt: session.access_token,
709
+ const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
710
+ headers: this.headers,
711
+ jwt: session.access_token,
712
+ })
713
+ return { data: { user: null, session: null }, error }
712
714
  })
713
- return { data: { user: null, session: null }, error }
714
715
  } catch (error) {
715
716
  if (isAuthError(error)) {
716
717
  return { data: { user: null, session: null }, error }
@@ -768,7 +769,55 @@ export default class GoTrueClient {
768
769
  * Returns the session, refreshing it if necessary.
769
770
  * The session returned can be null if the session is not detected which can happen in the event a user is not signed-in or has logged out.
770
771
  */
771
- async getSession(): Promise<
772
+ async getSession() {
773
+ return this._useSession(async (result) => {
774
+ return result
775
+ })
776
+ }
777
+
778
+ /**
779
+ * Use instead of {@link #getSession} inside the library. It is
780
+ * semantically usually what you want, as getting a session involves some
781
+ * processing afterwards that requires only one client operating on the
782
+ * session at once across multiple tabs or processes.
783
+ */
784
+ private async _useSession<R>(
785
+ fn: (
786
+ result:
787
+ | {
788
+ data: {
789
+ session: Session
790
+ }
791
+ error: null
792
+ }
793
+ | {
794
+ data: {
795
+ session: null
796
+ }
797
+ error: AuthError
798
+ }
799
+ | {
800
+ data: {
801
+ session: null
802
+ }
803
+ error: null
804
+ }
805
+ ) => Promise<R>
806
+ ): Promise<R> {
807
+ return await stackGuard('_useSession', async () => {
808
+ // the use of __loadSession here is the only correct use of the function!
809
+ const result = await this.__loadSession()
810
+
811
+ return await fn(result)
812
+ })
813
+ }
814
+
815
+ /**
816
+ * NEVER USE DIRECTLY!
817
+ *
818
+ * Always use {@link #_useSession}.
819
+ */
820
+ private async __loadSession(): Promise<
772
821
  | {
773
822
  data: {
774
823
  session: Session
@@ -788,11 +837,15 @@ export default class GoTrueClient {
788
837
  error: null
789
838
  }
790
839
  > {
840
+ if (this.logDebugMessages && !isInStackGuard('_useSession')) {
841
+ throw new Error('Please use #_useSession()')
842
+ }
843
+
791
844
  // make sure we've read the session from the url if there is one
792
845
  // save to just await, as long we make sure _initialize() never throws
793
846
  await this.initializePromise
794
847
 
795
- this._debug('#getSession()', 'begin')
848
+ this._debug('#__loadSession()', 'begin')
796
849
 
797
850
  try {
798
851
  let currentSession: Session | null = null
@@ -824,7 +877,7 @@ export default class GoTrueClient {
824
877
  : false
825
878
 
826
879
  this._debug(
827
- '#getSession()',
880
+ '#__loadSession()',
828
881
  `session has${hasExpired ? '' : ' not'} expired`,
829
882
  'expires_at',
830
883
  currentSession.expires_at
@@ -841,7 +894,7 @@ export default class GoTrueClient {
841
894
 
842
895
  return { data: { session }, error: null }
843
896
  } finally {
844
- this._debug('#getSession()', 'end')
897
+ this._debug('#__loadSession()', 'end')
845
898
  }
846
899
  }
847
900
 
@@ -851,20 +904,22 @@ export default class GoTrueClient {
851
904
  */
852
905
  async getUser(jwt?: string): Promise<UserResponse> {
853
906
  try {
854
- if (!jwt) {
855
- const { data, error } = await this.getSession()
856
- if (error) {
857
- throw error
858
- }
907
+ return await this._useSession(async (result) => {
908
+ if (!jwt) {
909
+ const { data, error } = result
910
+ if (error) {
911
+ throw error
912
+ }
859
913
 
860
- // Default to Authorization header if there is no existing session
861
- jwt = data.session?.access_token ?? undefined
862
- }
914
+ // Default to Authorization header if there is no existing session
915
+ jwt = data.session?.access_token ?? undefined
916
+ }
863
917
 
864
- return await _request(this.fetch, 'GET', `${this.url}/user`, {
865
- headers: this.headers,
866
- jwt: jwt,
867
- xform: _userResponse,
918
+ return await _request(this.fetch, 'GET', `${this.url}/user`, {
919
+ headers: this.headers,
920
+ jwt: jwt,
921
+ xform: _userResponse,
922
+ })
868
923
  })
869
924
  } catch (error) {
870
925
  if (isAuthError(error)) {
@@ -885,27 +940,29 @@ export default class GoTrueClient {
885
940
  } = {}
886
941
  ): Promise<UserResponse> {
887
942
  try {
888
- const { data: sessionData, error: sessionError } = await this.getSession()
889
- if (sessionError) {
890
- throw sessionError
891
- }
892
- if (!sessionData.session) {
893
- throw new AuthSessionMissingError()
894
- }
895
- const session: Session = sessionData.session
896
- const { data, error: userError } = await _request(this.fetch, 'PUT', `${this.url}/user`, {
897
- headers: this.headers,
898
- redirectTo: options?.emailRedirectTo,
899
- body: attributes,
900
- jwt: session.access_token,
901
- xform: _userResponse,
902
- })
903
- if (userError) throw userError
904
- session.user = data.user as User
905
- await this._saveSession(session)
906
- await this._notifyAllSubscribers('USER_UPDATED', session)
943
+ return await this._useSession(async (result) => {
944
+ const { data: sessionData, error: sessionError } = result
945
+ if (sessionError) {
946
+ throw sessionError
947
+ }
948
+ if (!sessionData.session) {
949
+ throw new AuthSessionMissingError()
950
+ }
951
+ const session: Session = sessionData.session
952
+ const { data, error: userError } = await _request(this.fetch, 'PUT', `${this.url}/user`, {
953
+ headers: this.headers,
954
+ redirectTo: options?.emailRedirectTo,
955
+ body: attributes,
956
+ jwt: session.access_token,
957
+ xform: _userResponse,
958
+ })
959
+ if (userError) throw userError
960
+ session.user = data.user as User
961
+ await this._saveSession(session)
962
+ await this._notifyAllSubscribers('USER_UPDATED', session)
907
963
 
908
- return { data: { user: session.user }, error: null }
964
+ return { data: { user: session.user }, error: null }
965
+ })
909
966
  } catch (error) {
910
967
  if (isAuthError(error)) {
911
968
  return { data: { user: null }, error }
@@ -997,29 +1054,31 @@ export default class GoTrueClient {
997
1054
  */
998
1055
  async refreshSession(currentSession?: { refresh_token: string }): Promise<AuthResponse> {
999
1056
  try {
1000
- if (!currentSession) {
1001
- const { data, error } = await this.getSession()
1002
- if (error) {
1003
- throw error
1004
- }
1057
+ return await this._useSession(async (result) => {
1058
+ if (!currentSession) {
1059
+ const { data, error } = result
1060
+ if (error) {
1061
+ throw error
1062
+ }
1005
1063
 
1006
- currentSession = data.session ?? undefined
1007
- }
1064
+ currentSession = data.session ?? undefined
1065
+ }
1008
1066
 
1009
- if (!currentSession?.refresh_token) {
1010
- throw new AuthSessionMissingError()
1011
- }
1067
+ if (!currentSession?.refresh_token) {
1068
+ throw new AuthSessionMissingError()
1069
+ }
1012
1070
 
1013
- const { session, error } = await this._callRefreshToken(currentSession.refresh_token)
1014
- if (error) {
1015
- return { data: { user: null, session: null }, error: error }
1016
- }
1071
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token)
1072
+ if (error) {
1073
+ return { data: { user: null, session: null }, error: error }
1074
+ }
1017
1075
 
1018
- if (!session) {
1019
- return { data: { user: null, session: null }, error: null }
1020
- }
1076
+ if (!session) {
1077
+ return { data: { user: null, session: null }, error: null }
1078
+ }
1021
1079
 
1022
- return { data: { user: session.user, session }, error: null }
1080
+ return { data: { user: session.user, session }, error: null }
1081
+ })
1023
1082
  } catch (error) {
1024
1083
  if (isAuthError(error)) {
1025
1084
  return { data: { user: null, session: null }, error }
@@ -1142,27 +1201,29 @@ export default class GoTrueClient {
1142
1201
  * If using others scope, no `SIGNED_OUT` event is fired!
1143
1202
  */
1144
1203
  async signOut({ scope }: SignOut = { scope: 'global' }): Promise<{ error: AuthError | null }> {
1145
- const { data, error: sessionError } = await this.getSession()
1146
- if (sessionError) {
1147
- return { error: sessionError }
1148
- }
1149
- const accessToken = data.session?.access_token
1150
- if (accessToken) {
1151
- const { error } = await this.admin.signOut(accessToken, scope)
1152
- if (error) {
1153
- // ignore 404s since user might not exist anymore
1154
- // ignore 401s since an invalid or expired JWT should sign out the current session
1155
- if (!(isAuthApiError(error) && (error.status === 404 || error.status === 401))) {
1156
- return { error }
1204
+ return await this._useSession(async (result) => {
1205
+ const { data, error: sessionError } = result
1206
+ if (sessionError) {
1207
+ return { error: sessionError }
1208
+ }
1209
+ const accessToken = data.session?.access_token
1210
+ if (accessToken) {
1211
+ const { error } = await this.admin.signOut(accessToken, scope)
1212
+ if (error) {
1213
+ // ignore 404s since user might not exist anymore
1214
+ // ignore 401s since an invalid or expired JWT should sign out the current session
1215
+ if (!(isAuthApiError(error) && (error.status === 404 || error.status === 401))) {
1216
+ return { error }
1217
+ }
1157
1218
  }
1158
1219
  }
1159
- }
1160
- if (scope !== 'others') {
1161
- await this._removeSession()
1162
- await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`)
1163
- await this._notifyAllSubscribers('SIGNED_OUT', null)
1164
- }
1165
- return { error: null }
1220
+ if (scope !== 'others') {
1221
+ await this._removeSession()
1222
+ await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`)
1223
+ await this._notifyAllSubscribers('SIGNED_OUT', null)
1224
+ }
1225
+ return { error: null }
1226
+ })
1166
1227
  }
1167
1228
 
1168
1229
  /**
@@ -1195,20 +1256,22 @@ export default class GoTrueClient {
1195
1256
  }
1196
1257
 
1197
1258
  private async _emitInitialSession(id: string): Promise<void> {
1198
- try {
1199
- const {
1200
- data: { session },
1201
- error,
1202
- } = await this.getSession()
1203
- if (error) throw error
1259
+ return await this._useSession(async (result) => {
1260
+ try {
1261
+ const {
1262
+ data: { session },
1263
+ error,
1264
+ } = result
1265
+ if (error) throw error
1204
1266
 
1205
- await this.stateChangeEmitters.get(id)?.callback('INITIAL_SESSION', session)
1206
- this._debug('INITIAL_SESSION', 'callback id', id, 'session', session)
1207
- } catch (err) {
1208
- await this.stateChangeEmitters.get(id)?.callback('INITIAL_SESSION', null)
1209
- this._debug('INITIAL_SESSION', 'callback id', id, 'error', err)
1210
- console.error(err)
1211
- }
1267
+ await this.stateChangeEmitters.get(id)?.callback('INITIAL_SESSION', session)
1268
+ this._debug('INITIAL_SESSION', 'callback id', id, 'session', session)
1269
+ } catch (err) {
1270
+ await this.stateChangeEmitters.get(id)?.callback('INITIAL_SESSION', null)
1271
+ this._debug('INITIAL_SESSION', 'callback id', id, 'error', err)
1272
+ console.error(err)
1273
+ }
1274
+ })
1212
1275
  }
1213
1276
 
1214
1277
  /**
@@ -1634,28 +1697,30 @@ export default class GoTrueClient {
1634
1697
  const now = Date.now()
1635
1698
 
1636
1699
  try {
1637
- const {
1638
- data: { session },
1639
- } = await this.getSession()
1640
-
1641
- if (!session || !session.refresh_token || !session.expires_at) {
1642
- this._debug('#_autoRefreshTokenTick()', 'no session')
1643
- return
1644
- }
1700
+ return await this._useSession(async (result) => {
1701
+ const {
1702
+ data: { session },
1703
+ } = result
1704
+
1705
+ if (!session || !session.refresh_token || !session.expires_at) {
1706
+ this._debug('#_autoRefreshTokenTick()', 'no session')
1707
+ return
1708
+ }
1645
1709
 
1646
- // session will expire in this many ticks (or has already expired if <= 0)
1647
- const expiresInTicks = Math.floor(
1648
- (session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION
1649
- )
1710
+ // session will expire in this many ticks (or has already expired if <= 0)
1711
+ const expiresInTicks = Math.floor(
1712
+ (session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION
1713
+ )
1650
1714
 
1651
- this._debug(
1652
- '#_autoRefreshTokenTick()',
1653
- `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`
1654
- )
1715
+ this._debug(
1716
+ '#_autoRefreshTokenTick()',
1717
+ `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`
1718
+ )
1655
1719
 
1656
- if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1657
- await this._callRefreshToken(session.refresh_token)
1658
- }
1720
+ if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1721
+ await this._callRefreshToken(session.refresh_token)
1722
+ }
1723
+ })
1659
1724
  } catch (e: any) {
1660
1725
  console.error('Auto refresh tick failed with error. This is likely a transient error.', e)
1661
1726
  }
@@ -1777,14 +1842,16 @@ export default class GoTrueClient {
1777
1842
 
1778
1843
  private async _unenroll(params: MFAUnenrollParams): Promise<AuthMFAUnenrollResponse> {
1779
1844
  try {
1780
- const { data: sessionData, error: sessionError } = await this.getSession()
1781
- if (sessionError) {
1782
- return { data: null, error: sessionError }
1783
- }
1845
+ return await this._useSession(async (result) => {
1846
+ const { data: sessionData, error: sessionError } = result
1847
+ if (sessionError) {
1848
+ return { data: null, error: sessionError }
1849
+ }
1784
1850
 
1785
- return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1786
- headers: this.headers,
1787
- jwt: sessionData?.session?.access_token,
1851
+ return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1852
+ headers: this.headers,
1853
+ jwt: sessionData?.session?.access_token,
1854
+ })
1788
1855
  })
1789
1856
  } catch (error) {
1790
1857
  if (isAuthError(error)) {
@@ -1799,30 +1866,32 @@ export default class GoTrueClient {
1799
1866
  */
1800
1867
  private async _enroll(params: MFAEnrollParams): Promise<AuthMFAEnrollResponse> {
1801
1868
  try {
1802
- const { data: sessionData, error: sessionError } = await this.getSession()
1803
- if (sessionError) {
1804
- return { data: null, error: sessionError }
1805
- }
1869
+ return await this._useSession(async (result) => {
1870
+ const { data: sessionData, error: sessionError } = result
1871
+ if (sessionError) {
1872
+ return { data: null, error: sessionError }
1873
+ }
1806
1874
 
1807
- const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
1808
- body: {
1809
- friendly_name: params.friendlyName,
1810
- factor_type: params.factorType,
1811
- issuer: params.issuer,
1812
- },
1813
- headers: this.headers,
1814
- jwt: sessionData?.session?.access_token,
1815
- })
1875
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
1876
+ body: {
1877
+ friendly_name: params.friendlyName,
1878
+ factor_type: params.factorType,
1879
+ issuer: params.issuer,
1880
+ },
1881
+ headers: this.headers,
1882
+ jwt: sessionData?.session?.access_token,
1883
+ })
1816
1884
 
1817
- if (error) {
1818
- return { data: null, error }
1819
- }
1885
+ if (error) {
1886
+ return { data: null, error }
1887
+ }
1820
1888
 
1821
- if (data?.totp?.qr_code) {
1822
- data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
1823
- }
1889
+ if (data?.totp?.qr_code) {
1890
+ data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
1891
+ }
1824
1892
 
1825
- return { data, error: null }
1893
+ return { data, error: null }
1894
+ })
1826
1895
  } catch (error) {
1827
1896
  if (isAuthError(error)) {
1828
1897
  return { data: null, error }
@@ -1836,32 +1905,34 @@ export default class GoTrueClient {
1836
1905
  */
1837
1906
  private async _verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse> {
1838
1907
  try {
1839
- const { data: sessionData, error: sessionError } = await this.getSession()
1840
- if (sessionError) {
1841
- return { data: null, error: sessionError }
1842
- }
1908
+ return await this._useSession(async (result) => {
1909
+ const { data: sessionData, error: sessionError } = result
1910
+ if (sessionError) {
1911
+ return { data: null, error: sessionError }
1912
+ }
1843
1913
 
1844
- const { data, error } = await _request(
1845
- this.fetch,
1846
- 'POST',
1847
- `${this.url}/factors/${params.factorId}/verify`,
1848
- {
1849
- body: { code: params.code, challenge_id: params.challengeId },
1850
- headers: this.headers,
1851
- jwt: sessionData?.session?.access_token,
1914
+ const { data, error } = await _request(
1915
+ this.fetch,
1916
+ 'POST',
1917
+ `${this.url}/factors/${params.factorId}/verify`,
1918
+ {
1919
+ body: { code: params.code, challenge_id: params.challengeId },
1920
+ headers: this.headers,
1921
+ jwt: sessionData?.session?.access_token,
1922
+ }
1923
+ )
1924
+ if (error) {
1925
+ return { data: null, error }
1852
1926
  }
1853
- )
1854
- if (error) {
1855
- return { data: null, error }
1856
- }
1857
1927
 
1858
- await this._saveSession({
1859
- expires_at: Math.round(Date.now() / 1000) + data.expires_in,
1860
- ...data,
1861
- })
1862
- await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
1928
+ await this._saveSession({
1929
+ expires_at: Math.round(Date.now() / 1000) + data.expires_in,
1930
+ ...data,
1931
+ })
1932
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
1863
1933
 
1864
- return { data, error }
1934
+ return { data, error }
1935
+ })
1865
1936
  } catch (error) {
1866
1937
  if (isAuthError(error)) {
1867
1938
  return { data: null, error }
@@ -1875,20 +1946,22 @@ export default class GoTrueClient {
1875
1946
  */
1876
1947
  private async _challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse> {
1877
1948
  try {
1878
- const { data: sessionData, error: sessionError } = await this.getSession()
1879
- if (sessionError) {
1880
- return { data: null, error: sessionError }
1881
- }
1882
-
1883
- return await _request(
1884
- this.fetch,
1885
- 'POST',
1886
- `${this.url}/factors/${params.factorId}/challenge`,
1887
- {
1888
- headers: this.headers,
1889
- jwt: sessionData?.session?.access_token,
1949
+ return await this._useSession(async (result) => {
1950
+ const { data: sessionData, error: sessionError } = result
1951
+ if (sessionError) {
1952
+ return { data: null, error: sessionError }
1890
1953
  }
1891
- )
1954
+
1955
+ return await _request(
1956
+ this.fetch,
1957
+ 'POST',
1958
+ `${this.url}/factors/${params.factorId}/challenge`,
1959
+ {
1960
+ headers: this.headers,
1961
+ jwt: sessionData?.session?.access_token,
1962
+ }
1963
+ )
1964
+ })
1892
1965
  } catch (error) {
1893
1966
  if (isAuthError(error)) {
1894
1967
  return { data: null, error }
@@ -1946,39 +2019,41 @@ export default class GoTrueClient {
1946
2019
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
1947
2020
  */
1948
2021
  private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
1949
- const {
1950
- data: { session },
1951
- error: sessionError,
1952
- } = await this.getSession()
1953
- if (sessionError) {
1954
- return { data: null, error: sessionError }
1955
- }
1956
- if (!session) {
1957
- return {
1958
- data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
1959
- error: null,
2022
+ return await this._useSession(async (result) => {
2023
+ const {
2024
+ data: { session },
2025
+ error: sessionError,
2026
+ } = result
2027
+ if (sessionError) {
2028
+ return { data: null, error: sessionError }
2029
+ }
2030
+ if (!session) {
2031
+ return {
2032
+ data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
2033
+ error: null,
2034
+ }
1960
2035
  }
1961
- }
1962
2036
 
1963
- const payload = this._decodeJWT(session.access_token)
2037
+ const payload = this._decodeJWT(session.access_token)
1964
2038
 
1965
- let currentLevel: AuthenticatorAssuranceLevels | null = null
2039
+ let currentLevel: AuthenticatorAssuranceLevels | null = null
1966
2040
 
1967
- if (payload.aal) {
1968
- currentLevel = payload.aal
1969
- }
2041
+ if (payload.aal) {
2042
+ currentLevel = payload.aal
2043
+ }
1970
2044
 
1971
- let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
2045
+ let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
1972
2046
 
1973
- const verifiedFactors =
1974
- session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
2047
+ const verifiedFactors =
2048
+ session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
1975
2049
 
1976
- if (verifiedFactors.length > 0) {
1977
- nextLevel = 'aal2'
1978
- }
2050
+ if (verifiedFactors.length > 0) {
2051
+ nextLevel = 'aal2'
2052
+ }
1979
2053
 
1980
- const currentAuthenticationMethods = payload.amr || []
2054
+ const currentAuthenticationMethods = payload.amr || []
1981
2055
 
1982
- return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2056
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2057
+ })
1983
2058
  }
1984
2059
  }