@supabase/auth-js 2.80.1-canary.0 → 2.80.1-canary.2
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.
- package/README.md +36 -18
- package/dist/main/AuthAdminApi.js +2 -4
- package/dist/main/AuthAdminApi.js.map +1 -1
- package/dist/main/AuthClient.js +2 -4
- package/dist/main/AuthClient.js.map +1 -1
- package/dist/main/GoTrueAdminApi.d.ts +48 -1
- package/dist/main/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/main/GoTrueAdminApi.js +162 -12
- package/dist/main/GoTrueAdminApi.js.map +1 -1
- package/dist/main/GoTrueClient.d.ts +58 -2
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +293 -156
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/index.js +7 -23
- package/dist/main/index.js.map +1 -1
- package/dist/main/lib/error-codes.d.ts +1 -1
- package/dist/main/lib/fetch.js +2 -12
- package/dist/main/lib/fetch.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +11 -0
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +39 -42
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/types.d.ts +283 -2
- package/dist/main/lib/types.d.ts.map +1 -1
- package/dist/main/lib/types.js.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/main/lib/webauthn.d.ts +7 -5
- package/dist/main/lib/webauthn.d.ts.map +1 -1
- package/dist/main/lib/webauthn.js +5 -15
- package/dist/main/lib/webauthn.js.map +1 -1
- package/dist/module/GoTrueAdminApi.d.ts +48 -1
- package/dist/module/GoTrueAdminApi.d.ts.map +1 -1
- package/dist/module/GoTrueAdminApi.js +161 -11
- package/dist/module/GoTrueAdminApi.js.map +1 -1
- package/dist/module/GoTrueClient.d.ts +58 -2
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +292 -153
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/error-codes.d.ts +1 -1
- package/dist/module/lib/fetch.js +1 -11
- package/dist/module/lib/fetch.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +11 -0
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +38 -9
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/types.d.ts +283 -2
- package/dist/module/lib/types.d.ts.map +1 -1
- package/dist/module/lib/types.js.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.js +1 -1
- package/dist/module/lib/webauthn.d.ts +7 -5
- package/dist/module/lib/webauthn.d.ts.map +1 -1
- package/dist/module/lib/webauthn.js +3 -13
- package/dist/module/lib/webauthn.js.map +1 -1
- package/dist/tsconfig.module.tsbuildinfo +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +12 -13
- package/src/GoTrueAdminApi.ts +186 -0
- package/src/GoTrueClient.ts +378 -150
- package/src/lib/error-codes.ts +1 -1
- package/src/lib/helpers.ts +46 -8
- package/src/lib/types.ts +307 -1
- package/src/lib/version.ts +1 -1
- package/src/lib/webauthn.ts +12 -8
package/src/GoTrueClient.ts
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
getAlgorithm,
|
|
39
39
|
getCodeChallengeAndMethod,
|
|
40
40
|
getItemAsync,
|
|
41
|
+
insecureUserWarningProxy,
|
|
41
42
|
isBrowser,
|
|
42
43
|
parseParametersFromURL,
|
|
43
44
|
removeItemAsync,
|
|
@@ -105,6 +106,9 @@ import type {
|
|
|
105
106
|
MFAVerifyWebauthnParamFields,
|
|
106
107
|
MFAVerifyWebauthnParams,
|
|
107
108
|
OAuthResponse,
|
|
109
|
+
AuthOAuthServerApi,
|
|
110
|
+
AuthOAuthAuthorizationDetailsResponse,
|
|
111
|
+
AuthOAuthConsentResponse,
|
|
108
112
|
Prettify,
|
|
109
113
|
Provider,
|
|
110
114
|
ResendParams,
|
|
@@ -166,6 +170,7 @@ const DEFAULT_OPTIONS: Omit<
|
|
|
166
170
|
flowType: 'implicit',
|
|
167
171
|
debug: false,
|
|
168
172
|
hasCustomAuthorizationHeader: false,
|
|
173
|
+
throwOnError: false,
|
|
169
174
|
}
|
|
170
175
|
|
|
171
176
|
async function lockNoOp<R>(name: string, acquireTimeout: number, fn: () => Promise<R>): Promise<R> {
|
|
@@ -183,7 +188,7 @@ async function lockNoOp<R>(name: string, acquireTimeout: number, fn: () => Promi
|
|
|
183
188
|
const GLOBAL_JWKS: { [storageKey: string]: { cachedAt: number; jwks: { keys: JWK[] } } } = {}
|
|
184
189
|
|
|
185
190
|
export default class GoTrueClient {
|
|
186
|
-
private static nextInstanceID =
|
|
191
|
+
private static nextInstanceID: Record<string, number> = {}
|
|
187
192
|
|
|
188
193
|
private instanceID: number
|
|
189
194
|
|
|
@@ -196,6 +201,12 @@ export default class GoTrueClient {
|
|
|
196
201
|
* Namespace for the MFA methods.
|
|
197
202
|
*/
|
|
198
203
|
mfa: GoTrueMFAApi
|
|
204
|
+
/**
|
|
205
|
+
* Namespace for the OAuth 2.1 authorization server methods.
|
|
206
|
+
* Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
|
|
207
|
+
* Used to implement the authorization code flow on the consent page.
|
|
208
|
+
*/
|
|
209
|
+
oauth: AuthOAuthServerApi
|
|
199
210
|
/**
|
|
200
211
|
* The storage key used to identify the values saved in localStorage
|
|
201
212
|
*/
|
|
@@ -252,6 +263,7 @@ export default class GoTrueClient {
|
|
|
252
263
|
protected lock: LockFunc
|
|
253
264
|
protected lockAcquired = false
|
|
254
265
|
protected pendingInLock: Promise<any>[] = []
|
|
266
|
+
protected throwOnError: boolean
|
|
255
267
|
|
|
256
268
|
/**
|
|
257
269
|
* Used to broadcast state change events to other tabs listening.
|
|
@@ -265,24 +277,26 @@ export default class GoTrueClient {
|
|
|
265
277
|
* Create a new client for use in the browser.
|
|
266
278
|
*/
|
|
267
279
|
constructor(options: GoTrueClientOptions) {
|
|
268
|
-
this.instanceID = GoTrueClient.nextInstanceID
|
|
269
|
-
GoTrueClient.nextInstanceID += 1
|
|
270
|
-
|
|
271
|
-
if (this.instanceID > 0 && isBrowser()) {
|
|
272
|
-
console.warn(
|
|
273
|
-
'Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.'
|
|
274
|
-
)
|
|
275
|
-
}
|
|
276
|
-
|
|
277
280
|
const settings = { ...DEFAULT_OPTIONS, ...options }
|
|
281
|
+
this.storageKey = settings.storageKey
|
|
282
|
+
|
|
283
|
+
this.instanceID = GoTrueClient.nextInstanceID[this.storageKey] ?? 0
|
|
284
|
+
GoTrueClient.nextInstanceID[this.storageKey] = this.instanceID + 1
|
|
278
285
|
|
|
279
286
|
this.logDebugMessages = !!settings.debug
|
|
280
287
|
if (typeof settings.debug === 'function') {
|
|
281
288
|
this.logger = settings.debug
|
|
282
289
|
}
|
|
283
290
|
|
|
291
|
+
if (this.instanceID > 0 && isBrowser()) {
|
|
292
|
+
const message = `${this._logPrefix()} Multiple GoTrueClient instances detected in the same browser context. It is not an error, but this should be avoided as it may produce undefined behavior when used concurrently under the same storage key.`
|
|
293
|
+
console.warn(message)
|
|
294
|
+
if (this.logDebugMessages) {
|
|
295
|
+
console.trace(message)
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
284
299
|
this.persistSession = settings.persistSession
|
|
285
|
-
this.storageKey = settings.storageKey
|
|
286
300
|
this.autoRefreshToken = settings.autoRefreshToken
|
|
287
301
|
this.admin = new GoTrueAdminApi({
|
|
288
302
|
url: settings.url,
|
|
@@ -297,6 +311,7 @@ export default class GoTrueClient {
|
|
|
297
311
|
this.detectSessionInUrl = settings.detectSessionInUrl
|
|
298
312
|
this.flowType = settings.flowType
|
|
299
313
|
this.hasCustomAuthorizationHeader = settings.hasCustomAuthorizationHeader
|
|
314
|
+
this.throwOnError = settings.throwOnError
|
|
300
315
|
|
|
301
316
|
if (settings.lock) {
|
|
302
317
|
this.lock = settings.lock
|
|
@@ -322,6 +337,12 @@ export default class GoTrueClient {
|
|
|
322
337
|
webauthn: new WebAuthnApi(this),
|
|
323
338
|
}
|
|
324
339
|
|
|
340
|
+
this.oauth = {
|
|
341
|
+
getAuthorizationDetails: this._getAuthorizationDetails.bind(this),
|
|
342
|
+
approveAuthorization: this._approveAuthorization.bind(this),
|
|
343
|
+
denyAuthorization: this._denyAuthorization.bind(this),
|
|
344
|
+
}
|
|
345
|
+
|
|
325
346
|
if (this.persistSession) {
|
|
326
347
|
if (settings.storage) {
|
|
327
348
|
this.storage = settings.storage
|
|
@@ -362,12 +383,35 @@ export default class GoTrueClient {
|
|
|
362
383
|
this.initialize()
|
|
363
384
|
}
|
|
364
385
|
|
|
386
|
+
/**
|
|
387
|
+
* Returns whether error throwing mode is enabled for this client.
|
|
388
|
+
*/
|
|
389
|
+
public isThrowOnErrorEnabled(): boolean {
|
|
390
|
+
return this.throwOnError
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Centralizes return handling with optional error throwing. When `throwOnError` is enabled
|
|
395
|
+
* and the provided result contains a non-nullish error, the error is thrown instead of
|
|
396
|
+
* being returned. This ensures consistent behavior across all public API methods.
|
|
397
|
+
*/
|
|
398
|
+
private _returnResult<T extends { error: any }>(result: T): T {
|
|
399
|
+
if (this.throwOnError && result && result.error) {
|
|
400
|
+
throw result.error
|
|
401
|
+
}
|
|
402
|
+
return result
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
private _logPrefix(): string {
|
|
406
|
+
return (
|
|
407
|
+
'GoTrueClient@' +
|
|
408
|
+
`${this.storageKey}:${this.instanceID} (${version}) ${new Date().toISOString()}`
|
|
409
|
+
)
|
|
410
|
+
}
|
|
411
|
+
|
|
365
412
|
private _debug(...args: any[]): GoTrueClient {
|
|
366
413
|
if (this.logDebugMessages) {
|
|
367
|
-
this.logger(
|
|
368
|
-
`GoTrueClient@${this.instanceID} (${version}) ${new Date().toISOString()}`,
|
|
369
|
-
...args
|
|
370
|
-
)
|
|
414
|
+
this.logger(this._logPrefix(), ...args)
|
|
371
415
|
}
|
|
372
416
|
|
|
373
417
|
return this
|
|
@@ -400,12 +444,16 @@ export default class GoTrueClient {
|
|
|
400
444
|
*/
|
|
401
445
|
private async _initialize(): Promise<InitializeResult> {
|
|
402
446
|
try {
|
|
403
|
-
|
|
447
|
+
let params: { [parameter: string]: string } = {}
|
|
404
448
|
let callbackUrlType = 'none'
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
449
|
+
|
|
450
|
+
if (isBrowser()) {
|
|
451
|
+
params = parseParametersFromURL(window.location.href)
|
|
452
|
+
if (this._isImplicitGrantCallback(params)) {
|
|
453
|
+
callbackUrlType = 'implicit'
|
|
454
|
+
} else if (await this._isPKCECallback(params)) {
|
|
455
|
+
callbackUrlType = 'pkce'
|
|
456
|
+
}
|
|
409
457
|
}
|
|
410
458
|
|
|
411
459
|
/**
|
|
@@ -464,12 +512,12 @@ export default class GoTrueClient {
|
|
|
464
512
|
return { error: null }
|
|
465
513
|
} catch (error) {
|
|
466
514
|
if (isAuthError(error)) {
|
|
467
|
-
return { error }
|
|
515
|
+
return this._returnResult({ error })
|
|
468
516
|
}
|
|
469
517
|
|
|
470
|
-
return {
|
|
518
|
+
return this._returnResult({
|
|
471
519
|
error: new AuthUnknownError('Unexpected error during initialization', error),
|
|
472
|
-
}
|
|
520
|
+
})
|
|
473
521
|
} finally {
|
|
474
522
|
await this._handleVisibilityChange()
|
|
475
523
|
this._debug('#_initialize()', 'end')
|
|
@@ -494,7 +542,7 @@ export default class GoTrueClient {
|
|
|
494
542
|
const { data, error } = res
|
|
495
543
|
|
|
496
544
|
if (error || !data) {
|
|
497
|
-
return { data: { user: null, session: null }, error: error }
|
|
545
|
+
return this._returnResult({ data: { user: null, session: null }, error: error })
|
|
498
546
|
}
|
|
499
547
|
const session: Session | null = data.session
|
|
500
548
|
const user: User | null = data.user
|
|
@@ -504,10 +552,10 @@ export default class GoTrueClient {
|
|
|
504
552
|
await this._notifyAllSubscribers('SIGNED_IN', session)
|
|
505
553
|
}
|
|
506
554
|
|
|
507
|
-
return { data: { user, session }, error: null }
|
|
555
|
+
return this._returnResult({ data: { user, session }, error: null })
|
|
508
556
|
} catch (error) {
|
|
509
557
|
if (isAuthError(error)) {
|
|
510
|
-
return { data: { user: null, session: null }, error }
|
|
558
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
511
559
|
}
|
|
512
560
|
|
|
513
561
|
throw error
|
|
@@ -572,7 +620,7 @@ export default class GoTrueClient {
|
|
|
572
620
|
const { data, error } = res
|
|
573
621
|
|
|
574
622
|
if (error || !data) {
|
|
575
|
-
return { data: { user: null, session: null }, error: error }
|
|
623
|
+
return this._returnResult({ data: { user: null, session: null }, error: error })
|
|
576
624
|
}
|
|
577
625
|
|
|
578
626
|
const session: Session | null = data.session
|
|
@@ -583,10 +631,10 @@ export default class GoTrueClient {
|
|
|
583
631
|
await this._notifyAllSubscribers('SIGNED_IN', session)
|
|
584
632
|
}
|
|
585
633
|
|
|
586
|
-
return { data: { user, session }, error: null }
|
|
634
|
+
return this._returnResult({ data: { user, session }, error: null })
|
|
587
635
|
} catch (error) {
|
|
588
636
|
if (isAuthError(error)) {
|
|
589
|
-
return { data: { user: null, session: null }, error }
|
|
637
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
590
638
|
}
|
|
591
639
|
|
|
592
640
|
throw error
|
|
@@ -636,25 +684,26 @@ export default class GoTrueClient {
|
|
|
636
684
|
const { data, error } = res
|
|
637
685
|
|
|
638
686
|
if (error) {
|
|
639
|
-
return { data: { user: null, session: null }, error }
|
|
687
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
640
688
|
} else if (!data || !data.session || !data.user) {
|
|
641
|
-
|
|
689
|
+
const invalidTokenError = new AuthInvalidTokenResponseError()
|
|
690
|
+
return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError })
|
|
642
691
|
}
|
|
643
692
|
if (data.session) {
|
|
644
693
|
await this._saveSession(data.session)
|
|
645
694
|
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
646
695
|
}
|
|
647
|
-
return {
|
|
696
|
+
return this._returnResult({
|
|
648
697
|
data: {
|
|
649
698
|
user: data.user,
|
|
650
699
|
session: data.session,
|
|
651
700
|
...(data.weak_password ? { weakPassword: data.weak_password } : null),
|
|
652
701
|
},
|
|
653
702
|
error,
|
|
654
|
-
}
|
|
703
|
+
})
|
|
655
704
|
} catch (error) {
|
|
656
705
|
if (isAuthError(error)) {
|
|
657
|
-
return { data: { user: null, session: null }, error }
|
|
706
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
658
707
|
}
|
|
659
708
|
throw error
|
|
660
709
|
}
|
|
@@ -830,19 +879,17 @@ export default class GoTrueClient {
|
|
|
830
879
|
throw error
|
|
831
880
|
}
|
|
832
881
|
if (!data || !data.session || !data.user) {
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
error: new AuthInvalidTokenResponseError(),
|
|
836
|
-
}
|
|
882
|
+
const invalidTokenError = new AuthInvalidTokenResponseError()
|
|
883
|
+
return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError })
|
|
837
884
|
}
|
|
838
885
|
if (data.session) {
|
|
839
886
|
await this._saveSession(data.session)
|
|
840
887
|
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
841
888
|
}
|
|
842
|
-
return { data: { ...data }, error }
|
|
889
|
+
return this._returnResult({ data: { ...data }, error })
|
|
843
890
|
} catch (error) {
|
|
844
891
|
if (isAuthError(error)) {
|
|
845
|
-
return { data: { user: null, session: null }, error }
|
|
892
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
846
893
|
}
|
|
847
894
|
|
|
848
895
|
throw error
|
|
@@ -1018,19 +1065,17 @@ export default class GoTrueClient {
|
|
|
1018
1065
|
throw error
|
|
1019
1066
|
}
|
|
1020
1067
|
if (!data || !data.session || !data.user) {
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
error: new AuthInvalidTokenResponseError(),
|
|
1024
|
-
}
|
|
1068
|
+
const invalidTokenError = new AuthInvalidTokenResponseError()
|
|
1069
|
+
return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError })
|
|
1025
1070
|
}
|
|
1026
1071
|
if (data.session) {
|
|
1027
1072
|
await this._saveSession(data.session)
|
|
1028
1073
|
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
1029
1074
|
}
|
|
1030
|
-
return { data: { ...data }, error }
|
|
1075
|
+
return this._returnResult({ data: { ...data }, error })
|
|
1031
1076
|
} catch (error) {
|
|
1032
1077
|
if (isAuthError(error)) {
|
|
1033
|
-
return { data: { user: null, session: null }, error }
|
|
1078
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1034
1079
|
}
|
|
1035
1080
|
|
|
1036
1081
|
throw error
|
|
@@ -1066,19 +1111,23 @@ export default class GoTrueClient {
|
|
|
1066
1111
|
throw error
|
|
1067
1112
|
}
|
|
1068
1113
|
if (!data || !data.session || !data.user) {
|
|
1069
|
-
|
|
1114
|
+
const invalidTokenError = new AuthInvalidTokenResponseError()
|
|
1115
|
+
return this._returnResult({
|
|
1070
1116
|
data: { user: null, session: null, redirectType: null },
|
|
1071
|
-
error:
|
|
1072
|
-
}
|
|
1117
|
+
error: invalidTokenError,
|
|
1118
|
+
})
|
|
1073
1119
|
}
|
|
1074
1120
|
if (data.session) {
|
|
1075
1121
|
await this._saveSession(data.session)
|
|
1076
1122
|
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
1077
1123
|
}
|
|
1078
|
-
return { data: { ...data, redirectType: redirectType ?? null }, error }
|
|
1124
|
+
return this._returnResult({ data: { ...data, redirectType: redirectType ?? null }, error })
|
|
1079
1125
|
} catch (error) {
|
|
1080
1126
|
if (isAuthError(error)) {
|
|
1081
|
-
return {
|
|
1127
|
+
return this._returnResult({
|
|
1128
|
+
data: { user: null, session: null, redirectType: null },
|
|
1129
|
+
error,
|
|
1130
|
+
})
|
|
1082
1131
|
}
|
|
1083
1132
|
|
|
1084
1133
|
throw error
|
|
@@ -1107,21 +1156,19 @@ export default class GoTrueClient {
|
|
|
1107
1156
|
|
|
1108
1157
|
const { data, error } = res
|
|
1109
1158
|
if (error) {
|
|
1110
|
-
return { data: { user: null, session: null }, error }
|
|
1159
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1111
1160
|
} else if (!data || !data.session || !data.user) {
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
error: new AuthInvalidTokenResponseError(),
|
|
1115
|
-
}
|
|
1161
|
+
const invalidTokenError = new AuthInvalidTokenResponseError()
|
|
1162
|
+
return this._returnResult({ data: { user: null, session: null }, error: invalidTokenError })
|
|
1116
1163
|
}
|
|
1117
1164
|
if (data.session) {
|
|
1118
1165
|
await this._saveSession(data.session)
|
|
1119
1166
|
await this._notifyAllSubscribers('SIGNED_IN', data.session)
|
|
1120
1167
|
}
|
|
1121
|
-
return { data, error }
|
|
1168
|
+
return this._returnResult({ data, error })
|
|
1122
1169
|
} catch (error) {
|
|
1123
1170
|
if (isAuthError(error)) {
|
|
1124
|
-
return { data: { user: null, session: null }, error }
|
|
1171
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1125
1172
|
}
|
|
1126
1173
|
throw error
|
|
1127
1174
|
}
|
|
@@ -1168,7 +1215,7 @@ export default class GoTrueClient {
|
|
|
1168
1215
|
},
|
|
1169
1216
|
redirectTo: options?.emailRedirectTo,
|
|
1170
1217
|
})
|
|
1171
|
-
return { data: { user: null, session: null }, error }
|
|
1218
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1172
1219
|
}
|
|
1173
1220
|
if ('phone' in credentials) {
|
|
1174
1221
|
const { phone, options } = credentials
|
|
@@ -1182,12 +1229,15 @@ export default class GoTrueClient {
|
|
|
1182
1229
|
channel: options?.channel ?? 'sms',
|
|
1183
1230
|
},
|
|
1184
1231
|
})
|
|
1185
|
-
return {
|
|
1232
|
+
return this._returnResult({
|
|
1233
|
+
data: { user: null, session: null, messageId: data?.message_id },
|
|
1234
|
+
error,
|
|
1235
|
+
})
|
|
1186
1236
|
}
|
|
1187
1237
|
throw new AuthInvalidCredentialsError('You must provide either an email or phone number.')
|
|
1188
1238
|
} catch (error) {
|
|
1189
1239
|
if (isAuthError(error)) {
|
|
1190
|
-
return { data: { user: null, session: null }, error }
|
|
1240
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1191
1241
|
}
|
|
1192
1242
|
|
|
1193
1243
|
throw error
|
|
@@ -1218,9 +1268,9 @@ export default class GoTrueClient {
|
|
|
1218
1268
|
if (error) {
|
|
1219
1269
|
throw error
|
|
1220
1270
|
}
|
|
1221
|
-
|
|
1222
1271
|
if (!data) {
|
|
1223
|
-
|
|
1272
|
+
const tokenVerificationError = new Error('An error occurred on token verification.')
|
|
1273
|
+
throw tokenVerificationError
|
|
1224
1274
|
}
|
|
1225
1275
|
|
|
1226
1276
|
const session: Session | null = data.session
|
|
@@ -1234,10 +1284,10 @@ export default class GoTrueClient {
|
|
|
1234
1284
|
)
|
|
1235
1285
|
}
|
|
1236
1286
|
|
|
1237
|
-
return { data: { user, session }, error: null }
|
|
1287
|
+
return this._returnResult({ data: { user, session }, error: null })
|
|
1238
1288
|
} catch (error) {
|
|
1239
1289
|
if (isAuthError(error)) {
|
|
1240
|
-
return { data: { user: null, session: null }, error }
|
|
1290
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1241
1291
|
}
|
|
1242
1292
|
|
|
1243
1293
|
throw error
|
|
@@ -1269,7 +1319,7 @@ export default class GoTrueClient {
|
|
|
1269
1319
|
)
|
|
1270
1320
|
}
|
|
1271
1321
|
|
|
1272
|
-
|
|
1322
|
+
const result = await _request(this.fetch, 'POST', `${this.url}/sso`, {
|
|
1273
1323
|
body: {
|
|
1274
1324
|
...('providerId' in params ? { provider_id: params.providerId } : null),
|
|
1275
1325
|
...('domain' in params ? { domain: params.domain } : null),
|
|
@@ -1284,9 +1334,10 @@ export default class GoTrueClient {
|
|
|
1284
1334
|
headers: this.headers,
|
|
1285
1335
|
xform: _ssoResponse,
|
|
1286
1336
|
})
|
|
1337
|
+
return this._returnResult(result)
|
|
1287
1338
|
} catch (error) {
|
|
1288
1339
|
if (isAuthError(error)) {
|
|
1289
|
-
return { data: null, error }
|
|
1340
|
+
return this._returnResult({ data: null, error })
|
|
1290
1341
|
}
|
|
1291
1342
|
throw error
|
|
1292
1343
|
}
|
|
@@ -1318,11 +1369,11 @@ export default class GoTrueClient {
|
|
|
1318
1369
|
headers: this.headers,
|
|
1319
1370
|
jwt: session.access_token,
|
|
1320
1371
|
})
|
|
1321
|
-
return { data: { user: null, session: null }, error }
|
|
1372
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1322
1373
|
})
|
|
1323
1374
|
} catch (error) {
|
|
1324
1375
|
if (isAuthError(error)) {
|
|
1325
|
-
return { data: { user: null, session: null }, error }
|
|
1376
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1326
1377
|
}
|
|
1327
1378
|
throw error
|
|
1328
1379
|
}
|
|
@@ -1345,7 +1396,7 @@ export default class GoTrueClient {
|
|
|
1345
1396
|
},
|
|
1346
1397
|
redirectTo: options?.emailRedirectTo,
|
|
1347
1398
|
})
|
|
1348
|
-
return { data: { user: null, session: null }, error }
|
|
1399
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1349
1400
|
} else if ('phone' in credentials) {
|
|
1350
1401
|
const { phone, type, options } = credentials
|
|
1351
1402
|
const { data, error } = await _request(this.fetch, 'POST', endpoint, {
|
|
@@ -1356,14 +1407,17 @@ export default class GoTrueClient {
|
|
|
1356
1407
|
gotrue_meta_security: { captcha_token: options?.captchaToken },
|
|
1357
1408
|
},
|
|
1358
1409
|
})
|
|
1359
|
-
return {
|
|
1410
|
+
return this._returnResult({
|
|
1411
|
+
data: { user: null, session: null, messageId: data?.message_id },
|
|
1412
|
+
error,
|
|
1413
|
+
})
|
|
1360
1414
|
}
|
|
1361
1415
|
throw new AuthInvalidCredentialsError(
|
|
1362
1416
|
'You must provide either an email or phone number and a type'
|
|
1363
1417
|
)
|
|
1364
1418
|
} catch (error) {
|
|
1365
1419
|
if (isAuthError(error)) {
|
|
1366
|
-
return { data: { user: null, session: null }, error }
|
|
1420
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1367
1421
|
}
|
|
1368
1422
|
throw error
|
|
1369
1423
|
}
|
|
@@ -1585,22 +1639,20 @@ export default class GoTrueClient {
|
|
|
1585
1639
|
}
|
|
1586
1640
|
}
|
|
1587
1641
|
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
})
|
|
1603
|
-
currentSession = proxySession
|
|
1642
|
+
// Wrap the user object with a warning proxy on the server
|
|
1643
|
+
// This warns when properties of the user are accessed, not when session.user itself is accessed
|
|
1644
|
+
if (
|
|
1645
|
+
this.storage.isServer &&
|
|
1646
|
+
currentSession.user &&
|
|
1647
|
+
!(currentSession.user as any).__isUserNotAvailableProxy
|
|
1648
|
+
) {
|
|
1649
|
+
const suppressWarningRef = { value: this.suppressGetSessionWarning }
|
|
1650
|
+
currentSession.user = insecureUserWarningProxy(currentSession.user, suppressWarningRef)
|
|
1651
|
+
|
|
1652
|
+
// Update the client-level suppression flag when the proxy suppresses the warning
|
|
1653
|
+
if (suppressWarningRef.value) {
|
|
1654
|
+
this.suppressGetSessionWarning = true
|
|
1655
|
+
}
|
|
1604
1656
|
}
|
|
1605
1657
|
|
|
1606
1658
|
return { data: { session: currentSession }, error: null }
|
|
@@ -1608,10 +1660,10 @@ export default class GoTrueClient {
|
|
|
1608
1660
|
|
|
1609
1661
|
const { data: session, error } = await this._callRefreshToken(currentSession.refresh_token)
|
|
1610
1662
|
if (error) {
|
|
1611
|
-
return { data: { session: null }, error }
|
|
1663
|
+
return this._returnResult({ data: { session: null }, error })
|
|
1612
1664
|
}
|
|
1613
1665
|
|
|
1614
|
-
return { data: { session }, error: null }
|
|
1666
|
+
return this._returnResult({ data: { session }, error: null })
|
|
1615
1667
|
} finally {
|
|
1616
1668
|
this._debug('#__loadSession()', 'end')
|
|
1617
1669
|
}
|
|
@@ -1675,7 +1727,7 @@ export default class GoTrueClient {
|
|
|
1675
1727
|
await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`)
|
|
1676
1728
|
}
|
|
1677
1729
|
|
|
1678
|
-
return { data: { user: null }, error }
|
|
1730
|
+
return this._returnResult({ data: { user: null }, error })
|
|
1679
1731
|
}
|
|
1680
1732
|
|
|
1681
1733
|
throw error
|
|
@@ -1734,15 +1786,17 @@ export default class GoTrueClient {
|
|
|
1734
1786
|
jwt: session.access_token,
|
|
1735
1787
|
xform: _userResponse,
|
|
1736
1788
|
})
|
|
1737
|
-
if (userError)
|
|
1789
|
+
if (userError) {
|
|
1790
|
+
throw userError
|
|
1791
|
+
}
|
|
1738
1792
|
session.user = data.user as User
|
|
1739
1793
|
await this._saveSession(session)
|
|
1740
1794
|
await this._notifyAllSubscribers('USER_UPDATED', session)
|
|
1741
|
-
return { data: { user: session.user }, error: null }
|
|
1795
|
+
return this._returnResult({ data: { user: session.user }, error: null })
|
|
1742
1796
|
})
|
|
1743
1797
|
} catch (error) {
|
|
1744
1798
|
if (isAuthError(error)) {
|
|
1745
|
-
return { data: { user: null }, error }
|
|
1799
|
+
return this._returnResult({ data: { user: null }, error })
|
|
1746
1800
|
}
|
|
1747
1801
|
|
|
1748
1802
|
throw error
|
|
@@ -1789,7 +1843,7 @@ export default class GoTrueClient {
|
|
|
1789
1843
|
currentSession.refresh_token
|
|
1790
1844
|
)
|
|
1791
1845
|
if (error) {
|
|
1792
|
-
return { data: { user: null, session: null }, error: error }
|
|
1846
|
+
return this._returnResult({ data: { user: null, session: null }, error: error })
|
|
1793
1847
|
}
|
|
1794
1848
|
|
|
1795
1849
|
if (!refreshedSession) {
|
|
@@ -1813,10 +1867,10 @@ export default class GoTrueClient {
|
|
|
1813
1867
|
await this._notifyAllSubscribers('SIGNED_IN', session)
|
|
1814
1868
|
}
|
|
1815
1869
|
|
|
1816
|
-
return { data: { user: session.user, session }, error: null }
|
|
1870
|
+
return this._returnResult({ data: { user: session.user, session }, error: null })
|
|
1817
1871
|
} catch (error) {
|
|
1818
1872
|
if (isAuthError(error)) {
|
|
1819
|
-
return { data: { session: null, user: null }, error }
|
|
1873
|
+
return this._returnResult({ data: { session: null, user: null }, error })
|
|
1820
1874
|
}
|
|
1821
1875
|
|
|
1822
1876
|
throw error
|
|
@@ -1857,18 +1911,18 @@ export default class GoTrueClient {
|
|
|
1857
1911
|
|
|
1858
1912
|
const { data: session, error } = await this._callRefreshToken(currentSession.refresh_token)
|
|
1859
1913
|
if (error) {
|
|
1860
|
-
return { data: { user: null, session: null }, error: error }
|
|
1914
|
+
return this._returnResult({ data: { user: null, session: null }, error: error })
|
|
1861
1915
|
}
|
|
1862
1916
|
|
|
1863
1917
|
if (!session) {
|
|
1864
|
-
return { data: { user: null, session: null }, error: null }
|
|
1918
|
+
return this._returnResult({ data: { user: null, session: null }, error: null })
|
|
1865
1919
|
}
|
|
1866
1920
|
|
|
1867
|
-
return { data: { user: session.user, session }, error: null }
|
|
1921
|
+
return this._returnResult({ data: { user: session.user, session }, error: null })
|
|
1868
1922
|
})
|
|
1869
1923
|
} catch (error) {
|
|
1870
1924
|
if (isAuthError(error)) {
|
|
1871
|
-
return { data: { user: null, session: null }, error }
|
|
1925
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
1872
1926
|
}
|
|
1873
1927
|
|
|
1874
1928
|
throw error
|
|
@@ -1999,10 +2053,10 @@ export default class GoTrueClient {
|
|
|
1999
2053
|
window.location.hash = ''
|
|
2000
2054
|
this._debug('#_getSessionFromURL()', 'clearing window.location.hash')
|
|
2001
2055
|
|
|
2002
|
-
return { data: { session, redirectType: params.type }, error: null }
|
|
2056
|
+
return this._returnResult({ data: { session, redirectType: params.type }, error: null })
|
|
2003
2057
|
} catch (error) {
|
|
2004
2058
|
if (isAuthError(error)) {
|
|
2005
|
-
return { data: { session: null, redirectType: null }, error }
|
|
2059
|
+
return this._returnResult({ data: { session: null, redirectType: null }, error })
|
|
2006
2060
|
}
|
|
2007
2061
|
|
|
2008
2062
|
throw error
|
|
@@ -2050,7 +2104,7 @@ export default class GoTrueClient {
|
|
|
2050
2104
|
return await this._useSession(async (result) => {
|
|
2051
2105
|
const { data, error: sessionError } = result
|
|
2052
2106
|
if (sessionError) {
|
|
2053
|
-
return { error: sessionError }
|
|
2107
|
+
return this._returnResult({ error: sessionError })
|
|
2054
2108
|
}
|
|
2055
2109
|
const accessToken = data.session?.access_token
|
|
2056
2110
|
if (accessToken) {
|
|
@@ -2064,7 +2118,7 @@ export default class GoTrueClient {
|
|
|
2064
2118
|
(error.status === 404 || error.status === 401 || error.status === 403)
|
|
2065
2119
|
)
|
|
2066
2120
|
) {
|
|
2067
|
-
return { error }
|
|
2121
|
+
return this._returnResult({ error })
|
|
2068
2122
|
}
|
|
2069
2123
|
}
|
|
2070
2124
|
}
|
|
@@ -2072,14 +2126,36 @@ export default class GoTrueClient {
|
|
|
2072
2126
|
await this._removeSession()
|
|
2073
2127
|
await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`)
|
|
2074
2128
|
}
|
|
2075
|
-
return { error: null }
|
|
2129
|
+
return this._returnResult({ error: null })
|
|
2076
2130
|
})
|
|
2077
2131
|
}
|
|
2078
2132
|
|
|
2079
2133
|
/**
|
|
2080
2134
|
* Receive a notification every time an auth event happens.
|
|
2135
|
+
* Safe to use without an async function as callback.
|
|
2136
|
+
*
|
|
2137
|
+
* @param callback A callback function to be invoked when an auth event happens.
|
|
2138
|
+
*/
|
|
2139
|
+
onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => void): {
|
|
2140
|
+
data: { subscription: Subscription }
|
|
2141
|
+
}
|
|
2142
|
+
|
|
2143
|
+
/**
|
|
2144
|
+
* Avoid using an async function inside `onAuthStateChange` as you might end
|
|
2145
|
+
* up with a deadlock. The callback function runs inside an exclusive lock,
|
|
2146
|
+
* so calling other Supabase Client APIs that also try to acquire the
|
|
2147
|
+
* exclusive lock, might cause a deadlock. This behavior is observable across
|
|
2148
|
+
* tabs. In the next major library version, this behavior will not be supported.
|
|
2149
|
+
*
|
|
2150
|
+
* Receive a notification every time an auth event happens.
|
|
2151
|
+
*
|
|
2081
2152
|
* @param callback A callback function to be invoked when an auth event happens.
|
|
2153
|
+
* @deprecated Due to the possibility of deadlocks with async functions as callbacks, use the version without an async function.
|
|
2082
2154
|
*/
|
|
2155
|
+
onAuthStateChange(callback: (event: AuthChangeEvent, session: Session | null) => Promise<void>): {
|
|
2156
|
+
data: { subscription: Subscription }
|
|
2157
|
+
}
|
|
2158
|
+
|
|
2083
2159
|
onAuthStateChange(
|
|
2084
2160
|
callback: (event: AuthChangeEvent, session: Session | null) => void | Promise<void>
|
|
2085
2161
|
): {
|
|
@@ -2172,7 +2248,7 @@ export default class GoTrueClient {
|
|
|
2172
2248
|
})
|
|
2173
2249
|
} catch (error) {
|
|
2174
2250
|
if (isAuthError(error)) {
|
|
2175
|
-
return { data: null, error }
|
|
2251
|
+
return this._returnResult({ data: null, error })
|
|
2176
2252
|
}
|
|
2177
2253
|
|
|
2178
2254
|
throw error
|
|
@@ -2194,10 +2270,10 @@ export default class GoTrueClient {
|
|
|
2194
2270
|
try {
|
|
2195
2271
|
const { data, error } = await this.getUser()
|
|
2196
2272
|
if (error) throw error
|
|
2197
|
-
return { data: { identities: data.user.identities ?? [] }, error: null }
|
|
2273
|
+
return this._returnResult({ data: { identities: data.user.identities ?? [] }, error: null })
|
|
2198
2274
|
} catch (error) {
|
|
2199
2275
|
if (isAuthError(error)) {
|
|
2200
|
-
return { data: null, error }
|
|
2276
|
+
return this._returnResult({ data: null, error })
|
|
2201
2277
|
}
|
|
2202
2278
|
throw error
|
|
2203
2279
|
}
|
|
@@ -2246,10 +2322,13 @@ export default class GoTrueClient {
|
|
|
2246
2322
|
if (isBrowser() && !credentials.options?.skipBrowserRedirect) {
|
|
2247
2323
|
window.location.assign(data?.url)
|
|
2248
2324
|
}
|
|
2249
|
-
return {
|
|
2325
|
+
return this._returnResult({
|
|
2326
|
+
data: { provider: credentials.provider, url: data?.url },
|
|
2327
|
+
error: null,
|
|
2328
|
+
})
|
|
2250
2329
|
} catch (error) {
|
|
2251
2330
|
if (isAuthError(error)) {
|
|
2252
|
-
return { data: { provider: credentials.provider, url: null }, error }
|
|
2331
|
+
return this._returnResult({ data: { provider: credentials.provider, url: null }, error })
|
|
2253
2332
|
}
|
|
2254
2333
|
throw error
|
|
2255
2334
|
}
|
|
@@ -2284,21 +2363,21 @@ export default class GoTrueClient {
|
|
|
2284
2363
|
|
|
2285
2364
|
const { data, error } = res
|
|
2286
2365
|
if (error) {
|
|
2287
|
-
return { data: { user: null, session: null }, error }
|
|
2366
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
2288
2367
|
} else if (!data || !data.session || !data.user) {
|
|
2289
|
-
return {
|
|
2368
|
+
return this._returnResult({
|
|
2290
2369
|
data: { user: null, session: null },
|
|
2291
2370
|
error: new AuthInvalidTokenResponseError(),
|
|
2292
|
-
}
|
|
2371
|
+
})
|
|
2293
2372
|
}
|
|
2294
2373
|
if (data.session) {
|
|
2295
2374
|
await this._saveSession(data.session)
|
|
2296
2375
|
await this._notifyAllSubscribers('USER_UPDATED', data.session)
|
|
2297
2376
|
}
|
|
2298
|
-
return { data, error }
|
|
2377
|
+
return this._returnResult({ data, error })
|
|
2299
2378
|
} catch (error) {
|
|
2300
2379
|
if (isAuthError(error)) {
|
|
2301
|
-
return { data: { user: null, session: null }, error }
|
|
2380
|
+
return this._returnResult({ data: { user: null, session: null }, error })
|
|
2302
2381
|
}
|
|
2303
2382
|
throw error
|
|
2304
2383
|
}
|
|
@@ -2333,7 +2412,7 @@ export default class GoTrueClient {
|
|
|
2333
2412
|
})
|
|
2334
2413
|
} catch (error) {
|
|
2335
2414
|
if (isAuthError(error)) {
|
|
2336
|
-
return { data: null, error }
|
|
2415
|
+
return this._returnResult({ data: null, error })
|
|
2337
2416
|
}
|
|
2338
2417
|
throw error
|
|
2339
2418
|
}
|
|
@@ -2379,7 +2458,7 @@ export default class GoTrueClient {
|
|
|
2379
2458
|
this._debug(debugName, 'error', error)
|
|
2380
2459
|
|
|
2381
2460
|
if (isAuthError(error)) {
|
|
2382
|
-
return { data: { session: null, user: null }, error }
|
|
2461
|
+
return this._returnResult({ data: { session: null, user: null }, error })
|
|
2383
2462
|
}
|
|
2384
2463
|
throw error
|
|
2385
2464
|
} finally {
|
|
@@ -2986,7 +3065,7 @@ export default class GoTrueClient {
|
|
|
2986
3065
|
return await this._useSession(async (result) => {
|
|
2987
3066
|
const { data: sessionData, error: sessionError } = result
|
|
2988
3067
|
if (sessionError) {
|
|
2989
|
-
return { data: null, error: sessionError }
|
|
3068
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
2990
3069
|
}
|
|
2991
3070
|
|
|
2992
3071
|
return await _request(this.fetch, 'DELETE', `${this.url}/factors/${params.factorId}`, {
|
|
@@ -2996,7 +3075,7 @@ export default class GoTrueClient {
|
|
|
2996
3075
|
})
|
|
2997
3076
|
} catch (error) {
|
|
2998
3077
|
if (isAuthError(error)) {
|
|
2999
|
-
return { data: null, error }
|
|
3078
|
+
return this._returnResult({ data: null, error })
|
|
3000
3079
|
}
|
|
3001
3080
|
throw error
|
|
3002
3081
|
}
|
|
@@ -3013,7 +3092,7 @@ export default class GoTrueClient {
|
|
|
3013
3092
|
return await this._useSession(async (result) => {
|
|
3014
3093
|
const { data: sessionData, error: sessionError } = result
|
|
3015
3094
|
if (sessionError) {
|
|
3016
|
-
return { data: null, error: sessionError }
|
|
3095
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3017
3096
|
}
|
|
3018
3097
|
|
|
3019
3098
|
const body = {
|
|
@@ -3032,18 +3111,18 @@ export default class GoTrueClient {
|
|
|
3032
3111
|
jwt: sessionData?.session?.access_token,
|
|
3033
3112
|
})) as AuthMFAEnrollResponse
|
|
3034
3113
|
if (error) {
|
|
3035
|
-
return { data: null, error }
|
|
3114
|
+
return this._returnResult({ data: null, error })
|
|
3036
3115
|
}
|
|
3037
3116
|
|
|
3038
3117
|
if (params.factorType === 'totp' && data.type === 'totp' && data?.totp?.qr_code) {
|
|
3039
3118
|
data.totp.qr_code = `data:image/svg+xml;utf-8,${data.totp.qr_code}`
|
|
3040
3119
|
}
|
|
3041
3120
|
|
|
3042
|
-
return { data, error: null }
|
|
3121
|
+
return this._returnResult({ data, error: null })
|
|
3043
3122
|
})
|
|
3044
3123
|
} catch (error) {
|
|
3045
3124
|
if (isAuthError(error)) {
|
|
3046
|
-
return { data: null, error }
|
|
3125
|
+
return this._returnResult({ data: null, error })
|
|
3047
3126
|
}
|
|
3048
3127
|
throw error
|
|
3049
3128
|
}
|
|
@@ -3063,7 +3142,7 @@ export default class GoTrueClient {
|
|
|
3063
3142
|
return await this._useSession(async (result) => {
|
|
3064
3143
|
const { data: sessionData, error: sessionError } = result
|
|
3065
3144
|
if (sessionError) {
|
|
3066
|
-
return { data: null, error: sessionError }
|
|
3145
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3067
3146
|
}
|
|
3068
3147
|
|
|
3069
3148
|
const body: StrictOmit<
|
|
@@ -3112,7 +3191,7 @@ export default class GoTrueClient {
|
|
|
3112
3191
|
}
|
|
3113
3192
|
)
|
|
3114
3193
|
if (error) {
|
|
3115
|
-
return { data: null, error }
|
|
3194
|
+
return this._returnResult({ data: null, error })
|
|
3116
3195
|
}
|
|
3117
3196
|
|
|
3118
3197
|
await this._saveSession({
|
|
@@ -3121,11 +3200,11 @@ export default class GoTrueClient {
|
|
|
3121
3200
|
})
|
|
3122
3201
|
await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
|
|
3123
3202
|
|
|
3124
|
-
return { data, error }
|
|
3203
|
+
return this._returnResult({ data, error })
|
|
3125
3204
|
})
|
|
3126
3205
|
} catch (error) {
|
|
3127
3206
|
if (isAuthError(error)) {
|
|
3128
|
-
return { data: null, error }
|
|
3207
|
+
return this._returnResult({ data: null, error })
|
|
3129
3208
|
}
|
|
3130
3209
|
throw error
|
|
3131
3210
|
}
|
|
@@ -3150,7 +3229,7 @@ export default class GoTrueClient {
|
|
|
3150
3229
|
return await this._useSession(async (result) => {
|
|
3151
3230
|
const { data: sessionData, error: sessionError } = result
|
|
3152
3231
|
if (sessionError) {
|
|
3153
|
-
return { data: null, error: sessionError }
|
|
3232
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3154
3233
|
}
|
|
3155
3234
|
|
|
3156
3235
|
const response = (await _request(
|
|
@@ -3214,7 +3293,7 @@ export default class GoTrueClient {
|
|
|
3214
3293
|
})
|
|
3215
3294
|
} catch (error) {
|
|
3216
3295
|
if (isAuthError(error)) {
|
|
3217
|
-
return { data: null, error }
|
|
3296
|
+
return this._returnResult({ data: null, error })
|
|
3218
3297
|
}
|
|
3219
3298
|
throw error
|
|
3220
3299
|
}
|
|
@@ -3234,7 +3313,7 @@ export default class GoTrueClient {
|
|
|
3234
3313
|
factorId: params.factorId,
|
|
3235
3314
|
})
|
|
3236
3315
|
if (challengeError) {
|
|
3237
|
-
return { data: null, error: challengeError }
|
|
3316
|
+
return this._returnResult({ data: null, error: challengeError })
|
|
3238
3317
|
}
|
|
3239
3318
|
|
|
3240
3319
|
return await this._verify({
|
|
@@ -3282,44 +3361,193 @@ export default class GoTrueClient {
|
|
|
3282
3361
|
* {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
|
|
3283
3362
|
*/
|
|
3284
3363
|
private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
|
|
3285
|
-
|
|
3364
|
+
const {
|
|
3365
|
+
data: { session },
|
|
3366
|
+
error: sessionError,
|
|
3367
|
+
} = await this.getSession()
|
|
3368
|
+
|
|
3369
|
+
if (sessionError) {
|
|
3370
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3371
|
+
}
|
|
3372
|
+
if (!session) {
|
|
3373
|
+
return {
|
|
3374
|
+
data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
|
|
3375
|
+
error: null,
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
const { payload } = decodeJWT(session.access_token)
|
|
3380
|
+
|
|
3381
|
+
let currentLevel: AuthenticatorAssuranceLevels | null = null
|
|
3382
|
+
|
|
3383
|
+
if (payload.aal) {
|
|
3384
|
+
currentLevel = payload.aal
|
|
3385
|
+
}
|
|
3386
|
+
|
|
3387
|
+
let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
|
|
3388
|
+
|
|
3389
|
+
const verifiedFactors =
|
|
3390
|
+
session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
|
|
3391
|
+
|
|
3392
|
+
if (verifiedFactors.length > 0) {
|
|
3393
|
+
nextLevel = 'aal2'
|
|
3394
|
+
}
|
|
3395
|
+
|
|
3396
|
+
const currentAuthenticationMethods = payload.amr || []
|
|
3397
|
+
|
|
3398
|
+
return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
|
|
3399
|
+
}
|
|
3400
|
+
|
|
3401
|
+
/**
|
|
3402
|
+
* Retrieves details about an OAuth authorization request.
|
|
3403
|
+
* Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
|
|
3404
|
+
*
|
|
3405
|
+
* Returns authorization details including client info, scopes, and user information.
|
|
3406
|
+
* If the API returns a redirect_uri, it means consent was already given - the caller
|
|
3407
|
+
* should handle the redirect manually if needed.
|
|
3408
|
+
*/
|
|
3409
|
+
private async _getAuthorizationDetails(
|
|
3410
|
+
authorizationId: string
|
|
3411
|
+
): Promise<AuthOAuthAuthorizationDetailsResponse> {
|
|
3412
|
+
try {
|
|
3286
3413
|
return await this._useSession(async (result) => {
|
|
3287
3414
|
const {
|
|
3288
3415
|
data: { session },
|
|
3289
3416
|
error: sessionError,
|
|
3290
3417
|
} = result
|
|
3418
|
+
|
|
3291
3419
|
if (sessionError) {
|
|
3292
|
-
return { data: null, error: sessionError }
|
|
3420
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3293
3421
|
}
|
|
3422
|
+
|
|
3294
3423
|
if (!session) {
|
|
3295
|
-
return {
|
|
3296
|
-
|
|
3297
|
-
|
|
3424
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() })
|
|
3425
|
+
}
|
|
3426
|
+
|
|
3427
|
+
return await _request(
|
|
3428
|
+
this.fetch,
|
|
3429
|
+
'GET',
|
|
3430
|
+
`${this.url}/oauth/authorizations/${authorizationId}`,
|
|
3431
|
+
{
|
|
3432
|
+
headers: this.headers,
|
|
3433
|
+
jwt: session.access_token,
|
|
3434
|
+
xform: (data: any) => ({ data, error: null }),
|
|
3298
3435
|
}
|
|
3436
|
+
)
|
|
3437
|
+
})
|
|
3438
|
+
} catch (error) {
|
|
3439
|
+
if (isAuthError(error)) {
|
|
3440
|
+
return this._returnResult({ data: null, error })
|
|
3441
|
+
}
|
|
3442
|
+
|
|
3443
|
+
throw error
|
|
3444
|
+
}
|
|
3445
|
+
}
|
|
3446
|
+
|
|
3447
|
+
/**
|
|
3448
|
+
* Approves an OAuth authorization request.
|
|
3449
|
+
* Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
|
|
3450
|
+
*/
|
|
3451
|
+
private async _approveAuthorization(
|
|
3452
|
+
authorizationId: string,
|
|
3453
|
+
options?: { skipBrowserRedirect?: boolean }
|
|
3454
|
+
): Promise<AuthOAuthConsentResponse> {
|
|
3455
|
+
try {
|
|
3456
|
+
return await this._useSession(async (result) => {
|
|
3457
|
+
const {
|
|
3458
|
+
data: { session },
|
|
3459
|
+
error: sessionError,
|
|
3460
|
+
} = result
|
|
3461
|
+
|
|
3462
|
+
if (sessionError) {
|
|
3463
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3299
3464
|
}
|
|
3300
3465
|
|
|
3301
|
-
|
|
3466
|
+
if (!session) {
|
|
3467
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() })
|
|
3468
|
+
}
|
|
3302
3469
|
|
|
3303
|
-
|
|
3470
|
+
const response = await _request(
|
|
3471
|
+
this.fetch,
|
|
3472
|
+
'POST',
|
|
3473
|
+
`${this.url}/oauth/authorizations/${authorizationId}/consent`,
|
|
3474
|
+
{
|
|
3475
|
+
headers: this.headers,
|
|
3476
|
+
jwt: session.access_token,
|
|
3477
|
+
body: { action: 'approve' },
|
|
3478
|
+
xform: (data: any) => ({ data, error: null }),
|
|
3479
|
+
}
|
|
3480
|
+
)
|
|
3304
3481
|
|
|
3305
|
-
if (
|
|
3306
|
-
|
|
3482
|
+
if (response.data && response.data.redirect_url) {
|
|
3483
|
+
// Automatically redirect in browser unless skipBrowserRedirect is true
|
|
3484
|
+
if (isBrowser() && !options?.skipBrowserRedirect) {
|
|
3485
|
+
window.location.assign(response.data.redirect_url)
|
|
3486
|
+
}
|
|
3307
3487
|
}
|
|
3308
3488
|
|
|
3309
|
-
|
|
3489
|
+
return response
|
|
3490
|
+
})
|
|
3491
|
+
} catch (error) {
|
|
3492
|
+
if (isAuthError(error)) {
|
|
3493
|
+
return this._returnResult({ data: null, error })
|
|
3494
|
+
}
|
|
3495
|
+
|
|
3496
|
+
throw error
|
|
3497
|
+
}
|
|
3498
|
+
}
|
|
3499
|
+
|
|
3500
|
+
/**
|
|
3501
|
+
* Denies an OAuth authorization request.
|
|
3502
|
+
* Only relevant when the OAuth 2.1 server is enabled in Supabase Auth.
|
|
3503
|
+
*/
|
|
3504
|
+
private async _denyAuthorization(
|
|
3505
|
+
authorizationId: string,
|
|
3506
|
+
options?: { skipBrowserRedirect?: boolean }
|
|
3507
|
+
): Promise<AuthOAuthConsentResponse> {
|
|
3508
|
+
try {
|
|
3509
|
+
return await this._useSession(async (result) => {
|
|
3510
|
+
const {
|
|
3511
|
+
data: { session },
|
|
3512
|
+
error: sessionError,
|
|
3513
|
+
} = result
|
|
3310
3514
|
|
|
3311
|
-
|
|
3312
|
-
|
|
3515
|
+
if (sessionError) {
|
|
3516
|
+
return this._returnResult({ data: null, error: sessionError })
|
|
3517
|
+
}
|
|
3313
3518
|
|
|
3314
|
-
if (
|
|
3315
|
-
|
|
3519
|
+
if (!session) {
|
|
3520
|
+
return this._returnResult({ data: null, error: new AuthSessionMissingError() })
|
|
3316
3521
|
}
|
|
3317
3522
|
|
|
3318
|
-
const
|
|
3523
|
+
const response = await _request(
|
|
3524
|
+
this.fetch,
|
|
3525
|
+
'POST',
|
|
3526
|
+
`${this.url}/oauth/authorizations/${authorizationId}/consent`,
|
|
3527
|
+
{
|
|
3528
|
+
headers: this.headers,
|
|
3529
|
+
jwt: session.access_token,
|
|
3530
|
+
body: { action: 'deny' },
|
|
3531
|
+
xform: (data: any) => ({ data, error: null }),
|
|
3532
|
+
}
|
|
3533
|
+
)
|
|
3534
|
+
|
|
3535
|
+
if (response.data && response.data.redirect_url) {
|
|
3536
|
+
// Automatically redirect in browser unless skipBrowserRedirect is true
|
|
3537
|
+
if (isBrowser() && !options?.skipBrowserRedirect) {
|
|
3538
|
+
window.location.assign(response.data.redirect_url)
|
|
3539
|
+
}
|
|
3540
|
+
}
|
|
3319
3541
|
|
|
3320
|
-
return
|
|
3542
|
+
return response
|
|
3321
3543
|
})
|
|
3322
|
-
})
|
|
3544
|
+
} catch (error) {
|
|
3545
|
+
if (isAuthError(error)) {
|
|
3546
|
+
return this._returnResult({ data: null, error })
|
|
3547
|
+
}
|
|
3548
|
+
|
|
3549
|
+
throw error
|
|
3550
|
+
}
|
|
3323
3551
|
}
|
|
3324
3552
|
|
|
3325
3553
|
private async fetchJwk(kid: string, jwks: { keys: JWK[] } = { keys: [] }): Promise<JWK | null> {
|
|
@@ -3403,7 +3631,7 @@ export default class GoTrueClient {
|
|
|
3403
3631
|
if (!token) {
|
|
3404
3632
|
const { data, error } = await this.getSession()
|
|
3405
3633
|
if (error || !data.session) {
|
|
3406
|
-
return { data: null, error }
|
|
3634
|
+
return this._returnResult({ data: null, error })
|
|
3407
3635
|
}
|
|
3408
3636
|
token = data.session.access_token
|
|
3409
3637
|
}
|
|
@@ -3475,7 +3703,7 @@ export default class GoTrueClient {
|
|
|
3475
3703
|
}
|
|
3476
3704
|
} catch (error) {
|
|
3477
3705
|
if (isAuthError(error)) {
|
|
3478
|
-
return { data: null, error }
|
|
3706
|
+
return this._returnResult({ data: null, error })
|
|
3479
3707
|
}
|
|
3480
3708
|
throw error
|
|
3481
3709
|
}
|