Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

get-jwks

Package Overview
Dependencies
Maintainers
29
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

get-jwks - npm Package Compare versions

Comparing version 4.2.0 to 4.3.0

.github/workflows/notify-release.yml

10

package.json
{
"name": "get-jwks",
"version": "4.2.0",
"version": "4.3.0",
"description": "Fetch utils for JWKS keys",

@@ -10,3 +10,3 @@ "main": "src/get-jwks.js",

"scripts": {
"test": "tap",
"test": "tap test/*.spec.js",
"lint": "eslint ."

@@ -37,9 +37,9 @@ },

"fastify": "^3.12.0",
"fastify-jwt": "^2.3.0",
"fastify-jwt": "^3.0.0",
"jsonwebtoken": "^8.5.1",
"nock": "^13.0.7",
"prettier": "^2.2.1",
"sinon": "^10.0.0",
"tap": "^14.11.0"
"sinon": "^11.0.0",
"tap": "^15.0.2"
}
}

@@ -18,2 +18,3 @@ # get-jwks

```js
const https = require('https')
const buildGetJwks = require('get-jwks')

@@ -26,2 +27,5 @@

providerDiscovery: false,
agent: new https.Agent({
keepAlive: true,
}),
})

@@ -33,3 +37,5 @@ ```

- `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
- `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.
- `agent`: The custom agent to use for requests, as specified in [node-fetch documentation](https://github.com/node-fetch/node-fetch#custom-agent). Defaults to `null`.

@@ -46,3 +52,3 @@ > `max` and `maxAge` are provided to [lru-cache](https://www.npmjs.com/package/lru-cache).

const jwk = await getJwks.getJwk({
domain: 'https://exampe.com/',
domain: 'https://example.com/',
alg: 'token_alg',

@@ -120,8 +126,5 @@ kid: 'token_kid',

```js
const { createDecoder, createVerifier } = require('fast-jwt')
const { createVerifier } = require('fast-jwt')
const buildGetJwks = require('get-jwks')
// JWT signed with JWKS
const token = '...'
// well known url of the token issuer

@@ -131,17 +134,17 @@ // often encoded as the `iss` property of the token payload

// complete is necessary to get the header
const decode = createDecoder({ complete: true })
const getJwks = buildGetJwks({ allowedDomains: [...]})
// decode the token and extract the header
const {
header: { kid, alg },
} = decode(token)
// create a verifier function with key as a function
const verifyWithPromise = createVerifier({
key: async function (token) {
const publicKey = await getJwks.getPublicKey({
kid: token.kid,
alg: token.alg,
domain,
})
return publicKey
},
})
const getJwks = buildGetJwks()
const publicKey = await getJwks.getPublicKey({ kid, domain, alg })
const verifyWithPromise = createVerifier({ key: publicKey })
// verify the token via the public key
const payload = await verifyWithPromise(token)
```

@@ -18,23 +18,4 @@ 'use strict'

async function getJwksUri(normalizedDomain) {
const response = await fetch(
`${normalizedDomain}.well-known/openid-configuration`,
{
timeout: 5000,
}
)
const body = await response.json()
if (!response.ok) {
const error = new Error(response.statusText)
error.response = response
error.body = body
throw error
}
if (!body.jwks_uri) {
throw new Error(errors.NO_JWKS_URI)
}
return body.jwks_uri
function ensureNoLeadingSlash(path) {
return path.startsWith('/') ? path.substring(1) : path
}

@@ -47,3 +28,6 @@

const providerDiscovery = options.providerDiscovery || false
const jwksPath = options.jwksPath
? ensureNoLeadingSlash(options.jwksPath)
: false
const agent = options.agent || null
const staleCache = new LRU({ max: max * 2, maxAge })

@@ -56,2 +40,26 @@ const cache = new LRU({

async function getJwksUri(normalizedDomain) {
const response = await fetch(
`${normalizedDomain}.well-known/openid-configuration`,
{
agent,
timeout: 5000,
}
)
const body = await response.json()
if (!response.ok) {
const error = new Error(response.statusText)
error.response = response
error.body = body
throw error
}
if (!body.jwks_uri) {
throw new Error(errors.NO_JWKS_URI)
}
return body.jwks_uri
}
async function getPublicKey(signature) {

@@ -97,7 +105,9 @@ return jwkToPem(await this.getJwk(signature))

async function retrieveJwk(normalizedDomain, alg, kid) {
const jwksUri = providerDiscovery
const jwksUri = jwksPath
? normalizedDomain + jwksPath
: providerDiscovery
? await getJwksUri(normalizedDomain)
: `${normalizedDomain}.well-known/jwks.json`
const response = await fetch(jwksUri, { timeout: 5000 })
const response = await fetch(jwksUri, { agent, timeout: 5000 })
const body = await response.json()

@@ -116,3 +126,5 @@

const jwk = body.keys.find(key => (key.alg === undefined || key.alg === alg) && key.kid === kid)
const jwk = body.keys.find(
key => (key.alg === undefined || key.alg === alg) && key.kid === kid
)

@@ -119,0 +131,0 @@ if (!jwk) {

@@ -26,3 +26,3 @@ 'use strict'

t.equal(publicKey, jwkToPem(jwk))
t.deepEqual(jwk, localKey)
t.same(jwk, localKey)
}

@@ -29,0 +29,0 @@ )

@@ -5,3 +5,3 @@ 'use strict'

const nock = require('nock')
const { createDecoder, createVerifier } = require('fast-jwt')
const { createVerifier } = require('fast-jwt')

@@ -21,19 +21,19 @@ const { jwks, token } = require('./constants')

t.test('fast-jwt integration tests', async t => {
const myDomain = 'https://localhost/'
nock(myDomain).get('/.well-known/jwks.json').reply(200, jwks)
const domain = 'https://localhost/'
nock(domain).get('/.well-known/jwks.json').reply(200, jwks)
const decodeComplete = createDecoder({ complete: true })
const sections = decodeComplete(token)
const {
header: { kid, alg },
} = sections
const getJwks = buildGetJwks()
const publicKey = await getJwks.getPublicKey({ kid, domain: myDomain, alg })
const verifyWithPromise = createVerifier({ key: publicKey })
const verifyWithPromise = createVerifier({
key: async function (token) {
const publicKey = await getJwks.getPublicKey({
kid: token.kid,
alg: token.alg,
domain,
})
return publicKey
},
})
const payload = await verifyWithPromise(token)
t.strictEqual(payload.name, 'Jane Doe')
t.done()
t.equal(payload.name, 'Jane Doe')
})

@@ -55,5 +55,4 @@ 'use strict'

t.strictEqual(response.statusCode, 200)
t.strictEqual(response.body, 'Jane Doe')
t.done()
t.equal(response.statusCode, 200)
t.equal(response.body, 'Jane Doe')
})

@@ -99,5 +98,4 @@

t.strictEqual(response.statusCode, 200)
t.strictEqual(response.body, 'Jane Doe')
t.done()
t.equal(response.statusCode, 200)
t.equal(response.body, 'Jane Doe')
})

@@ -49,5 +49,20 @@ 'use strict'

t.ok(jwk)
t.deepEqual(jwk, key)
t.same(jwk, key)
})
t.test('returns a jwk if alg and kid match and path is specified', async t => {
nock(domain).get('/otherdir/jwks.json').reply(200, jwks)
const getJwks = buildGetJwks({ jwksPath: '/otherdir/jwks.json' })
const key = jwks.keys[0]
const jwk = await getJwks.getJwk({
domain,
alg: key.alg,
kid: key.kid,
})
t.ok(jwk)
t.same(jwk, key)
})
t.test('returns a jwk if no alg is provided and kid match', async t => {

@@ -61,3 +76,3 @@ nock(domain).get('/.well-known/jwks.json').reply(200, jwks)

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

@@ -76,3 +91,3 @@

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

@@ -122,2 +137,11 @@

t.test('supports path without leading slash', async t => {
nock(domain).get('/otherdir/jwks.json').reply(200, jwks)
const getJwks = buildGetJwks({ jwksPath: 'otherdir/jwks.json' })
const [{ alg, kid }] = jwks.keys
const key = await getJwks.getJwk({ domain: 'https://localhost', alg, kid })
t.ok(key)
})
t.test('does not execute concurrent requests', () => {

@@ -166,3 +190,3 @@ nock(domain).get('/.well-known/jwks.json').once().reply(200, jwks)

t.sameStrict(key, key1)
t.strictSame(key, key1)
})

@@ -169,0 +193,0 @@

@@ -54,3 +54,3 @@ 'use strict'

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

@@ -67,3 +67,3 @@

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

@@ -83,3 +83,3 @@

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

@@ -192,3 +192,3 @@

t.sameStrict(key, key1)
t.strictSame(key, key1)
}

@@ -195,0 +195,0 @@ )

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc