Skip to content

Commit e62fac6

Browse files
authored
Improve out of the box types by using a prefix when decorating (#224)
* Use a prefix when decorating fastify This enables out of the box typing + can, if the old way is eventually dropped, stop the risk of clashes between other fastify plugins and/or core methods and the names used in auth configurations. Signed-off-by: Pelle Wessman <[email protected]> * Fix feedback from @mcollina --------- Signed-off-by: Pelle Wessman <[email protected]>
1 parent 09dc053 commit e62fac6

File tree

5 files changed

+35
-17
lines changed

5 files changed

+35
-17
lines changed

README.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -221,20 +221,20 @@ See the [`example/`](./examples/) folder for more examples.
221221
## Reference
222222

223223
This Fastify plugin decorates the fastify instance with the [`simple-oauth2`](https://github.com/lelylan/simple-oauth2)
224-
instance inside a **namespace** specified by the property `name`.
224+
instance inside a **namespace** specified by the property `name` both with and without an `oauth2` prefix.
225225

226226
E.g. For `name: 'customOauth2'`, the `simple-oauth2` instance will become accessible like this:
227227

228-
`fastify.customOauth2.oauth2`
228+
`fastify.oauth2CustomOauth2.oauth2` and `fastify.customOauth2.oauth2`
229229

230230
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**.
231231

232232
E.g.
233233

234-
- `fastify.facebook.oauth2`
235-
- `fastify.github.oauth2`
236-
- `fastify.spotify.oauth2`
237-
- `fastify.vkontakte.oauth2`
234+
- `fastify.oauth2Facebook.oauth2`
235+
- `fastify.oauth2Github.oauth2`
236+
- `fastify.oauth2Spotify.oauth2`
237+
- `fastify.oauth2Vkontakte.oauth2`
238238

239239
Assuming we have registered multiple OAuth providers like this:
240240

@@ -263,7 +263,7 @@ fastify.googleOAuth2.getNewAccessTokenUsingRefreshToken(currentAccessToken, (err
263263

264264
```js
265265
fastify.get('/external', { /* Hooks can be used here */ }, async (req, reply) => {
266-
const authorizationEndpoint = fastify.customOAuth2.generateAuthorizationUri(req, reply);
266+
const authorizationEndpoint = fastify.oauth2CustomOAuth2.generateAuthorizationUri(req, reply);
267267
reply.redirect(authorizationEndpoint)
268268
});
269269
```
@@ -282,8 +282,8 @@ fastify.googleOAuth2.revokeAllToken(currentAccessToken, undefined, (err) => {
282282
```
283283
E.g. For `name: 'customOauth2'`, the helpers `getAccessTokenFromAuthorizationCodeFlow` and `getNewAccessTokenUsingRefreshToken` will become accessible like this:
284284

285-
- `fastify.customOauth2.getAccessTokenFromAuthorizationCodeFlow`
286-
- `fastify.customOauth2.getNewAccessTokenUsingRefreshToken`
285+
- `fastify.oauth2CustomOauth2.getAccessTokenFromAuthorizationCodeFlow`
286+
- `fastify.oauth2CustomOauth2.getNewAccessTokenUsingRefreshToken`
287287

288288
## Usage with TypeScript
289289

@@ -302,6 +302,8 @@ declare module 'fastify' {
302302
}
303303
```
304304

305+
All auth configurations are made available with an `oauth2` prefix that's typed to `OAuth2Namespace | undefined`, such as eg. `fastify.oauth2CustomOauth2` for `customOauth2`.
306+
305307
## Provider Quirks
306308

307309
The following providers require additional work to be set up correctly.

index.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -206,15 +206,18 @@ function fastifyOauth2 (fastify, options, next) {
206206
fastify.get(startRedirectPath, { schema }, startRedirectHandler)
207207
}
208208

209+
const decoration = {
210+
oauth2,
211+
getAccessTokenFromAuthorizationCodeFlow,
212+
getNewAccessTokenUsingRefreshToken,
213+
generateAuthorizationUri,
214+
revokeToken,
215+
revokeAllToken
216+
}
217+
209218
try {
210-
fastify.decorate(name, {
211-
oauth2,
212-
getAccessTokenFromAuthorizationCodeFlow,
213-
getNewAccessTokenUsingRefreshToken,
214-
generateAuthorizationUri,
215-
revokeToken,
216-
revokeAllToken
217-
})
219+
fastify.decorate(name, decoration)
220+
fastify.decorate(`oauth2${name.slice(0, 1).toUpperCase()}${name.slice(1)}`, decoration)
218221
} catch (e) {
219222
next(e)
220223
return

test/index.test.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ t.test('fastify-oauth2', t => {
8585
})
8686

8787
fastify.get('/', function (request, reply) {
88+
if (this.githubOAuth2 !== this.oauth2GithubOAuth2) {
89+
throw new Error('Expected oauth2GithubOAuth2 to match githubOAuth2')
90+
}
8891
this.githubOAuth2.getAccessTokenFromAuthorizationCodeFlow(request, (err, result) => {
8992
if (err) throw err
9093

types/index.d.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,3 +162,12 @@ declare namespace fastifyOauth2 {
162162
declare function fastifyOauth2(...params: Parameters<FastifyOauth2>): ReturnType<FastifyOauth2>
163163

164164
export = fastifyOauth2
165+
166+
type UpperCaseCharacters = 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G' | 'H' | 'I' | 'J' | 'K' | 'L' | 'M' | 'N' | 'O' | 'P' | 'Q' | 'R' | 'S' | 'T' | 'U' | 'V' | 'W' | 'X' | 'Y' | 'Z';
167+
168+
declare module 'fastify' {
169+
interface FastifyInstance {
170+
// UpperCaseCharacters ensures that the name has at least one character in it + is a simple camel-case:ification
171+
[key: `oauth2${UpperCaseCharacters}${string}`]: fastifyOauth2.OAuth2Namespace | undefined;
172+
}
173+
}

types/index.test-d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ expectAssignable<ProviderConfiguration>(fastifyOauth2.YANDEX_CONFIGURATION);
121121

122122
server.get('/testOauth/callback', async (request, reply) => {
123123
expectType<OAuth2Namespace>(server.testOAuthName);
124+
expectType<OAuth2Namespace | undefined>(server.oauth2TestOAuthName);
124125

125126
expectType<OAuth2Token>(await server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request));
126127
expectType<Promise<OAuth2Token>>(server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request));

0 commit comments

Comments
 (0)