diff --git a/lib/models/client.js b/lib/models/client.js index f5000d1d2..2f48b6e18 100644 --- a/lib/models/client.js +++ b/lib/models/client.js @@ -283,19 +283,6 @@ module.exports = function getClient(provider) { }, }); - if (client.jwks && client.jwks.keys) { - try { - client.jwks.keys - .map(checkJWK.bind(undefined, 'jwks')) - .filter(Boolean) - .forEach((key) => { - client.keystore.add(key); - }); - } catch (err) { - throw new InvalidClientMetadata(err.message); - } - } - const algs = new Set(); if (client.clientSecret) { @@ -348,6 +335,19 @@ module.exports = function getClient(provider) { } } + if (client.jwks && client.jwks.keys) { + try { + client.jwks.keys + .map(checkJWK.bind(undefined, 'jwks')) + .filter(Boolean) + .forEach((key) => { + client.keystore.add(key); + }); + } catch (err) { + throw new InvalidClientMetadata(err.message); + } + } + return client; } diff --git a/test/provider/provider_instance.test.js b/test/provider/provider_instance.test.js index 10dbc0023..96694f6b1 100644 --- a/test/provider/provider_instance.test.js +++ b/test/provider/provider_instance.test.js @@ -105,6 +105,55 @@ describe('provider instance', () => { lazy = i(client).lazyAlgs; expect(lazy).to.be.undefined; }); + + it('instantiates keystore and its HS derived keys lazily even if there is jwks already', async () => { + const provider = new Provider('http://localhost', { + clients: [{ + client_id: 'foo', + client_secret: 'foobar', + redirect_uris: ['https://rp.example.com'], + token_endpoint_auth_method: 'client_secret_jwt', + token_endpoint_auth_signing_alg: 'HS256', + id_token_encrypted_response_alg: 'dir', + id_token_encrypted_response_enc: 'A128CBC-HS256', + jwks: { + keys: [ + { + e: 'AQAB', + n: 'thyd94GamW5pbQBWAM-TJIX5Fy2T-3J83cONeelhb71nWc_RC1UoobE0iu4LKs9cDAJpXiAjdzbwqS87n7bGU6smXgeA5xCjDh9ukw1TN2F4k5YwHuQEUvk_esss53vHfN2s0C1XXdwy3HxDtzD23UKt7wQB1YsLBS8S3VUk-ruNuUTYRGW0ho-sfoe7TDWiS10eS3GPxJJixhvcA-GrH1KtPDJAAkR3UNFBOY6XQRRoovD5IColB81ycr2eLWJofbn0O_TZXSOEu5thIjKayFIOYsKH2ogBIArJefckcxR-jYGtFTv9nqkWMzKyi_wo-ipfrNaKILDp3TEALYu8_Q', + kty: 'RSA', + kid: 'O8ndoV8gKPCRVHnBebuL_b-rIfdRc8et4-z5tlTLLgw', + }, + ], + }, + }], + features: { + encryption: { enabled: true }, + requestObjects: { + request: false, + requestUri: false, + }, + }, + whitelistedJWA: { + idTokenEncryptionAlgValues: ['dir'], + }, + }); + + const client = await provider.Client.find('foo'); + let lazy = i(client).lazyAlgs; + expect(lazy).to.be.ok; + expect(lazy.size).to.eql(2); + expect(client.keystore.size).to.eql(1); + expect([...lazy]).to.eql(['HS256', 'A128CBC-HS256']); + expect(client.keystore.get({ alg: 'HS256' })).to.be.ok; + expect(client.keystore.size).to.eql(2); + expect(lazy.size).to.eql(1); + expect(client.keystore.get({ alg: 'A128CBC-HS256' })).to.be.ok; + expect(client.keystore.size).to.eql(3); + expect(lazy.size).to.eql(0); + lazy = i(client).lazyAlgs; + expect(lazy).to.be.undefined; + }); }); describe('#urlFor', () => {