Skip to content

Commit 9bac05f

Browse files
authored
add: request object to generateStateFunction (#41)
1 parent 50fb809 commit 9bac05f

File tree

3 files changed

+80
-1
lines changed

3 files changed

+80
-1
lines changed

README.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,44 @@ fastify.register(oauthPlugin, {
7878
})
7979
```
8080

81+
## Set custom state
82+
83+
The `generateStateFunction` accepts a function to generate the `state` parameter for the OAUTH flow. This function receives the Fastify's `request` object as parameter.
84+
When you set it, it is required to provide the function `checkStateFunction` also in order to validate the states generated.
85+
86+
```js
87+
const validStates = new Set()
88+
89+
fastify.register(oauthPlugin, {
90+
name: 'facebookOAuth2',
91+
credentials: {
92+
client: {
93+
id: '<CLIENT_ID>',
94+
secret: '<CLIENT_SECRET>'
95+
},
96+
auth: oauthPlugin.FACEBOOK_CONFIGURATION
97+
},
98+
// register a fastify url to start the redirect flow
99+
startRedirectPath: '/login/facebook',
100+
// facebook redirect here after the user login
101+
callbackUri: 'http://localhost:3000/login/facebook/callback',
102+
// custom function to generate the state
103+
generateStateFunction: (request) => {
104+
const state = request.query.customCode
105+
validStates.add(state)
106+
return state
107+
},
108+
// custom function to check the state is valid
109+
checkStateFunction: (returnedState, callback) => {
110+
if (validStates.has(returnedState)) {
111+
callback()
112+
return
113+
}
114+
callback(new Error('Invalid state'))
115+
}
116+
})
117+
```
118+
81119
## Example
82120

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

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const oauthPlugin = fp(function (fastify, options, next) {
5555
const startRedirectPath = options.startRedirectPath
5656

5757
function startRedirectHandler (request, reply) {
58-
const state = generateStateFunction()
58+
const state = generateStateFunction(request)
5959
const urlOptions = Object.assign({}, callbackUriParams, {
6060
redirect_uri: callbackUri,
6161
scope: scope,

test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,47 @@ t.test('options.callbackUriParams', t => {
289289
})
290290
})
291291

292+
t.test('options.generateStateFunction with request', t => {
293+
t.plan(5)
294+
const fastify = createFastify({ logger: true })
295+
296+
fastify.register(oauthPlugin, {
297+
name: 'the-name',
298+
credentials: {
299+
client: {
300+
id: 'my-client-id',
301+
secret: 'my-secret'
302+
},
303+
auth: oauthPlugin.GITHUB_CONFIGURATION
304+
},
305+
startRedirectPath: '/login/github',
306+
callbackUri: '/callback',
307+
generateStateFunction: (request) => {
308+
t.ok(request, 'the request param has been set')
309+
return request.query.code
310+
},
311+
checkStateFunction: () => true,
312+
scope: ['notifications']
313+
})
314+
315+
t.tearDown(fastify.close.bind(fastify))
316+
317+
fastify.listen(0, function (err) {
318+
t.error(err)
319+
320+
fastify.inject({
321+
method: 'GET',
322+
url: '/login/github',
323+
query: { code: 'generated_code' }
324+
}, function (err, responseStart) {
325+
t.error(err)
326+
t.equal(responseStart.statusCode, 302)
327+
const matched = responseStart.headers.location.match(/https:\/\/github\.com\/login\/oauth\/authorize\?response_type=code&client_id=my-client-id&redirect_uri=%2Fcallback&scope=notifications&state=generated_code/)
328+
t.ok(matched)
329+
})
330+
})
331+
})
332+
292333
t.test('options.generateStateFunction should be an object', t => {
293334
t.plan(1)
294335

0 commit comments

Comments
 (0)