Skip to content

Commit 932c6d7

Browse files
philschphilsch
andauthored
feat: introduce option to set additional getToken parameters (#178)
* introduce option to set additional getToken parameters * add test * rename to options.tokenRequestParams, small section for README * use t.plan, linting * simplify implementation Co-authored-by: philsch <[email protected]>
1 parent f2ea13d commit 932c6d7

File tree

4 files changed

+101
-2
lines changed

4 files changed

+101
-2
lines changed

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,11 @@ fastify.register(oauthPlugin, {
184184
});
185185
```
186186

187+
## Set custom tokenRequest body Parameters
188+
189+
The `tokenRequestParams` parameter accepts an object that will be translated to additional parameters in the POST body
190+
when requesting access tokens via the service’s token endpoint.
191+
187192
## Examples
188193

189194
See the [`example/`](./examples/) folder for more examples.

index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export interface FastifyOAuth2Options {
2424
credentials: Credentials;
2525
callbackUri: string;
2626
callbackUriParams?: Object;
27+
tokenRequestParams?: Object;
2728
generateStateFunction?: Function;
2829
checkStateFunction?: Function;
2930
startRedirectPath: string;

index.js

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ const oauthPlugin = fp(function (fastify, options, next) {
3838
if (options.callbackUriParams && typeof options.callbackUriParams !== 'object') {
3939
return next(new Error('options.callbackUriParams should be a object'))
4040
}
41+
if (options.tokenRequestParams && typeof options.tokenRequestParams !== 'object') {
42+
return next(new Error('options.tokenRequestParams should be a object'))
43+
}
4144
if (options.generateStateFunction && typeof options.generateStateFunction !== 'function') {
4245
return next(new Error('options.generateStateFunction should be a function'))
4346
}
@@ -61,6 +64,7 @@ const oauthPlugin = fp(function (fastify, options, next) {
6164
const credentials = options.credentials
6265
const callbackUri = options.callbackUri
6366
const callbackUriParams = options.callbackUriParams || {}
67+
const tokenRequestParams = options.tokenRequestParams || {}
6468
const scope = options.scope
6569
const generateStateFunction = options.generateStateFunction || defaultGenerateStateFunction
6670
const checkStateFunction = options.checkStateFunction || defaultCheckStateFunction
@@ -88,10 +92,12 @@ const oauthPlugin = fp(function (fastify, options, next) {
8892
}
8993

9094
const cbk = function (o, code, callback) {
91-
return callbackify(o.oauth2.getToken.bind(o.oauth2, {
95+
const body = Object.assign({}, tokenRequestParams, {
9296
code,
9397
redirect_uri: callbackUri
94-
}))(callback)
98+
})
99+
100+
return callbackify(o.oauth2.getToken.bind(o.oauth2, body))(callback)
95101
}
96102

97103
function getAccessTokenFromAuthorizationCodeFlowCallbacked (request, callback) {

test/plugin.test.js

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,93 @@ t.test('options.callbackUriParams', t => {
297297
})
298298
})
299299

300+
t.test('options.tokenRequestParams should be an object', t => {
301+
t.plan(1)
302+
303+
const fastify = createFastify({ logger: { level: 'silent' } })
304+
305+
fastify.register(oauthPlugin, {
306+
name: 'the-name',
307+
credentials: {
308+
client: {
309+
id: 'my-client-id',
310+
secret: 'my-secret'
311+
},
312+
auth: oauthPlugin.GITHUB_CONFIGURATION
313+
},
314+
callbackUri: '/callback',
315+
tokenRequestParams: 1
316+
})
317+
.ready(err => {
318+
t.strictSame(err.message, 'options.tokenRequestParams should be a object')
319+
})
320+
})
321+
322+
t.test('options.tokenRequestParams', t => {
323+
t.plan(2)
324+
325+
const fastify = createFastify({ logger: { level: 'silent' } })
326+
const oAuthCode = '123456789'
327+
328+
fastify.register(oauthPlugin, {
329+
name: 'githubOAuth2',
330+
credentials: {
331+
client: {
332+
id: 'my-client-id',
333+
secret: 'my-secret'
334+
},
335+
auth: oauthPlugin.GITHUB_CONFIGURATION
336+
},
337+
startRedirectPath: '/login/github',
338+
callbackUri: 'http://localhost:3000/callback',
339+
generateStateFunction: function () {
340+
return 'dummy'
341+
},
342+
checkStateFunction: function (state, callback) {
343+
callback()
344+
},
345+
tokenRequestParams: {
346+
param1: '123'
347+
},
348+
scope: ['notifications']
349+
})
350+
351+
const githubScope = nock('https://github.com')
352+
.post(
353+
'/login/oauth/access_token',
354+
'grant_type=authorization_code&param1=123&code=123456789&redirect_uri=http%3A%2F%2Flocalhost%3A3000%2Fcallback',
355+
{
356+
reqheaders: {
357+
authorization: 'Basic bXktY2xpZW50LWlkOm15LXNlY3JldA=='
358+
}
359+
}
360+
)
361+
.reply(200, {})
362+
363+
fastify.get('/callback', function (request, reply) {
364+
return this.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(request)
365+
.catch(e => {
366+
reply.code(400)
367+
return e.message
368+
})
369+
})
370+
371+
t.teardown(fastify.close.bind(fastify))
372+
373+
fastify.listen({ port: 0 }, function (err) {
374+
t.error(err)
375+
376+
fastify.inject({
377+
method: 'GET',
378+
url: '/callback?code=' + oAuthCode
379+
}, function (err, responseStart) {
380+
t.error(err)
381+
382+
githubScope.done()
383+
})
384+
})
385+
})
386+
300387
t.test('options.generateStateFunction with request', t => {
301388
t.plan(5)
302389
const fastify = createFastify()

0 commit comments

Comments
 (0)