Skip to content

Commit c1ddb73

Browse files
authored
Typescript support (#39)
* chore(): upgrade tooling * feat(): added baseline typescript definitions * chore(): upgrade to use v6 facebook API, added ts docs * chore(): reverted package upgrade
1 parent 69e4dbe commit c1ddb73

File tree

5 files changed

+115
-17
lines changed

5 files changed

+115
-17
lines changed

README.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -93,34 +93,52 @@ E.g. For `name: 'customOauth2'`, the `simple-oauth2` instance will become access
9393

9494
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**.
9595

96-
E.g.
96+
E.g.
9797

9898
- `fastify.facebook.oauth2`
9999
- `fastify.github.oauth2`
100100
- `fastify.spotify.oauth2`
101101
- `fastify.vkontakte.oauth2`
102102

103103
Assuming we have registered multiple OAuth providers like this:
104+
104105
- `fastify.register(oauthPlugin, { name: 'facebook', { ... } // facebooks credentials, startRedirectPath, callbackUri etc )`
105106
- `fastify.register(oauthPlugin, { name: 'github', { ... } // githubs credentials, startRedirectPath, callbackUri etc )`
106107
- `fastify.register(oauthPlugin, { name: 'spotify', { ... } // spotifys credentials, startRedirectPath, callbackUri etc )`
107108
- `fastify.register(oauthPlugin, { name: 'vkontakte', { ... } // vkontaktes credentials, startRedirectPath, callbackUri etc )`
108109

109-
110110
## Utilities
111111

112112
This fastify plugin adds 2 utility decorators to your fastify instance using the same **namespace**:
113113

114-
- `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:
115-
- `access_token`
116-
- `refresh_token` (optional, only if the `offline scope` was originally requested)
117-
- `token_type` (generally `'bearer'`)
118-
- `expires_in` (number of seconds for the token to expire, e.g. `240000`)
119-
- `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).
114+
- `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:
115+
- `access_token`
116+
- `refresh_token` (optional, only if the `offline scope` was originally requested)
117+
- `token_type` (generally `'bearer'`)
118+
- `expires_in` (number of seconds for the token to expire, e.g. `240000`)
119+
- `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).
120120

121121
E.g. For `name: 'customOauth2'`, both helpers `getAccessTokenFromAuthorizationCodeFlow` and `getNewAccessTokenUsingRefreshToken` will become accessible like this:
122-
- `fastify.customOauth2.getAccessTokenFromAuthorizationCodeFlow`
123-
- `fastify.customOauth2.getNewAccessTokenUsingRefreshToken`
122+
123+
- `fastify.customOauth2.getAccessTokenFromAuthorizationCodeFlow`
124+
- `fastify.customOauth2.getNewAccessTokenUsingRefreshToken`
125+
126+
## Usage with Typescript
127+
128+
Type definitions are provided with package. Decoration are applied during runtime and are based on auth configuration name. One solution is leverage typescript declaration merging to add type-safe namespace.
129+
130+
In project declarations files .d.ts
131+
132+
```ts
133+
import { OAuth2Namespace } from 'fastify-oauth2';
134+
135+
declare module 'fastify' {
136+
interface FastifyInstance {
137+
facebookOAuth2: OAuth2Namespace;
138+
myCustomOAuth2: OAuth2Namespace;
139+
}
140+
}
141+
```
124142

125143
## License
126144

examples/facebook.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ fastify.get('/login/facebook/callback', function (request, reply) {
2626
}
2727

2828
sget.concat({
29-
url: 'https://graph.facebook.com/v3.0/me',
29+
url: 'https://graph.facebook.com/v6.0/me',
3030
method: 'GET',
3131
headers: {
3232
Authorization: 'Bearer ' + result.access_token

index.d.ts

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import * as fastify from 'fastify';
2+
import * as http from 'http';
3+
4+
5+
export interface OAuth2Token{
6+
token_type: 'bearer';
7+
access_token: string;
8+
refresh_token?: string;
9+
expires_in: number
10+
}
11+
12+
export interface OAuth2Namespace{
13+
getAccessTokenFromAuthorizationCodeFlow(
14+
request: fastify.FastifyRequest<http.IncomingMessage>,
15+
): Promise<OAuth2Token>
16+
17+
getAccessTokenFromAuthorizationCodeFlow(
18+
request: fastify.FastifyRequest<http.IncomingMessage>,
19+
callback: (token: OAuth2Token) => void
20+
): void
21+
22+
getNewAccessTokenUsingRefreshToken(
23+
refreshToken: string,
24+
params: Object,
25+
callback: (token: OAuth2Token) => void
26+
): void
27+
28+
getNewAccessTokenUsingRefreshToken(
29+
refreshToken: string,
30+
params: Object,
31+
): Promise<OAuth2Token>
32+
}
33+
34+
export interface ProviderConfiguration {
35+
authorizeHost: string;
36+
authorizePath: string;
37+
tokenHost: string;
38+
tokenPath: string;
39+
}
40+
41+
export interface Credentials {
42+
client: {
43+
id: string;
44+
secret: string;
45+
};
46+
auth: ProviderConfiguration;
47+
}
48+
49+
export interface FastifyOAuth2Options {
50+
name: string;
51+
scope: string[];
52+
credentials: Credentials;
53+
callbackUri: string;
54+
callbackUriParams?: Object;
55+
generateStateFunction?: Function;
56+
checkStateFunction?: Function;
57+
startRedirectPath: string;
58+
}
59+
60+
61+
declare function fastifyOauth2(
62+
instance: fastify.FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse>,
63+
options: FastifyOAuth2Options,
64+
callback: (err?: fastify.FastifyError) => void
65+
): void;
66+
67+
68+
declare namespace fastifyOauth2 {
69+
const FACEBOOK_CONFIGURATION: ProviderConfiguration;
70+
const GITHUB_CONFIGURATION: ProviderConfiguration;
71+
const LINKEDIN_CONFIGURATION: ProviderConfiguration;
72+
const GOOGLE_CONFIGURATION: ProviderConfiguration;
73+
const MICROSOFT_CONFIGURATION: ProviderConfiguration;
74+
const SPOTIFY_CONFIGURATION: ProviderConfiguration;
75+
const VKONTAKTE_CONFIGURATION: ProviderConfiguration;
76+
}
77+
78+
export default fastifyOauth2;
79+
80+

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ const oauthPlugin = fp(function (fastify, options, next) {
129129

130130
oauthPlugin.FACEBOOK_CONFIGURATION = {
131131
authorizeHost: 'https://facebook.com',
132-
authorizePath: '/v3.0/dialog/oauth',
132+
authorizePath: '/v6.0/dialog/oauth',
133133
tokenHost: 'https://graph.facebook.com',
134-
tokenPath: '/v3.0/oauth/access_token'
134+
tokenPath: '/v6.0/oauth/access_token'
135135
}
136136

137137
oauthPlugin.GITHUB_CONFIGURATION = {

package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@
2525
"homepage": "https://github.com/fastify/fastify-oauth2#readme",
2626
"devDependencies": {
2727
"fastify": "^2.0.1",
28-
"nock": "^9.3.2",
28+
"nock": "^9.0.0",
2929
"pre-commit": "^1.2.2",
3030
"simple-get": "^3.0.2",
31-
"snazzy": "^7.1.1",
32-
"standard": "^11.0.1",
33-
"tap": "^12.0.1"
31+
"snazzy": "^8.0.0",
32+
"standard": "^14.3.3",
33+
"tap": "^12.0.0"
3434
},
3535
"dependencies": {
3636
"es6-promisify": "^6.0.0",

0 commit comments

Comments
 (0)