Skip to content

Commit

Permalink
feat: configure timeout via options parameter (#223)
Browse files Browse the repository at this point in the history
* feat: configure timeout via options parameter

* feat: update readme and unit tests

* fix: remove .only
  • Loading branch information
MarioSimou committed Jul 19, 2023
1 parent 138b447 commit 267eacc
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 9 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ const buildGetJwks = require('get-jwks')
const getJwks = buildGetJwks({
max: 100,
ttl: 60 * 1000,
timeout: 5000,
allowedDomains: ['https://example.com'],
providerDiscovery: false,
agent: new https.Agent({
Expand All @@ -31,6 +32,7 @@ const getJwks = buildGetJwks({

- `max`: Max items to hold in cache. Defaults to 100.
- `ttl`: Milliseconds an item will remain in cache. Defaults to 60s.
- `timeout`: Specifies how long it should wait to retrieve a JWK before it fails. The time is set in milliseconds. Defaults to 5s.
- `allowedDomains`: Array of allowed domains. By default all domains are allowed.
- `providerDiscovery`: Indicates if the Provider Configuration Information is used to automatically get the jwks_uri from the [OpenID Provider Discovery Endpoint](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfig). This endpoint is exposing the [Provider Metadata](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata). With this flag set to true the domain will be treated as the OpenID Issuer which is the iss property in the token. Defaults to false. Ignored if jwksPath is specified.
- `jwksPath`: Specify a relative path to the jwks_uri. Example `/otherdir/jwks.json`. Takes precedence over providerDiscovery. Optional.
Expand Down
1 change: 1 addition & 0 deletions src/get-jwks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type GetJwksOptions = {
providerDiscovery?: boolean
jwksPath?: string
agent?: Agent
timeout?: number
}

type GetJwks = {
Expand Down
5 changes: 3 additions & 2 deletions src/get-jwks.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ function ensureNoLeadingSlash(path) {
function buildGetJwks(options = {}) {
const max = options.max || 100
const ttl = options.ttl || 60 * 1000 /* 1 minute */
const timeout = options.timeout || 5 * 1000 /* 5 seconds */
const allowedDomains = (options.allowedDomains || []).map(ensureTrailingSlash)
const providerDiscovery = options.providerDiscovery || false
const jwksPath = options.jwksPath
Expand All @@ -35,7 +36,7 @@ function buildGetJwks(options = {}) {
`${normalizedDomain}.well-known/openid-configuration`,
{
agent,
timeout: 5000,
timeout,
}
)
const body = await response.json()
Expand Down Expand Up @@ -101,7 +102,7 @@ function buildGetJwks(options = {}) {
? await getJwksUri(normalizedDomain)
: `${normalizedDomain}.well-known/jwks.json`

const response = await fetch(jwksUri, { agent, timeout: 5000 })
const response = await fetch(jwksUri, { agent, timeout })
const body = await response.json()

if (!response.ok) {
Expand Down
41 changes: 35 additions & 6 deletions test/getJwk.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ t.test('rejects if alg and kid do not match', async t => {

await t.rejects(
getJwks.getJwk({ domain, alg: 'NOT', kid: 'FOUND' }),
'No matching JWK found in the set.'
'No matching JWK found in the set.',
)
})

Expand Down Expand Up @@ -90,7 +90,7 @@ t.test(

t.ok(jwk)
t.same(jwk, key)
}
},
)

t.test('caches a successful response', async t => {
Expand Down Expand Up @@ -125,7 +125,7 @@ t.test('rejects if response is an empty object', async t => {

return t.rejects(
getJwks.getJwk({ domain, alg, kid }),
'No JWKS found in the response.'
'No JWKS found in the response.',
)
})

Expand All @@ -136,7 +136,7 @@ t.test('rejects if no JWKS are found in the response', async t => {

return t.rejects(
getJwks.getJwk({ domain, alg, kid }),
'No JWKS found in the response.'
'No JWKS found in the response.',
)
})

Expand Down Expand Up @@ -241,7 +241,7 @@ t.test('allowed domains', async t => {
const [{ alg, kid }] = jwks.keys

t.ok(await getJwks.getJwk({ domain: domainFromToken, alg, kid }))
}
},
)
})

Expand Down Expand Up @@ -269,7 +269,36 @@ t.test('allowed domains', async t => {

return t.rejects(
getJwks.getJwk({ domain, alg, kid }),
'The domain is not allowed.'
'The domain is not allowed.',
)
})
})

t.test('timeout', async t => {
const domain = 'https://example.com'
const [{ alg, kid }] = jwks.keys

t.beforeEach(() =>
nock(domain).get('/.well-known/jwks.json').reply(200, jwks),
)

let timeout
const buildGetJwks = t.mock('../src/get-jwks', {
'node-fetch': (init, options) => {
timeout = options.timeout
return require('node-fetch')(init, options)
},
})

t.test('timeout defaults to 5 seconds', async t => {
const getJwks = buildGetJwks()
await getJwks.getJwk({ domain, alg, kid })
t.equal(timeout, 5000)
})

t.test('ensures that timeout is set to 10 seconds', async t => {
const getJwks = buildGetJwks({ timeout: 10000 })
await getJwks.getJwk({ domain, alg, kid })
t.equal(timeout, 10000)
})
})
30 changes: 29 additions & 1 deletion test/getJwksUri.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,33 @@ t.test(
}

await t.rejects(getJwks.getJwksUri(domain), expectedError)
}
},
)

t.test('timeout', async t => {
t.beforeEach(() =>
nock(domain)
.get('/.well-known/openid-configuration')
.reply(200, { jwks_uri: 'http://localhost' }),
)

let timeout
const buildGetJwks = t.mock('../src/get-jwks', {
'node-fetch': (input, options) => {
timeout = options.timeout
return require('node-fetch')(input, options)
},
})

t.test('timeout defaults to 5 seconds', async t => {
const getJwks = buildGetJwks()
await getJwks.getJwksUri(domain)
t.equal(timeout, 5000)
})

t.test('ensures that timeout is set to 10 seconds', async t => {
const getJwks = buildGetJwks({ timeout: 10000 })
await getJwks.getJwksUri(domain)
t.equal(timeout, 10000)
})
})

0 comments on commit 267eacc

Please sign in to comment.