@supabase/gotrue-js 2.71.0-rc.5 → 2.71.0-rc.6
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 +32 -7
- package/dist/main/GoTrueClient.d.ts.map +1 -1
- package/dist/main/GoTrueClient.js +53 -10
- package/dist/main/GoTrueClient.js.map +1 -1
- package/dist/main/lib/constants.d.ts +1 -1
- package/dist/main/lib/constants.d.ts.map +1 -1
- package/dist/main/lib/constants.js +1 -1
- package/dist/main/lib/constants.js.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 +32 -7
- package/dist/module/GoTrueClient.d.ts.map +1 -1
- package/dist/module/GoTrueClient.js +53 -10
- package/dist/module/GoTrueClient.js.map +1 -1
- package/dist/module/lib/constants.d.ts +1 -1
- package/dist/module/lib/constants.d.ts.map +1 -1
- package/dist/module/lib/constants.js +1 -1
- package/dist/module/lib/constants.js.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 +73 -12
- package/src/lib/constants.ts +1 -1
- package/src/lib/version.ts +1 -1
package/src/GoTrueClient.ts
CHANGED
|
@@ -134,6 +134,16 @@ async function lockNoOp<R>(name: string, acquireTimeout: number, fn: () => Promi
|
|
|
134
134
|
return await fn()
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* Caches JWKS values for all clients created in the same environment. This is
|
|
139
|
+
* especially useful for shared-memory execution environments such as Vercel's
|
|
140
|
+
* Fluid Compute, AWS Lambda or Supabase's Edge Functions. Regardless of how
|
|
141
|
+
* many clients are created, if they share the same storage key they will use
|
|
142
|
+
* the same JWKS cache, significantly speeding up getClaims() with asymmetric
|
|
143
|
+
* JWTs.
|
|
144
|
+
*/
|
|
145
|
+
const GLOBAL_JWKS: { [storageKey: string]: { cachedAt: number; jwks: { keys: JWK[] } } } = {}
|
|
146
|
+
|
|
137
147
|
export default class GoTrueClient {
|
|
138
148
|
private static nextInstanceID = 0
|
|
139
149
|
|
|
@@ -154,11 +164,26 @@ export default class GoTrueClient {
|
|
|
154
164
|
protected storageKey: string
|
|
155
165
|
|
|
156
166
|
protected flowType: AuthFlowType
|
|
167
|
+
|
|
157
168
|
/**
|
|
158
169
|
* The JWKS used for verifying asymmetric JWTs
|
|
159
170
|
*/
|
|
160
|
-
protected jwks
|
|
161
|
-
|
|
171
|
+
protected get jwks() {
|
|
172
|
+
return GLOBAL_JWKS[this.storageKey]?.jwks ?? { keys: [] }
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
protected set jwks(value: { keys: JWK[] }) {
|
|
176
|
+
GLOBAL_JWKS[this.storageKey] = { ...GLOBAL_JWKS[this.storageKey], jwks: value }
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
protected get jwks_cached_at() {
|
|
180
|
+
return GLOBAL_JWKS[this.storageKey]?.cachedAt ?? Number.MIN_SAFE_INTEGER
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
protected set jwks_cached_at(value: number) {
|
|
184
|
+
GLOBAL_JWKS[this.storageKey] = { ...GLOBAL_JWKS[this.storageKey], cachedAt: value }
|
|
185
|
+
}
|
|
186
|
+
|
|
162
187
|
protected autoRefreshToken: boolean
|
|
163
188
|
protected persistSession: boolean
|
|
164
189
|
protected storage: SupportedStorage
|
|
@@ -242,8 +267,12 @@ export default class GoTrueClient {
|
|
|
242
267
|
} else {
|
|
243
268
|
this.lock = lockNoOp
|
|
244
269
|
}
|
|
245
|
-
|
|
246
|
-
this.
|
|
270
|
+
|
|
271
|
+
if (!this.jwks) {
|
|
272
|
+
this.jwks = { keys: [] }
|
|
273
|
+
this.jwks_cached_at = Number.MIN_SAFE_INTEGER
|
|
274
|
+
}
|
|
275
|
+
|
|
247
276
|
this.mfa = {
|
|
248
277
|
verify: this._verify.bind(this),
|
|
249
278
|
enroll: this._enroll.bind(this),
|
|
@@ -2946,11 +2975,13 @@ export default class GoTrueClient {
|
|
|
2946
2975
|
return jwk
|
|
2947
2976
|
}
|
|
2948
2977
|
|
|
2978
|
+
const now = Date.now()
|
|
2979
|
+
|
|
2949
2980
|
// try fetching from cache
|
|
2950
2981
|
jwk = this.jwks.keys.find((key) => key.kid === kid)
|
|
2951
2982
|
|
|
2952
2983
|
// jwk exists and jwks isn't stale
|
|
2953
|
-
if (jwk && this.jwks_cached_at + JWKS_TTL >
|
|
2984
|
+
if (jwk && this.jwks_cached_at + JWKS_TTL > now) {
|
|
2954
2985
|
return jwk
|
|
2955
2986
|
}
|
|
2956
2987
|
// jwk isn't cached in memory so we need to fetch it from the well-known endpoint
|
|
@@ -2963,8 +2994,10 @@ export default class GoTrueClient {
|
|
|
2963
2994
|
if (!data.keys || data.keys.length === 0) {
|
|
2964
2995
|
throw new AuthInvalidJwtError('JWKS is empty')
|
|
2965
2996
|
}
|
|
2997
|
+
|
|
2966
2998
|
this.jwks = data
|
|
2967
|
-
this.jwks_cached_at =
|
|
2999
|
+
this.jwks_cached_at = now
|
|
3000
|
+
|
|
2968
3001
|
// Find the signing key
|
|
2969
3002
|
jwk = data.keys.find((key: any) => key.kid === kid)
|
|
2970
3003
|
if (!jwk) {
|
|
@@ -2974,12 +3007,35 @@ export default class GoTrueClient {
|
|
|
2974
3007
|
}
|
|
2975
3008
|
|
|
2976
3009
|
/**
|
|
2977
|
-
*
|
|
2978
|
-
*
|
|
3010
|
+
* Extracts the JWT claims present in the access token by first verifying the
|
|
3011
|
+
* JWT against the server's JSON Web Key Set endpoint
|
|
3012
|
+
* `/.well-known/jwks.json` which is often cached, resulting in significantly
|
|
3013
|
+
* faster responses. Prefer this method over {@link #getUser} which always
|
|
3014
|
+
* sends a request to the Auth server for each JWT.
|
|
3015
|
+
*
|
|
3016
|
+
* If the project is not using an asymmetric JWT signing key (like ECC or
|
|
3017
|
+
* RSA) it always sends a request to the Auth server (similar to {@link
|
|
3018
|
+
* #getUser}) to verify the JWT.
|
|
3019
|
+
*
|
|
3020
|
+
* @param jwt An optional specific JWT you wish to verify, not the one you
|
|
3021
|
+
* can obtain from {@link #getSession}.
|
|
3022
|
+
* @param options Various additional options that allow you to customize the
|
|
3023
|
+
* behavior of this method.
|
|
2979
3024
|
*/
|
|
2980
3025
|
async getClaims(
|
|
2981
3026
|
jwt?: string,
|
|
2982
|
-
|
|
3027
|
+
options: {
|
|
3028
|
+
/**
|
|
3029
|
+
* @deprecated Please use options.jwks instead.
|
|
3030
|
+
*/
|
|
3031
|
+
keys?: JWK[]
|
|
3032
|
+
|
|
3033
|
+
/** If set to `true` the `exp` claim will not be validated against the current time. */
|
|
3034
|
+
allowExpired?: boolean
|
|
3035
|
+
|
|
3036
|
+
/** If set, this JSON Web Key Set is going to have precedence over the cached value available on the server. */
|
|
3037
|
+
jwks?: { keys: JWK[] }
|
|
3038
|
+
} = {}
|
|
2983
3039
|
): Promise<
|
|
2984
3040
|
| {
|
|
2985
3041
|
data: { claims: JwtPayload; header: JwtHeader; signature: Uint8Array }
|
|
@@ -3005,8 +3061,10 @@ export default class GoTrueClient {
|
|
|
3005
3061
|
raw: { header: rawHeader, payload: rawPayload },
|
|
3006
3062
|
} = decodeJWT(token)
|
|
3007
3063
|
|
|
3008
|
-
|
|
3009
|
-
|
|
3064
|
+
if (!options?.allowExpired) {
|
|
3065
|
+
// Reject expired JWTs should only happen if jwt argument was passed
|
|
3066
|
+
validateExp(payload.exp)
|
|
3067
|
+
}
|
|
3010
3068
|
|
|
3011
3069
|
// If symmetric algorithm or WebCrypto API is unavailable, fallback to getUser()
|
|
3012
3070
|
if (
|
|
@@ -3030,7 +3088,10 @@ export default class GoTrueClient {
|
|
|
3030
3088
|
}
|
|
3031
3089
|
|
|
3032
3090
|
const algorithm = getAlgorithm(header.alg)
|
|
3033
|
-
const signingKey = await this.fetchJwk(
|
|
3091
|
+
const signingKey = await this.fetchJwk(
|
|
3092
|
+
header.kid,
|
|
3093
|
+
options?.keys ? { keys: options.keys } : options?.jwks
|
|
3094
|
+
)
|
|
3034
3095
|
|
|
3035
3096
|
// Convert JWK to CryptoKey
|
|
3036
3097
|
const publicKey = await crypto.subtle.importKey('jwk', signingKey, algorithm, true, [
|
package/src/lib/constants.ts
CHANGED
package/src/lib/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '2.71.0-rc.
|
|
1
|
+
export const version = '2.71.0-rc.6'
|