Skip to content

Commit 4ef62fd

Browse files
gjovanovEomm
authored andcommitted
breaking: support multiple strategies (#34)
1 parent 68e1cd5 commit 4ef62fd

File tree

7 files changed

+49
-23
lines changed

7 files changed

+49
-23
lines changed

README.md

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ fastify.register(oauthPlugin, {
3131
})
3232

3333
fastify.get('/login/facebook/callback', async function (request, reply) {
34-
const token = await this.getAccessTokenFromAuthorizationCodeFlow(request)
34+
const token = await this.facebookOAuth2.getAccessTokenFromAuthorizationCodeFlow(request)
3535

3636
console.log(token.access_token)
3737

@@ -85,11 +85,31 @@ See the [`example/`](./examples/) folder for more example.
8585
## Reference
8686

8787
This fastify plugin decorates the fastify instance with the [`simple-oauth2`](https://github.com/lelylan/simple-oauth2)
88-
instance.
88+
instance inside a **namespace** specified by the property `name`.
89+
90+
E.g. For `name: 'customOauth2'`, the `simple-oauth2` instance will become accessible like this:
91+
92+
`fastify.customOauth2.oauth2`
93+
94+
In this manner we are able to register multiple OAuth providers and each OAuth providers `simple-oauth2` instance will live in it's own **namespace**.
95+
96+
E.g.
97+
98+
- `fastify.facebook.oauth2`
99+
- `fastify.github.oauth2`
100+
- `fastify.spotify.oauth2`
101+
- `fastify.vkontakte.oauth2`
102+
103+
Assuming we have registered multiple OAuth providers like this:
104+
- `fastify.register(oauthPlugin, { name: 'facebook', { ... } // facebooks credentials, startRedirectPath, callbackUri etc )`
105+
- `fastify.register(oauthPlugin, { name: 'github', { ... } // githubs credentials, startRedirectPath, callbackUri etc )`
106+
- `fastify.register(oauthPlugin, { name: 'spotify', { ... } // spotifys credentials, startRedirectPath, callbackUri etc )`
107+
- `fastify.register(oauthPlugin, { name: 'vkontakte', { ... } // vkontaktes credentials, startRedirectPath, callbackUri etc )`
108+
89109

90110
## Utilities
91111

92-
This fastify plugin adds 2 utility decorators to your fastify instance:
112+
This fastify plugin adds 2 utility decorators to your fastify instance using the same **namespace**:
93113

94114
- `getAccessTokenFromAuthorizationCodeFlow(request, callback)`: A function that uses the Authorization code flow to fetch an OAuth2 token using the data in the last request of the flow. If the callback is not passed it will return a promise. The object resulting from the callback call or the promise resolution is a *token response* object containing the following keys:
95115
- `access_token`
@@ -98,6 +118,10 @@ This fastify plugin adds 2 utility decorators to your fastify instance:
98118
- `expires_in` (number of seconds for the token to expire, e.g. `240000`)
99119
- `getNewAccessTokenUsingRefreshToken(refreshToken, params, callback)`: A function that takes a refresh token and retrieves a new *token response* object. This is generally useful with background processing workers to re-issue a new token when the original token has expired. The `params` argument is optional and it's an object that can be used to pass in extra parameters to the refresh request (e.g. a stricter set of scopes). If the callback is not passed this function will return a promise. The object resulting from the callback call or the promise resolution is a new *token response* object (see fields above).
100120

121+
E.g. For `name: 'customOauth2'`, both helpers `getAccessTokenFromAuthorizationCodeFlow` and `getNewAccessTokenUsingRefreshToken` will become accessible like this:
122+
- `fastify.customOauth2.getAccessTokenFromAuthorizationCodeFlow`
123+
- `fastify.customOauth2.getNewAccessTokenUsingRefreshToken`
124+
101125
## License
102126

103127
Licensed under [MIT](./LICENSE).

examples/facebook.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ fastify.register(oauthPlugin, {
1919
})
2020

2121
fastify.get('/login/facebook/callback', function (request, reply) {
22-
this.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
22+
this.facebookOAuth2.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
2323
if (err) {
2424
reply.send(err)
2525
return

examples/google.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fastify.register(oauthPlugin, {
2020
})
2121

2222
fastify.get('/login/google/callback', function (request, reply) {
23-
this.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
23+
this.googleOAuth2.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
2424
if (err) {
2525
reply.send(err)
2626
return

examples/spotify.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fastify.register(oauthPlugin, {
1616
})
1717

1818
fastify.get('/login/spotify/callback', async (req, reply) => {
19-
const token = await fastify.getAccessTokenFromAuthorizationCodeFlow(req)
19+
const token = await fastify.Spotify.getAccessTokenFromAuthorizationCodeFlow(req)
2020

2121
req.log.info('The Spotify token is %o', token)
2222
reply.send({ access_token: token.access_token })

examples/vkontakte.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ fastify.register(oauthPlugin, {
1616
})
1717

1818
fastify.get('/login/vk/callback', async (req, reply) => {
19-
const token = await fastify.getAccessTokenFromAuthorizationCodeFlow(req)
19+
const token = await fastify.vkOAuth2.getAccessTokenFromAuthorizationCodeFlow(req)
2020

2121
console.log(token)
2222
reply.send({ access_token: token.access_token })

index.js

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,12 @@ const oauthPlugin = fp(function (fastify, options, next) {
6262
state: state
6363
})
6464

65-
const authorizationUri = this[name].authorizationCode.authorizeURL(urlOptions)
65+
const authorizationUri = this[name].oauth2.authorizationCode.authorizeURL(urlOptions)
6666
reply.redirect(authorizationUri)
6767
}
6868

6969
const cbk = function (o, code, callback) {
70-
return o.authorizationCode.getToken({
70+
return o.oauth2.authorizationCode.getToken({
7171
code: code,
7272
redirect_uri: callbackUri
7373
}, callback)
@@ -95,7 +95,7 @@ const oauthPlugin = fp(function (fastify, options, next) {
9595
}
9696

9797
function getNewAccessTokenUsingRefreshTokenCallbacked (refreshToken, params, callback) {
98-
const accessToken = fastify[name].accessToken.create({ refresh_token: refreshToken })
98+
const accessToken = fastify[name].oauth2.accessToken.create({ refresh_token: refreshToken })
9999
accessToken.refresh(params, callback)
100100
}
101101
const getNewAccessTokenUsingRefreshTokenPromisified = promisify(getNewAccessTokenUsingRefreshTokenCallbacked)
@@ -111,12 +111,14 @@ const oauthPlugin = fp(function (fastify, options, next) {
111111

112112
if (startRedirectPath) {
113113
fastify.get(startRedirectPath, startRedirectHandler)
114-
fastify.decorate('getAccessTokenFromAuthorizationCodeFlow', getAccessTokenFromAuthorizationCodeFlow)
115-
fastify.decorate('getNewAccessTokenUsingRefreshToken', getNewAccessTokenUsingRefreshToken)
116114
}
117115

118116
try {
119-
fastify.decorate(name, oauth2)
117+
fastify.decorate(name, {
118+
oauth2: oauth2,
119+
getAccessTokenFromAuthorizationCodeFlow,
120+
getNewAccessTokenUsingRefreshToken
121+
})
120122
} catch (e) {
121123
next(e)
122124
return

test.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ t.test('fastify-oauth2', t => {
8080
})
8181

8282
fastify.get('/', function (request, reply) {
83-
this.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
83+
this.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
8484
if (err) throw err
8585

8686
// attempts to refresh the token
87-
this.getNewAccessTokenUsingRefreshToken(result.refresh_token, undefined, (err, result) => {
87+
this.githubOAuth2.getNewAccessTokenUsingRefreshToken(result.refresh_token, undefined, (err, result) => {
8888
if (err) throw err
8989

9090
const newToken = result
@@ -122,10 +122,10 @@ t.test('fastify-oauth2', t => {
122122
})
123123

124124
fastify.get('/', function (request, reply) {
125-
return this.getAccessTokenFromAuthorizationCodeFlow(request)
125+
return this.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(request)
126126
.then(result => {
127127
// attempts to refresh the token
128-
return this.getNewAccessTokenUsingRefreshToken(result.refresh_token)
128+
return this.githubOAuth2.getNewAccessTokenUsingRefreshToken(result.refresh_token)
129129
})
130130
.then(token => {
131131
return {
@@ -159,7 +159,7 @@ t.test('fastify-oauth2', t => {
159159
})
160160

161161
fastify.get('/', function (request, reply) {
162-
return this.getAccessTokenFromAuthorizationCodeFlow(request)
162+
return this.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(request)
163163
.catch(e => {
164164
reply.code(400)
165165
return e.message
@@ -195,7 +195,7 @@ t.test('options.name should be a string', t => {
195195
})
196196
})
197197

198-
t.test('options.credentials should be and object', t => {
198+
t.test('options.credentials should be an object', t => {
199199
t.plan(1)
200200

201201
const fastify = createFastify({ logger: { level: 'silent' } })
@@ -208,7 +208,7 @@ t.test('options.credentials should be and object', t => {
208208
})
209209
})
210210

211-
t.test('options.callbackUri should be and object', t => {
211+
t.test('options.callbackUri should be an object', t => {
212212
t.plan(1)
213213

214214
const fastify = createFastify({ logger: { level: 'silent' } })
@@ -228,7 +228,7 @@ t.test('options.callbackUri should be and object', t => {
228228
})
229229
})
230230

231-
t.test('options.callbackUriParams should be and object', t => {
231+
t.test('options.callbackUriParams should be an object', t => {
232232
t.plan(1)
233233

234234
const fastify = createFastify({ logger: { level: 'silent' } })
@@ -289,7 +289,7 @@ t.test('options.callbackUriParams', t => {
289289
})
290290
})
291291

292-
t.test('options.generateStateFunction should be and object', t => {
292+
t.test('options.generateStateFunction should be an object', t => {
293293
t.plan(1)
294294

295295
const fastify = createFastify({ logger: { level: 'silent' } })
@@ -311,7 +311,7 @@ t.test('options.generateStateFunction should be and object', t => {
311311
})
312312
})
313313

314-
t.test('options.checkStateFunction should be and object', t => {
314+
t.test('options.checkStateFunction should be an object', t => {
315315
t.plan(1)
316316

317317
const fastify = createFastify({ logger: { level: 'silent' } })

0 commit comments

Comments
 (0)