@supabase/gotrue-js 2.42.0 → 2.43.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.
@@ -2,7 +2,7 @@ import GoTrueAdminApi from './GoTrueAdminApi';
2
2
  import { DEFAULT_HEADERS, EXPIRY_MARGIN, GOTRUE_URL, STORAGE_KEY } from './lib/constants';
3
3
  import { AuthImplicitGrantRedirectError, AuthPKCEGrantCodeExchangeError, AuthInvalidCredentialsError, AuthSessionMissingError, AuthInvalidTokenResponseError, AuthUnknownError, isAuthApiError, isAuthError, isAuthRetryableFetchError, } from './lib/errors';
4
4
  import { _request, _sessionResponse, _userResponse, _ssoResponse } from './lib/fetch';
5
- import { decodeJWTPayload, Deferred, getItemAsync, getParameterByName, isBrowser, removeItemAsync, resolveFetch, setItemAsync, uuid, retryable, sleep, generatePKCEVerifier, generatePKCEChallenge, supportsLocalStorage, } from './lib/helpers';
5
+ import { decodeJWTPayload, Deferred, getItemAsync, getParameterByName, isBrowser, removeItemAsync, resolveFetch, setItemAsync, uuid, retryable, sleep, generatePKCEVerifier, generatePKCEChallenge, supportsLocalStorage, stackGuard, isInStackGuard, } from './lib/helpers';
6
6
  import localStorageAdapter from './lib/local-storage';
7
7
  import { polyfillGlobalThis } from './lib/polyfills';
8
8
  polyfillGlobalThis(); // Make "globalThis" available
@@ -104,10 +104,10 @@ export default class GoTrueClient {
104
104
  * manually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc).
105
105
  */
