@supabase/gotrue-js 2.41.0 → 2.42.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,8 +29,6 @@ import {
29
29
  generatePKCEVerifier,
30
30
  generatePKCEChallenge,
31
31
  supportsLocalStorage,
32
- stackGuard,
33
- isInStackGuard,
34
32
  } from './lib/helpers'
35
33
  import localStorageAdapter from './lib/local-storage'
36
34
  import { polyfillGlobalThis } from './lib/polyfills'
@@ -281,6 +279,8 @@ export default class GoTrueClient {
281
279
  redirectType
282
280
  )
283
281
 
282
+ await this._saveSession(session)
283
+
284
284
  setTimeout(async () => {
285
285
  if (redirectType === 'recovery') {
286
286
  await this._notifyAllSubscribers('PASSWORD_RECOVERY', session)
@@ -291,6 +291,7 @@ export default class GoTrueClient {
291
291
 
292
292
  return { error: null }
293
293
  }
294
+
294
295
  // no login attempt via callback url try to recover session from storage
295
296
  await this._recoverAndRefresh()
296
297
  return { error: null }
@@ -698,20 +699,18 @@ export default class GoTrueClient {
698
699
  */
699
700
  async reauthenticate(): Promise<AuthResponse> {
700
701
  try {
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()
702
+ const {
703
+ data: { session },
704
+ error: sessionError,
705
+ } = await this.getSession()
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,
712
- })
713
- return { data: { user: null, session: null }, error }
709
+ const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
710
+ headers: this.headers,
711
+ jwt: session.access_token,
714
712
  })
713
+ return { data: { user: null, session: null }, error }
715
714
  } catch (error) {
716
715
  if (isAuthError(error)) {
717
716
  return { data: { user: null, session: null }, error }
@@ -769,55 +768,7 @@ export default class GoTrueClient {
769
768
  * Returns the session, refreshing it if necessary.
770
769
  * 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.
771
770
  */
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<
771
+ async getSession(): Promise<
821
772
  | {
822
773
  data: {
823
774
  session: Session
@@ -837,15 +788,11 @@ export default class GoTrueClient {
837
788
  error: null
838
789
  }
839
790
  > {
840
- if (this.logDebugMessages && !isInStackGuard('_useSession')) {
841
- throw new Error('Please use #_useSession()')
842
- }
843
-
844
791
  // make sure we've read the session from the url if there is one
845
792
  // save to just await, as long we make sure _initialize() never throws
846
793
  await this.initializePromise
847
794
 
848
- this._debug('#__loadSession()', 'begin')
795
+ this._debug('#getSession()', 'begin')
849
796
 
850
797
  try {
851
798
  let currentSession: Session | null = null
@@ -877,7 +824,7 @@ export default class GoTrueClient {
877
824
  : false
878
825
 
879
826
  this._debug(
880
- '#__loadSession()',
827
+ '#getSession()',
881
828
  `session has${hasExpired ? '' : ' not'} expired`,
882
829
  'expires_at',
883
830
  currentSession.expires_at
@@ -894,7 +841,7 @@ export default class GoTrueClient {
894
841
 
895
842
  return { data: { session }, error: null }
896
843
  } finally {
897
- this._debug('#__loadSession()', 'end')
844
+ this._debug('#getSession()', 'end')
898
845
  }
899
846
  }
900
847
 
@@ -904,22 +851,20 @@ export default class GoTrueClient {
904
851
  */
905
852
  async getUser(jwt?: string): Promise<UserResponse> {
906
853
  try {
907
- return await this._useSession(async (result) => {
908
- if (!jwt) {
909
- const { data, error } = result
910
- if (error) {
911
- throw error
912
- }
913
-
914
- // Default to Authorization header if there is no existing session
915
- jwt = data.session?.access_token ?? undefined
854
+ if (!jwt) {
855
+ const { data, error } = await this.getSession()
856
+ if (error) {
857
+ throw error
916
858
  }
917
859
 
918
- return await _request(this.fetch, 'GET', `${this.url}/user`, {
919
- headers: this.headers,
920
- jwt: jwt,
921
- xform: _userResponse,
922
- })
860
+ // Default to Authorization header if there is no existing session
861
+ jwt = data.session?.access_token ?? undefined
862
+ }
863
+
864
+ return await _request(this.fetch, 'GET', `${this.url}/user`, {
865
+ headers: this.headers,
866
+ jwt: jwt,
867
+ xform: _userResponse,
923
868
  })
924
869
  } catch (error) {
925
870
  if (isAuthError(error)) {
@@ -940,29 +885,27 @@ export default class GoTrueClient {
940
885
  } = {}
941
886
  ): Promise<UserResponse> {
942
887
  try {
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)
963
-
964
- return { data: { user: session.user }, error: null }
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,
965
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)
907
+
908
+ return { data: { user: session.user }, error: null }
966
909
  } catch (error) {
967
910
  if (isAuthError(error)) {
968
911
  return { data: { user: null }, error }
@@ -1054,31 +997,29 @@ export default class GoTrueClient {
1054
997
  */
1055
998
  async refreshSession(currentSession?: { refresh_token: string }): Promise<AuthResponse> {
1056
999
  try {
1057
- return await this._useSession(async (result) => {
1058
- if (!currentSession) {
1059
- const { data, error } = result
1060
- if (error) {
1061
- throw error
1062
- }
1063
-
1064
- currentSession = data.session ?? undefined
1000
+ if (!currentSession) {
1001
+ const { data, error } = await this.getSession()
1002
+ if (error) {
1003
+ throw error
1065
1004
  }
1066
1005
 
1067
- if (!currentSession?.refresh_token) {
1068
- throw new AuthSessionMissingError()
1069
- }
1006
+ currentSession = data.session ?? undefined
1007
+ }
1070
1008
 
1071
- const { session, error } = await this._callRefreshToken(currentSession.refresh_token)
1072
- if (error) {
1073
- return { data: { user: null, session: null }, error: error }
1074
- }
1009
+ if (!currentSession?.refresh_token) {
1010
+ throw new AuthSessionMissingError()
1011
+ }
1075
1012
 
1076
- if (!session) {
1077
- return { data: { user: null, session: null }, error: null }
1078
- }
1013
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token)
1014
+ if (error) {
1015
+ return { data: { user: null, session: null }, error: error }
1016
+ }
1079
1017
 
1080
- return { data: { user: session.user, session }, error: null }
1081
- })
1018
+ if (!session) {
1019
+ return { data: { user: null, session: null }, error: null }
1020
+ }
1021
+
1022
+ return { data: { user: session.user, session }, error: null }
1082
1023
  } catch (error) {
1083
1024
  if (isAuthError(error)) {
1084
1025
  return { data: { user: null, session: null }, error }
@@ -1201,29 +1142,27 @@ export default class GoTrueClient {
1201
1142
  * If using others scope, no `SIGNED_OUT` event is fired!
1202
1143
  */
1203
1144
  async signOut({ scope }: SignOut = { scope: 'global' }): Promise<{ error: AuthError | null }> {
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
- }
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 }
1218
1157
  }
1219
1158
  }
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
- })
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 }
1227
1166
  }
1228
1167
 
1229
1168
  /**
@@ -1256,22 +1195,20 @@ export default class GoTrueClient {
1256
1195
  }
1257
1196
 
1258
1197
  private async _emitInitialSession(id: string): Promise<void> {
1259
- return await this._useSession(async (result) => {
1260
- try {
1261
- const {
1262
- data: { session },
1263
- error,
1264
- } = result
1265
- if (error) throw error
1198
+ try {
1199
+ const {
1200
+ data: { session },
1201
+ error,
1202
+ } = await this.getSession()
1203
+ if (error) throw error
1266
1204
 
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
- })
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
+ }
1275
1212
  }
1276
1213
 
1277
1214
  /**
@@ -1697,30 +1634,28 @@ export default class GoTrueClient {
1697
1634
  const now = Date.now()
1698
1635
 
1699
1636
  try {
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
- }
1637
+ const {
1638
+ data: { session },
1639
+ } = await this.getSession()
1709
1640
 
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
- )
1641
+ if (!session || !session.refresh_token || !session.expires_at) {
1642
+ this._debug('#_autoRefreshTokenTick()', 'no session')
1643
+ return
1644
+ }
1714
1645
 
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
- )
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
+ )
1719
1650
 
1720
- if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1721
- await this._callRefreshToken(session.refresh_token)
1722
- }
1723
- })
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
+ )
1655
+
1656
+ if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1657
+ await this._callRefreshToken(session.refresh_token)
1658
+ }
1724
1659
  } catch (e: any) {
1725
1660
  console.error('Auto refresh tick failed with error. This is likely a transient error.', e)
1726
1661
  }
@@ -1842,16 +1777,14 @@ export default class GoTrueClient {
1842
1777
 
1843
1778
  private async _unenroll(params: MFAUnenrollParams): Promise<AuthMFAUnenrollResponse> {
1844
1779
  try {
1845
- return await this._useSession(async (result) => {
1846
- const { data: sessionData, error: sessionError } = result
1847
- if (sessionError) {
1848
- return { data: null, error: sessionError }
1849
- }
1780
+ const { data: sessionData, error: sessionError } = await this.getSession()
1781
+ if (sessionError) {
1782
+ return { data: null, error: sessionError }
1783
+ }
1850
1784
 
1851
- return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1852
- headers: this.headers,
1853
- jwt: sessionData?.session?.access_token,
1854
- })
1785
+ return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1786
+ headers: this.headers,
1787
+ jwt: sessionData?.session?.access_token,
1855
1788
  })
1856
1789
  } catch (error) {
1857
1790
  if (isAuthError(error)) {
@@ -1866,32 +1799,30 @@ export default class GoTrueClient {
1866
1799
  */
1867
1800
  private async _enroll(params: MFAEnrollParams): Promise<AuthMFAEnrollResponse> {
1868
1801
  try {
1869
- return await this._useSession(async (result) => {
1870
- const { data: sessionData, error: sessionError } = result
1871
- if (sessionError) {
1872
- return { data: null, error: sessionError }
1873
- }
1802
+ const { data: sessionData, error: sessionError } = await this.getSession()
1803
+ if (sessionError) {
1804
+ return { data: null, error: sessionError }
1805
+ }
1874
1806
 
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
- })
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
+ })
1884
1816
 
1885
- if (error) {
1886
- return { data: null, error }
1887
- }
1817
+ if (error) {
1818
+ return { data: null, error }
1819
+ }
1888
1820
 
1889
- if (data?.totp?.qr_code) {
1890
- data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
1891
- }
1821
+ if (data?.totp?.qr_code) {
1822
+ data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
1823
+ }
1892
1824
 
1893
- return { data, error: null }
1894
- })
1825
+ return { data, error: null }
1895
1826
  } catch (error) {
1896
1827
  if (isAuthError(error)) {
1897
1828
  return { data: null, error }
@@ -1905,34 +1836,32 @@ export default class GoTrueClient {
1905
1836
  */
1906
1837
  private async _verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse> {
1907
1838
  try {
1908
- return await this._useSession(async (result) => {
1909
- const { data: sessionData, error: sessionError } = result
1910
- if (sessionError) {
1911
- return { data: null, error: sessionError }
1912
- }
1839
+ const { data: sessionData, error: sessionError } = await this.getSession()
1840
+ if (sessionError) {
1841
+ return { data: null, error: sessionError }
1842
+ }
1913
1843
 
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 }
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,
1926
1852
  }
1853
+ )
1854
+ if (error) {
1855
+ return { data: null, error }
1856
+ }
1927
1857
 
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)
1933
-
1934
- return { data, error }
1858
+ await this._saveSession({
1859
+ expires_at: Math.round(Date.now() / 1000) + data.expires_in,
1860
+ ...data,
1935
1861
  })
1862
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
1863
+
1864
+ return { data, error }
1936
1865
  } catch (error) {
1937
1866
  if (isAuthError(error)) {
1938
1867
  return { data: null, error }
@@ -1946,22 +1875,20 @@ export default class GoTrueClient {
1946
1875
  */
1947
1876
  private async _challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse> {
1948
1877
  try {
1949
- return await this._useSession(async (result) => {
1950
- const { data: sessionData, error: sessionError } = result
1951
- if (sessionError) {
1952
- return { data: null, error: sessionError }
1953
- }
1878
+ const { data: sessionData, error: sessionError } = await this.getSession()
1879
+ if (sessionError) {
1880
+ return { data: null, error: sessionError }
1881
+ }
1954
1882
 
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
- })
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,
1890
+ }
1891
+ )
1965
1892
  } catch (error) {
1966
1893
  if (isAuthError(error)) {
1967
1894
  return { data: null, error }
@@ -2019,41 +1946,39 @@ export default class GoTrueClient {
2019
1946
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
2020
1947
  */
2021
1948
  private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
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
- }
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,
2035
1960
  }
1961
+ }
2036
1962
 
2037
- const payload = this._decodeJWT(session.access_token)
1963
+ const payload = this._decodeJWT(session.access_token)
2038
1964
 
2039
- let currentLevel: AuthenticatorAssuranceLevels | null = null
1965
+ let currentLevel: AuthenticatorAssuranceLevels | null = null
2040
1966
 
2041
- if (payload.aal) {
2042
- currentLevel = payload.aal
2043
- }
1967
+ if (payload.aal) {
1968
+ currentLevel = payload.aal
1969
+ }
2044
1970
 
2045
- let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
1971
+ let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
2046
1972
 
2047
- const verifiedFactors =
2048
- session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
1973
+ const verifiedFactors =
1974
+ session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
2049
1975
 
2050
- if (verifiedFactors.length > 0) {
2051
- nextLevel = 'aal2'
2052
- }
1976
+ if (verifiedFactors.length > 0) {
1977
+ nextLevel = 'aal2'
1978
+ }
2053
1979
 
2054
- const currentAuthenticationMethods = payload.amr || []
1980
+ const currentAuthenticationMethods = payload.amr || []
2055
1981
 
2056
- return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2057
- })
1982
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2058
1983
  }
2059
1984
  }