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