106
106
  initialize() {
107
- if (!this.initializePromise) {
108
- this.initializePromise = this._initialize();
107
+ if (this.initializePromise) {
108
+ return this.initializePromise;
109
109
  }
110
- return this.initializePromise;
110
+ return this._initialize();
111
111
  }
112
112
  /**
113
113
  * IMPORTANT:
@@ -117,49 +117,52 @@ export default class GoTrueClient {
117
117
  */
118
118
  async _initialize() {
119
119
  if (this.initializePromise) {
120
- return this.initializePromise;
120
+ throw new Error('Double call of #_initialize()');
121
121
  }
122
- try {
123
- const isPKCEFlow = isBrowser() ? await this._isPKCEFlow() : false;
124
- this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
125
- if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
126
- const { data, error } = await this._getSessionFromUrl(isPKCEFlow);
127
- if (error) {
128
- this._debug('#_initialize()', 'error detecting session from URL', error);
129
- // failed login attempt via url,
130
- // remove old session as in verifyOtp, signUp and signInWith*
131
- await this._removeSession();
132
- return { error };
133
- }
134
- const { session, redirectType } = data;
135
- this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
136
- await this._saveSession(session);
137
- setTimeout(async () => {
138
- if (redirectType === 'recovery') {
139
- await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
140
- }
141
- else {
142
- await this._notifyAllSubscribers('SIGNED_IN', session);
122
+ this.initializePromise = stackGuard('_initialize', async () => {
123
+ try {
124
+ const isPKCEFlow = isBrowser() ? await this._isPKCEFlow() : false;
125
+ this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
126
+ if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
127
+ const { data, error } = await this._getSessionFromUrl(isPKCEFlow);
128
+ if (error) {
129
+ this._debug('#_initialize()', 'error detecting session from URL', error);
130
+ // failed login attempt via url,
131
+ // remove old session as in verifyOtp, signUp and signInWith*
132
+ await this._removeSession();
133
+ return { error };
143
134
  }
144
- }, 0);
135
+ const { session, redirectType } = data;
136
+ this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
137
+ await this._saveSession(session);
138
+ setTimeout(async () => {
139
+ if (redirectType === 'recovery') {
140
+ await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
141
+ }
142
+ else {
143
+ await this._notifyAllSubscribers('SIGNED_IN', session);
144
+ }
145
+ }, 0);
146
+ return { error: null };
147
+ }
148
+ // no login attempt via callback url try to recover session from storage
149
+ await this._recoverAndRefresh();
145
150
  return { error: null };
146
151
  }
147
- // no login attempt via callback url try to recover session from storage
148
- await this._recoverAndRefresh();
149
- return { error: null };
150
- }
151
- catch (error) {
152
- if (isAuthError(error)) {
153
- return { error };
152
+ catch (error) {
153
+ if (isAuthError(error)) {
154
+ return { error };
155
+ }
156
+ return {
157
+ error: new AuthUnknownError('Unexpected error during initialization', error),
158
+ };
154
159
  }
155
- return {
156
- error: new AuthUnknownError('Unexpected error during initialization', error),
157
- };
158
- }
159
- finally {
160
- await this._handleVisibilityChange();
161
- this._debug('#_initialize()', 'end');
162
- }
160
+ finally {
161
+ await this._handleVisibilityChange();
162
+ this._debug('#_initialize()', 'end');
163
+ }
164
+ });
165
+ return await this.initializePromise;
163
166
  }
164
167
  /**
165
168
  * Creates a new user.
@@ -521,16 +524,18 @@ export default class GoTrueClient {
521
524
  */
522
525
  async reauthenticate() {
523
526
  try {
524
- const { data: { session }, error: sessionError, } = await this.getSession();
525
- if (sessionError)
526
- throw sessionError;
527
- if (!session)
528
- throw new AuthSessionMissingError();
529
- const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
530
- headers: this.headers,
531
- jwt: session.access_token,
527
+ return await this._useSession(async (result) => {
528
+ const { data: { session }, error: sessionError, } = result;
529
+ if (sessionError)
530
+ throw sessionError;
531
+ if (!session)
532
+ throw new AuthSessionMissingError();
533
+ const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
534
+ headers: this.headers,
535
+ jwt: session.access_token,
536
+ });
537
+ return { data: { user: null, session: null }, error };
532
538
  });
533
- return { data: { user: null, session: null }, error };
534
539
  }
535
540
  catch (error) {
536
541
  if (isAuthError(error)) {
@@ -587,10 +592,42 @@ export default class GoTrueClient {
587
592
  * 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.
588
593
  */
589
594
  async getSession() {
595
+ return this._useSession(async (result) => {
596
+ return result;
597
+ });
598
+ }
599
+ /**
600
+ * Use instead of {@link #getSession} inside the library. It is
601
+ * semantically usually what you want, as getting a session involves some
602
+ * processing afterwards that requires only one client operating on the
603
+ * session at once across multiple tabs or processes.
604
+ */
605
+ async _useSession(fn) {
606
+ return await stackGuard('_useSession', async () => {
607
+ // the use of __loadSession here is the only correct use of the function!
608
+ const result = await this.__loadSession();
609
+ return await fn(result);
610
+ });
611
+ }
612
+ /**
613
+ * NEVER USE DIRECTLY!
614
+ *
615
+ * Always use {@link #_useSession}.
616
+ */
617
+ async __loadSession() {
618
+ this._debug('#__loadSession()', 'begin');
619
+ if (this.logDebugMessages && !isInStackGuard('_useSession')) {
620
+ throw new Error('Please use #_useSession()');
621
+ }
590
622
  // make sure we've read the session from the url if there is one
591
623
  // save to just await, as long we make sure _initialize() never throws
592
- await this.initializePromise;
593
- this._debug('#getSession()', 'begin');
624
+ if (!isInStackGuard('_initialize')) {
625
+ // only wait when not called from within #_initialize() since it's
626
+ // waiting for itself. one such pathway is #_initialize() ->
627
+ // #_handleVisibilityChange() -> #_onVisbilityChanged() ->
628
+ // #_loadSession().
629
+ await this.initializePromise;
630
+ }
594
631
  try {
595
632
  let currentSession = null;
596
633
  if (this.persistSession) {
@@ -616,7 +653,7 @@ export default class GoTrueClient {
616
653
  const hasExpired = currentSession.expires_at
617
654
  ? currentSession.expires_at <= Date.now() / 1000
618
655
  : false;
619
- this._debug('#getSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
656
+ this._debug('#__loadSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
620
657
  if (!hasExpired) {
621
658
  return { data: { session: currentSession }, error: null };
622
659
  }
@@ -627,7 +664,7 @@ export default class GoTrueClient {
627
664
  return { data: { session }, error: null };
628
665
  }
629
666
  finally {
630
- this._debug('#getSession()', 'end');
667
+ this._debug('#__loadSession()', 'end');
631
668
  }
632
669
  }
633
670
  /**
@@ -635,20 +672,22 @@ export default class GoTrueClient {
635
672
  * @param jwt Takes in an optional access token jwt. If no jwt is provided, getUser() will attempt to get the jwt from the current session.
636
673
  */
637
674
  async getUser(jwt) {
638
- var _a, _b;
639
675
  try {
640
- if (!jwt) {
641
- const { data, error } = await this.getSession();
642
- if (error) {
643
- throw error;
676
+ return await this._useSession(async (result) => {
677
+ var _a, _b;
678
+ if (!jwt) {
679
+ const { data, error } = result;
680
+ if (error) {
681
+ throw error;
682
+ }
683
+ // Default to Authorization header if there is no existing session
684
+ jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
644
685
  }
645
- // Default to Authorization header if there is no existing session
646
- jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
647
- }
648
- return await _request(this.fetch, 'GET', `${this.url}/user`, {
649
- headers: this.headers,
650
- jwt: jwt,
651
- xform: _userResponse,
686
+ return await _request(this.fetch, 'GET', `${this.url}/user`, {
687
+ headers: this.headers,
688
+ jwt: jwt,
689
+ xform: _userResponse,
690
+ });
652
691
  });
653
692
  }
654
693
  catch (error) {
@@ -663,27 +702,29 @@ export default class GoTrueClient {
663
702
  */
664
703
  async updateUser(attributes, options = {}) {
665
704
  try {
666
- const { data: sessionData, error: sessionError } = await this.getSession();
667
- if (sessionError) {
668
- throw sessionError;
669
- }
670
- if (!sessionData.session) {
671
- throw new AuthSessionMissingError();
672
- }
673
- const session = sessionData.session;
674
- const { data, error: userError } = await _request(this.fetch, 'PUT', `${this.url}/user`, {
675
- headers: this.headers,
676
- redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
677
- body: attributes,
678
- jwt: session.access_token,
679
- xform: _userResponse,
705
+ return await this._useSession(async (result) => {
706
+ const { data: sessionData, error: sessionError } = result;
707
+ if (sessionError) {
708
+ throw sessionError;
709
+ }
710
+ if (!sessionData.session) {
711
+ throw new AuthSessionMissingError();
712
+ }
713
+ const session = sessionData.session;
714
+ const { data, error: userError } = await _request(this.fetch, 'PUT', `${this.url}/user`, {
715
+ headers: this.headers,
716
+ redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
717
+ body: attributes,
718
+ jwt: session.access_token,
719
+ xform: _userResponse,
720
+ });
721
+ if (userError)
722
+ throw userError;
723
+ session.user = data.user;
724
+ await this._saveSession(session);
725
+ await this._notifyAllSubscribers('USER_UPDATED', session);
726
+ return { data: { user: session.user }, error: null };
680
727
  });
681
- if (userError)
682
- throw userError;
683
- session.user = data.user;
684
- await this._saveSession(session);
685
- await this._notifyAllSubscribers('USER_UPDATED', session);
686
- return { data: { user: session.user }, error: null };
687
728
  }
688
729
  catch (error) {
689
730
  if (isAuthError(error)) {
@@ -759,26 +800,28 @@ export default class GoTrueClient {
759
800
  * @param currentSession The current session. If passed in, it must contain a refresh token.
760
801
  */
761
802
  async refreshSession(currentSession) {
762
- var _a;
763
803
  try {
764
- if (!currentSession) {
765
- const { data, error } = await this.getSession();
804
+ return await this._useSession(async (result) => {
805
+ var _a;
806
+ if (!currentSession) {
807
+ const { data, error } = result;
808
+ if (error) {
809
+ throw error;
810
+ }
811
+ currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : undefined;
812
+ }
813
+ if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
814
+ throw new AuthSessionMissingError();
815
+ }
816
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
766
817
  if (error) {
767
- throw error;
818
+ return { data: { user: null, session: null }, error: error };
768
819
  }
769
- currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : undefined;
770
- }
771
- if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
772
- throw new AuthSessionMissingError();
773
- }
774
- const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
775
- if (error) {
776
- return { data: { user: null, session: null }, error: error };
777
- }
778
- if (!session) {
779
- return { data: { user: null, session: null }, error: null };
780
- }
781
- return { data: { user: session.user, session }, error: null };
820
+ if (!session) {
821
+ return { data: { user: null, session: null }, error: null };
822
+ }
823
+ return { data: { user: session.user, session }, error: null };
824
+ });
782
825
  }
783
826
  catch (error) {
784
827
  if (isAuthError(error)) {
@@ -892,28 +935,30 @@ export default class GoTrueClient {
892
935
  * If using others scope, no `SIGNED_OUT` event is fired!
893
936
  */
894
937
  async signOut({ scope } = { scope: 'global' }) {
895
- var _a;
896
- const { data, error: sessionError } = await this.getSession();
897
- if (sessionError) {
898
- return { error: sessionError };
899
- }
900
- const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
901
- if (accessToken) {
902
- const { error } = await this.admin.signOut(accessToken, scope);
903
- if (error) {
904
- // ignore 404s since user might not exist anymore
905
- // ignore 401s since an invalid or expired JWT should sign out the current session
906
- if (!(isAuthApiError(error) && (error.status === 404 || error.status === 401))) {
907
- return { error };
938
+ return await this._useSession(async (result) => {
939
+ var _a;
940
+ const { data, error: sessionError } = result;
941
+ if (sessionError) {
942
+ return { error: sessionError };
943
+ }
944
+ const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
945
+ if (accessToken) {
946
+ const { error } = await this.admin.signOut(accessToken, scope);
947
+ if (error) {
948
+ // ignore 404s since user might not exist anymore
949
+ // ignore 401s since an invalid or expired JWT should sign out the current session
950
+ if (!(isAuthApiError(error) && (error.status === 404 || error.status === 401))) {
951
+ return { error };
952
+ }
908
953
  }
909
954
  }
910
- }
911
- if (scope !== 'others') {
912
- await this._removeSession();
913
- await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
914
- await this._notifyAllSubscribers('SIGNED_OUT', null);
915
- }
916
- return { error: null };
955
+ if (scope !== 'others') {
956
+ await this._removeSession();
957
+ await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
958
+ await this._notifyAllSubscribers('SIGNED_OUT', null);
959
+ }
960
+ return { error: null };
961
+ });
917
962
  }
918
963
  /**
919
964
  * Receive a notification every time an auth event happens.
@@ -935,19 +980,21 @@ export default class GoTrueClient {
935
980
  return { data: { subscription } };
936
981
  }
937
982
  async _emitInitialSession(id) {
938
- var _a, _b;
939
- try {
940
- const { data: { session }, error, } = await this.getSession();
941
- if (error)
942
- throw error;
943
- await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
944
- this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
945
- }
946
- catch (err) {
947
- await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
948
- this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
949
- console.error(err);
950
- }
983
+ return await this._useSession(async (result) => {
984
+ var _a, _b;
985
+ try {
986
+ const { data: { session }, error, } = result;
987
+ if (error)
988
+ throw error;
989
+ await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
990
+ this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
991
+ }
992
+ catch (err) {
993
+ await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
994
+ this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
995
+ console.error(err);
996
+ }
997
+ });
951
998
  }
952
999
  /**
953
1000
  * Sends a password reset request to an email address.
@@ -1287,17 +1334,19 @@ export default class GoTrueClient {
1287
1334
  try {
1288
1335
  const now = Date.now();
1289
1336
  try {
1290
- const { data: { session }, } = await this.getSession();
1291
- if (!session || !session.refresh_token || !session.expires_at) {
1292
- this._debug('#_autoRefreshTokenTick()', 'no session');
1293
- return;
1294
- }
1295
- // session will expire in this many ticks (or has already expired if <= 0)
1296
- const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
1297
- this._debug('#_autoRefreshTokenTick()', `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`);
1298
- if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1299
- await this._callRefreshToken(session.refresh_token);
1300
- }
1337
+ return await this._useSession(async (result) => {
1338
+ const { data: { session }, } = result;
1339
+ if (!session || !session.refresh_token || !session.expires_at) {
1340
+ this._debug('#_autoRefreshTokenTick()', 'no session');
1341
+ return;
1342
+ }
1343
+ // session will expire in this many ticks (or has already expired if <= 0)
1344
+ const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
1345
+ this._debug('#_autoRefreshTokenTick()', `access token expires in ${expiresInTicks} ticks, a tick lasts ${AUTO_REFRESH_TICK_DURATION}ms, refresh threshold is ${AUTO_REFRESH_TICK_THRESHOLD} ticks`);
1346
+ if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1347
+ await this._callRefreshToken(session.refresh_token);
1348
+ }
1349
+ });
1301
1350
  }
1302
1351
  catch (e) {
1303
1352
  console.error('Auto refresh tick failed with error. This is likely a transient error.', e);
@@ -1389,15 +1438,17 @@ export default class GoTrueClient {
1389
1438
  return `${this.url}/authorize?${urlParams.join('&')}`;
1390
1439
  }
1391
1440
  async _unenroll(params) {
1392
- var _a;
1393
1441
  try {
1394
- const { data: sessionData, error: sessionError } = await this.getSession();
1395
- if (sessionError) {
1396
- return { data: null, error: sessionError };
1397
- }
1398
- return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1399
- headers: this.headers,
1400
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1442
+ return await this._useSession(async (result) => {
1443
+ var _a;
1444
+ const { data: sessionData, error: sessionError } = result;
1445
+ if (sessionError) {
1446
+ return { data: null, error: sessionError };
1447
+ }
1448
+ return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1449
+ headers: this.headers,
1450
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1451
+ });
1401
1452
  });
1402
1453
  }
1403
1454
  catch (error) {
@@ -1411,28 +1462,30 @@ export default class GoTrueClient {
1411
1462
  * {@see GoTrueMFAApi#enroll}
1412
1463
  */
1413
1464
  async _enroll(params) {
1414
- var _a, _b;
1415
1465
  try {
1416
- const { data: sessionData, error: sessionError } = await this.getSession();
1417
- if (sessionError) {
1418
- return { data: null, error: sessionError };
1419
- }
1420
- const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
1421
- body: {
1422
- friendly_name: params.friendlyName,
1423
- factor_type: params.factorType,
1424
- issuer: params.issuer,
1425
- },
1426
- headers: this.headers,
1427
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1466
+ return await this._useSession(async (result) => {
1467
+ var _a, _b;
1468
+ const { data: sessionData, error: sessionError } = result;
1469
+ if (sessionError) {
1470
+ return { data: null, error: sessionError };
1471
+ }
1472
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
1473
+ body: {
1474
+ friendly_name: params.friendlyName,
1475
+ factor_type: params.factorType,
1476
+ issuer: params.issuer,
1477
+ },
1478
+ headers: this.headers,
1479
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1480
+ });
1481
+ if (error) {
1482
+ return { data: null, error };
1483
+ }
1484
+ if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
1485
+ data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
1486
+ }
1487
+ return { data, error: null };
1428
1488
  });
1429
- if (error) {
1430
- return { data: null, error };
1431
- }
1432
- if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
1433
- data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
1434
- }
1435
- return { data, error: null };
1436
1489
  }
1437
1490
  catch (error) {
1438
1491
  if (isAuthError(error)) {
@@ -1445,23 +1498,25 @@ export default class GoTrueClient {
1445
1498
  * {@see GoTrueMFAApi#verify}
1446
1499
  */
1447
1500
  async _verify(params) {
1448
- var _a;
1449
1501
  try {
1450
- const { data: sessionData, error: sessionError } = await this.getSession();
1451
- if (sessionError) {
1452
- return { data: null, error: sessionError };
1453
- }
1454
- const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1455
- body: { code: params.code, challenge_id: params.challengeId },
1456
- headers: this.headers,
1457
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1502
+ return await this._useSession(async (result) => {
1503
+ var _a;
1504
+ const { data: sessionData, error: sessionError } = result;
1505
+ if (sessionError) {
1506
+ return { data: null, error: sessionError };
1507
+ }
1508
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1509
+ body: { code: params.code, challenge_id: params.challengeId },
1510
+ headers: this.headers,
1511
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1512
+ });
1513
+ if (error) {
1514
+ return { data: null, error };
1515
+ }
1516
+ await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1517
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1518
+ return { data, error };
1458
1519
  });
1459
- if (error) {
1460
- return { data: null, error };
1461
- }
1462
- await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1463
- await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1464
- return { data, error };
1465
1520
  }
1466
1521
  catch (error) {
1467
1522
  if (isAuthError(error)) {
@@ -1474,15 +1529,17 @@ export default class GoTrueClient {
1474
1529
  * {@see GoTrueMFAApi#challenge}
1475
1530
  */
1476
1531
  async _challenge(params) {
1477
- var _a;
1478
1532
  try {
1479
- const { data: sessionData, error: sessionError } = await this.getSession();
1480
- if (sessionError) {
1481
- return { data: null, error: sessionError };
1482
- }
1483
- return await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1484
- headers: this.headers,
1485
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1533
+ return await this._useSession(async (result) => {
1534
+ var _a;
1535
+ const { data: sessionData, error: sessionError } = result;
1536
+ if (sessionError) {
1537
+ return { data: null, error: sessionError };
1538
+ }
1539
+ return await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1540
+ headers: this.headers,
1541
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1542
+ });
1486
1543
  });
1487
1544
  }
1488
1545
  catch (error) {
@@ -1530,29 +1587,31 @@ export default class GoTrueClient {
1530
1587
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
1531
1588
  */
1532
1589
  async _getAuthenticatorAssuranceLevel() {
1533
- var _a, _b;
1534
- const { data: { session }, error: sessionError, } = await this.getSession();
1535
- if (sessionError) {
1536
- return { data: null, error: sessionError };
1537
- }
1538
- if (!session) {
1539
- return {
1540
- data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
1541
- error: null,
1542
- };
1543
- }
1544
- const payload = this._decodeJWT(session.access_token);
1545
- let currentLevel = null;
1546
- if (payload.aal) {
1547
- currentLevel = payload.aal;
1548
- }
1549
- let nextLevel = currentLevel;
1550
- const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : [];
1551
- if (verifiedFactors.length > 0) {
1552
- nextLevel = 'aal2';
1553
- }
1554
- const currentAuthenticationMethods = payload.amr || [];
1555
- return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
1590
+ return await this._useSession(async (result) => {
1591
+ var _a, _b;
1592
+ const { data: { session }, error: sessionError, } = result;
1593
+ if (sessionError) {
1594
+ return { data: null, error: sessionError };
1595
+ }
1596
+ if (!session) {
1597
+ return {
1598
+ data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
1599
+ error: null,
1600
+ };
1601
+ }
1602
+ const payload = this._decodeJWT(session.access_token);
1603
+ let currentLevel = null;
1604
+ if (payload.aal) {
1605
+ currentLevel = payload.aal;
1606
+ }
1607
+ let nextLevel = currentLevel;
1608
+ const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : [];
1609
+ if (verifiedFactors.length > 0) {
1610
+ nextLevel = 'aal2';
1611
+ }
1612
+ const currentAuthenticationMethods = payload.amr || [];
1613
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
1614
+ });
1556
1615
  }
1557
1616
  }
1558
1617
  GoTrueClient.nextInstanceID = 0;