@supabase/gotrue-js 2.39.2 → 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.
@@ -1,17 +1,8 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import GoTrueAdminApi from './GoTrueAdminApi';
11
2
  import { DEFAULT_HEADERS, EXPIRY_MARGIN, GOTRUE_URL, STORAGE_KEY } from './lib/constants';
12
3
  import { AuthImplicitGrantRedirectError, AuthPKCEGrantCodeExchangeError, AuthInvalidCredentialsError, AuthSessionMissingError, AuthInvalidTokenResponseError, AuthUnknownError, isAuthApiError, isAuthError, isAuthRetryableFetchError, } from './lib/errors';
13
4
  import { _request, _sessionResponse, _userResponse, _ssoResponse } from './lib/fetch';
14
- 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';
15
6
  import localStorageAdapter from './lib/local-storage';
16
7
  import { polyfillGlobalThis } from './lib/polyfills';
17
8
  polyfillGlobalThis(); // Make "globalThis" available
@@ -94,10 +85,10 @@ export default class GoTrueClient {
94
85
  catch (e) {
95
86
  console.error('Failed to create a new BroadcastChannel, multi-tab state changes will not be available', e);
96
87
  }
97
- (_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.addEventListener('message', (event) => __awaiter(this, void 0, void 0, function* () {
88
+ (_a = this.broadcastChannel) === null || _a === void 0 ? void 0 : _a.addEventListener('message', async (event) => {
98
89
  this._debug('received broadcast notification from other tab or client', event);
99
- yield this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages
100
- }));
90
+ await this._notifyAllSubscribers(event.data.event, event.data.session, false); // broadcast = false so we don't get an endless loop of messages
91
+ });
101
92
  }
102
93
  this.initialize();
103
94
  }
