Skip to content

Commit ab9d39b

Browse files
authored
Merge pull request #43 from mfpopa/master
Fix #42
2 parents 12c032e + f46a9c5 commit ab9d39b

File tree

3 files changed

+162
-65
lines changed

3 files changed

+162
-65
lines changed

index.d.ts

Lines changed: 55 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,12 @@
11
import * as fastify from 'fastify';
22
import * as http from 'http';
33

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-
614
declare function fastifyOauth2(
625
instance: fastify.FastifyInstance<http.Server, http.IncomingMessage, http.ServerResponse>,
63-
options: FastifyOAuth2Options,
64-
callback: (err?: fastify.FastifyError) => void
6+
options: fastifyOauth2.FastifyOAuth2Options,
7+
callback: (err?: fastify.FastifyError) => void,
658
): void;
669

67-
6810
declare namespace fastifyOauth2 {
6911
const FACEBOOK_CONFIGURATION: ProviderConfiguration;
7012
const GITHUB_CONFIGURATION: ProviderConfiguration;
@@ -73,8 +15,58 @@ declare namespace fastifyOauth2 {
7315
const MICROSOFT_CONFIGURATION: ProviderConfiguration;
7416
const SPOTIFY_CONFIGURATION: ProviderConfiguration;
7517
const VKONTAKTE_CONFIGURATION: ProviderConfiguration;
76-
}
77-
78-
export default fastifyOauth2;
7918

19+
interface OAuth2Token {
20+
token_type: 'bearer';
21+
access_token: string;
22+
refresh_token?: string;
23+
expires_in: number;
24+
}
25+
26+
interface OAuth2Namespace {
27+
getAccessTokenFromAuthorizationCodeFlow(
28+
request: fastify.FastifyRequest<http.IncomingMessage>,
29+
): Promise<OAuth2Token>;
30+
31+
getAccessTokenFromAuthorizationCodeFlow(
32+
request: fastify.FastifyRequest<http.IncomingMessage>,
33+
callback: (token: OAuth2Token) => void,
34+
): void;
35+
36+
getNewAccessTokenUsingRefreshToken(
37+
refreshToken: string,
38+
params: Object,
39+
callback: (token: OAuth2Token) => void,
40+
): void;
41+
42+
getNewAccessTokenUsingRefreshToken(refreshToken: string, params: Object): Promise<OAuth2Token>;
43+
}
44+
45+
interface ProviderConfiguration {
46+
authorizeHost: string;
47+
authorizePath: string;
48+
tokenHost: string;
49+
tokenPath: string;
50+
}
51+
52+
interface Credentials {
53+
client: {
54+
id: string;
55+
secret: string;
56+
};
57+
auth: ProviderConfiguration;
58+
}
59+
60+
interface FastifyOAuth2Options {
61+
name: string;
62+
scope: string[];
63+
credentials: Credentials;
64+
callbackUri: string;
65+
callbackUriParams?: Object;
66+
generateStateFunction?: Function;
67+
checkStateFunction?: Function;
68+
startRedirectPath: string;
69+
}
70+
}
8071

72+
export = fastifyOauth2;

