@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.
@@ -109,10 +109,10 @@ class GoTrueClient {
109
109
  * manually when checking for an error from an auth redirect (oauth, magiclink, password recovery, etc).
110
110
  */
111
111
  initialize() {
112
- if (!this.initializePromise) {
113
- this.initializePromise = this._initialize();
112
+ if (this.initializePromise) {
113
+ return this.initializePromise;
114
114
  }
115
- return this.initializePromise;
115
+ return this._initialize();
116
116
  }
117
117
  /**
118
118
  * IMPORTANT:
@@ -122,49 +122,52 @@ class GoTrueClient {
122
122
  */
123
123
  async _initialize() {
124
124
  if (this.initializePromise) {
125
- return this.initializePromise;
125
+ throw new Error('Double call of #_initialize()');
126
126
  }
127
- try {
128
- const isPKCEFlow = (0, helpers_1.isBrowser)() ? await this._isPKCEFlow() : false;
129
- this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
130
- if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
131
- const { data, error } = await this._getSessionFromUrl(isPKCEFlow);
132
- if (error) {
133
- this._debug('#_initialize()', 'error detecting session from URL', error);
134
- // failed login attempt via url,
135
- // remove old session as in verifyOtp, signUp and signInWith*
136
- await this._removeSession();
137
- return { error };
138
- }
139
- const { session, redirectType } = data;
140
- this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
141
- await this._saveSession(session);
142
- setTimeout(async () => {
143
- if (redirectType === 'recovery') {
144
- await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
145
- }
146
- else {
147
- await this._notifyAllSubscribers('SIGNED_IN', session);
127
+ this.initializePromise = (0, helpers_1.stackGuard)('_initialize', async () => {
128
+ try {
129
+ const isPKCEFlow = (0, helpers_1.isBrowser)() ? await this._isPKCEFlow() : false;
130
+ this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
131
+ if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
132
+ const { data, error } = await this._getSessionFromUrl(isPKCEFlow);
133
+ if (error) {
134
+ this._debug('#_initialize()', 'error detecting session from URL', error);
135
+ // failed login attempt via url,
136
+ // remove old session as in verifyOtp, signUp and signInWith*
137
+ await this._removeSession();
138
+ return { error };
148
139
  }
149
- }, 0);
140
+ const { session, redirectType } = data;
141
+ this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
142
+ await this._saveSession(session);
143
+ setTimeout(async () => {
144
+ if (redirectType === 'recovery') {
145
+ await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
146
+ }
147
+ else {
148
+ await this._notifyAllSubscribers('SIGNED_IN', session);
149
+ }
150
+ }, 0);
151
+ return { error: null };
152
+ }
153
+ // no login attempt via callback url try to recover session from storage
154
+ await this._recoverAndRefresh();
150
155
  return { error: null };
151
156
  }
152
- // no login attempt via callback url try to recover session from storage
153
- await this._recoverAndRefresh();
154
- return { error: null };
155
- }
156
- catch (error) {
157
- if ((0, errors_1.isAuthError)(error)) {
158
- return { error };
157
+ catch (error) {
158
+ if ((0, errors_1.isAuthError)(error)) {
159
+ return { error };
160
+ }
161
+ return {
162
+ error: new errors_1.AuthUnknownError('Unexpected error during initialization', error),
163
+ };
159
164
  }
160
- return {
161
- error: new errors_1.AuthUnknownError('Unexpected error during initialization', error),
162
- };
163
- }
164
- finally {
165
- await this._handleVisibilityChange();
166
- this._debug('#_initialize()', 'end');
167
- }
165
+ finally {
166
+ await this._handleVisibilityChange();
167
+ this._debug('#_initialize()', 'end');
168
+ }
169
+ });
170
+ return await this.initializePromise;
168
171
  }
169
172
  /**
170
173
  * Creates a new user.
@@ -526,16 +529,18 @@ class GoTrueClient {
526
529
  */
527
530
  async reauthenticate() {
528
531
  try {
529
- const { data: { session }, error: sessionError, } = await this.getSession();
530
- if (sessionError)
531
- throw sessionError;
532
- if (!session)
533
- throw new errors_1.AuthSessionMissingError();
534
- const { error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/reauthenticate`, {
535
- headers: this.headers,
536
- jwt: session.access_token,
532
+ return await this._useSession(async (result) => {
533
+ const { data: { session }, error: sessionError, } = result;
534
+ if (sessionError)
535
+ throw sessionError;
536
+ if (!session)
537
+ throw new errors_1.AuthSessionMissingError();
538
+ const { error } = await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/reauthenticate`, {
539
+ headers: this.headers,
540
+ jwt: session.access_token,
541
+ });
542
+ return { data: { user: null, session: null }, error };
537
543
  });
538
- return { data: { user: null, session: null }, error };
539
544
  }
540
545
  catch (error) {
541
546
  if ((0, errors_1.isAuthError)(error)) {
@@ -592,10 +597,42 @@ class GoTrueClient {
592
597
  * 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.
593
598
  */
594
599
  async getSession() {
600
+ return this._useSession(async (result) => {
601
+ return result;
602
+ });
603
+ }
604
+ /**
605
+ * Use instead of {@link #getSession} inside the library. It is
606
+ * semantically usually what you want, as getting a session involves some
607
+ * processing afterwards that requires only one client operating on the
608
+ * session at once across multiple tabs or processes.
609
+ */
610
+ async _useSession(fn) {
611
+ return await (0, helpers_1.stackGuard)('_useSession', async () => {
612
+ // the use of __loadSession here is the only correct use of the function!
613
+ const result = await this.__loadSession();
614
+ return await fn(result);
615
+ });
616
+ }
617
+ /**
618
+ * NEVER USE DIRECTLY!
619
+ *
620
+ * Always use {@link #_useSession}.
621
+ */
622
+ async __loadSession() {
623
+ this._debug('#__loadSession()', 'begin');
624
+ if (this.logDebugMessages && !(0, helpers_1.isInStackGuard)('_useSession')) {
625
+ throw new Error('Please use #_useSession()');
626
+ }
595
627
  // make sure we've read the session from the url if there is one
596
628
  // save to just await, as long we make sure _initialize() never throws
597
- await this.initializePromise;
598
- this._debug('#getSession()', 'begin');
629
+ if (!(0, helpers_1.isInStackGuard)('_initialize')) {
630
+ // only wait when not called from within #_initialize() since it's
631
+ // waiting for itself. one such pathway is #_initialize() ->
632
+ // #_handleVisibilityChange() -> #_onVisbilityChanged() ->
633
+ // #_loadSession().
634
+ await this.initializePromise;
635
+ }
599
636
  try {
600
637
  let currentSession = null;
601
638
  if (this.persistSession) {
@@ -621,7 +658,7 @@ class GoTrueClient {
621
658
  const hasExpired = currentSession.expires_at
622
659
  ? currentSession.expires_at <= Date.now() / 1000
623
660
  : false;
624
- this._debug('#getSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
661
+ this._debug('#__loadSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
625
662
  if (!hasExpired) {
626
663
  return { data: { session: currentSession }, error: null };
627
664
  }
@@ -632,7 +669,7 @@ class GoTrueClient {
632
669
  return { data: { session }, error: null };
633
670
  }
634
671
  finally {
635
- this._debug('#getSession()', 'end');
672
+ this._debug('#__loadSession()', 'end');
636
673
  }
637
674
  }
638
675
  /**
@@ -640,20 +677,22 @@ class GoTrueClient {
640
677
  * @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.
641
678
  */
642
679
  async getUser(jwt) {
643
- var _a, _b;
644
680
  try {
645
- if (!jwt) {
646
- const { data, error } = await this.getSession();
647
- if (error) {
648
- throw error;
681
+ return await this._useSession(async (result) => {
682
+ var _a, _b;
683
+ if (!jwt) {
684
+ const { data, error } = result;
685
+ if (error) {
686
+ throw error;
687
+ }
688
+ // Default to Authorization header if there is no existing session
689
+ jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
649
690
  }
650
- // Default to Authorization header if there is no existing session
651
- jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
652
- }
653
- return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/user`, {
654
- headers: this.headers,
655
- jwt: jwt,
656
- xform: fetch_1._userResponse,
691
+ return await (0, fetch_1._request)(this.fetch, 'GET', `${this.url}/user`, {
692
+ headers: this.headers,
693
+ jwt: jwt,
694
+ xform: fetch_1._userResponse,
695
+ });
657
696
  });
658
697
  }
659
698
  catch (error) {
@@ -668,27 +707,29 @@ class GoTrueClient {
668
707
  */
669
708
  async updateUser(attributes, options = {}) {
670
709
  try {
671
- const { data: sessionData, error: sessionError } = await this.getSession();
672
- if (sessionError) {
673
- throw sessionError;
674
- }
675
- if (!sessionData.session) {
676
- throw new errors_1.AuthSessionMissingError();
677
- }
678
- const session = sessionData.session;
679
- const { data, error: userError } = await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/user`, {
680
- headers: this.headers,
681
- redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
682
- body: attributes,
683
- jwt: session.access_token,
684
- xform: fetch_1._userResponse,
710
+ return await this._useSession(async (result) => {
711
+ const { data: sessionData, error: sessionError } = result;
712
+ if (sessionError) {
713
+ throw sessionError;
714
+ }
715
+ if (!sessionData.session) {
716
+ throw new errors_1.AuthSessionMissingError();
717
+ }
718
+ const session = sessionData.session;
719
+ const { data, error: userError } = await (0, fetch_1._request)(this.fetch, 'PUT', `${this.url}/user`, {
720
+ headers: this.headers,
721
+ redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
722
+ body: attributes,
723
+ jwt: session.access_token,
724
+ xform: fetch_1._userResponse,
725
+ });
726
+ if (userError)
727
+ throw userError;
728
+ session.user = data.user;
729
+ await this._saveSession(session);
730
+ await this._notifyAllSubscribers('USER_UPDATED', session);
731
+ return { data: { user: session.user }, error: null };
685
732
  });
686
- if (userError)
687
- throw userError;
688
- session.user = data.user;
689
- await this._saveSession(session);
690
- await this._notifyAllSubscribers('USER_UPDATED', session);
691
- return { data: { user: session.user }, error: null };
692
733
  }
693
734
  catch (error) {
694
735
  if ((0, errors_1.isAuthError)(error)) {
@@ -764,26 +805,28 @@ class GoTrueClient {
764
805
  * @param currentSession The current session. If passed in, it must contain a refresh token.
765
806
  */
766
807
  async refreshSession(currentSession) {
767
- var _a;
768
808
  try {
769
- if (!currentSession) {
770
- const { data, error } = await this.getSession();
809
+ return await this._useSession(async (result) => {
810
+ var _a;
811
+ if (!currentSession) {
812
+ const { data, error } = result;
813
+ if (error) {
814
+ throw error;
815
+ }
816
+ currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : undefined;
817
+ }
818
+ if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
819
+ throw new errors_1.AuthSessionMissingError();
820
+ }
821
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
771
822
  if (error) {
772
- throw error;
823
+ return { data: { user: null, session: null }, error: error };
773
824
  }
774
- currentSession = (_a = data.session) !== null && _a !== void 0 ? _a : undefined;
775
- }
776
- if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
777
- throw new errors_1.AuthSessionMissingError();
778
- }
779
- const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
780
- if (error) {
781
- return { data: { user: null, session: null }, error: error };
782
- }
783
- if (!session) {
784
- return { data: { user: null, session: null }, error: null };
785
- }
786
- return { data: { user: session.user, session }, error: null };
825
+ if (!session) {
826
+ return { data: { user: null, session: null }, error: null };
827
+ }
828
+ return { data: { user: session.user, session }, error: null };
829
+ });
787
830
  }
788
831
  catch (error) {
789
832
  if ((0, errors_1.isAuthError)(error)) {
@@ -897,28 +940,30 @@ class GoTrueClient {
897
940
  * If using others scope, no `SIGNED_OUT` event is fired!
898
941
  */
899
942
  async signOut({ scope } = { scope: 'global' }) {
900
- var _a;
901
- const { data, error: sessionError } = await this.getSession();
902
- if (sessionError) {
903
- return { error: sessionError };
904
- }
905
- const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
906
- if (accessToken) {
907
- const { error } = await this.admin.signOut(accessToken, scope);
908
- if (error) {
909
- // ignore 404s since user might not exist anymore
910
- // ignore 401s since an invalid or expired JWT should sign out the current session
911
- if (!((0, errors_1.isAuthApiError)(error) && (error.status === 404 || error.status === 401))) {
912
- return { error };
943
+ return await this._useSession(async (result) => {
944
+ var _a;
945
+ const { data, error: sessionError } = result;
946
+ if (sessionError) {
947
+ return { error: sessionError };
948
+ }
949
+ const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
950
+ if (accessToken) {
951
+ const { error } = await this.admin.signOut(accessToken, scope);
952
+ if (error) {
953
+ // ignore 404s since user might not exist anymore
954
+ // ignore 401s since an invalid or expired JWT should sign out the current session
955
+ if (!((0, errors_1.isAuthApiError)(error) && (error.status === 404 || error.status === 401))) {
956
+ return { error };
957
+ }
913
958
  }
914
959
  }
915
- }
916
- if (scope !== 'others') {
917
- await this._removeSession();
918
- await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`);
919
- await this._notifyAllSubscribers('SIGNED_OUT', null);
920
- }
921
- return { error: null };
960
+ if (scope !== 'others') {
961
+ await this._removeSession();
962
+ await (0, helpers_1.removeItemAsync)(this.storage, `${this.storageKey}-code-verifier`);
963
+ await this._notifyAllSubscribers('SIGNED_OUT', null);
964
+ }
965
+ return { error: null };
966
+ });
922
967
  }
923
968
  /**
924
969
  * Receive a notification every time an auth event happens.
@@ -940,19 +985,21 @@ class GoTrueClient {
940
985
  return { data: { subscription } };
941
986
  }
942
987
  async _emitInitialSession(id) {
943
- var _a, _b;
944
- try {
945
- const { data: { session }, error, } = await this.getSession();
946
- if (error)
947
- throw error;
948
- await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
949
- this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
950
- }
951
- catch (err) {
952
- await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
953
- this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
954
- console.error(err);
955
- }
988
+ return await this._useSession(async (result) => {
989
+ var _a, _b;
990
+ try {
991
+ const { data: { session }, error, } = result;
992
+ if (error)
993
+ throw error;
994
+ await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
995
+ this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
996
+ }
997
+ catch (err) {
998
+ await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
999
+ this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
1000
+ console.error(err);
1001
+ }
1002
+ });
956
1003
  }
957
1004
  /**
958
1005
  * Sends a password reset request to an email address.
@@ -1292,17 +1339,19 @@ class GoTrueClient {
1292
1339
  try {
1293
1340
  const now = Date.now();
1294
1341
  try {
1295
- const { data: { session }, } = await this.getSession();
1296
- if (!session || !session.refresh_token || !session.expires_at) {
1297
- this._debug('#_autoRefreshTokenTick()', 'no session');
1298
- return;
1299
- }
1300
- // session will expire in this many ticks (or has already expired if <= 0)
1301
- const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
1302
- 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`);
1303
- if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1304
- await this._callRefreshToken(session.refresh_token);
1305
- }
1342
+ return await this._useSession(async (result) => {
1343
+ const { data: { session }, } = result;
1344
+ if (!session || !session.refresh_token || !session.expires_at) {
1345
+ this._debug('#_autoRefreshTokenTick()', 'no session');
1346
+ return;
1347
+ }
1348
+ // session will expire in this many ticks (or has already expired if <= 0)
1349
+ const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
1350
+ 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`);
1351
+ if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1352
+ await this._callRefreshToken(session.refresh_token);
1353
+ }
1354
+ });
1306
1355
  }
1307
1356
  catch (e) {
1308
1357
  console.error('Auto refresh tick failed with error. This is likely a transient error.', e);
@@ -1394,15 +1443,17 @@ class GoTrueClient {
1394
1443
  return `${this.url}/authorize?${urlParams.join('&')}`;
1395
1444
  }
1396
1445
  async _unenroll(params) {
1397
- var _a;
1398
1446
  try {
1399
- const { data: sessionData, error: sessionError } = await this.getSession();
1400
- if (sessionError) {
1401
- return { data: null, error: sessionError };
1402
- }
1403
- return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1404
- headers: this.headers,
1405
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1447
+ return await this._useSession(async (result) => {
1448
+ var _a;
1449
+ const { data: sessionData, error: sessionError } = result;
1450
+ if (sessionError) {
1451
+ return { data: null, error: sessionError };
1452
+ }
1453
+ return await (0, fetch_1._request)(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1454
+ headers: this.headers,
1455
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1456
+ });
1406
1457
  });
1407
1458
  }
1408
1459
  catch (error) {
@@ -1416,28 +1467,30 @@ class GoTrueClient {
1416
1467
  * {@see GoTrueMFAApi#enroll}
1417
1468
  */
1418
1469
  async _enroll(params) {
1419
- var _a, _b;
1420
1470
  try {
1421
- const { data: sessionData, error: sessionError } = await this.getSession();
1422
- if (sessionError) {
1423
- return { data: null, error: sessionError };
1424
- }
1425
- const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors`, {
1426
- body: {
1427
- friendly_name: params.friendlyName,
1428
- factor_type: params.factorType,
1429
- issuer: params.issuer,
1430
- },
1431
- headers: this.headers,
1432
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1471
+ return await this._useSession(async (result) => {
1472
+ var _a, _b;
1473
+ const { data: sessionData, error: sessionError } = result;
1474
+ if (sessionError) {
1475
+ return { data: null, error: sessionError };
1476
+ }
1477
+ const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors`, {
1478
+ body: {
1479
+ friendly_name: params.friendlyName,
1480
+ factor_type: params.factorType,
1481
+ issuer: params.issuer,
1482
+ },
1483
+ headers: this.headers,
1484
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1485
+ });
1486
+ if (error) {
1487
+ return { data: null, error };
1488
+ }
1489
+ if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
1490
+ data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
1491
+ }
1492
+ return { data, error: null };
1433
1493
  });
1434
- if (error) {
1435
- return { data: null, error };
1436
- }
1437
- if ((_b = data === null || data === void 0 ? void 0 : data.totp) === null || _b === void 0 ? void 0 : _b.qr_code) {
1438
- data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
1439
- }
1440
- return { data, error: null };
1441
1494
  }
1442
1495
  catch (error) {
1443
1496
  if ((0, errors_1.isAuthError)(error)) {
@@ -1450,23 +1503,25 @@ class GoTrueClient {
1450
1503
  * {@see GoTrueMFAApi#verify}
1451
1504
  */
1452
1505
  async _verify(params) {
1453
- var _a;
1454
1506
  try {
1455
- const { data: sessionData, error: sessionError } = await this.getSession();
1456
- if (sessionError) {
1457
- return { data: null, error: sessionError };
1458
- }
1459
- const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1460
- body: { code: params.code, challenge_id: params.challengeId },
1461
- headers: this.headers,
1462
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1507
+ return await this._useSession(async (result) => {
1508
+ var _a;
1509
+ const { data: sessionData, error: sessionError } = result;
1510
+ if (sessionError) {
1511
+ return { data: null, error: sessionError };
1512
+ }
1513
+ const { data, error } = await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1514
+ body: { code: params.code, challenge_id: params.challengeId },
1515
+ headers: this.headers,
1516
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1517
+ });
1518
+ if (error) {
1519
+ return { data: null, error };
1520
+ }
1521
+ await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1522
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1523
+ return { data, error };
1463
1524
  });
1464
- if (error) {
1465
- return { data: null, error };
1466
- }
1467
- await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1468
- await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1469
- return { data, error };
1470
1525
  }
1471
1526
  catch (error) {
1472
1527
  if ((0, errors_1.isAuthError)(error)) {
@@ -1479,15 +1534,17 @@ class GoTrueClient {
1479
1534
  * {@see GoTrueMFAApi#challenge}
1480
1535
  */
1481
1536
  async _challenge(params) {
1482
- var _a;
1483
1537
  try {
1484
- const { data: sessionData, error: sessionError } = await this.getSession();
1485
- if (sessionError) {
1486
- return { data: null, error: sessionError };
1487
- }
1488
- return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1489
- headers: this.headers,
1490
- jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1538
+ return await this._useSession(async (result) => {
1539
+ var _a;
1540
+ const { data: sessionData, error: sessionError } = result;
1541
+ if (sessionError) {
1542
+ return { data: null, error: sessionError };
1543
+ }
1544
+ return await (0, fetch_1._request)(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1545
+ headers: this.headers,
1546
+ jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1547
+ });
1491
1548
  });
1492
1549
  }
1493
1550
  catch (error) {
@@ -1535,29 +1592,31 @@ class GoTrueClient {
1535
1592
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
1536
1593
  */
1537
1594
  async _getAuthenticatorAssuranceLevel() {
1538
- var _a, _b;
1539
- const { data: { session }, error: sessionError, } = await this.getSession();
1540
- if (sessionError) {
1541
- return { data: null, error: sessionError };
1542
- }
1543
- if (!session) {
1544
- return {
1545
- data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
1546
- error: null,
1547
- };
1548
- }
1549
- const payload = this._decodeJWT(session.access_token);
1550
- let currentLevel = null;
1551
- if (payload.aal) {
1552
- currentLevel = payload.aal;
1553
- }
1554
- let nextLevel = currentLevel;
1555
- const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : [];
1556
- if (verifiedFactors.length > 0) {
1557
- nextLevel = 'aal2';
1558
- }
1559
- const currentAuthenticationMethods = payload.amr || [];
1560
- return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
1595
+ return await this._useSession(async (result) => {
1596
+ var _a, _b;
1597
+ const { data: { session }, error: sessionError, } = result;
1598
+ if (sessionError) {
1599
+ return { data: null, error: sessionError };
1600
+ }
1601
+ if (!session) {
1602
+ return {
1603
+ data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
1604
+ error: null,
1605
+ };
1606
+ }
1607
+ const payload = this._decodeJWT(session.access_token);
1608
+ let currentLevel = null;
1609
+ if (payload.aal) {
1610
+ currentLevel = payload.aal;
1611
+ }
1612
+ let nextLevel = currentLevel;
1613
+ const verifiedFactors = (_b = (_a = session.user.factors) === null || _a === void 0 ? void 0 : _a.filter((factor) => factor.status === 'verified')) !== null && _b !== void 0 ? _b : [];
1614
+ if (verifiedFactors.length > 0) {
1615
+ nextLevel = 'aal2';
1616
+ }
1617
+ const currentAuthenticationMethods = payload.amr || [];
1618
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null };
1619
+ });
1561
1620
  }
1562
1621
  }
1563
1622
  exports.default = GoTrueClient;