@@ -124,53 +115,50 @@ export default class GoTrueClient {
124
115
  * 2. Never return a session from this method as it would be cached over
125
116
  * the whole lifetime of the client
126
117
  */
127
- _initialize() {
128
- return __awaiter(this, void 0, void 0, function* () {
129
- if (this.initializePromise) {
130
- return this.initializePromise;
131
- }
132
- try {
133
- const isPKCEFlow = isBrowser() ? yield this._isPKCEFlow() : false;
134
- this._debug('#_initialize()', 'begin', 'is PKCE flow', isPKCEFlow);
135
- if (isPKCEFlow || (this.detectSessionInUrl && this._isImplicitGrantFlow())) {
136
- const { data, error } = yield this._getSessionFromUrl(isPKCEFlow);
137
- if (error) {
138
- this._debug('#_initialize()', 'error detecting session from URL', error);
139
- // failed login attempt via url,
140
- // remove old session as in verifyOtp, signUp and signInWith*
141
- yield this._removeSession();
142
- return { error };
143
- }
144
- const { session, redirectType } = data;
145
- this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
146
- yield this._saveSession(session);
147
- setTimeout(() => __awaiter(this, void 0, void 0, function* () {
148
- if (redirectType === 'recovery') {
149
- yield this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
150
- }
151
- else {
152
- yield this._notifyAllSubscribers('SIGNED_IN', session);
153
- }
154
- }), 0);
155
- return { error: null };
156
- }
157
- // no login attempt via callback url try to recover session from storage
158
- yield this._recoverAndRefresh();
159
- return { error: null };
160
- }
161
- catch (error) {
162
- if (isAuthError(error)) {
118
+ async _initialize() {
119
+ if (this.initializePromise) {
120
+ return this.initializePromise;
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();
163
132
  return { error };
164
133
  }
165
- return {
166
- error: new AuthUnknownError('Unexpected error during initialization', error),
167
- };
134
+ const { session, redirectType } = data;
135
+ this._debug('#_initialize()', 'detected session in URL', session, 'redirect type', redirectType);
136
+ setTimeout(async () => {
137
+ if (redirectType === 'recovery') {
138
+ await this._notifyAllSubscribers('PASSWORD_RECOVERY', session);
139
+ }
140
+ else {
141
+ await this._notifyAllSubscribers('SIGNED_IN', session);
142
+ }
143
+ }, 0);
144
+ return { error: null };
168
145
  }
169
- finally {
170
- yield this._handleVisibilityChange();
171
- this._debug('#_initialize()', 'end');
146
+ // no login attempt via callback url try to recover session from storage
147
+ await this._recoverAndRefresh();
148
+ return { error: null };
149
+ }
150
+ catch (error) {
151
+ if (isAuthError(error)) {
152
+ return { error };
172
153
  }
173
- });
154
+ return {
155
+ error: new AuthUnknownError('Unexpected error during initialization', error),
156
+ };
157
+ }
158
+ finally {
159
+ await this._handleVisibilityChange();
160
+ this._debug('#_initialize()', 'end');
161
+ }
174
162
  }
175
163
  /**
176
164
  * Creates a new user.
@@ -182,72 +170,70 @@ export default class GoTrueClient {
182
170
  * @returns A logged-in session if the server has "autoconfirm" ON
183
171
  * @returns A user if the server has "autoconfirm" OFF
184
172
  */
185
- signUp(credentials) {
173
+ async signUp(credentials) {
186
174
  var _a, _b, _c;
187
- return __awaiter(this, void 0, void 0, function* () {
188
- try {
189
- yield this._removeSession();
190
- let res;
191
- if ('email' in credentials) {
192
- const { email, password, options } = credentials;
193
- let codeChallenge = null;
194
- let codeChallengeMethod = null;
195
- if (this.flowType === 'pkce') {
196
- const codeVerifier = generatePKCEVerifier();
197
- yield setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
198
- codeChallenge = yield generatePKCEChallenge(codeVerifier);
199
- codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
200
- }
201
- res = yield _request(this.fetch, 'POST', `${this.url}/signup`, {
202
- headers: this.headers,
203
- redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
204
- body: {
205
- email,
206
- password,
207
- data: (_a = options === null || options === void 0 ? void 0 : options.data) !== null && _a !== void 0 ? _a : {},
208
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
209
- code_challenge: codeChallenge,
210
- code_challenge_method: codeChallengeMethod,
211
- },
212
- xform: _sessionResponse,
213
- });
214
- }
215
- else if ('phone' in credentials) {
216
- const { phone, password, options } = credentials;
217
- res = yield _request(this.fetch, 'POST', `${this.url}/signup`, {
218
- headers: this.headers,
219
- body: {
220
- phone,
221
- password,
222
- data: (_b = options === null || options === void 0 ? void 0 : options.data) !== null && _b !== void 0 ? _b : {},
223
- channel: (_c = options === null || options === void 0 ? void 0 : options.channel) !== null && _c !== void 0 ? _c : 'sms',
224
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
225
- },
226
- xform: _sessionResponse,
227
- });
228
- }
229
- else {
230
- throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a password');
231
- }
232
- const { data, error } = res;
233
- if (error || !data) {
234
- return { data: { user: null, session: null }, error: error };
235
- }
236
- const session = data.session;
237
- const user = data.user;
238
- if (data.session) {
239
- yield this._saveSession(data.session);
240
- yield this._notifyAllSubscribers('SIGNED_IN', session);
241
- }
242
- return { data: { user, session }, error: null };
175
+ try {
176
+ await this._removeSession();
177
+ let res;
178
+ if ('email' in credentials) {
179
+ const { email, password, options } = credentials;
180
+ let codeChallenge = null;
181
+ let codeChallengeMethod = null;
182
+ if (this.flowType === 'pkce') {
183
+ const codeVerifier = generatePKCEVerifier();
184
+ await setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
185
+ codeChallenge = await generatePKCEChallenge(codeVerifier);
186
+ codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
187
+ }
188
+ res = await _request(this.fetch, 'POST', `${this.url}/signup`, {
189
+ headers: this.headers,
190
+ redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
191
+ body: {
192
+ email,
193
+ password,
194
+ data: (_a = options === null || options === void 0 ? void 0 : options.data) !== null && _a !== void 0 ? _a : {},
195
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
196
+ code_challenge: codeChallenge,
197
+ code_challenge_method: codeChallengeMethod,
198
+ },
199
+ xform: _sessionResponse,
200
+ });
243
201
  }
244
- catch (error) {
245
- if (isAuthError(error)) {
246
- return { data: { user: null, session: null }, error };
247
- }
248
- throw error;
202
+ else if ('phone' in credentials) {
203
+ const { phone, password, options } = credentials;
204
+ res = await _request(this.fetch, 'POST', `${this.url}/signup`, {
205
+ headers: this.headers,
206
+ body: {
207
+ phone,
208
+ password,
209
+ data: (_b = options === null || options === void 0 ? void 0 : options.data) !== null && _b !== void 0 ? _b : {},
210
+ channel: (_c = options === null || options === void 0 ? void 0 : options.channel) !== null && _c !== void 0 ? _c : 'sms',
211
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
212
+ },
213
+ xform: _sessionResponse,
214
+ });
249
215
  }
250
- });
216
+ else {
217
+ throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a password');
218
+ }
219
+ const { data, error } = res;
220
+ if (error || !data) {
221
+ return { data: { user: null, session: null }, error: error };
222
+ }
223
+ const session = data.session;
224
+ const user = data.user;
225
+ if (data.session) {
226
+ await this._saveSession(data.session);
227
+ await this._notifyAllSubscribers('SIGNED_IN', session);
228
+ }
229
+ return { data: { user, session }, error: null };
230
+ }
231
+ catch (error) {
232
+ if (isAuthError(error)) {
233
+ return { data: { user: null, session: null }, error };
234
+ }
235
+ throw error;
236
+ }
251
237
  }
252
238
  /**
253
239
  * Log in an existing user with an email and password or phone and password.
@@ -257,146 +243,138 @@ export default class GoTrueClient {
257
243
  * email/phone and password combination is wrong or that the account can only
258
244
  * be accessed via social login.
259
245
  */
260
- signInWithPassword(credentials) {
261
- return __awaiter(this, void 0, void 0, function* () {
262
- try {
263
- yield this._removeSession();
264
- let res;
265
- if ('email' in credentials) {
266
- const { email, password, options } = credentials;
267
- res = yield _request(this.fetch, 'POST', `${this.url}/token?grant_type=password`, {
268
- headers: this.headers,
269
- body: {
270
- email,
271
- password,
272
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
273
- },
274
- xform: _sessionResponse,
275
- });
276
- }
277
- else if ('phone' in credentials) {
278
- const { phone, password, options } = credentials;
279
- res = yield _request(this.fetch, 'POST', `${this.url}/token?grant_type=password`, {
280
- headers: this.headers,
281
- body: {
282
- phone,
283
- password,
284
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
285
- },
286
- xform: _sessionResponse,
287
- });
288
- }
289
- else {
290
- throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a password');
291
- }
292
- const { data, error } = res;
293
- if (error) {
294
- return { data: { user: null, session: null }, error };
295
- }
296
- else if (!data || !data.session || !data.user) {
297
- return { data: { user: null, session: null }, error: new AuthInvalidTokenResponseError() };
298
- }
299
- if (data.session) {
300
- yield this._saveSession(data.session);
301
- yield this._notifyAllSubscribers('SIGNED_IN', data.session);
302
- }
303
- return { data: { user: data.user, session: data.session }, error };
246
+ async signInWithPassword(credentials) {
247
+ try {
248
+ await this._removeSession();
249
+ let res;
250
+ if ('email' in credentials) {
251
+ const { email, password, options } = credentials;
252
+ res = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=password`, {
253
+ headers: this.headers,
254
+ body: {
255
+ email,
256
+ password,
257
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
258
+ },
259
+ xform: _sessionResponse,
260
+ });
304
261
  }
305
- catch (error) {
306
- if (isAuthError(error)) {
307
- return { data: { user: null, session: null }, error };
308
- }
309
- throw error;
262
+ else if ('phone' in credentials) {
263
+ const { phone, password, options } = credentials;
264
+ res = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=password`, {
265
+ headers: this.headers,
266
+ body: {
267
+ phone,
268
+ password,
269
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
270
+ },
271
+ xform: _sessionResponse,
272
+ });
310
273
  }
311
- });
274
+ else {
275
+ throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a password');
276
+ }
277
+ const { data, error } = res;
278
+ if (error) {
279
+ return { data: { user: null, session: null }, error };
280
+ }
281
+ else if (!data || !data.session || !data.user) {
282
+ return { data: { user: null, session: null }, error: new AuthInvalidTokenResponseError() };
283
+ }
284
+ if (data.session) {
285
+ await this._saveSession(data.session);
286
+ await this._notifyAllSubscribers('SIGNED_IN', data.session);
287
+ }
288
+ return { data: { user: data.user, session: data.session }, error };
289
+ }
290
+ catch (error) {
291
+ if (isAuthError(error)) {
292
+ return { data: { user: null, session: null }, error };
293
+ }
294
+ throw error;
295
+ }
312
296
  }
313
297
  /**
314
298
  * Log in an existing user via a third-party provider.
315
299
  * This method supports the PKCE flow.
316
300
  */
317
- signInWithOAuth(credentials) {
301
+ async signInWithOAuth(credentials) {
318
302
  var _a, _b, _c, _d;
319
- return __awaiter(this, void 0, void 0, function* () {
320
- yield this._removeSession();
321
- return yield this._handleProviderSignIn(credentials.provider, {
322
- redirectTo: (_a = credentials.options) === null || _a === void 0 ? void 0 : _a.redirectTo,
323
- scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes,
324
- queryParams: (_c = credentials.options) === null || _c === void 0 ? void 0 : _c.queryParams,
325
- skipBrowserRedirect: (_d = credentials.options) === null || _d === void 0 ? void 0 : _d.skipBrowserRedirect,
326
- });
303
+ await this._removeSession();
304
+ return await this._handleProviderSignIn(credentials.provider, {
305
+ redirectTo: (_a = credentials.options) === null || _a === void 0 ? void 0 : _a.redirectTo,
306
+ scopes: (_b = credentials.options) === null || _b === void 0 ? void 0 : _b.scopes,
307
+ queryParams: (_c = credentials.options) === null || _c === void 0 ? void 0 : _c.queryParams,
308
+ skipBrowserRedirect: (_d = credentials.options) === null || _d === void 0 ? void 0 : _d.skipBrowserRedirect,
327
309
  });
328
310
  }
329
311
  /**
330
312
  * Log in an existing user by exchanging an Auth Code issued during the PKCE flow.
331
313
  */
332
- exchangeCodeForSession(authCode) {
333
- return __awaiter(this, void 0, void 0, function* () {
334
- const codeVerifier = yield getItemAsync(this.storage, `${this.storageKey}-code-verifier`);
335
- const { data, error } = yield _request(this.fetch, 'POST', `${this.url}/token?grant_type=pkce`, {
314
+ async exchangeCodeForSession(authCode) {
315
+ const codeVerifier = await getItemAsync(this.storage, `${this.storageKey}-code-verifier`);
316
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=pkce`, {
317
+ headers: this.headers,
318
+ body: {
319
+ auth_code: authCode,
320
+ code_verifier: codeVerifier,
321
+ },
322
+ xform: _sessionResponse,
323
+ });
324
+ await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
325
+ if (error) {
326
+ return { data: { user: null, session: null }, error };
327
+ }
328
+ else if (!data || !data.session || !data.user) {
329
+ return { data: { user: null, session: null }, error: new AuthInvalidTokenResponseError() };
330
+ }
331
+ if (data.session) {
332
+ await this._saveSession(data.session);
333
+ await this._notifyAllSubscribers('SIGNED_IN', data.session);
334
+ }
335
+ return { data, error };
336
+ }
337
+ /**
338
+ * Allows signing in with an OIDC ID token. The authentication provider used
339
+ * should be enabled and configured.
340
+ */
341
+ async signInWithIdToken(credentials) {
342
+ await this._removeSession();
343
+ try {
344
+ const { options, provider, token, access_token, nonce } = credentials;
345
+ const res = await _request(this.fetch, 'POST', `${this.url}/token?grant_type=id_token`, {
336
346
  headers: this.headers,
337
347
  body: {
338
- auth_code: authCode,
339
- code_verifier: codeVerifier,
348
+ provider,
349
+ id_token: token,
350
+ access_token,
351
+ nonce,
352
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
340
353
  },
341
354
  xform: _sessionResponse,
342
355
  });
343
- yield removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
356
+ const { data, error } = res;
344
357
  if (error) {
345
358
  return { data: { user: null, session: null }, error };
346
359
  }
347
360
  else if (!data || !data.session || !data.user) {
348
- return { data: { user: null, session: null }, error: new AuthInvalidTokenResponseError() };
361
+ return {
362
+ data: { user: null, session: null },
363
+ error: new AuthInvalidTokenResponseError(),
364
+ };
349
365
  }
350
366
  if (data.session) {
351
- yield this._saveSession(data.session);
352
- yield this._notifyAllSubscribers('SIGNED_IN', data.session);
367
+ await this._saveSession(data.session);
368
+ await this._notifyAllSubscribers('SIGNED_IN', data.session);
353
369
  }
354
370
  return { data, error };
355
- });
356
- }
357
- /**
358
- * Allows signing in with an OIDC ID token. The authentication provider used
359
- * should be enabled and configured.
360
- */
361
- signInWithIdToken(credentials) {
362
- return __awaiter(this, void 0, void 0, function* () {
363
- yield this._removeSession();
364
- try {
365
- const { options, provider, token, access_token, nonce } = credentials;
366
- const res = yield _request(this.fetch, 'POST', `${this.url}/token?grant_type=id_token`, {
367
- headers: this.headers,
368
- body: {
369
- provider,
370
- id_token: token,
371
- access_token,
372
- nonce,
373
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
374
- },
375
- xform: _sessionResponse,
376
- });
377
- const { data, error } = res;
378
- if (error) {
379
- return { data: { user: null, session: null }, error };
380
- }
381
- else if (!data || !data.session || !data.user) {
382
- return {
383
- data: { user: null, session: null },
384
- error: new AuthInvalidTokenResponseError(),
385
- };
386
- }
387
- if (data.session) {
388
- yield this._saveSession(data.session);
389
- yield this._notifyAllSubscribers('SIGNED_IN', data.session);
390
- }
391
- return { data, error };
392
- }
393
- catch (error) {
394
- if (isAuthError(error)) {
395
- return { data: { user: null, session: null }, error };
396
- }
397
- throw error;
371
+ }
372
+ catch (error) {
373
+ if (isAuthError(error)) {
374
+ return { data: { user: null, session: null }, error };
398
375
  }
399
- });
376
+ throw error;
377
+ }
400
378
  }
401
379
  /**
402
380
  * Log in a user using magiclink or a one-time password (OTP).
@@ -415,97 +393,93 @@ export default class GoTrueClient {
415
393
  * at this time.
416
394
  * This method supports PKCE when an email is passed.
417
395
  */
418
- signInWithOtp(credentials) {
396
+ async signInWithOtp(credentials) {
419
397
  var _a, _b, _c, _d, _e;
420
- return __awaiter(this, void 0, void 0, function* () {
421
- try {
422
- yield this._removeSession();
423
- if ('email' in credentials) {
424
- const { email, options } = credentials;
425
- let codeChallenge = null;
426
- let codeChallengeMethod = null;
427
- if (this.flowType === 'pkce') {
428
- const codeVerifier = generatePKCEVerifier();
429
- yield setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
430
- codeChallenge = yield generatePKCEChallenge(codeVerifier);
431
- codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
432
- }
433
- const { error } = yield _request(this.fetch, 'POST', `${this.url}/otp`, {
434
- headers: this.headers,
435
- body: {
436
- email,
437
- data: (_a = options === null || options === void 0 ? void 0 : options.data) !== null && _a !== void 0 ? _a : {},
438
- create_user: (_b = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _b !== void 0 ? _b : true,
439
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
440
- code_challenge: codeChallenge,
441
- code_challenge_method: codeChallengeMethod,
442
- },
443
- redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
444
- });
445
- return { data: { user: null, session: null }, error };
446
- }
447
- if ('phone' in credentials) {
448
- const { phone, options } = credentials;
449
- const { data, error } = yield _request(this.fetch, 'POST', `${this.url}/otp`, {
450
- headers: this.headers,
451
- body: {
452
- phone,
453
- data: (_c = options === null || options === void 0 ? void 0 : options.data) !== null && _c !== void 0 ? _c : {},
454
- create_user: (_d = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _d !== void 0 ? _d : true,
455
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
456
- channel: (_e = options === null || options === void 0 ? void 0 : options.channel) !== null && _e !== void 0 ? _e : 'sms',
457
- },
458
- });
459
- return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error };
460
- }
461
- throw new AuthInvalidCredentialsError('You must provide either an email or phone number.');
398
+ try {
399
+ await this._removeSession();
400
+ if ('email' in credentials) {
401
+ const { email, options } = credentials;
402
+ let codeChallenge = null;
403
+ let codeChallengeMethod = null;
404
+ if (this.flowType === 'pkce') {
405
+ const codeVerifier = generatePKCEVerifier();
406
+ await setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
407
+ codeChallenge = await generatePKCEChallenge(codeVerifier);
408
+ codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
409
+ }
410
+ const { error } = await _request(this.fetch, 'POST', `${this.url}/otp`, {
411
+ headers: this.headers,
412
+ body: {
413
+ email,
414
+ data: (_a = options === null || options === void 0 ? void 0 : options.data) !== null && _a !== void 0 ? _a : {},
415
+ create_user: (_b = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _b !== void 0 ? _b : true,
416
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
417
+ code_challenge: codeChallenge,
418
+ code_challenge_method: codeChallengeMethod,
419
+ },
420
+ redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
421
+ });
422
+ return { data: { user: null, session: null }, error };
462
423
  }
463
- catch (error) {
464
- if (isAuthError(error)) {
465
- return { data: { user: null, session: null }, error };
466
- }
467
- throw error;
424
+ if ('phone' in credentials) {
425
+ const { phone, options } = credentials;
426
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/otp`, {
427
+ headers: this.headers,
428
+ body: {
429
+ phone,
430
+ data: (_c = options === null || options === void 0 ? void 0 : options.data) !== null && _c !== void 0 ? _c : {},
431
+ create_user: (_d = options === null || options === void 0 ? void 0 : options.shouldCreateUser) !== null && _d !== void 0 ? _d : true,
432
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
433
+ channel: (_e = options === null || options === void 0 ? void 0 : options.channel) !== null && _e !== void 0 ? _e : 'sms',
434
+ },
435
+ });
436
+ return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error };
468
437
  }
469
- });
438
+ throw new AuthInvalidCredentialsError('You must provide either an email or phone number.');
439
+ }
440
+ catch (error) {
441
+ if (isAuthError(error)) {
442
+ return { data: { user: null, session: null }, error };
443
+ }
444
+ throw error;
445
+ }
470
446
  }
471
447
  /**
472
448
  * Log in a user given a User supplied OTP received via mobile.
473
449
  */
474
- verifyOtp(params) {
450
+ async verifyOtp(params) {
475
451
  var _a, _b;
476
- return __awaiter(this, void 0, void 0, function* () {
477
- try {
478
- if (params.type !== 'email_change' && params.type !== 'phone_change') {
479
- // we don't want to remove the authenticated session if the user is performing an email_change or phone_change verification
480
- yield this._removeSession();
481
- }
482
- const { data, error } = yield _request(this.fetch, 'POST', `${this.url}/verify`, {
483
- headers: this.headers,
484
- body: Object.assign(Object.assign({}, params), { gotrue_meta_security: { captcha_token: (_a = params.options) === null || _a === void 0 ? void 0 : _a.captchaToken } }),
485
- redirectTo: (_b = params.options) === null || _b === void 0 ? void 0 : _b.redirectTo,
486
- xform: _sessionResponse,
487
- });
488
- if (error) {
489
- throw error;
490
- }
491
- if (!data) {
492
- throw new Error('An error occurred on token verification.');
493
- }
494
- const session = data.session;
495
- const user = data.user;
496
- if (session === null || session === void 0 ? void 0 : session.access_token) {
497
- yield this._saveSession(session);
498
- yield this._notifyAllSubscribers('SIGNED_IN', session);
499
- }
500
- return { data: { user, session }, error: null };
452
+ try {
453
+ if (params.type !== 'email_change' && params.type !== 'phone_change') {
454
+ // we don't want to remove the authenticated session if the user is performing an email_change or phone_change verification
455
+ await this._removeSession();
501
456
  }
502
- catch (error) {
503
- if (isAuthError(error)) {
504
- return { data: { user: null, session: null }, error };
505
- }
457
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/verify`, {
458
+ headers: this.headers,
459
+ body: Object.assign(Object.assign({}, params), { gotrue_meta_security: { captcha_token: (_a = params.options) === null || _a === void 0 ? void 0 : _a.captchaToken } }),
460
+ redirectTo: (_b = params.options) === null || _b === void 0 ? void 0 : _b.redirectTo,
461
+ xform: _sessionResponse,
462
+ });
463
+ if (error) {
506
464
  throw error;
507
465
  }
508
- });
466
+ if (!data) {
467
+ throw new Error('An error occurred on token verification.');
468
+ }
469
+ const session = data.session;
470
+ const user = data.user;
471
+ if (session === null || session === void 0 ? void 0 : session.access_token) {
472
+ await this._saveSession(session);
473
+ await this._notifyAllSubscribers('SIGNED_IN', session);
474
+ }
475
+ return { data: { user, session }, error: null };
476
+ }
477
+ catch (error) {
478
+ if (isAuthError(error)) {
479
+ return { data: { user: null, session: null }, error };
480
+ }
481
+ throw error;
482
+ }
509
483
  }
510
484
  /**
511
485
  * Attempts a single-sign on using an enterprise Identity Provider. A
@@ -521,185 +495,205 @@ export default class GoTrueClient {
521
495
  * If you have built an organization-specific login page, you can use the
522
496
  * organization's SSO Identity Provider UUID directly instead.
523
497
  */
524
- signInWithSSO(params) {
498
+ async signInWithSSO(params) {
525
499
  var _a, _b, _c;
526
- return __awaiter(this, void 0, void 0, function* () {
527
- try {
528
- yield this._removeSession();
529
- return yield _request(this.fetch, 'POST', `${this.url}/sso`, {
530
- body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, ('providerId' in params ? { provider_id: params.providerId } : null)), ('domain' in params ? { domain: params.domain } : null)), { redirect_to: (_b = (_a = params.options) === null || _a === void 0 ? void 0 : _a.redirectTo) !== null && _b !== void 0 ? _b : undefined }), (((_c = params === null || params === void 0 ? void 0 : params.options) === null || _c === void 0 ? void 0 : _c.captchaToken)
531
- ? { gotrue_meta_security: { captcha_token: params.options.captchaToken } }
532
- : null)), { skip_http_redirect: true }),
533
- headers: this.headers,
534
- xform: _ssoResponse,
535
- });
536
- }
537
- catch (error) {
538
- if (isAuthError(error)) {
539
- return { data: null, error };
540
- }
541
- throw error;
500
+ try {
501
+ await this._removeSession();
502
+ return await _request(this.fetch, 'POST', `${this.url}/sso`, {
503
+ body: Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, ('providerId' in params ? { provider_id: params.providerId } : null)), ('domain' in params ? { domain: params.domain } : null)), { redirect_to: (_b = (_a = params.options) === null || _a === void 0 ? void 0 : _a.redirectTo) !== null && _b !== void 0 ? _b : undefined }), (((_c = params === null || params === void 0 ? void 0 : params.options) === null || _c === void 0 ? void 0 : _c.captchaToken)
504
+ ? { gotrue_meta_security: { captcha_token: params.options.captchaToken } }
505
+ : null)), { skip_http_redirect: true }),
506
+ headers: this.headers,
507
+ xform: _ssoResponse,
508
+ });
509
+ }
510
+ catch (error) {
511
+ if (isAuthError(error)) {
512
+ return { data: null, error };
542
513
  }
543
- });
514
+ throw error;
515
+ }
544
516
  }
545
517
  /**
546
518
  * Sends a reauthentication OTP to the user's email or phone number.
547
519
  * Requires the user to be signed-in.
548
520
  */
549
- reauthenticate() {
550
- return __awaiter(this, void 0, void 0, function* () {
551
- try {
552
- const { data: { session }, error: sessionError, } = yield this.getSession();
521
+ async reauthenticate() {
522
+ try {
523
+ return await this._useSession(async (result) => {
524
+ const { data: { session }, error: sessionError, } = result;
553
525
  if (sessionError)
554
526
  throw sessionError;
555
527
  if (!session)
556
528
  throw new AuthSessionMissingError();
557
- const { error } = yield _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
529
+ const { error } = await _request(this.fetch, 'GET', `${this.url}/reauthenticate`, {
558
530
  headers: this.headers,
559
531
  jwt: session.access_token,
560
532
  });
561
533
  return { data: { user: null, session: null }, error };
534
+ });
535
+ }
536
+ catch (error) {
537
+ if (isAuthError(error)) {
538
+ return { data: { user: null, session: null }, error };
562
539
  }
563
- catch (error) {
564
- if (isAuthError(error)) {
565
- return { data: { user: null, session: null }, error };
566
- }
567
- throw error;
568
- }
569
- });
540
+ throw error;
541
+ }
570
542
  }
571
543
  /**
572
544
  * Resends an existing signup confirmation email, email change email, SMS OTP or phone change OTP.
573
545
  */
574
- resend(credentials) {
575
- return __awaiter(this, void 0, void 0, function* () {
576
- try {
577
- if (credentials.type != 'email_change' && credentials.type != 'phone_change') {
578
- yield this._removeSession();
579
- }
580
- const endpoint = `${this.url}/resend`;
581
- if ('email' in credentials) {
582
- const { email, type, options } = credentials;
583
- const { error } = yield _request(this.fetch, 'POST', endpoint, {
584
- headers: this.headers,
585
- body: {
586
- email,
587
- type,
588
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
589
- },
590
- redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
591
- });
592
- return { data: { user: null, session: null }, error };
593
- }
594
- else if ('phone' in credentials) {
595
- const { phone, type, options } = credentials;
596
- const { data, error } = yield _request(this.fetch, 'POST', endpoint, {
597
- headers: this.headers,
598
- body: {
599
- phone,
600
- type,
601
- gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
602
- },
603
- });
604
- return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error };
605
- }
606
- throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a type');
546
+ async resend(credentials) {
547
+ try {
548
+ if (credentials.type != 'email_change' && credentials.type != 'phone_change') {
549
+ await this._removeSession();
607
550
  }
608
- catch (error) {
609
- if (isAuthError(error)) {
610
- return { data: { user: null, session: null }, error };
611
- }
612
- throw error;
551
+ const endpoint = `${this.url}/resend`;
552
+ if ('email' in credentials) {
553
+ const { email, type, options } = credentials;
554
+ const { error } = await _request(this.fetch, 'POST', endpoint, {
555
+ headers: this.headers,
556
+ body: {
557
+ email,
558
+ type,
559
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
560
+ },
561
+ redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
562
+ });
563
+ return { data: { user: null, session: null }, error };
613
564
  }
614
- });
565
+ else if ('phone' in credentials) {
566
+ const { phone, type, options } = credentials;
567
+ const { data, error } = await _request(this.fetch, 'POST', endpoint, {
568
+ headers: this.headers,
569
+ body: {
570
+ phone,
571
+ type,
572
+ gotrue_meta_security: { captcha_token: options === null || options === void 0 ? void 0 : options.captchaToken },
573
+ },
574
+ });
575
+ return { data: { user: null, session: null, messageId: data === null || data === void 0 ? void 0 : data.message_id }, error };
576
+ }
577
+ throw new AuthInvalidCredentialsError('You must provide either an email or phone number and a type');
578
+ }
579
+ catch (error) {
580
+ if (isAuthError(error)) {
581
+ return { data: { user: null, session: null }, error };
582
+ }
583
+ throw error;
584
+ }
615
585
  }
616
586
  /**
617
587
  * Returns the session, refreshing it if necessary.
618
588
  * 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.
619
589
  */
620
- getSession() {
621
- return __awaiter(this, void 0, void 0, function* () {
622
- // make sure we've read the session from the url if there is one
623
- // save to just await, as long we make sure _initialize() never throws
624
- yield this.initializePromise;
625
- this._debug('#getSession()', 'begin');
626
- try {
627
- let currentSession = null;
628
- if (this.persistSession) {
629
- const maybeSession = yield getItemAsync(this.storage, this.storageKey);
630
- this._debug('#getSession()', 'session from storage', maybeSession);
631
- if (maybeSession !== null) {
632
- if (this._isValidSession(maybeSession)) {
633
- currentSession = maybeSession;
634
- }
635
- else {
636
- this._debug('#getSession()', 'session from storage is not valid');
637
- yield this._removeSession();
638
- }
590
+ async getSession() {
591
+ return this._useSession(async (result) => {
592
+ return result;
593
+ });
594
+ }
595
+ /**
596
+ * Use instead of {@link #getSession} inside the library. It is
597
+ * semantically usually what you want, as getting a session involves some
598
+ * processing afterwards that requires only one client operating on the
599
+ * session at once across multiple tabs or processes.
600
+ */
601
+ async _useSession(fn) {
602
+ return await stackGuard('_useSession', async () => {
603
+ // the use of __loadSession here is the only correct use of the function!
604
+ const result = await this.__loadSession();
605
+ return await fn(result);
606
+ });
607
+ }
608
+ /**
609
+ * NEVER USE DIRECTLY!
610
+ *
611
+ * Always use {@link #_useSession}.
612
+ */
613
+ async __loadSession() {
614
+ if (this.logDebugMessages && !isInStackGuard('_useSession')) {
615
+ throw new Error('Please use #_useSession()');
616
+ }
617
+ // make sure we've read the session from the url if there is one
618
+ // save to just await, as long we make sure _initialize() never throws
619
+ await this.initializePromise;
620
+ this._debug('#__loadSession()', 'begin');
621
+ try {
622
+ let currentSession = null;
623
+ if (this.persistSession) {
624
+ const maybeSession = await getItemAsync(this.storage, this.storageKey);
625
+ this._debug('#getSession()', 'session from storage', maybeSession);
626
+ if (maybeSession !== null) {
627
+ if (this._isValidSession(maybeSession)) {
628
+ currentSession = maybeSession;
629
+ }
630
+ else {
631
+ this._debug('#getSession()', 'session from storage is not valid');
632
+ await this._removeSession();
639
633
  }
640
634
  }
641
- else {
642
- currentSession = this.inMemorySession;
643
- this._debug('#getSession()', 'session from memory', currentSession);
644
- }
645
- if (!currentSession) {
646
- return { data: { session: null }, error: null };
647
- }
648
- const hasExpired = currentSession.expires_at
649
- ? currentSession.expires_at <= Date.now() / 1000
650
- : false;
651
- this._debug('#getSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
652
- if (!hasExpired) {
653
- return { data: { session: currentSession }, error: null };
654
- }
655
- const { session, error } = yield this._callRefreshToken(currentSession.refresh_token);
656
- if (error) {
657
- return { data: { session: null }, error };
658
- }
659
- return { data: { session }, error: null };
660
635
  }
661
- finally {
662
- this._debug('#getSession()', 'end');
636
+ else {
637
+ currentSession = this.inMemorySession;
638
+ this._debug('#getSession()', 'session from memory', currentSession);
663
639
  }
664
- });
640
+ if (!currentSession) {
641
+ return { data: { session: null }, error: null };
642
+ }
643
+ const hasExpired = currentSession.expires_at
644
+ ? currentSession.expires_at <= Date.now() / 1000
645
+ : false;
646
+ this._debug('#__loadSession()', `session has${hasExpired ? '' : ' not'} expired`, 'expires_at', currentSession.expires_at);
647
+ if (!hasExpired) {
648
+ return { data: { session: currentSession }, error: null };
649
+ }
650
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
651
+ if (error) {
652
+ return { data: { session: null }, error };
653
+ }
654
+ return { data: { session }, error: null };
655
+ }
656
+ finally {
657
+ this._debug('#__loadSession()', 'end');
658
+ }
665
659
  }
666
660
  /**
667
661
  * Gets the current user details if there is an existing session.
668
662
  * @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.
669
663
  */
670
- getUser(jwt) {
671
- var _a, _b;
672
- return __awaiter(this, void 0, void 0, function* () {
673
- try {
664
+ async getUser(jwt) {
665
+ try {
666
+ return await this._useSession(async (result) => {
667
+ var _a, _b;
674
668
  if (!jwt) {
675
- const { data, error } = yield this.getSession();
669
+ const { data, error } = result;
676
670
  if (error) {
677
671
  throw error;
678
672
  }
679
673
  // Default to Authorization header if there is no existing session
680
674
  jwt = (_b = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token) !== null && _b !== void 0 ? _b : undefined;
681
675
  }
682
- return yield _request(this.fetch, 'GET', `${this.url}/user`, {
676
+ return await _request(this.fetch, 'GET', `${this.url}/user`, {
683
677
  headers: this.headers,
684
678
  jwt: jwt,
685
679
  xform: _userResponse,
686
680
  });
681
+ });
682
+ }
683
+ catch (error) {
684
+ if (isAuthError(error)) {
685
+ return { data: { user: null }, error };
687
686
  }
688
- catch (error) {
689
- if (isAuthError(error)) {
690
- return { data: { user: null }, error };
691
- }
692
- throw error;
693
- }
694
- });
687
+ throw error;
688
+ }
695
689
  }
696
690
  /**
697
691
  * Updates user data for a logged in user.
698
692
  */
699
- updateUser(attributes, options = {}) {
700
- return __awaiter(this, void 0, void 0, function* () {
701
- try {
702
- const { data: sessionData, error: sessionError } = yield this.getSession();
693
+ async updateUser(attributes, options = {}) {
694
+ try {
695
+ return await this._useSession(async (result) => {
696
+ const { data: sessionData, error: sessionError } = result;
703
697
  if (sessionError) {
704
698
  throw sessionError;
705
699
  }
@@ -707,7 +701,7 @@ export default class GoTrueClient {
707
701
  throw new AuthSessionMissingError();
708
702
  }
709
703
  const session = sessionData.session;
710
- const { data, error: userError } = yield _request(this.fetch, 'PUT', `${this.url}/user`, {
704
+ const { data, error: userError } = await _request(this.fetch, 'PUT', `${this.url}/user`, {
711
705
  headers: this.headers,
712
706
  redirectTo: options === null || options === void 0 ? void 0 : options.emailRedirectTo,
713
707
  body: attributes,
@@ -717,17 +711,17 @@ export default class GoTrueClient {
717
711
  if (userError)
718
712
  throw userError;
719
713
  session.user = data.user;
720
- yield this._saveSession(session);
721
- yield this._notifyAllSubscribers('USER_UPDATED', session);
714
+ await this._saveSession(session);
715
+ await this._notifyAllSubscribers('USER_UPDATED', session);
722
716
  return { data: { user: session.user }, error: null };
717
+ });
718
+ }
719
+ catch (error) {
720
+ if (isAuthError(error)) {
721
+ return { data: { user: null }, error };
723
722
  }
724
- catch (error) {
725
- if (isAuthError(error)) {
726
- return { data: { user: null }, error };
727
- }
728
- throw error;
729
- }
730
- });
723
+ throw error;
724
+ }
731
725
  }
732
726
  /**
733
727
  * Decodes a JWT (without performing any validation).
@@ -740,56 +734,54 @@ export default class GoTrueClient {
740
734
  * If the refresh token or access token in the current session is invalid, an error will be thrown.
741
735
  * @param currentSession The current session that minimally contains an access token and refresh token.
742
736
  */
743
- setSession(currentSession) {
744
- return __awaiter(this, void 0, void 0, function* () {
745
- try {
746
- if (!currentSession.access_token || !currentSession.refresh_token) {
747
- throw new AuthSessionMissingError();
748
- }
749
- const timeNow = Date.now() / 1000;
750
- let expiresAt = timeNow;
751
- let hasExpired = true;
752
- let session = null;
753
- const payload = decodeJWTPayload(currentSession.access_token);
754
- if (payload.exp) {
755
- expiresAt = payload.exp;
756
- hasExpired = expiresAt <= timeNow;
757
- }
758
- if (hasExpired) {
759
- const { session: refreshedSession, error } = yield this._callRefreshToken(currentSession.refresh_token);
760
- if (error) {
761
- return { data: { user: null, session: null }, error: error };
762
- }
763
- if (!refreshedSession) {
764
- return { data: { user: null, session: null }, error: null };
765
- }
766
- session = refreshedSession;
737
+ async setSession(currentSession) {
738
+ try {
739
+ if (!currentSession.access_token || !currentSession.refresh_token) {
740
+ throw new AuthSessionMissingError();
741
+ }
742
+ const timeNow = Date.now() / 1000;
743
+ let expiresAt = timeNow;
744
+ let hasExpired = true;
745
+ let session = null;
746
+ const payload = decodeJWTPayload(currentSession.access_token);
747
+ if (payload.exp) {
748
+ expiresAt = payload.exp;
749
+ hasExpired = expiresAt <= timeNow;
750
+ }
751
+ if (hasExpired) {
752
+ const { session: refreshedSession, error } = await this._callRefreshToken(currentSession.refresh_token);
753
+ if (error) {
754
+ return { data: { user: null, session: null }, error: error };
767
755
  }
768
- else {
769
- const { data, error } = yield this.getUser(currentSession.access_token);
770
- if (error) {
771
- throw error;
772
- }
773
- session = {
774
- access_token: currentSession.access_token,
775
- refresh_token: currentSession.refresh_token,
776
- user: data.user,
777
- token_type: 'bearer',
778
- expires_in: expiresAt - timeNow,
779
- expires_at: expiresAt,
780
- };
781
- yield this._saveSession(session);
782
- yield this._notifyAllSubscribers('SIGNED_IN', session);
756
+ if (!refreshedSession) {
757
+ return { data: { user: null, session: null }, error: null };
783
758
  }
784
- return { data: { user: session.user, session }, error: null };
759
+ session = refreshedSession;
785
760
  }
786
- catch (error) {
787
- if (isAuthError(error)) {
788
- return { data: { session: null, user: null }, error };
761
+ else {
762
+ const { data, error } = await this.getUser(currentSession.access_token);
763
+ if (error) {
764
+ throw error;
789
765
  }
790
- throw error;
766
+ session = {
767
+ access_token: currentSession.access_token,
768
+ refresh_token: currentSession.refresh_token,
769
+ user: data.user,
770
+ token_type: 'bearer',
771
+ expires_in: expiresAt - timeNow,
772
+ expires_at: expiresAt,
773
+ };
774
+ await this._saveSession(session);
775
+ await this._notifyAllSubscribers('SIGNED_IN', session);
791
776
  }
792
- });
777
+ return { data: { user: session.user, session }, error: null };
778
+ }
779
+ catch (error) {
780
+ if (isAuthError(error)) {
781
+ return { data: { session: null, user: null }, error };
782
+ }
783
+ throw error;
784
+ }
793
785
  }
794
786
  /**
795
787
  * Returns a new session, regardless of expiry status.
@@ -797,12 +789,12 @@ export default class GoTrueClient {
797
789
  * If the current session's refresh token is invalid, an error will be thrown.
798
790
  * @param currentSession The current session. If passed in, it must contain a refresh token.
799
791
  */
800
- refreshSession(currentSession) {
801
- var _a;
802
- return __awaiter(this, void 0, void 0, function* () {
803
- try {
792
+ async refreshSession(currentSession) {
793
+ try {
794
+ return await this._useSession(async (result) => {
795
+ var _a;
804
796
  if (!currentSession) {
805
- const { data, error } = yield this.getSession();
797
+ const { data, error } = result;
806
798
  if (error) {
807
799
  throw error;
808
800
  }
@@ -811,7 +803,7 @@ export default class GoTrueClient {
811
803
  if (!(currentSession === null || currentSession === void 0 ? void 0 : currentSession.refresh_token)) {
812
804
  throw new AuthSessionMissingError();
813
805
  }
814
- const { session, error } = yield this._callRefreshToken(currentSession.refresh_token);
806
+ const { session, error } = await this._callRefreshToken(currentSession.refresh_token);
815
807
  if (error) {
816
808
  return { data: { user: null, session: null }, error: error };
817
809
  }
@@ -819,96 +811,94 @@ export default class GoTrueClient {
819
811
  return { data: { user: null, session: null }, error: null };
820
812
  }
821
813
  return { data: { user: session.user, session }, error: null };
814
+ });
815
+ }
816
+ catch (error) {
817
+ if (isAuthError(error)) {
818
+ return { data: { user: null, session: null }, error };
822
819
  }
823
- catch (error) {
824
- if (isAuthError(error)) {
825
- return { data: { user: null, session: null }, error };
826
- }
827
- throw error;
828
- }
829
- });
820
+ throw error;
821
+ }
830
822
  }
831
823
  /**
832
824
  * Gets the session data from a URL string
833
825
  */
834
- _getSessionFromUrl(isPKCEFlow) {
835
- return __awaiter(this, void 0, void 0, function* () {
836
- try {
837
- if (!isBrowser())
838
- throw new AuthImplicitGrantRedirectError('No browser detected.');
839
- if (this.flowType === 'implicit' && !this._isImplicitGrantFlow()) {
840
- throw new AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.');
841
- }
842
- else if (this.flowType == 'pkce' && !isPKCEFlow) {
843
- throw new AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.');
844
- }
845
- if (isPKCEFlow) {
846
- const authCode = getParameterByName('code');
847
- if (!authCode)
848
- throw new AuthPKCEGrantCodeExchangeError('No code detected.');
849
- const { data, error } = yield this.exchangeCodeForSession(authCode);
850
- if (error)
851
- throw error;
852
- if (!data.session)
853
- throw new AuthPKCEGrantCodeExchangeError('No session detected.');
854
- let url = new URL(window.location.href);
855
- url.searchParams.delete('code');
856
- window.history.replaceState(window.history.state, '', url.toString());
857
- return { data: { session: data.session, redirectType: null }, error: null };
858
- }
859
- const error_description = getParameterByName('error_description');
860
- if (error_description) {
861
- const error_code = getParameterByName('error_code');
862
- if (!error_code)
863
- throw new AuthImplicitGrantRedirectError('No error_code detected.');
864
- const error = getParameterByName('error');
865
- if (!error)
866
- throw new AuthImplicitGrantRedirectError('No error detected.');
867
- throw new AuthImplicitGrantRedirectError(error_description, { error, code: error_code });
868
- }
869
- const provider_token = getParameterByName('provider_token');
870
- const provider_refresh_token = getParameterByName('provider_refresh_token');
871
- const access_token = getParameterByName('access_token');
872
- if (!access_token)
873
- throw new AuthImplicitGrantRedirectError('No access_token detected.');
874
- const expires_in = getParameterByName('expires_in');
875
- if (!expires_in)
876
- throw new AuthImplicitGrantRedirectError('No expires_in detected.');
877
- const refresh_token = getParameterByName('refresh_token');
878
- if (!refresh_token)
879
- throw new AuthImplicitGrantRedirectError('No refresh_token detected.');
880
- const token_type = getParameterByName('token_type');
881
- if (!token_type)
882
- throw new AuthImplicitGrantRedirectError('No token_type detected.');
883
- const timeNow = Math.round(Date.now() / 1000);
884
- const expires_at = timeNow + parseInt(expires_in);
885
- const { data, error } = yield this.getUser(access_token);
826
+ async _getSessionFromUrl(isPKCEFlow) {
827
+ try {
828
+ if (!isBrowser())
829
+ throw new AuthImplicitGrantRedirectError('No browser detected.');
830
+ if (this.flowType === 'implicit' && !this._isImplicitGrantFlow()) {
831
+ throw new AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.');
832
+ }
833
+ else if (this.flowType == 'pkce' && !isPKCEFlow) {
834
+ throw new AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.');
835
+ }
836
+ if (isPKCEFlow) {
837
+ const authCode = getParameterByName('code');
838
+ if (!authCode)
839
+ throw new AuthPKCEGrantCodeExchangeError('No code detected.');
840
+ const { data, error } = await this.exchangeCodeForSession(authCode);
886
841
  if (error)
887
842
  throw error;
888
- const user = data.user;
889
- const session = {
890
- provider_token,
891
- provider_refresh_token,
892
- access_token,
893
- expires_in: parseInt(expires_in),
894
- expires_at,
895
- refresh_token,
896
- token_type,
897
- user,
898
- };
899
- const redirectType = getParameterByName('type');
900
- // Remove tokens from URL
901
- window.location.hash = '';
902
- this._debug('#_getSessionFromUrl()', 'clearing window.location.hash');
903
- return { data: { session, redirectType }, error: null };
904
- }
905
- catch (error) {
906
- if (isAuthError(error)) {
907
- return { data: { session: null, redirectType: null }, error };
908
- }
843
+ if (!data.session)
844
+ throw new AuthPKCEGrantCodeExchangeError('No session detected.');
845
+ let url = new URL(window.location.href);
846
+ url.searchParams.delete('code');
847
+ window.history.replaceState(window.history.state, '', url.toString());
848
+ return { data: { session: data.session, redirectType: null }, error: null };
849
+ }
850
+ const error_description = getParameterByName('error_description');
851
+ if (error_description) {
852
+ const error_code = getParameterByName('error_code');
853
+ if (!error_code)
854
+ throw new AuthImplicitGrantRedirectError('No error_code detected.');
855
+ const error = getParameterByName('error');
856
+ if (!error)
857
+ throw new AuthImplicitGrantRedirectError('No error detected.');
858
+ throw new AuthImplicitGrantRedirectError(error_description, { error, code: error_code });
859
+ }
860
+ const provider_token = getParameterByName('provider_token');
861
+ const provider_refresh_token = getParameterByName('provider_refresh_token');
862
+ const access_token = getParameterByName('access_token');
863
+ if (!access_token)
864
+ throw new AuthImplicitGrantRedirectError('No access_token detected.');
865
+ const expires_in = getParameterByName('expires_in');
866
+ if (!expires_in)
867
+ throw new AuthImplicitGrantRedirectError('No expires_in detected.');
868
+ const refresh_token = getParameterByName('refresh_token');
869
+ if (!refresh_token)
870
+ throw new AuthImplicitGrantRedirectError('No refresh_token detected.');
871
+ const token_type = getParameterByName('token_type');
872
+ if (!token_type)
873
+ throw new AuthImplicitGrantRedirectError('No token_type detected.');
874
+ const timeNow = Math.round(Date.now() / 1000);
875
+ const expires_at = timeNow + parseInt(expires_in);
876
+ const { data, error } = await this.getUser(access_token);
877
+ if (error)
909
878
  throw error;
879
+ const user = data.user;
880
+ const session = {
881
+ provider_token,
882
+ provider_refresh_token,
883
+ access_token,
884
+ expires_in: parseInt(expires_in),
885
+ expires_at,
886
+ refresh_token,
887
+ token_type,
888
+ user,
889
+ };
890
+ const redirectType = getParameterByName('type');
891
+ // Remove tokens from URL
892
+ window.location.hash = '';
893
+ this._debug('#_getSessionFromUrl()', 'clearing window.location.hash');
894
+ return { data: { session, redirectType }, error: null };
895
+ }
896
+ catch (error) {
897
+ if (isAuthError(error)) {
898
+ return { data: { session: null, redirectType: null }, error };
910
899
  }
911
- });
900
+ throw error;
901
+ }
912
902
  }
913
903
  /**
914
904
  * Checks if the current URL contains parameters given by an implicit oauth grant flow (https://www.rfc-editor.org/rfc/rfc6749.html#section-4.2)
@@ -921,11 +911,9 @@ export default class GoTrueClient {
921
911
  /**
922
912
  * Checks if the current URL and backing storage contain parameters given by a PKCE flow
923
913
  */
924
- _isPKCEFlow() {
925
- return __awaiter(this, void 0, void 0, function* () {
926
- const currentStorageContent = yield getItemAsync(this.storage, `${this.storageKey}-code-verifier`);
927
- return Boolean(getParameterByName('code')) && Boolean(currentStorageContent);
928
- });
914
+ async _isPKCEFlow() {
915
+ const currentStorageContent = await getItemAsync(this.storage, `${this.storageKey}-code-verifier`);
916
+ return Boolean(getParameterByName('code')) && Boolean(currentStorageContent);
929
917
  }
930
918
  /**
931
919
  * Inside a browser context, `signOut()` will remove the logged in user from the browser session
@@ -936,16 +924,16 @@ export default class GoTrueClient {
936
924
  *
937
925
  * If using others scope, no `SIGNED_OUT` event is fired!
938
926
  */
939
- signOut({ scope } = { scope: 'global' }) {
940
- var _a;
941
- return __awaiter(this, void 0, void 0, function* () {
942
- const { data, error: sessionError } = yield this.getSession();
927
+ async signOut({ scope } = { scope: 'global' }) {
928
+ return await this._useSession(async (result) => {
929
+ var _a;
930
+ const { data, error: sessionError } = result;
943
931
  if (sessionError) {
944
932
  return { error: sessionError };
945
933
  }
946
934
  const accessToken = (_a = data.session) === null || _a === void 0 ? void 0 : _a.access_token;
947
935
  if (accessToken) {
948
- const { error } = yield this.admin.signOut(accessToken, scope);
936
+ const { error } = await this.admin.signOut(accessToken, scope);
949
937
  if (error) {
950
938
  // ignore 404s since user might not exist anymore
951
939
  // ignore 401s since an invalid or expired JWT should sign out the current session
@@ -955,9 +943,9 @@ export default class GoTrueClient {
955
943
  }
956
944
  }
957
945
  if (scope !== 'others') {
958
- yield this._removeSession();
959
- yield removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
960
- yield this._notifyAllSubscribers('SIGNED_OUT', null);
946
+ await this._removeSession();
947
+ await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`);
948
+ await this._notifyAllSubscribers('SIGNED_OUT', null);
961
949
  }
962
950
  return { error: null };
963
951
  });
@@ -981,18 +969,18 @@ export default class GoTrueClient {
981
969
  this._emitInitialSession(id);
982
970
  return { data: { subscription } };
983
971
  }
984
- _emitInitialSession(id) {
985
- var _a, _b;
986
- return __awaiter(this, void 0, void 0, function* () {
972
+ async _emitInitialSession(id) {
973
+ return await this._useSession(async (result) => {
974
+ var _a, _b;
987
975
  try {
988
- const { data: { session }, error, } = yield this.getSession();
976
+ const { data: { session }, error, } = result;
989
977
  if (error)
990
978
  throw error;
991
- yield ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
979
+ await ((_a = this.stateChangeEmitters.get(id)) === null || _a === void 0 ? void 0 : _a.callback('INITIAL_SESSION', session));
992
980
  this._debug('INITIAL_SESSION', 'callback id', id, 'session', session);
993
981
  }
994
982
  catch (err) {
995
- yield ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
983
+ await ((_b = this.stateChangeEmitters.get(id)) === null || _b === void 0 ? void 0 : _b.callback('INITIAL_SESSION', null));
996
984
  this._debug('INITIAL_SESSION', 'callback id', id, 'error', err);
997
985
  console.error(err);
998
986
  }
@@ -1005,72 +993,68 @@ export default class GoTrueClient {
1005
993
  * @param options.redirectTo The URL to send the user to after they click the password reset link.
1006
994
  * @param options.captchaToken Verification token received when the user completes the captcha on the site.
1007
995
  */
1008
- resetPasswordForEmail(email, options = {}) {
1009
- return __awaiter(this, void 0, void 0, function* () {
1010
- let codeChallenge = null;
1011
- let codeChallengeMethod = null;
1012
- if (this.flowType === 'pkce') {
1013
- const codeVerifier = generatePKCEVerifier();
1014
- yield setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
1015
- codeChallenge = yield generatePKCEChallenge(codeVerifier);
1016
- codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
1017
- }
1018
- try {
1019
- return yield _request(this.fetch, 'POST', `${this.url}/recover`, {
1020
- body: {
1021
- email,
1022
- code_challenge: codeChallenge,
1023
- code_challenge_method: codeChallengeMethod,
1024
- gotrue_meta_security: { captcha_token: options.captchaToken },
1025
- },
1026
- headers: this.headers,
1027
- redirectTo: options.redirectTo,
1028
- });
1029
- }
1030
- catch (error) {
1031
- if (isAuthError(error)) {
1032
- return { data: null, error };
1033
- }
1034
- throw error;
996
+ async resetPasswordForEmail(email, options = {}) {
997
+ let codeChallenge = null;
998
+ let codeChallengeMethod = null;
999
+ if (this.flowType === 'pkce') {
1000
+ const codeVerifier = generatePKCEVerifier();
1001
+ await setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
1002
+ codeChallenge = await generatePKCEChallenge(codeVerifier);
1003
+ codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
1004
+ }
1005
+ try {
1006
+ return await _request(this.fetch, 'POST', `${this.url}/recover`, {
1007
+ body: {
1008
+ email,
1009
+ code_challenge: codeChallenge,
1010
+ code_challenge_method: codeChallengeMethod,
1011
+ gotrue_meta_security: { captcha_token: options.captchaToken },
1012
+ },
1013
+ headers: this.headers,
1014
+ redirectTo: options.redirectTo,
1015
+ });
1016
+ }
1017
+ catch (error) {
1018
+ if (isAuthError(error)) {
1019
+ return { data: null, error };
1035
1020
  }
1036
- });
1021
+ throw error;
1022
+ }
1037
1023
  }
1038
1024
  /**
1039
1025
  * Generates a new JWT.
1040
1026
  * @param refreshToken A valid refresh token that was returned on login.
1041
1027
  */
1042
- _refreshAccessToken(refreshToken) {
1043
- return __awaiter(this, void 0, void 0, function* () {
1044
- const debugName = `#_refreshAccessToken(${refreshToken.substring(0, 5)}...)`;
1045
- this._debug(debugName, 'begin');
1046
- try {
1047
- const startedAt = Date.now();
1048
- // will attempt to refresh the token with exponential backoff
1049
- return yield retryable((attempt) => __awaiter(this, void 0, void 0, function* () {
1050
- yield sleep(attempt * 200); // 0, 200, 400, 800, ...
1051
- this._debug(debugName, 'refreshing attempt', attempt);
1052
- return yield _request(this.fetch, 'POST', `${this.url}/token?grant_type=refresh_token`, {
1053
- body: { refresh_token: refreshToken },
1054
- headers: this.headers,
1055
- xform: _sessionResponse,
1056
- });
1057
- }), (attempt, _, result) => result &&
1058
- result.error &&
1059
- isAuthRetryableFetchError(result.error) &&
1060
- // retryable only if the request can be sent before the backoff overflows the tick duration
1061
- Date.now() + (attempt + 1) * 200 - startedAt < AUTO_REFRESH_TICK_DURATION);
1062
- }
1063
- catch (error) {
1064
- this._debug(debugName, 'error', error);
1065
- if (isAuthError(error)) {
1066
- return { data: { session: null, user: null }, error };
1067
- }
1068
- throw error;
1069
- }
1070
- finally {
1071
- this._debug(debugName, 'end');
1028
+ async _refreshAccessToken(refreshToken) {
1029
+ const debugName = `#_refreshAccessToken(${refreshToken.substring(0, 5)}...)`;
1030
+ this._debug(debugName, 'begin');
1031
+ try {
1032
+ const startedAt = Date.now();
1033
+ // will attempt to refresh the token with exponential backoff
1034
+ return await retryable(async (attempt) => {
1035
+ await sleep(attempt * 200); // 0, 200, 400, 800, ...
1036
+ this._debug(debugName, 'refreshing attempt', attempt);
1037
+ return await _request(this.fetch, 'POST', `${this.url}/token?grant_type=refresh_token`, {
1038
+ body: { refresh_token: refreshToken },
1039
+ headers: this.headers,
1040
+ xform: _sessionResponse,
1041
+ });
1042
+ }, (attempt, _, result) => result &&
1043
+ result.error &&
1044
+ isAuthRetryableFetchError(result.error) &&
1045
+ // retryable only if the request can be sent before the backoff overflows the tick duration
1046
+ Date.now() + (attempt + 1) * 200 - startedAt < AUTO_REFRESH_TICK_DURATION);
1047
+ }
1048
+ catch (error) {
1049
+ this._debug(debugName, 'error', error);
1050
+ if (isAuthError(error)) {
1051
+ return { data: { session: null, user: null }, error };
1072
1052
  }
1073
- });
1053
+ throw error;
1054
+ }
1055
+ finally {
1056
+ this._debug(debugName, 'end');
1057
+ }
1074
1058
  }
1075
1059
  _isValidSession(maybeSession) {
1076
1060
  const isValidSession = typeof maybeSession === 'object' &&
@@ -1080,172 +1064,160 @@ export default class GoTrueClient {
1080
1064
  'expires_at' in maybeSession;
1081
1065
  return isValidSession;
1082
1066
  }
1083
- _handleProviderSignIn(provider, options) {
1084
- return __awaiter(this, void 0, void 0, function* () {
1085
- const url = yield this._getUrlForProvider(provider, {
1086
- redirectTo: options.redirectTo,
1087
- scopes: options.scopes,
1088
- queryParams: options.queryParams,
1089
- });
1090
- this._debug('#_handleProviderSignIn()', 'provider', provider, 'options', options, 'url', url);
1091
- // try to open on the browser
1092
- if (isBrowser() && !options.skipBrowserRedirect) {
1093
- window.location.assign(url);
1094
- }
1095
- return { data: { provider, url }, error: null };
1067
+ async _handleProviderSignIn(provider, options) {
1068
+ const url = await this._getUrlForProvider(provider, {
1069
+ redirectTo: options.redirectTo,
1070
+ scopes: options.scopes,
1071
+ queryParams: options.queryParams,
1096
1072
  });
1073
+ this._debug('#_handleProviderSignIn()', 'provider', provider, 'options', options, 'url', url);
1074
+ // try to open on the browser
1075
+ if (isBrowser() && !options.skipBrowserRedirect) {
1076
+ window.location.assign(url);
1077
+ }
1078
+ return { data: { provider, url }, error: null };
1097
1079
  }
1098
1080
  /**
1099
1081
  * Recovers the session from LocalStorage and refreshes
1100
1082
  * Note: this method is async to accommodate for AsyncStorage e.g. in React native.
1101
1083
  */
1102
- _recoverAndRefresh() {
1084
+ async _recoverAndRefresh() {
1103
1085
  var _a;
1104
- return __awaiter(this, void 0, void 0, function* () {
1105
- const debugName = '#_recoverAndRefresh()';
1106
- this._debug(debugName, 'begin');
1107
- try {
1108
- const currentSession = yield getItemAsync(this.storage, this.storageKey);
1109
- this._debug(debugName, 'session from storage', currentSession);
1110
- if (!this._isValidSession(currentSession)) {
1111
- this._debug(debugName, 'session is not valid');
1112
- if (currentSession !== null) {
1113
- yield this._removeSession();
1114
- }
1115
- return;
1086
+ const debugName = '#_recoverAndRefresh()';
1087
+ this._debug(debugName, 'begin');
1088
+ try {
1089
+ const currentSession = await getItemAsync(this.storage, this.storageKey);
1090
+ this._debug(debugName, 'session from storage', currentSession);
1091
+ if (!this._isValidSession(currentSession)) {
1092
+ this._debug(debugName, 'session is not valid');
1093
+ if (currentSession !== null) {
1094
+ await this._removeSession();
1116
1095
  }
1117
- const timeNow = Math.round(Date.now() / 1000);
1118
- const expiresWithMargin = ((_a = currentSession.expires_at) !== null && _a !== void 0 ? _a : Infinity) < timeNow + EXPIRY_MARGIN;
1119
- this._debug(debugName, `session has${expiresWithMargin ? '' : ' not'} expired with margin of ${EXPIRY_MARGIN}s`);
1120
- if (expiresWithMargin) {
1121
- if (this.autoRefreshToken && currentSession.refresh_token) {
1122
- const { error } = yield this._callRefreshToken(currentSession.refresh_token);
1123
- if (error) {
1124
- console.error(error);
1125
- if (!isAuthRetryableFetchError(error)) {
1126
- this._debug(debugName, 'refresh failed with a non-retryable error, removing the session', error);
1127
- yield this._removeSession();
1128
- }
1096
+ return;
1097
+ }
1098
+ const timeNow = Math.round(Date.now() / 1000);
1099
+ const expiresWithMargin = ((_a = currentSession.expires_at) !== null && _a !== void 0 ? _a : Infinity) < timeNow + EXPIRY_MARGIN;
1100
+ this._debug(debugName, `session has${expiresWithMargin ? '' : ' not'} expired with margin of ${EXPIRY_MARGIN}s`);
1101
+ if (expiresWithMargin) {
1102
+ if (this.autoRefreshToken && currentSession.refresh_token) {
1103
+ const { error } = await this._callRefreshToken(currentSession.refresh_token);
1104
+ if (error) {
1105
+ console.error(error);
1106
+ if (!isAuthRetryableFetchError(error)) {
1107
+ this._debug(debugName, 'refresh failed with a non-retryable error, removing the session', error);
1108
+ await this._removeSession();
1129
1109
  }
1130
1110
  }
1131
1111
  }
1132
- else {
1133
- // no need to persist currentSession again, as we just loaded it from
1134
- // local storage; persisting it again may overwrite a value saved by
1135
- // another client with access to the same local storage
1136
- yield this._notifyAllSubscribers('SIGNED_IN', currentSession);
1137
- }
1138
- }
1139
- catch (err) {
1140
- this._debug(debugName, 'error', err);
1141
- console.error(err);
1142
- return;
1143
1112
  }
1144
- finally {
1145
- this._debug(debugName, 'end');
1113
+ else {
1114
+ // no need to persist currentSession again, as we just loaded it from
1115
+ // local storage; persisting it again may overwrite a value saved by
1116
+ // another client with access to the same local storage
1117
+ await this._notifyAllSubscribers('SIGNED_IN', currentSession);
1146
1118
  }
1147
- });
1119
+ }
1120
+ catch (err) {
1121
+ this._debug(debugName, 'error', err);
1122
+ console.error(err);
1123
+ return;
1124
+ }
1125
+ finally {
1126
+ this._debug(debugName, 'end');
1127
+ }
1148
1128
  }
1149
- _callRefreshToken(refreshToken) {
1129
+ async _callRefreshToken(refreshToken) {
1150
1130
  var _a, _b;
1151
- return __awaiter(this, void 0, void 0, function* () {
1152
- if (!refreshToken) {
1131
+ if (!refreshToken) {
1132
+ throw new AuthSessionMissingError();
1133
+ }
1134
+ // refreshing is already in progress
1135
+ if (this.refreshingDeferred) {
1136
+ return this.refreshingDeferred.promise;
1137
+ }
1138
+ const debugName = `#_callRefreshToken(${refreshToken.substring(0, 5)}...)`;
1139
+ this._debug(debugName, 'begin');
1140
+ try {
1141
+ this.refreshingDeferred = new Deferred();
1142
+ const { data, error } = await this._refreshAccessToken(refreshToken);
1143
+ if (error)
1144
+ throw error;
1145
+ if (!data.session)
1153
1146
  throw new AuthSessionMissingError();
1154
- }
1155
- // refreshing is already in progress
1156
- if (this.refreshingDeferred) {
1157
- return this.refreshingDeferred.promise;
1158
- }
1159
- const debugName = `#_callRefreshToken(${refreshToken.substring(0, 5)}...)`;
1160
- this._debug(debugName, 'begin');
1161
- try {
1162
- this.refreshingDeferred = new Deferred();
1163
- const { data, error } = yield this._refreshAccessToken(refreshToken);
1164
- if (error)
1165
- throw error;
1166
- if (!data.session)
1167
- throw new AuthSessionMissingError();
1168
- yield this._saveSession(data.session);
1169
- yield this._notifyAllSubscribers('TOKEN_REFRESHED', data.session);
1170
- const result = { session: data.session, error: null };
1171
- this.refreshingDeferred.resolve(result);
1147
+ await this._saveSession(data.session);
1148
+ await this._notifyAllSubscribers('TOKEN_REFRESHED', data.session);
1149
+ const result = { session: data.session, error: null };
1150
+ this.refreshingDeferred.resolve(result);
1151
+ return result;
1152
+ }
1153
+ catch (error) {
1154
+ this._debug(debugName, 'error', error);
1155
+ if (isAuthError(error)) {
1156
+ const result = { session: null, error };
1157
+ (_a = this.refreshingDeferred) === null || _a === void 0 ? void 0 : _a.resolve(result);
1172
1158
  return result;
1173
1159
  }
1174
- catch (error) {
1175
- this._debug(debugName, 'error', error);
1176
- if (isAuthError(error)) {
1177
- const result = { session: null, error };
1178
- (_a = this.refreshingDeferred) === null || _a === void 0 ? void 0 : _a.resolve(result);
1179
- return result;
1180
- }
1181
- (_b = this.refreshingDeferred) === null || _b === void 0 ? void 0 : _b.reject(error);
1182
- throw error;
1183
- }
1184
- finally {
1185
- this.refreshingDeferred = null;
1186
- this._debug(debugName, 'end');
1187
- }
1188
- });
1160
+ (_b = this.refreshingDeferred) === null || _b === void 0 ? void 0 : _b.reject(error);
1161
+ throw error;
1162
+ }
1163
+ finally {
1164
+ this.refreshingDeferred = null;
1165
+ this._debug(debugName, 'end');
1166
+ }
1189
1167
  }
1190
- _notifyAllSubscribers(event, session, broadcast = true) {
1191
- return __awaiter(this, void 0, void 0, function* () {
1192
- const debugName = `#_notifyAllSubscribers(${event})`;
1193
- this._debug(debugName, 'begin', session, `broadcast = ${broadcast}`);
1194
- try {
1195
- if (this.broadcastChannel && broadcast) {
1196
- this.broadcastChannel.postMessage({ event, session });
1168
+ async _notifyAllSubscribers(event, session, broadcast = true) {
1169
+ const debugName = `#_notifyAllSubscribers(${event})`;
1170
+ this._debug(debugName, 'begin', session, `broadcast = ${broadcast}`);
1171
+ try {
1172
+ if (this.broadcastChannel && broadcast) {
1173
+ this.broadcastChannel.postMessage({ event, session });
1174
+ }
1175
+ const errors = [];
1176
+ const promises = Array.from(this.stateChangeEmitters.values()).map(async (x) => {
1177
+ try {
1178
+ await x.callback(event, session);
1197
1179
  }
1198
- const errors = [];
1199
- const promises = Array.from(this.stateChangeEmitters.values()).map((x) => __awaiter(this, void 0, void 0, function* () {
1200
- try {
1201
- yield x.callback(event, session);
1202
- }
1203
- catch (e) {
1204
- errors.push(e);
1205
- }
1206
- }));
1207
- yield Promise.all(promises);
1208
- if (errors.length > 0) {
1209
- for (let i = 0; i < errors.length; i += 1) {
1210
- console.error(errors[i]);
1211
- }
1212
- throw errors[0];
1180
+ catch (e) {
1181
+ errors.push(e);
1213
1182
  }
1183
+ });
1184
+ await Promise.all(promises);
1185
+ if (errors.length > 0) {
1186
+ for (let i = 0; i < errors.length; i += 1) {
1187
+ console.error(errors[i]);
1188
+ }
1189
+ throw errors[0];
1214
1190
  }
1215
- finally {
1216
- this._debug(debugName, 'end');
1217
- }
1218
- });
1191
+ }
1192
+ finally {
1193
+ this._debug(debugName, 'end');
1194
+ }
1219
1195
  }
1220
1196
  /**
1221
1197
  * set currentSession and currentUser
1222
1198
  * process to _startAutoRefreshToken if possible
1223
1199
  */
1224
- _saveSession(session) {
1225
- return __awaiter(this, void 0, void 0, function* () {
1226
- this._debug('#_saveSession()', session);
1227
- if (!this.persistSession) {
1228
- this.inMemorySession = session;
1229
- }
1230
- if (this.persistSession && session.expires_at) {
1231
- yield this._persistSession(session);
1232
- }
1233
- });
1200
+ async _saveSession(session) {
1201
+ this._debug('#_saveSession()', session);
1202
+ if (!this.persistSession) {
1203
+ this.inMemorySession = session;
1204
+ }
1205
+ if (this.persistSession && session.expires_at) {
1206
+ await this._persistSession(session);
1207
+ }
1234
1208
  }
1235
1209
  _persistSession(currentSession) {
1236
1210
  this._debug('#_persistSession()', currentSession);
1237
1211
  return setItemAsync(this.storage, this.storageKey, currentSession);
1238
1212
  }
1239
- _removeSession() {
1240
- return __awaiter(this, void 0, void 0, function* () {
1241
- this._debug('#_removeSession()');
1242
- if (this.persistSession) {
1243
- yield removeItemAsync(this.storage, this.storageKey);
1244
- }
1245
- else {
1246
- this.inMemorySession = null;
1247
- }
1248
- });
1213
+ async _removeSession() {
1214
+ this._debug('#_removeSession()');
1215
+ if (this.persistSession) {
1216
+ await removeItemAsync(this.storage, this.storageKey);
1217
+ }
1218
+ else {
1219
+ this.inMemorySession = null;
1220
+ }
1249
1221
  }
1250
1222
  /**
1251
1223
  * Removes any registered visibilitychange callback.
@@ -1270,45 +1242,41 @@ export default class GoTrueClient {
1270
1242
  * This is the private implementation of {@link #startAutoRefresh}. Use this
1271
1243
  * within the library.
1272
1244
  */
1273
- _startAutoRefresh() {
1274
- return __awaiter(this, void 0, void 0, function* () {
1275
- yield this._stopAutoRefresh();
1276
- this._debug('#_startAutoRefresh()');
1277
- const ticker = setInterval(() => this._autoRefreshTokenTick(), AUTO_REFRESH_TICK_DURATION);
1278
- this.autoRefreshTicker = ticker;
1279
- if (ticker && typeof ticker === 'object' && typeof ticker.unref === 'function') {
1280
- // ticker is a NodeJS Timeout object that has an `unref` method
1281
- // https://nodejs.org/api/timers.html#timeoutunref
1282
- // When auto refresh is used in NodeJS (like for testing) the
1283
- // `setInterval` is preventing the process from being marked as
1284
- // finished and tests run endlessly. This can be prevented by calling
1285
- // `unref()` on the returned object.
1286
- ticker.unref();
1287
- // @ts-ignore
1288
- }
1289
- else if (typeof Deno !== 'undefined' && typeof Deno.unrefTimer === 'function') {
1290
- // similar like for NodeJS, but with the Deno API
1291
- // https://deno.land/api@latest?unstable&s=Deno.unrefTimer
1292
- // @ts-ignore
1293
- Deno.unrefTimer(ticker);
1294
- }
1295
- // run the tick immediately
1296
- yield this._autoRefreshTokenTick();
1297
- });
1245
+ async _startAutoRefresh() {
1246
+ await this._stopAutoRefresh();
1247
+ this._debug('#_startAutoRefresh()');
1248
+ const ticker = setInterval(() => this._autoRefreshTokenTick(), AUTO_REFRESH_TICK_DURATION);
1249
+ this.autoRefreshTicker = ticker;
1250
+ if (ticker && typeof ticker === 'object' && typeof ticker.unref === 'function') {
1251
+ // ticker is a NodeJS Timeout object that has an `unref` method
1252
+ // https://nodejs.org/api/timers.html#timeoutunref
1253
+ // When auto refresh is used in NodeJS (like for testing) the
1254
+ // `setInterval` is preventing the process from being marked as
1255
+ // finished and tests run endlessly. This can be prevented by calling
1256
+ // `unref()` on the returned object.
1257
+ ticker.unref();
1258
+ // @ts-ignore
1259
+ }
1260
+ else if (typeof Deno !== 'undefined' && typeof Deno.unrefTimer === 'function') {
1261
+ // similar like for NodeJS, but with the Deno API
1262
+ // https://deno.land/api@latest?unstable&s=Deno.unrefTimer
1263
+ // @ts-ignore
1264
+ Deno.unrefTimer(ticker);
1265
+ }
1266
+ // run the tick immediately
1267
+ await this._autoRefreshTokenTick();
1298
1268
  }
1299
1269
  /**
1300
1270
  * This is the private implementation of {@link #stopAutoRefresh}. Use this
1301
1271
  * within the library.
1302
1272
  */
1303
- _stopAutoRefresh() {
1304
- return __awaiter(this, void 0, void 0, function* () {
1305
- this._debug('#_stopAutoRefresh()');
1306
- const ticker = this.autoRefreshTicker;
1307
- this.autoRefreshTicker = null;
1308
- if (ticker) {
1309
- clearInterval(ticker);
1310
- }
1311
- });
1273
+ async _stopAutoRefresh() {
1274
+ this._debug('#_stopAutoRefresh()');
1275
+ const ticker = this.autoRefreshTicker;
1276
+ this.autoRefreshTicker = null;
1277
+ if (ticker) {
1278
+ clearInterval(ticker);
1279
+ }
1312
1280
  }
1313
1281
  /**
1314
1282
  * Starts an auto-refresh process in the background. The session is checked
@@ -1332,11 +1300,9 @@ export default class GoTrueClient {
1332
1300
  *
1333
1301
  * {@see #stopAutoRefresh}
1334
1302
  */
1335
- startAutoRefresh() {
1336
- return __awaiter(this, void 0, void 0, function* () {
1337
- this._removeVisibilityChangedCallback();
1338
- yield this._startAutoRefresh();
1339
- });
1303
+ async startAutoRefresh() {
1304
+ this._removeVisibilityChangedCallback();
1305
+ await this._startAutoRefresh();
1340
1306
  }
1341
1307
  /**
1342
1308
  * Stops an active auto refresh process running in the background (if any).
@@ -1346,22 +1312,20 @@ export default class GoTrueClient {
1346
1312
  *
1347
1313
  * See {@link #startAutoRefresh} for more details.
1348
1314
  */
1349
- stopAutoRefresh() {
1350
- return __awaiter(this, void 0, void 0, function* () {
1351
- this._removeVisibilityChangedCallback();
1352
- yield this._stopAutoRefresh();
1353
- });
1315
+ async stopAutoRefresh() {
1316
+ this._removeVisibilityChangedCallback();
1317
+ await this._stopAutoRefresh();
1354
1318
  }
1355
1319
  /**
1356
1320
  * Runs the auto refresh token tick.
1357
1321
  */
1358
- _autoRefreshTokenTick() {
1359
- return __awaiter(this, void 0, void 0, function* () {
1360
- this._debug('#_autoRefreshTokenTick()', 'begin');
1322
+ async _autoRefreshTokenTick() {
1323
+ this._debug('#_autoRefreshTokenTick()', 'begin');
1324
+ try {
1325
+ const now = Date.now();
1361
1326
  try {
1362
- const now = Date.now();
1363
- try {
1364
- const { data: { session }, } = yield this.getSession();
1327
+ return await this._useSession(async (result) => {
1328
+ const { data: { session }, } = result;
1365
1329
  if (!session || !session.refresh_token || !session.expires_at) {
1366
1330
  this._debug('#_autoRefreshTokenTick()', 'no session');
1367
1331
  return;
@@ -1370,70 +1334,66 @@ export default class GoTrueClient {
1370
1334
  const expiresInTicks = Math.floor((session.expires_at * 1000 - now) / AUTO_REFRESH_TICK_DURATION);
1371
1335
  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`);
1372
1336
  if (expiresInTicks <= AUTO_REFRESH_TICK_THRESHOLD) {
1373
- yield this._callRefreshToken(session.refresh_token);
1337
+ await this._callRefreshToken(session.refresh_token);
1374
1338
  }
1375
- }
1376
- catch (e) {
1377
- console.error('Auto refresh tick failed with error. This is likely a transient error.', e);
1378
- }
1339
+ });
1379
1340
  }
1380
- finally {
1381
- this._debug('#_autoRefreshTokenTick()', 'end');
1341
+ catch (e) {
1342
+ console.error('Auto refresh tick failed with error. This is likely a transient error.', e);
1382
1343
  }
1383
- });
1344
+ }
1345
+ finally {
1346
+ this._debug('#_autoRefreshTokenTick()', 'end');
1347
+ }
1384
1348
  }
1385
1349
  /**
1386
1350
  * Registers callbacks on the browser / platform, which in-turn run
1387
1351
  * algorithms when the browser window/tab are in foreground. On non-browser
1388
1352
  * platforms it assumes always foreground.
1389
1353
  */
1390
- _handleVisibilityChange() {
1391
- return __awaiter(this, void 0, void 0, function* () {
1392
- this._debug('#_handleVisibilityChange()');
1393
- if (!isBrowser() || !(window === null || window === void 0 ? void 0 : window.addEventListener)) {
1394
- if (this.autoRefreshToken) {
1395
- // in non-browser environments the refresh token ticker runs always
1396
- this.startAutoRefresh();
1397
- }
1398
- return false;
1399
- }
1400
- try {
1401
- this.visibilityChangedCallback = () => __awaiter(this, void 0, void 0, function* () { return yield this._onVisibilityChanged(false); });
1402
- window === null || window === void 0 ? void 0 : window.addEventListener('visibilitychange', this.visibilityChangedCallback);
1403
- // now immediately call the visbility changed callback to setup with the
1404
- // current visbility state
1405
- yield this._onVisibilityChanged(true); // initial call
1406
- }
1407
- catch (error) {
1408
- console.error('_handleVisibilityChange', error);
1409
- }
1410
- });
1354
+ async _handleVisibilityChange() {
1355
+ this._debug('#_handleVisibilityChange()');
1356
+ if (!isBrowser() || !(window === null || window === void 0 ? void 0 : window.addEventListener)) {
1357
+ if (this.autoRefreshToken) {
1358
+ // in non-browser environments the refresh token ticker runs always
1359
+ this.startAutoRefresh();
1360
+ }
1361
+ return false;
1362
+ }
1363
+ try {
1364
+ this.visibilityChangedCallback = async () => await this._onVisibilityChanged(false);
1365
+ window === null || window === void 0 ? void 0 : window.addEventListener('visibilitychange', this.visibilityChangedCallback);
1366
+ // now immediately call the visbility changed callback to setup with the
1367
+ // current visbility state
1368
+ await this._onVisibilityChanged(true); // initial call
1369
+ }
1370
+ catch (error) {
1371
+ console.error('_handleVisibilityChange', error);
1372
+ }
1411
1373
  }
1412
1374
  /**
1413
1375
  * Callback registered with `window.addEventListener('visibilitychange')`.
1414
1376
  */
1415
- _onVisibilityChanged(isInitial) {
1416
- return __awaiter(this, void 0, void 0, function* () {
1417
- this._debug(`#_onVisibilityChanged(${isInitial})`, 'visibilityState', document.visibilityState);
1418
- if (document.visibilityState === 'visible') {
1419
- if (!isInitial) {
1420
- // initial visibility change setup is handled in another flow under #initialize()
1421
- yield this.initializePromise;
1422
- yield this._recoverAndRefresh();
1423
- this._debug('#_onVisibilityChanged()', 'finished waiting for initialize, _recoverAndRefresh');
1424
- }
1425
- if (this.autoRefreshToken) {
1426
- // in browser environments the refresh token ticker runs only on focused tabs
1427
- // which prevents race conditions
1428
- this._startAutoRefresh();
1429
- }
1377
+ async _onVisibilityChanged(isInitial) {
1378
+ this._debug(`#_onVisibilityChanged(${isInitial})`, 'visibilityState', document.visibilityState);
1379
+ if (document.visibilityState === 'visible') {
1380
+ if (!isInitial) {
1381
+ // initial visibility change setup is handled in another flow under #initialize()
1382
+ await this.initializePromise;
1383
+ await this._recoverAndRefresh();
1384
+ this._debug('#_onVisibilityChanged()', 'finished waiting for initialize, _recoverAndRefresh');
1385
+ }
1386
+ if (this.autoRefreshToken) {
1387
+ // in browser environments the refresh token ticker runs only on focused tabs
1388
+ // which prevents race conditions
1389
+ this._startAutoRefresh();
1430
1390
  }
1431
- else if (document.visibilityState === 'hidden') {
1432
- if (this.autoRefreshToken) {
1433
- this._stopAutoRefresh();
1434
- }
1391
+ }
1392
+ else if (document.visibilityState === 'hidden') {
1393
+ if (this.autoRefreshToken) {
1394
+ this._stopAutoRefresh();
1435
1395
  }
1436
- });
1396
+ }
1437
1397
  }
1438
1398
  /**
1439
1399
  * Generates the relevant login URL for a third-party provider.
@@ -1441,67 +1401,65 @@ export default class GoTrueClient {
1441
1401
  * @param options.scopes A space-separated list of scopes granted to the OAuth application.
1442
1402
  * @param options.queryParams An object of key-value pairs containing query parameters granted to the OAuth application.
1443
1403
  */
1444
- _getUrlForProvider(provider, options) {
1445
- return __awaiter(this, void 0, void 0, function* () {
1446
- const urlParams = [`provider=${encodeURIComponent(provider)}`];
1447
- if (options === null || options === void 0 ? void 0 : options.redirectTo) {
1448
- urlParams.push(`redirect_to=${encodeURIComponent(options.redirectTo)}`);
1449
- }
1450
- if (options === null || options === void 0 ? void 0 : options.scopes) {
1451
- urlParams.push(`scopes=${encodeURIComponent(options.scopes)}`);
1452
- }
1453
- if (this.flowType === 'pkce') {
1454
- const codeVerifier = generatePKCEVerifier();
1455
- yield setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
1456
- const codeChallenge = yield generatePKCEChallenge(codeVerifier);
1457
- const codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
1458
- this._debug('PKCE', 'code verifier', `${codeVerifier.substring(0, 5)}...`, 'code challenge', codeChallenge, 'method', codeChallengeMethod);
1459
- const flowParams = new URLSearchParams({
1460
- code_challenge: `${encodeURIComponent(codeChallenge)}`,
1461
- code_challenge_method: `${encodeURIComponent(codeChallengeMethod)}`,
1462
- });
1463
- urlParams.push(flowParams.toString());
1464
- }
1465
- if (options === null || options === void 0 ? void 0 : options.queryParams) {
1466
- const query = new URLSearchParams(options.queryParams);
1467
- urlParams.push(query.toString());
1468
- }
1469
- return `${this.url}/authorize?${urlParams.join('&')}`;
1470
- });
1404
+ async _getUrlForProvider(provider, options) {
1405
+ const urlParams = [`provider=${encodeURIComponent(provider)}`];
1406
+ if (options === null || options === void 0 ? void 0 : options.redirectTo) {
1407
+ urlParams.push(`redirect_to=${encodeURIComponent(options.redirectTo)}`);
1408
+ }
1409
+ if (options === null || options === void 0 ? void 0 : options.scopes) {
1410
+ urlParams.push(`scopes=${encodeURIComponent(options.scopes)}`);
1411
+ }
1412
+ if (this.flowType === 'pkce') {
1413
+ const codeVerifier = generatePKCEVerifier();
1414
+ await setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier);
1415
+ const codeChallenge = await generatePKCEChallenge(codeVerifier);
1416
+ const codeChallengeMethod = codeVerifier === codeChallenge ? 'plain' : 's256';
1417
+ this._debug('PKCE', 'code verifier', `${codeVerifier.substring(0, 5)}...`, 'code challenge', codeChallenge, 'method', codeChallengeMethod);
1418
+ const flowParams = new URLSearchParams({
1419
+ code_challenge: `${encodeURIComponent(codeChallenge)}`,
1420
+ code_challenge_method: `${encodeURIComponent(codeChallengeMethod)}`,
1421
+ });
1422
+ urlParams.push(flowParams.toString());
1423
+ }
1424
+ if (options === null || options === void 0 ? void 0 : options.queryParams) {
1425
+ const query = new URLSearchParams(options.queryParams);
1426
+ urlParams.push(query.toString());
1427
+ }
1428
+ return `${this.url}/authorize?${urlParams.join('&')}`;
1471
1429
  }
1472
- _unenroll(params) {
1473
- var _a;
1474
- return __awaiter(this, void 0, void 0, function* () {
1475
- try {
1476
- const { data: sessionData, error: sessionError } = yield this.getSession();
1430
+ async _unenroll(params) {
1431
+ try {
1432
+ return await this._useSession(async (result) => {
1433
+ var _a;
1434
+ const { data: sessionData, error: sessionError } = result;
1477
1435
  if (sessionError) {
1478
1436
  return { data: null, error: sessionError };
1479
1437
  }
1480
- return yield _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1438
+ return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
1481
1439
  headers: this.headers,
1482
1440
  jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1483
1441
  });
1442
+ });
1443
+ }
1444
+ catch (error) {
1445
+ if (isAuthError(error)) {
1446
+ return { data: null, error };
1484
1447
  }
1485
- catch (error) {
1486
- if (isAuthError(error)) {
1487
- return { data: null, error };
1488
- }
1489
- throw error;
1490
- }
1491
- });
1448
+ throw error;
1449
+ }
1492
1450
  }
1493
1451
  /**
1494
1452
  * {@see GoTrueMFAApi#enroll}
1495
1453
  */
1496
- _enroll(params) {
1497
- var _a, _b;
1498
- return __awaiter(this, void 0, void 0, function* () {
1499
- try {
1500
- const { data: sessionData, error: sessionError } = yield this.getSession();
1454
+ async _enroll(params) {
1455
+ try {
1456
+ return await this._useSession(async (result) => {
1457
+ var _a, _b;
1458
+ const { data: sessionData, error: sessionError } = result;
1501
1459
  if (sessionError) {
1502
1460
  return { data: null, error: sessionError };
1503
1461
  }
1504
- const { data, error } = yield _request(this.fetch, 'POST', `${this.url}/factors`, {
1462
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors`, {
1505
1463
  body: {
1506
1464
  friendly_name: params.friendlyName,
1507
1465
  factor_type: params.factorType,
@@ -1517,27 +1475,27 @@ export default class GoTrueClient {
1517
1475
  data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`;
1518
1476
  }
1519
1477
  return { data, error: null };
1478
+ });
1479
+ }
1480
+ catch (error) {
1481
+ if (isAuthError(error)) {
1482
+ return { data: null, error };
1520
1483
  }
1521
- catch (error) {
1522
- if (isAuthError(error)) {
1523
- return { data: null, error };
1524
- }
1525
- throw error;
1526
- }
1527
- });
1484
+ throw error;
1485
+ }
1528
1486
  }
1529
1487
  /**
1530
1488
  * {@see GoTrueMFAApi#verify}
1531
1489
  */
1532
- _verify(params) {
1533
- var _a;
1534
- return __awaiter(this, void 0, void 0, function* () {
1535
- try {
1536
- const { data: sessionData, error: sessionError } = yield this.getSession();
1490
+ async _verify(params) {
1491
+ try {
1492
+ return await this._useSession(async (result) => {
1493
+ var _a;
1494
+ const { data: sessionData, error: sessionError } = result;
1537
1495
  if (sessionError) {
1538
1496
  return { data: null, error: sessionError };
1539
1497
  }
1540
- const { data, error } = yield _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1498
+ const { data, error } = await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/verify`, {
1541
1499
  body: { code: params.code, challenge_id: params.challengeId },
1542
1500
  headers: this.headers,
1543
1501
  jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
@@ -1545,87 +1503,83 @@ export default class GoTrueClient {
1545
1503
  if (error) {
1546
1504
  return { data: null, error };
1547
1505
  }
1548
- yield this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1549
- yield this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1506
+ await this._saveSession(Object.assign({ expires_at: Math.round(Date.now() / 1000) + data.expires_in }, data));
1507
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data);
1550
1508
  return { data, error };
1509
+ });
1510
+ }
1511
+ catch (error) {
1512
+ if (isAuthError(error)) {
1513
+ return { data: null, error };
1551
1514
  }
1552
- catch (error) {
1553
- if (isAuthError(error)) {
1554
- return { data: null, error };
1555
- }
1556
- throw error;
1557
- }
1558
- });
1515
+ throw error;
1516
+ }
1559
1517
  }
1560
1518
  /**
1561
1519
  * {@see GoTrueMFAApi#challenge}
1562
1520
  */
1563
- _challenge(params) {
1564
- var _a;
1565
- return __awaiter(this, void 0, void 0, function* () {
1566
- try {
1567
- const { data: sessionData, error: sessionError } = yield this.getSession();
1521
+ async _challenge(params) {
1522
+ try {
1523
+ return await this._useSession(async (result) => {
1524
+ var _a;
1525
+ const { data: sessionData, error: sessionError } = result;
1568
1526
  if (sessionError) {
1569
1527
  return { data: null, error: sessionError };
1570
1528
  }
1571
- return yield _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1529
+ return await _request(this.fetch, 'POST', `${this.url}/factors/${params.factorId}/challenge`, {
1572
1530
  headers: this.headers,
1573
1531
  jwt: (_a = sessionData === null || sessionData === void 0 ? void 0 : sessionData.session) === null || _a === void 0 ? void 0 : _a.access_token,
1574
1532
  });
1533
+ });
1534
+ }
1535
+ catch (error) {
1536
+ if (isAuthError(error)) {
1537
+ return { data: null, error };
1575
1538
  }
1576
- catch (error) {
1577
- if (isAuthError(error)) {
1578
- return { data: null, error };
1579
- }
1580
- throw error;
1581
- }
1582
- });
1539
+ throw error;
1540
+ }
1583
1541
  }
1584
1542
  /**
1585
1543
  * {@see GoTrueMFAApi#challengeAndVerify}
1586
1544
  */
1587
- _challengeAndVerify(params) {
1588
- return __awaiter(this, void 0, void 0, function* () {
1589
- const { data: challengeData, error: challengeError } = yield this._challenge({
1590
- factorId: params.factorId,
1591
- });
1592
- if (challengeError) {
1593
- return { data: null, error: challengeError };
1594
- }
1595
- return yield this._verify({
1596
- factorId: params.factorId,
1597
- challengeId: challengeData.id,
1598
- code: params.code,
1599
- });
1545
+ async _challengeAndVerify(params) {
1546
+ const { data: challengeData, error: challengeError } = await this._challenge({
1547
+ factorId: params.factorId,
1548
+ });
1549
+ if (challengeError) {
1550
+ return { data: null, error: challengeError };
1551
+ }
1552
+ return await this._verify({
1553
+ factorId: params.factorId,
1554
+ challengeId: challengeData.id,
1555
+ code: params.code,
1600
1556
  });
1601
1557
  }
1602
1558
  /**
1603
1559
  * {@see GoTrueMFAApi#listFactors}
1604
1560
  */
1605
- _listFactors() {
1606
- return __awaiter(this, void 0, void 0, function* () {
1607
- const { data: { user }, error: userError, } = yield this.getUser();
1608
- if (userError) {
1609
- return { data: null, error: userError };
1610
- }
1611
- const factors = (user === null || user === void 0 ? void 0 : user.factors) || [];
1612
- const totp = factors.filter((factor) => factor.factor_type === 'totp' && factor.status === 'verified');
1613
- return {
1614
- data: {
1615
- all: factors,
1616
- totp,
1617
- },
1618
- error: null,
1619
- };
1620
- });
1561
+ async _listFactors() {
1562
+ const { data: { user }, error: userError, } = await this.getUser();
1563
+ if (userError) {
1564
+ return { data: null, error: userError };
1565
+ }
1566
+ const factors = (user === null || user === void 0 ? void 0 : user.factors) || [];
1567
+ const totp = factors.filter((factor) => factor.factor_type === 'totp' && factor.status === 'verified');
1568
+ return {
1569
+ data: {
1570
+ all: factors,
1571
+ totp,
1572
+ },
1573
+ error: null,
1574
+ };
1621
1575
  }
1622
1576
  /**
1623
1577
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
1624
1578
  */
1625
- _getAuthenticatorAssuranceLevel() {
1626
- var _a, _b;
1627
- return __awaiter(this, void 0, void 0, function* () {
1628
- const { data: { session }, error: sessionError, } = yield this.getSession();
1579
+ async _getAuthenticatorAssuranceLevel() {
1580
+ return await this._useSession(async (result) => {
1581
+ var _a, _b;
1582
+ const { data: { session }, error: sessionError, } = result;
1629
1583
  if (sessionError) {
1630
1584
  return { data: null, error: sessionError };
1631
1585
  }