@supabase/gotrue-js 2.70.0 → 2.71.0-rc.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 +4 -0
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +103 -6
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/helpers.d.ts +2 -1
- package/dist/main/lib/helpers.d.ts.map +1 -1
- package/dist/main/lib/helpers.js +30 -1
- package/dist/main/lib/helpers.js.map +1 -1
- package/dist/main/lib/local-storage.d.ts +0 -4
- package/dist/main/lib/local-storage.d.ts.map +1 -1
- package/dist/main/lib/local-storage.js +1 -25
- package/dist/main/lib/local-storage.js.map +1 -1
- package/dist/main/lib/types.d.ts +11 -0
- 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.d.ts.map +1 -1
- package/dist/main/lib/version.js +1 -1
- package/dist/main/lib/version.js.map +1 -1
- package/dist/module/GoTrueClient.d.ts +4 -0
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +105 -8
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/helpers.d.ts +2 -1
- package/dist/module/lib/helpers.d.ts.map +1 -1
- package/dist/module/lib/helpers.js +28 -0
- package/dist/module/lib/helpers.js.map +1 -1
- package/dist/module/lib/local-storage.d.ts +0 -4
- package/dist/module/lib/local-storage.d.ts.map +1 -1
- package/dist/module/lib/local-storage.js +0 -24
- package/dist/module/lib/local-storage.js.map +1 -1
- package/dist/module/lib/types.d.ts +11 -0
- 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.d.ts.map +1 -1
- package/dist/module/lib/version.js +1 -1
- package/dist/module/lib/version.js.map +1 -1
- package/package.json +1 -1
- package/src/GoTrueClient.ts +134 -7
- package/src/lib/helpers.ts +39 -1
- package/src/lib/local-storage.ts +0 -28
- package/src/lib/types.ts +12 -0
- package/src/lib/version.ts +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const version = "2.
|
|
1
|
+
export declare const version = "2.71.0-rc.2";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,OAAO,gBAAgB,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.71.0-rc.2';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/lib/version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,OAAO,GAAG,aAAa,CAAA"}
|
package/package.json
CHANGED
package/src/GoTrueClient.ts
CHANGED
|
@@ -41,14 +41,15 @@ import {
|
|
|
41
41
|
uuid,
|
|
42
42
|
retryable,
|
|
43
43
|
sleep,
|
|
44
|
-
supportsLocalStorage,
|
|
45
44
|
parseParametersFromURL,
|
|
46
45
|
getCodeChallengeAndMethod,
|
|
47
46
|
getAlgorithm,
|
|
48
47
|
validateExp,
|
|
49
48
|
decodeJWT,
|
|
49
|
+
userNotAvailableProxy,
|
|
50
|
+
supportsLocalStorage,
|
|
50
51
|
} from './lib/helpers'
|
|
51
|
-
import {
|
|
52
|
+
import { memoryLocalStorageAdapter } from './lib/local-storage'
|
|
52
53
|
import { polyfillGlobalThis } from './lib/polyfills'
|
|
53
54
|
import { version } from './lib/version'
|
|
54
55
|
import { LockAcquireTimeoutError, navigatorLock } from './lib/locks'
|
|
@@ -114,7 +115,10 @@ import { stringToUint8Array, bytesToBase64URL } from './lib/base64url'
|
|
|
114
115
|
|
|
115
116
|
polyfillGlobalThis() // Make "globalThis" available
|
|
116
117
|
|
|
117
|
-
const DEFAULT_OPTIONS: Omit<
|
|
118
|
+
const DEFAULT_OPTIONS: Omit<
|
|
119
|
+
Required<GoTrueClientOptions>,
|
|
120
|
+
'fetch' | 'storage' | 'userStorage' | 'lock'
|
|
121
|
+
> = {
|
|
118
122
|
url: GOTRUE_URL,
|
|
119
123
|
storageKey: STORAGE_KEY,
|
|
120
124
|
autoRefreshToken: true,
|
|
@@ -158,6 +162,10 @@ export default class GoTrueClient {
|
|
|
158
162
|
protected autoRefreshToken: boolean
|
|
159
163
|
protected persistSession: boolean
|
|
160
164
|
protected storage: SupportedStorage
|
|
165
|
+
/**
|
|
166
|
+
* @experimental
|
|
167
|
+
*/
|
|
168
|
+
protected userStorage: SupportedStorage | null = null
|
|
161
169
|
protected memoryStorage: { [key: string]: string } | null = null
|
|
162
170
|
protected stateChangeEmitters: Map<string, Subscription> = new Map()
|
|
163
171
|
protected autoRefreshTicker: ReturnType<typeof setInterval> | null = null
|
|
@@ -251,12 +259,16 @@ export default class GoTrueClient {
|
|
|
251
259
|
this.storage = settings.storage
|
|
252
260
|
} else {
|
|
253
261
|
if (supportsLocalStorage()) {
|
|
254
|
-
this.storage =
|
|
262
|
+
this.storage = globalThis.localStorage
|
|
255
263
|
} else {
|
|
256
264
|
this.memoryStorage = {}
|
|
257
265
|
this.storage = memoryLocalStorageAdapter(this.memoryStorage)
|
|
258
266
|
}
|
|
259
267
|
}
|
|
268
|
+
|
|
269
|
+
if (settings.userStorage) {
|
|
270
|
+
this.userStorage = settings.userStorage
|
|
271
|
+
}
|
|
260
272
|
} else {
|
|
261
273
|
this.memoryStorage = {}
|
|
262
274
|
this.storage = memoryLocalStorageAdapter(this.memoryStorage)
|
|
@@ -1347,7 +1359,20 @@ export default class GoTrueClient {
|
|
|
1347
1359
|
)
|
|
1348
1360
|
|
|
1349
1361
|
if (!hasExpired) {
|
|
1350
|
-
if (this.
|
|
1362
|
+
if (this.userStorage) {
|
|
1363
|
+
const maybeUser: { user?: User | null } | null = (await getItemAsync(
|
|
1364
|
+
this.userStorage,
|
|
1365
|
+
this.storageKey + '-user'
|
|
1366
|
+
)) as any
|
|
1367
|
+
|
|
1368
|
+
if (maybeUser?.user) {
|
|
1369
|
+
currentSession.user = maybeUser.user
|
|
1370
|
+
} else {
|
|
1371
|
+
currentSession.user = userNotAvailableProxy()
|
|
1372
|
+
}
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
if (this.storage.isServer && currentSession.user) {
|
|
1351
1376
|
let suppressWarning = this.suppressGetSessionWarning
|
|
1352
1377
|
const proxySession: Session = new Proxy(currentSession, {
|
|
1353
1378
|
get: (target: any, prop: string, receiver: any) => {
|
|
@@ -2128,7 +2153,47 @@ export default class GoTrueClient {
|
|
|
2128
2153
|
this._debug(debugName, 'begin')
|
|
2129
2154
|
|
|
2130
2155
|
try {
|
|
2131
|
-
const currentSession = await getItemAsync(this.storage, this.storageKey)
|
|
2156
|
+
const currentSession: Session = (await getItemAsync(this.storage, this.storageKey)) as any
|
|
2157
|
+
|
|
2158
|
+
if (this.userStorage) {
|
|
2159
|
+
let maybeUser: { user: User | null } | null = (await getItemAsync(
|
|
2160
|
+
this.userStorage,
|
|
2161
|
+
this.storageKey + '-user'
|
|
2162
|
+
)) as any
|
|
2163
|
+
|
|
2164
|
+
if (!this.storage.isServer && Object.is(this.storage, this.userStorage) && !maybeUser) {
|
|
2165
|
+
// storage and userStorage are the same storage medium, for example
|
|
2166
|
+
// window.localStorage if userStorage does not have the user from
|
|
2167
|
+
// storage stored, store it first thereby migrating the user object
|
|
2168
|
+
// from storage -> userStorage
|
|
2169
|
+
|
|
2170
|
+
maybeUser = { user: currentSession.user }
|
|
2171
|
+
await setItemAsync(this.userStorage, this.storageKey + '-user', maybeUser)
|
|
2172
|
+
}
|
|
2173
|
+
|
|
2174
|
+
currentSession.user = maybeUser?.user ?? userNotAvailableProxy()
|
|
2175
|
+
} else if (currentSession && !currentSession.user) {
|
|
2176
|
+
// user storage is not set, let's check if it was previously enabled so
|
|
2177
|
+
// we bring back the storage as it should be
|
|
2178
|
+
|
|
2179
|
+
if (!currentSession.user) {
|
|
2180
|
+
// test if userStorage was previously enabled and the storage medium was the same, to move the user back under the same key
|
|
2181
|
+
const separateUser: { user: User | null } | null = (await getItemAsync(
|
|
2182
|
+
this.storage,
|
|
2183
|
+
this.storageKey + '-user'
|
|
2184
|
+
)) as any
|
|
2185
|
+
|
|
2186
|
+
if (separateUser && separateUser?.user) {
|
|
2187
|
+
currentSession.user = separateUser.user
|
|
2188
|
+
|
|
2189
|
+
await removeItemAsync(this.storage, this.storageKey + '-user')
|
|
2190
|
+
await setItemAsync(this.storage, this.storageKey, currentSession)
|
|
2191
|
+
} else {
|
|
2192
|
+
currentSession.user = userNotAvailableProxy()
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
}
|
|
2196
|
+
|
|
2132
2197
|
this._debug(debugName, 'session from storage', currentSession)
|
|
2133
2198
|
|
|
2134
2199
|
if (!this._isValidSession(currentSession)) {
|
|
@@ -2165,6 +2230,29 @@ export default class GoTrueClient {
|
|
|
2165
2230
|
}
|
|
2166
2231
|
}
|
|
2167
2232
|
}
|
|
2233
|
+
} else if (
|
|
2234
|
+
currentSession.user &&
|
|
2235
|
+
(currentSession.user as any).__isUserNotAvailableProxy === true
|
|
2236
|
+
) {
|
|
2237
|
+
// If we have a proxy user, try to get the real user data
|
|
2238
|
+
try {
|
|
2239
|
+
const { data, error: userError } = await this._getUser(currentSession.access_token)
|
|
2240
|
+
|
|
2241
|
+
if (!userError && data?.user) {
|
|
2242
|
+
currentSession.user = data.user
|
|
2243
|
+
await this._saveSession(currentSession)
|
|
2244
|
+
await this._notifyAllSubscribers('SIGNED_IN', currentSession)
|
|
2245
|
+
} else {
|
|
2246
|
+
this._debug(debugName, 'could not get user data, skipping SIGNED_IN notification')
|
|
2247
|
+
}
|
|
2248
|
+
} catch (getUserError) {
|
|
2249
|
+
console.error('Error getting user data:', getUserError)
|
|
2250
|
+
this._debug(
|
|
2251
|
+
debugName,
|
|
2252
|
+
'error getting user data, skipping SIGNED_IN notification',
|
|
2253
|
+
getUserError
|
|
2254
|
+
)
|
|
2255
|
+
}
|
|
2168
2256
|
} else {
|
|
2169
2257
|
// no need to persist currentSession again, as we just loaded it from
|
|
2170
2258
|
// local storage; persisting it again may overwrite a value saved by
|
|
@@ -2278,13 +2366,52 @@ export default class GoTrueClient {
|
|
|
2278
2366
|
// _saveSession is always called whenever a new session has been acquired
|
|
2279
2367
|
// so we can safely suppress the warning returned by future getSession calls
|
|
2280
2368
|
this.suppressGetSessionWarning = true
|
|
2281
|
-
|
|
2369
|
+
|
|
2370
|
+
// Create a shallow copy to work with, to avoid mutating the original session object if it's used elsewhere
|
|
2371
|
+
const sessionToProcess = { ...session }
|
|
2372
|
+
|
|
2373
|
+
const userIsProxy =
|
|
2374
|
+
sessionToProcess.user && (sessionToProcess.user as any).__isUserNotAvailableProxy === true
|
|
2375
|
+
if (this.userStorage) {
|
|
2376
|
+
if (!userIsProxy && sessionToProcess.user) {
|
|
2377
|
+
// If it's a real user object, save it to userStorage.
|
|
2378
|
+
await setItemAsync(this.userStorage, this.storageKey + '-user', {
|
|
2379
|
+
user: sessionToProcess.user,
|
|
2380
|
+
})
|
|
2381
|
+
} else if (userIsProxy) {
|
|
2382
|
+
// If it's the proxy, it means user was not found in userStorage.
|
|
2383
|
+
// We should ensure no stale user data for this key exists in userStorage if we were to save null,
|
|
2384
|
+
// or simply not save the proxy. For now, we don't save the proxy here.
|
|
2385
|
+
// If there's a need to clear userStorage if user becomes proxy, that logic would go here.
|
|
2386
|
+
}
|
|
2387
|
+
|
|
2388
|
+
// Prepare the main session data for primary storage: remove the user property before cloning
|
|
2389
|
+
// This is important because the original session.user might be the proxy
|
|
2390
|
+
const mainSessionData: Omit<Session, 'user'> & { user?: User } = { ...sessionToProcess }
|
|
2391
|
+
delete mainSessionData.user // Remove user (real or proxy) before cloning for main storage
|
|
2392
|
+
|
|
2393
|
+
const clonedMainSessionData = structuredClone(mainSessionData)
|
|
2394
|
+
await setItemAsync(this.storage, this.storageKey, clonedMainSessionData)
|
|
2395
|
+
} else {
|
|
2396
|
+
// No userStorage is configured.
|
|
2397
|
+
// In this case, session.user should ideally not be a proxy.
|
|
2398
|
+
// If it were, structuredClone would fail. This implies an issue elsewhere if user is a proxy here
|
|
2399
|
+
const clonedSession = structuredClone(sessionToProcess) // sessionToProcess still has its original user property
|
|
2400
|
+
await setItemAsync(this.storage, this.storageKey, clonedSession)
|
|
2401
|
+
}
|
|
2282
2402
|
}
|
|
2283
2403
|
|
|
2284
2404
|
private async _removeSession() {
|
|
2285
2405
|
this._debug('#_removeSession()')
|
|
2286
2406
|
|
|
2287
2407
|
await removeItemAsync(this.storage, this.storageKey)
|
|
2408
|
+
await removeItemAsync(this.storage, this.storageKey + '-code-verifier')
|
|
2409
|
+
await removeItemAsync(this.storage, this.storageKey + '-user')
|
|
2410
|
+
|
|
2411
|
+
if (this.userStorage) {
|
|
2412
|
+
await removeItemAsync(this.userStorage, this.storageKey + '-user')
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2288
2415
|
await this._notifyAllSubscribers('SIGNED_OUT', null)
|
|
2289
2416
|
}
|
|
2290
2417
|
|
package/src/lib/helpers.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { API_VERSION_HEADER_NAME, BASE64URL_REGEX } from './constants'
|
|
2
2
|
import { AuthInvalidJwtError } from './errors'
|
|
3
3
|
import { base64UrlToUint8Array, stringFromBase64URL } from './base64url'
|
|
4
|
-
import { JwtHeader, JwtPayload, SupportedStorage } from './types'
|
|
4
|
+
import { JwtHeader, JwtPayload, SupportedStorage, User } from './types'
|
|
5
5
|
|
|
6
6
|
export function expiresAt(expiresIn: number) {
|
|
7
7
|
const timeNow = Math.round(Date.now() / 1000)
|
|
@@ -365,3 +365,41 @@ export function validateUUID(str: string) {
|
|
|
365
365
|
throw new Error('@supabase/auth-js: Expected parameter to be UUID but is not')
|
|
366
366
|
}
|
|
367
367
|
}
|
|
368
|
+
|
|
369
|
+
export function userNotAvailableProxy(): User {
|
|
370
|
+
const proxyTarget = {} as User
|
|
371
|
+
|
|
372
|
+
return new Proxy(proxyTarget, {
|
|
373
|
+
get: (target: any, prop: string) => {
|
|
374
|
+
if (prop === '__isUserNotAvailableProxy') {
|
|
375
|
+
return true
|
|
376
|
+
}
|
|
377
|
+
// Preventative check for common problematic symbols during cloning/inspection
|
|
378
|
+
// These symbols might be accessed by structuredClone or other internal mechanisms.
|
|
379
|
+
if (typeof prop === 'symbol') {
|
|
380
|
+
const sProp = (prop as symbol).toString()
|
|
381
|
+
if (
|
|
382
|
+
sProp === 'Symbol(Symbol.toPrimitive)' ||
|
|
383
|
+
sProp === 'Symbol(Symbol.toStringTag)' ||
|
|
384
|
+
sProp === 'Symbol(util.inspect.custom)'
|
|
385
|
+
) {
|
|
386
|
+
// Node.js util.inspect
|
|
387
|
+
return undefined
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
throw new Error(
|
|
391
|
+
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Accessing the "${prop}" property of the session object is not supported. Please use getUser() instead.`
|
|
392
|
+
)
|
|
393
|
+
},
|
|
394
|
+
set: (_target: any, prop: string) => {
|
|
395
|
+
throw new Error(
|
|
396
|
+
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Setting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`
|
|
397
|
+
)
|
|
398
|
+
},
|
|
399
|
+
deleteProperty: (_target: any, prop: string) => {
|
|
400
|
+
throw new Error(
|
|
401
|
+
`@supabase/auth-js: client was created with userStorage option and there was no user stored in the user storage. Deleting the "${prop}" property of the session object is not supported. Please use getUser() to fetch a user object you can manipulate.`
|
|
402
|
+
)
|
|
403
|
+
},
|
|
404
|
+
})
|
|
405
|
+
}
|
package/src/lib/local-storage.ts
CHANGED
|
@@ -1,33 +1,5 @@
|
|
|
1
|
-
import { supportsLocalStorage } from './helpers'
|
|
2
1
|
import { SupportedStorage } from './types'
|
|
3
2
|
|
|
4
|
-
/**
|
|
5
|
-
* Provides safe access to the globalThis.localStorage property.
|
|
6
|
-
*/
|
|
7
|
-
export const localStorageAdapter: SupportedStorage = {
|
|
8
|
-
getItem: (key) => {
|
|
9
|
-
if (!supportsLocalStorage()) {
|
|
10
|
-
return null
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
return globalThis.localStorage.getItem(key)
|
|
14
|
-
},
|
|
15
|
-
setItem: (key, value) => {
|
|
16
|
-
if (!supportsLocalStorage()) {
|
|
17
|
-
return
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
globalThis.localStorage.setItem(key, value)
|
|
21
|
-
},
|
|
22
|
-
removeItem: (key) => {
|
|
23
|
-
if (!supportsLocalStorage()) {
|
|
24
|
-
return
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
globalThis.localStorage.removeItem(key)
|
|
28
|
-
},
|
|
29
|
-
}
|
|
30
|
-
|
|
31
3
|
/**
|
|
32
4
|
* Returns a localStorage-like object that stores the key-value pairs in
|
|
33
5
|
* memory.
|
package/src/lib/types.ts
CHANGED
|
@@ -70,6 +70,14 @@ export type GoTrueClientOptions = {
|
|
|
70
70
|
persistSession?: boolean
|
|
71
71
|
/* Provide your own local storage implementation to use instead of the browser's local storage. */
|
|
72
72
|
storage?: SupportedStorage
|
|
73
|
+
/**
|
|
74
|
+
* Stores the user object in a separate storage location from the rest of the session data. When non-null, `storage` will only store a JSON object containing the access and refresh token and some adjacent metadata, while `userStorage` will only contain the user object under the key `storageKey + '-user'`.
|
|
75
|
+
*
|
|
76
|
+
* When this option is set and cookie storage is used, `getSession()` and other functions that load a session from the cookie store might not return back a user. It's very important to always use `getUser()` to fetch a user object in those scenarios.
|
|
77
|
+
*
|
|
78
|
+
* @experimental
|
|
79
|
+
*/
|
|
80
|
+
userStorage?: SupportedStorage
|
|
73
81
|
/* A custom fetch implementation. */
|
|
74
82
|
fetch?: Fetch
|
|
75
83
|
/* If set to 'pkce' PKCE flow. Defaults to the 'implicit' flow otherwise */
|
|
@@ -253,6 +261,10 @@ export interface Session {
|
|
|
253
261
|
*/
|
|
254
262
|
expires_at?: number
|
|
255
263
|
token_type: string
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* When using a separate user storage, accessing properties of this object will throw an error.
|
|
267
|
+
*/
|
|
256
268
|
user: User
|
|
257
269
|
}
|
|
258
270
|
|
package/src/lib/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.
|
|
1
|
+
export const version = '2.71.0-rc.2'
|