From c24b48f60802e9f53da7db881e824eb6e6e8be70 Mon Sep 17 00:00:00 2001 From: Jonas Lundeland Date: Fri, 2 Oct 2020 16:08:38 +0200 Subject: [PATCH] feat: add CallbackExtras to StrategyOptions and pass to callback --- lib/passport_strategy.js | 4 ++- test/passport/passport_strategy.test.js | 34 +++++++++++++++++++++++++ types/index.d.ts | 5 ++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/lib/passport_strategy.js b/lib/passport_strategy.js index 5cf68178..8c9e5089 100644 --- a/lib/passport_strategy.js +++ b/lib/passport_strategy.js @@ -30,6 +30,7 @@ function OpenIDConnectStrategy({ passReqToCallback = false, sessionKey, usePKCE, + extras = {}, } = {}, verify) { if (!(client instanceof BaseClient)) { throw new TypeError('client must be an instance of openid-client Client'); @@ -50,6 +51,7 @@ function OpenIDConnectStrategy({ this._usePKCE = usePKCE; this._key = sessionKey || `oidc:${url.parse(this._issuer.issuer).hostname}`; this._params = cloneDeep(params); + this._extras = cloneDeep(extras); if (!this._params.response_type) this._params.response_type = resolveResponseType.call(client); if (!this._params.redirect_uri) this._params.redirect_uri = resolveRedirectUri.call(client); @@ -147,7 +149,7 @@ OpenIDConnectStrategy.prototype.authenticate = function authenticate(req, option response_type: responseType, }; - const tokenset = await client.callback(opts.redirect_uri, reqParams, checks); + const tokenset = await client.callback(opts.redirect_uri, reqParams, checks, this._extras); const passReq = this._passReqToCallback; const loadUserinfo = this._verify.length > (passReq ? 3 : 2) && client.issuer.userinfo_endpoint; diff --git a/test/passport/passport_strategy.test.js b/test/passport/passport_strategy.test.js index a9dbae3c..06f498e4 100644 --- a/test/passport/passport_strategy.test.js +++ b/test/passport/passport_strategy.test.js @@ -69,6 +69,40 @@ describe('OpenIDConnectStrategy', () => { strategy.authenticate(req); }); + describe('authenticate', function () { + it('forwards options.extras to callback as extras param', async function () { + const extras = { + clientAssertionPayload: { + aud: 'https://oidc.corp.com/default-oidc-provider', + }, + }; + + const params = { + redirect_uri: 'http://domain.inc/oauth2/callback', + }; + + const strategy = new Strategy({ client: this.client, params, extras }, () => {}); + const req = new MockRequest('GET', '/login/oidc'); + req.session = { 'oidc:op.example.com': sinon.match.object }; + + /* Fake callback params */ + const callbackParams = { code: 'some-code' }; + sinon.stub(this.client, 'callbackParams').callsFake(() => callbackParams); + + this.client.callback = sinon.spy(); + + strategy.authenticate(req, {}); + sinon.assert.calledOnce(this.client.callback); + sinon.assert.calledWith( + this.client.callback, + params.redirect_uri, + callbackParams, + sinon.match.object, + extras, + ); + }); + }); + describe('initate', function () { it('starts authentication requests for GETs', function () { const params = { foo: 'bar' }; diff --git a/types/index.d.ts b/types/index.d.ts index 2bae1054..e454b5de 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -675,6 +675,11 @@ export interface StrategyOptions { * Authorization Request parameters. The strategy will use these. */ params?: AuthorizationParameters; + + /** + * "extras" argument value passed to the client.callback() call. + */ + extras?: CallbackExtras; /** * Boolean specifying whether the verify function should get the request object as first argument instead. * Default: 'false'