@supabase/gotrue-js 2.20.1 → 2.20.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/dist/main/GoTrueClient.d.ts +7 -2
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +36 -10
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/errors.d.ts +19 -0
- package/dist/main/lib/errors.d.ts.map +1 -1
- package/dist/main/lib/errors.js +17 -1
- package/dist/main/lib/errors.js.map +1 -1
- package/dist/main/lib/types.d.ts +3 -4
- package/dist/main/lib/types.d.ts.map +1 -1
- package/dist/main/lib/version.d.ts +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/module/GoTrueClient.d.ts +7 -2
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +37 -11
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/errors.d.ts +19 -0
- package/dist/module/lib/errors.d.ts.map +1 -1
- package/dist/module/lib/errors.js +15 -0
- package/dist/module/lib/errors.js.map +1 -1
- package/dist/module/lib/types.d.ts +3 -4
- package/dist/module/lib/types.d.ts.map +1 -1
- package/dist/module/lib/version.d.ts +1 -1
- package/dist/module/lib/version.js +1 -1
- package/package.json +1 -1
- package/src/GoTrueClient.ts +38 -12
- package/src/lib/errors.ts +17 -0
- package/src/lib/types.ts +3 -4
- package/src/lib/version.ts +1 -1
package/src/GoTrueClient.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { DEFAULT_HEADERS, EXPIRY_MARGIN, GOTRUE_URL, STORAGE_KEY } from './lib/c
|
|
|
3
3
|
import {
|
|
4
4
|
AuthError,
|
|
5
5
|
AuthImplicitGrantRedirectError,
|
|
6
|
+
AuthPKCEGrantCodeExchangeError,
|
|
6
7
|
AuthInvalidCredentialsError,
|
|
7
8
|
AuthRetryableFetchError,
|
|
8
9
|
AuthSessionMissingError,
|
|
@@ -66,7 +67,7 @@ import type {
|
|
|
66
67
|
AuthenticatorAssuranceLevels,
|
|
67
68
|
Factor,
|
|
68
69
|
MFAChallengeAndVerifyParams,
|
|
69
|
-
|
|
70
|
+
AuthFlowType,
|
|
70
71
|
} from './lib/types'
|
|
71
72
|
|
|
72
73
|
polyfillGlobalThis() // Make "globalThis" available
|
|
@@ -78,6 +79,7 @@ const DEFAULT_OPTIONS: Omit<Required<GoTrueClientOptions>, 'fetch' | 'storage'>
|
|
|
78
79
|
persistSession: true,
|
|
79
80
|
detectSessionInUrl: true,
|
|
80
81
|
headers: DEFAULT_HEADERS,
|
|
82
|
+
flowType: 'implicit',
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
/** Current session will be checked for refresh at this interval. */
|
|
@@ -108,6 +110,8 @@ export default class GoTrueClient {
|
|
|
108
110
|
*/
|
|
109
111
|
protected inMemorySession: Session | null
|
|
110
112
|
|
|
113
|
+
protected flowType: AuthFlowType
|
|
114
|
+
|
|
111
115
|
protected autoRefreshToken: boolean
|
|
112
116
|
protected persistSession: boolean
|
|
113
117
|
protected storage: SupportedStorage
|
|
@@ -154,6 +158,7 @@ export default class GoTrueClient {
|
|
|
154
158
|
this.headers = settings.headers
|
|
155
159
|
this.fetch = resolveFetch(settings.fetch)
|
|
156
160
|
this.detectSessionInUrl = settings.detectSessionInUrl
|
|
161
|
+
this.flowType = settings.flowType
|
|
157
162
|
|
|
158
163
|
this.mfa = {
|
|
159
164
|
verify: this._verify.bind(this),
|
|
@@ -208,8 +213,9 @@ export default class GoTrueClient {
|
|
|
208
213
|
}
|
|
209
214
|
|
|
210
215
|
try {
|
|
211
|
-
|
|
212
|
-
|
|
216
|
+
const isPKCEFlow = await this._isPKCEFlow()
|
|
217
|
+
if ((this.detectSessionInUrl && this._isImplicitGrantFlow()) || isPKCEFlow) {
|
|
218
|
+
const { data, error } = await this._getSessionFromUrl(isPKCEFlow)
|
|
213
219
|
|
|
214
220
|
if (error) {
|
|
215
221
|
// failed login attempt via url,
|
|
@@ -323,7 +329,7 @@ export default class GoTrueClient {
|
|
|
323
329
|
/**
|
|
324
330
|
* Log in an existing user with an email and password or phone and password.
|
|
325
331
|
*
|
|
326
|
-
* Be aware that you may get back an error message that will not
|
|
332
|
+
* Be aware that you may get back an error message that will not distinguish
|
|
327
333
|
* between the cases where the account does not exist or that the
|
|
328
334
|
* email/phone and password combination is wrong or that the account can only
|
|
329
335
|
* be accessed via social login.
|
|
@@ -386,7 +392,7 @@ export default class GoTrueClient {
|
|
|
386
392
|
scopes: credentials.options?.scopes,
|
|
387
393
|
queryParams: credentials.options?.queryParams,
|
|
388
394
|
skipBrowserRedirect: credentials.options?.skipBrowserRedirect,
|
|
389
|
-
flowType:
|
|
395
|
+
flowType: this.flowType ?? 'implicit',
|
|
390
396
|
})
|
|
391
397
|
}
|
|
392
398
|
|
|
@@ -394,7 +400,7 @@ export default class GoTrueClient {
|
|
|
394
400
|
* Log in an existing user via a third-party provider.
|
|
395
401
|
*/
|
|
396
402
|
async exchangeCodeForSession(authCode: string): Promise<AuthResponse> {
|
|
397
|
-
const codeVerifier = await getItemAsync(this.storage, `${this.storageKey}-
|
|
403
|
+
const codeVerifier = await getItemAsync(this.storage, `${this.storageKey}-code-verifier`)
|
|
398
404
|
const { data, error } = await _request(
|
|
399
405
|
this.fetch,
|
|
400
406
|
'POST',
|
|
@@ -408,7 +414,7 @@ export default class GoTrueClient {
|
|
|
408
414
|
xform: _sessionResponse,
|
|
409
415
|
}
|
|
410
416
|
)
|
|
411
|
-
await removeItemAsync(this.storage, `${this.storageKey}-
|
|
417
|
+
await removeItemAsync(this.storage, `${this.storageKey}-code-verifier`)
|
|
412
418
|
if (error || !data) return { data: { user: null, session: null }, error }
|
|
413
419
|
if (data.session) {
|
|
414
420
|
await this._saveSession(data.session)
|
|
@@ -845,7 +851,7 @@ export default class GoTrueClient {
|
|
|
845
851
|
/**
|
|
846
852
|
* Gets the session data from a URL string
|
|
847
853
|
*/
|
|
848
|
-
private async _getSessionFromUrl(): Promise<
|
|
854
|
+
private async _getSessionFromUrl(isPKCEFlow: boolean): Promise<
|
|
849
855
|
| {
|
|
850
856
|
data: { session: Session; redirectType: string | null }
|
|
851
857
|
error: null
|
|
@@ -854,8 +860,18 @@ export default class GoTrueClient {
|
|
|
854
860
|
> {
|
|
855
861
|
try {
|
|
856
862
|
if (!isBrowser()) throw new AuthImplicitGrantRedirectError('No browser detected.')
|
|
857
|
-
if (!this._isImplicitGrantFlow()) {
|
|
863
|
+
if (this.flowType == 'implicit' && !this._isImplicitGrantFlow()) {
|
|
858
864
|
throw new AuthImplicitGrantRedirectError('Not a valid implicit grant flow url.')
|
|
865
|
+
} else if (this.flowType == 'pkce' && !isPKCEFlow) {
|
|
866
|
+
throw new AuthPKCEGrantCodeExchangeError('Not a valid PKCE flow url.')
|
|
867
|
+
}
|
|
868
|
+
if (isPKCEFlow) {
|
|
869
|
+
const authCode = getParameterByName('code')
|
|
870
|
+
if (!authCode) throw new AuthPKCEGrantCodeExchangeError('No code detected.')
|
|
871
|
+
const { data, error } = await this.exchangeCodeForSession(authCode)
|
|
872
|
+
if (error) throw error
|
|
873
|
+
if (!data.session) throw new AuthPKCEGrantCodeExchangeError('No session detected.')
|
|
874
|
+
return { data: { session: data.session, redirectType: null }, error: null }
|
|
859
875
|
}
|
|
860
876
|
|
|
861
877
|
const error_description = getParameterByName('error_description')
|
|
@@ -920,6 +936,16 @@ export default class GoTrueClient {
|
|
|
920
936
|
Boolean(getParameterByName('error_description')))
|
|
921
937
|
)
|
|
922
938
|
}
|
|
939
|
+
/**
|
|
940
|
+
* Checks if the current URL and backing storage contain parameters given by a PKCE flow
|
|
941
|
+
*/
|
|
942
|
+
private async _isPKCEFlow(): Promise<boolean> {
|
|
943
|
+
const currentStorageContent = await getItemAsync(
|
|
944
|
+
this.storage,
|
|
945
|
+
`${this.storageKey}-code-verifier`
|
|
946
|
+
)
|
|
947
|
+
return isBrowser() && Boolean(getParameterByName('code')) && Boolean(currentStorageContent)
|
|
948
|
+
}
|
|
923
949
|
|
|
924
950
|
/**
|
|
925
951
|
* Inside a browser context, `signOut()` will remove the logged in user from the browser session
|
|
@@ -1073,7 +1099,7 @@ export default class GoTrueClient {
|
|
|
1073
1099
|
scopes?: string
|
|
1074
1100
|
queryParams?: { [key: string]: string }
|
|
1075
1101
|
skipBrowserRedirect?: boolean
|
|
1076
|
-
flowType:
|
|
1102
|
+
flowType: AuthFlowType
|
|
1077
1103
|
}
|
|
1078
1104
|
) {
|
|
1079
1105
|
const url: string = await this._getUrlForProvider(provider, {
|
|
@@ -1392,7 +1418,7 @@ export default class GoTrueClient {
|
|
|
1392
1418
|
redirectTo?: string
|
|
1393
1419
|
scopes?: string
|
|
1394
1420
|
queryParams?: { [key: string]: string }
|
|
1395
|
-
flowType:
|
|
1421
|
+
flowType: AuthFlowType
|
|
1396
1422
|
}
|
|
1397
1423
|
) {
|
|
1398
1424
|
const urlParams: string[] = [`provider=${encodeURIComponent(provider)}`]
|
|
@@ -1404,7 +1430,7 @@ export default class GoTrueClient {
|
|
|
1404
1430
|
}
|
|
1405
1431
|
if (options?.flowType === 'pkce') {
|
|
1406
1432
|
const codeVerifier = generatePKCEVerifier()
|
|
1407
|
-
await setItemAsync(this.storage, `${this.storageKey}-
|
|
1433
|
+
await setItemAsync(this.storage, `${this.storageKey}-code-verifier`, codeVerifier)
|
|
1408
1434
|
const codeChallenge = await generatePKCEChallenge(codeVerifier)
|
|
1409
1435
|
const flowParams = new URLSearchParams({
|
|
1410
1436
|
flow_type: `${encodeURIComponent(options.flowType)}`,
|
package/src/lib/errors.ts
CHANGED
|
@@ -92,6 +92,23 @@ export class AuthImplicitGrantRedirectError extends CustomAuthError {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
export class AuthPKCEGrantCodeExchangeError extends CustomAuthError {
|
|
96
|
+
details: { error: string; code: string } | null = null
|
|
97
|
+
constructor(message: string, details: { error: string; code: string } | null = null) {
|
|
98
|
+
super(message, 'AuthPKCEGrantCodeExchangeError', 500)
|
|
99
|
+
this.details = details
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
toJSON() {
|
|
103
|
+
return {
|
|
104
|
+
name: this.name,
|
|
105
|
+
message: this.message,
|
|
106
|
+
status: this.status,
|
|
107
|
+
details: this.details,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
95
112
|
export class AuthRetryableFetchError extends CustomAuthError {
|
|
96
113
|
constructor(message: string, status: number) {
|
|
97
114
|
super(message, 'AuthRetryableFetchError', status)
|
package/src/lib/types.ts
CHANGED
|
@@ -29,7 +29,6 @@ export type AuthChangeEvent =
|
|
|
29
29
|
| 'SIGNED_OUT'
|
|
30
30
|
| 'TOKEN_REFRESHED'
|
|
31
31
|
| 'USER_UPDATED'
|
|
32
|
-
| 'USER_DELETED'
|
|
33
32
|
| AuthChangeEventMFA
|
|
34
33
|
|
|
35
34
|
export type GoTrueClientOptions = {
|
|
@@ -49,6 +48,8 @@ export type GoTrueClientOptions = {
|
|
|
49
48
|
storage?: SupportedStorage
|
|
50
49
|
/* A custom fetch implementation. */
|
|
51
50
|
fetch?: Fetch
|
|
51
|
+
/* If set to 'pkce' PKCE flow. Defaults to the 'implicit' flow otherwise */
|
|
52
|
+
flowType?: AuthFlowType
|
|
52
53
|
}
|
|
53
54
|
|
|
54
55
|
export type AuthResponse =
|
|
@@ -435,7 +436,7 @@ export type SignInWithPasswordlessCredentials =
|
|
|
435
436
|
}
|
|
436
437
|
}
|
|
437
438
|
|
|
438
|
-
export type
|
|
439
|
+
export type AuthFlowType = 'implicit' | 'pkce'
|
|
439
440
|
export type SignInWithOAuthCredentials = {
|
|
440
441
|
/** One of the providers supported by GoTrue. */
|
|
441
442
|
provider: Provider
|
|
@@ -448,8 +449,6 @@ export type SignInWithOAuthCredentials = {
|
|
|
448
449
|
queryParams?: { [key: string]: string }
|
|
449
450
|
/** If set to true does not immediately redirect the current browser context to visit the OAuth authorization page for the provider. */
|
|
450
451
|
skipBrowserRedirect?: boolean
|
|
451
|
-
/** If set to 'pkce' PKCE flow. Defaults to the 'implicit' flow otherwise */
|
|
452
|
-
flowType?: OAuthFlowType
|
|
453
452
|
}
|
|
454
453
|
}
|
|
455
454
|
|
package/src/lib/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '2.20.
|
|
2
|
+
export const version = '2.20.2'
|