@supabase/gotrue-js 2.53.0 → 2.54.1

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.
@@ -2155,70 +2155,74 @@ export default class GoTrueClient {
2155
2155
  * {@see GoTrueMFAApi#verify}
2156
2156
  */
2157
2157
  private async _verify(params: MFAVerifyParams): Promise<AuthMFAVerifyResponse> {
2158
- try {
2159
- return await this._useSession(async (result) => {
2160
- const { data: sessionData, error: sessionError } = result
2161
- if (sessionError) {
2162
- return { data: null, error: sessionError }
2163
- }
2158
+ return this._acquireLock(-1, async () => {
2159
+ try {
2160
+ return await this._useSession(async (result) => {
2161
+ const { data: sessionData, error: sessionError } = result
2162
+ if (sessionError) {
2163
+ return { data: null, error: sessionError }
2164
+ }
2164
2165
 
2165
- const { data, error } = await _request(
2166
- this.fetch,
2167
- 'POST',
2168
- `${this.url}/factors/${params.factorId}/verify`,
2169
- {
2170
- body: { code: params.code, challenge_id: params.challengeId },
2171
- headers: this.headers,
2172
- jwt: sessionData?.session?.access_token,
2166
+ const { data, error } = await _request(
2167
+ this.fetch,
2168
+ 'POST',
2169
+ `${this.url}/factors/${params.factorId}/verify`,
2170
+ {
2171
+ body: { code: params.code, challenge_id: params.challengeId },
2172
+ headers: this.headers,
2173
+ jwt: sessionData?.session?.access_token,
2174
+ }
2175
+ )
2176
+ if (error) {
2177
+ return { data: null, error }
2173
2178
  }
2174
- )
2175
- if (error) {
2176
- return { data: null, error }
2177
- }
2178
2179
 
2179
- await this._saveSession({
2180
- expires_at: Math.round(Date.now() / 1000) + data.expires_in,
2181
- ...data,
2182
- })
2183
- await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
2180
+ await this._saveSession({
2181
+ expires_at: Math.round(Date.now() / 1000) + data.expires_in,
2182
+ ...data,
2183
+ })
2184
+ await this._notifyAllSubscribers('MFA_CHALLENGE_VERIFIED', data)
2184
2185
 
2185
- return { data, error }
2186
- })
2187
- } catch (error) {
2188
- if (isAuthError(error)) {
2189
- return { data: null, error }
2186
+ return { data, error }
2187
+ })
2188
+ } catch (error) {
2189
+ if (isAuthError(error)) {
2190
+ return { data: null, error }
2191
+ }
2192
+ throw error
2190
2193
  }
2191
- throw error
2192
- }
2194
+ })
2193
2195
  }
2194
2196
 
2195
2197
  /**
2196
2198
  * {@see GoTrueMFAApi#challenge}
2197
2199
  */
2198
2200
  private async _challenge(params: MFAChallengeParams): Promise<AuthMFAChallengeResponse> {
2199
- try {
2200
- return await this._useSession(async (result) => {
2201
- const { data: sessionData, error: sessionError } = result
2202
- if (sessionError) {
2203
- return { data: null, error: sessionError }
2204
- }
2205
-
2206
- return await _request(
2207
- this.fetch,
2208
- 'POST',
2209
- `${this.url}/factors/${params.factorId}/challenge`,
2210
- {
2211
- headers: this.headers,
2212
- jwt: sessionData?.session?.access_token,
2201
+ return this._acquireLock(-1, async () => {
2202
+ try {
2203
+ return await this._useSession(async (result) => {
2204
+ const { data: sessionData, error: sessionError } = result
2205
+ if (sessionError) {
2206
+ return { data: null, error: sessionError }
2213
2207
  }
2214
- )
2215
- })
2216
- } catch (error) {
2217
- if (isAuthError(error)) {
2218
- return { data: null, error }
2208
+
2209
+ return await _request(
2210
+ this.fetch,
2211
+ 'POST',
2212
+ `${this.url}/factors/${params.factorId}/challenge`,
2213
+ {
2214
+ headers: this.headers,
2215
+ jwt: sessionData?.session?.access_token,
2216
+ }
2217
+ )
2218
+ })
2219
+ } catch (error) {
2220
+ if (isAuthError(error)) {
2221
+ return { data: null, error }
2222
+ }
2223
+ throw error
2219
2224
  }
2220
- throw error
2221
- }
2225
+ })
2222
2226
  }
2223
2227
 
2224
2228
  /**
@@ -2227,12 +2231,16 @@ export default class GoTrueClient {
2227
2231
  private async _challengeAndVerify(
2228
2232
  params: MFAChallengeAndVerifyParams
2229
2233
  ): Promise<AuthMFAVerifyResponse> {
2234
+ // both _challenge and _verify independently acquire the lock, so no need
2235
+ // to acquire it here
2236
+
2230
2237
  const { data: challengeData, error: challengeError } = await this._challenge({
2231
2238
  factorId: params.factorId,
2232
2239
  })
2233
2240
  if (challengeError) {
2234
2241
  return { data: null, error: challengeError }
2235
2242
  }
2243
+
2236
2244
  return await this._verify({
2237
2245
  factorId: params.factorId,
2238
2246
  challengeId: challengeData.id,
@@ -2244,10 +2252,11 @@ export default class GoTrueClient {
2244
2252
  * {@see GoTrueMFAApi#listFactors}
2245
2253
  */
2246
2254
  private async _listFactors(): Promise<AuthMFAListFactorsResponse> {
2255
+ // use #getUser instead of #_getUser as the former acquires a lock
2247
2256
  const {
2248
2257
  data: { user },
2249
2258
  error: userError,
2250
- } = await this._getUser()
2259
+ } = await this.getUser()
2251
2260
  if (userError) {
2252
2261
  return { data: null, error: userError }
2253
2262
  }
@@ -2270,41 +2279,43 @@ export default class GoTrueClient {
2270
2279
  * {@see GoTrueMFAApi#getAuthenticatorAssuranceLevel}
2271
2280
  */
2272
2281
  private async _getAuthenticatorAssuranceLevel(): Promise<AuthMFAGetAuthenticatorAssuranceLevelResponse> {
2273
- return await this._useSession(async (result) => {
2274
- const {
2275
- data: { session },
2276
- error: sessionError,
2277
- } = result
2278
- if (sessionError) {
2279
- return { data: null, error: sessionError }
2280
- }
2281
- if (!session) {
2282
- return {
2283
- data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
2284
- error: null,
2282
+ return this._acquireLock(-1, async () => {
2283
+ return await this._useSession(async (result) => {
2284
+ const {
2285
+ data: { session },
2286
+ error: sessionError,
2287
+ } = result
2288
+ if (sessionError) {
2289
+ return { data: null, error: sessionError }
2290
+ }
2291
+ if (!session) {
2292
+ return {
2293
+ data: { currentLevel: null, nextLevel: null, currentAuthenticationMethods: [] },
2294
+ error: null,
2295
+ }
2285
2296
  }
2286
- }
2287
2297
 
2288
- const payload = this._decodeJWT(session.access_token)
2298
+ const payload = this._decodeJWT(session.access_token)
2289
2299
 
2290
- let currentLevel: AuthenticatorAssuranceLevels | null = null
2300
+ let currentLevel: AuthenticatorAssuranceLevels | null = null
2291
2301
 
2292
- if (payload.aal) {
2293
- currentLevel = payload.aal
2294
- }
2302
+ if (payload.aal) {
2303
+ currentLevel = payload.aal
2304
+ }
2295
2305
 
2296
- let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
2306
+ let nextLevel: AuthenticatorAssuranceLevels | null = currentLevel
2297
2307
 
2298
- const verifiedFactors =
2299
- session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
2308
+ const verifiedFactors =
2309
+ session.user.factors?.filter((factor: Factor) => factor.status === 'verified') ?? []
2300
2310
 
2301
- if (verifiedFactors.length > 0) {
2302
- nextLevel = 'aal2'
2303
- }
2311
+ if (verifiedFactors.length > 0) {
2312
+ nextLevel = 'aal2'
2313
+ }
2304
2314
 
2305
- const currentAuthenticationMethods = payload.amr || []
2315
+ const currentAuthenticationMethods = payload.amr || []
2306
2316
 
2307
- return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2317
+ return { data: { currentLevel, nextLevel, currentAuthenticationMethods }, error: null }
2318
+ })
2308
2319
  })
2309
2320
  }
2310
2321
  }
package/src/lib/types.ts CHANGED
@@ -378,6 +378,15 @@ export interface AdminUserAttributes extends Omit<UserAttributes, 'data'> {
378
378
  * Setting the ban duration to 'none' lifts the ban on the user.
379
379
  */
380
380
  ban_duration?: string | 'none'
381
+
382
+ /**
383
+ * The `role` claim set in the user's access token JWT.
384
+ *
385
+ * When a user signs up, this role is set to `authenticated` by default. You should only modify the `role` if you need to provision several levels of admin access that have different permissions on individual columns in your database.
386
+ *
387
+ * Setting this role to `service_role` is not recommended as it grants the user admin privileges.
388
+ */
389
+ role?: string
381
390
  }
382
391
 
383
392
  export interface Subscription {
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '2.53.0'
2
+ export const version = '2.54.1'