index.test-d.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import * as fastify from 'fastify';
2+
import * as fastifyOauth2 from '.';
3+
import { expectType, expectError, expectAssignable } from 'tsd';
4+
5+
/**
6+
* Preparing some data for testing.
7+
*/
8+
const auth = fastifyOauth2.GOOGLE_CONFIGURATION;
9+
const scope = ['r_emailaddress', 'r_basicprofile'];
10+
const credentials = {
11+
client: {
12+
id: 'test_id',
13+
secret: 'test_secret',
14+
},
15+
auth: auth,
16+
};
17+
const OAuth2Options = {
18+
name: 'testOAuthName',
19+
scope: scope,
20+
credentials: credentials,
21+
callbackUri: 'http://localhost/testOauth/callback',
22+
callbackUriParams: {},
23+
generateStateFunction: () => {},
24+
checkStateFunction: () => {},
25+
startRedirectPath: '/login/testOauth',
26+
};
27+
28+
const server = fastify();
29+
30+
server.register(fastifyOauth2, OAuth2Options);
31+
32+
declare module 'fastify' {
33+
// Developers need to define this in their code like they have to do with all decorators.
34+
interface FastifyInstance {
35+
testOAuthName: fastifyOauth2.OAuth2Namespace;
36+
}
37+
}
38+
39+
/**
40+
* Actual testing.
41+
*/
42+
expectType<fastifyOauth2.ProviderConfiguration>(auth);
43+
expectType<string[]>(scope);
44+
expectType<fastifyOauth2.Credentials>(credentials);
45+
46+
expectType<void>(fastifyOauth2(server, OAuth2Options, () => {}));
47+
expectError(fastifyOauth2()); // error because missing required arguments
48+
expectError(fastifyOauth2(server, {}, () => {})); // error because missing required options
49+
50+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.FACEBOOK_CONFIGURATION);
51+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.GITHUB_CONFIGURATION);
52+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.GOOGLE_CONFIGURATION);
53+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.LINKEDIN_CONFIGURATION);
54+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.MICROSOFT_CONFIGURATION);
55+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.SPOTIFY_CONFIGURATION);
56+
expectAssignable<fastifyOauth2.ProviderConfiguration>(fastifyOauth2.VKONTAKTE_CONFIGURATION);
57+
58+
server.get('/testOauth/callback', async request => {
59+
expectType<fastifyOauth2.OAuth2Namespace>(server.testOAuthName);
60+
61+
expectType<fastifyOauth2.OAuth2Token>(await server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request));
62+
expectType<Promise<fastifyOauth2.OAuth2Token>>(server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request));
63+
expectType<void>(
64+
server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request, (t: fastifyOauth2.OAuth2Token): void => {}),
65+
);
66+
67+
expectError<void>(await server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request)); // error because Promise should not return void
68+
expectError<fastifyOauth2.OAuth2Token>(
69+
server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request, (t: fastifyOauth2.OAuth2Token): void => {}),
70+
); // error because non-Promise function call should return void and have a callback argument
71+
expectError<void>(server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request)); // error because function call does not pass a callback as second argument.
72+
73+
const token = await server.testOAuthName.getAccessTokenFromAuthorizationCodeFlow(request);
74+
if (token.refresh_token) {
75+
expectType<fastifyOauth2.OAuth2Token>(
76+
await server.testOAuthName.getNewAccessTokenUsingRefreshToken(token.refresh_token, {}),
77+
);
78+
expectType<Promise<fastifyOauth2.OAuth2Token>>(
79+
server.testOAuthName.getNewAccessTokenUsingRefreshToken(token.refresh_token, {}),
80+
);
81+
expectType<void>(
82+
server.testOAuthName.getNewAccessTokenUsingRefreshToken(
83+
token.refresh_token,
84+
{},
85+
(t: fastifyOauth2.OAuth2Token): void => {},
86+
),
87+
);
88+
89+
expectError<void>(await server.testOAuthName.getNewAccessTokenUsingRefreshToken(token.refresh_token, {})); // error because Promise should not return void
90+
expectError<fastifyOauth2.OAuth2Token>(
91+
server.testOAuthName.getNewAccessTokenUsingRefreshToken(
92+
token.refresh_token,
93+
{},
94+
(t: fastifyOauth2.OAuth2Token): void => {},
95+
),
96+
); // error because non-Promise function call should return void and have a callback argument
97+
expectError<void>(server.testOAuthName.getNewAccessTokenUsingRefreshToken(token.refresh_token, {})); // error because function call does not pass a callback as second argument.
98+
}
99+
100+
return {
101+
access_token: token.access_token,
102+
};
103+
});

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@
66
"scripts": {
77
"lint": "standard | snazzy",
88
"unit": "tap test.js",
9-
"test": "npm run lint && npm run unit",
9+
"test": "npm run lint && npm run unit && npm run test:typescript",
10+
"test:typescript": "tsd",
1011
"coverage": "npm run unit -- --cov --coverage-report=html"
1112
},
1213
"repository": {
@@ -30,7 +31,8 @@
3031
"simple-get": "^3.0.2",
3132
"snazzy": "^8.0.0",
3233
"standard": "^14.3.3",
33-
"tap": "^12.0.0"
34+
"tap": "^12.0.0",
35+
"tsd": "^0.11.0"
3436
},
3537
"dependencies": {
3638
"es6-promisify": "^6.0.0",

0 commit comments

Comments
 (0)