From 96a8c99189f2399e9816ae1bca04b6d9cff93c26 Mon Sep 17 00:00:00 2001 From: Filip Skokan Date: Thu, 2 Mar 2023 10:36:21 +0100 Subject: [PATCH] fix(workerd): avoid "The script will never generate a response" edge cases completely closes #355 closes #509 --- src/jwks/remote.ts | 44 +++++++++++++++++--------------------------- tap/jwks.ts | 2 +- 2 files changed, 18 insertions(+), 28 deletions(-) diff --git a/src/jwks/remote.ts b/src/jwks/remote.ts index 29758a4687..7873998264 100644 --- a/src/jwks/remote.ts +++ b/src/jwks/remote.ts @@ -103,36 +103,26 @@ class RemoteJWKSet extends LocalJWKSet { } async reload() { - // see https://github.com/panva/jose/issues/355 + // Do not assume a fetch created in another request reliably resolves + // see https://github.com/panva/jose/issues/355 and https://github.com/panva/jose/issues/509 if (this._pendingFetch && isCloudflareWorkers()) { - return new Promise((resolve) => { - const isDone = () => { - if (this._pendingFetch === undefined) { - resolve() - } else { - setTimeout(isDone, 5) - } - } - isDone() - }) + this._pendingFetch = undefined } - if (!this._pendingFetch) { - this._pendingFetch = fetchJwks(this._url, this._timeoutDuration, this._options) - .then((json) => { - if (!isJWKSLike(json)) { - throw new JWKSInvalid('JSON Web Key Set malformed') - } - - this._jwks = { keys: json.keys } - this._jwksTimestamp = Date.now() - this._pendingFetch = undefined - }) - .catch((err: Error) => { - this._pendingFetch = undefined - throw err - }) - } + this._pendingFetch ||= fetchJwks(this._url, this._timeoutDuration, this._options) + .then((json) => { + if (!isJWKSLike(json)) { + throw new JWKSInvalid('JSON Web Key Set malformed') + } + + this._jwks = { keys: json.keys } + this._jwksTimestamp = Date.now() + this._pendingFetch = undefined + }) + .catch((err: Error) => { + this._pendingFetch = undefined + throw err + }) await this._pendingFetch } diff --git a/tap/jwks.ts b/tap/jwks.ts index 64e8b28384..57f2f0d3c9 100644 --- a/tap/jwks.ts +++ b/tap/jwks.ts @@ -16,7 +16,7 @@ export default (QUnit: QUnit, lib: typeof jose) => { jwks({ kid: 'foo', alg: 'RS256' }), 'no applicable key found in the JSON Web Key Set', ) - t.ok(await jwks({ alg, kid })) + t.ok(await Promise.all([jwks({ alg, kid }), jwks({ alg, kid })])) }) test('[createLocalJWKSet] establishes local JWKSet', async (t: typeof QUnit.assert) => {