public async getJwk()

in src/jwk.ts [239:281]


  public async getJwk(
    jwksUri: string,
    decomposedJwt: DecomposedJwt
  ): Promise<Jwk> {
    if (typeof decomposedJwt.header.kid !== "string") {
      throw new JwtWithoutValidKidError(
        "JWT header does not have valid kid claim"
      );
    }

    // Try to get JWK from cache:
    let jwk = this.jwksCache
      .get(jwksUri)
      ?.keys.find((key) => key.kid === decomposedJwt.header.kid);
    if (jwk) {
      return jwk;
    }

    // Await any wait period that is currently in effect
    // This prevents us from flooding the JWKS URI with requests
    await this.penaltyBox.wait(jwksUri, decomposedJwt.header.kid);

    // Fetch the JWKS and (try to) locate the JWK
    const jwks = await this.getJwks(jwksUri);
    jwk = jwks.keys.find((key) => key.kid === decomposedJwt.header.kid);

    // If the JWK could not be located, someone might be messing around with us
    // Register the failed attempt with the penaltyBox, so it can enforce a wait period
    // before trying again next time (instead of flooding the JWKS URI with requests)
    if (!jwk) {
      this.penaltyBox.registerFailedAttempt(jwksUri, decomposedJwt.header.kid);
      throw new KidNotFoundInJwksError(
        `JWK for kid "${decomposedJwt.header.kid}" not found in the JWKS`
      );
    } else {
      this.penaltyBox.registerSuccessfulAttempt(
        jwksUri,
        decomposedJwt.header.kid
      );
    }

    return jwk;
  }