Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 64da4eb

Browse files
Merge branch 'development' into dependabot/npm_and_yarn/sinon-15.2.0
2 parents 0448856 + 3d766a7 commit 64da4eb

28 files changed

+631
-1047
lines changed

‎.mocharc.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
recursive: true
22
reporter: "spec"
3-
retries: 1
3+
retries: 0
44
slow: 20
55
timeout: 2000
66
ui: "bdd"

‎CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
## Changelog
22

3+
## 5.0.0
4+
5+
- removed `bluebird` and `promisify-any`
6+
- uses native Promises and `async/await` everywhere
7+
- drop support for Node 14 (EOL), setting Node 16 as `engine` in `package.json`
8+
- this is a breaking change, because **it removes callback support** for
9+
`OAuthServer` and your model implementation.
10+
311
## 4.2.0
412
### Fixed
513
- fix(core): Bearer regular expression matching in authenticate handler #105

‎README.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,13 @@ Most users should refer to our [Express (active)](https://github.com/node-oauth/
4545

4646
More examples can be found here: https://github.com/14gasher/oauth-example
4747

48+
## Version 5 notes
49+
50+
Beginning with version `5.x` we removed dual support for callbacks and promises.
51+
With this version there is only support for Promises / async/await.
52+
53+
With this version we also bumped the `engine` to Node 16 as 14 is now deprecated.
54+
4855
## Migrating from OAuthJs and 3.x
4956

5057
Version 4.x should not be hard-breaking, however, there were many improvements and fixes that may

‎SECURITY.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
Use this section to tell people about which versions of your project are
66
currently being supported with security updates.
77

8-
| Version | Supported |
9-
| ------- | ------------------ |
10-
| 4.x.x | :white_check_mark: |
11-
| 3.x.x | :white_check_mark: but only very critical security issues |
12-
| < 3 | :x: |
8+
| Version | Supported |
9+
|---------|--------------------------------------------------|
10+
| 5.x.x | :white_check_mark: |
11+
| 4.x.x | :white_check_mark: but only high severity issues |
12+
| 3.x.x | :x: |
13+
| < 3 | :x: |
1314

1415
## Reporting a Vulnerability
1516

‎lib/grant-types/abstract-grant-type.js‎

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66

77
const InvalidArgumentError = require('../errors/invalid-argument-error');
88
const InvalidScopeError = require('../errors/invalid-scope-error');
9-
const Promise = require('bluebird');
10-
const promisify = require('promisify-any').use(Promise);
119
const isFormat = require('@node-oauth/formats');
1210
const tokenUtil = require('../utils/token-util');
1311

@@ -36,12 +34,10 @@ function AbstractGrantType(options) {
3634
* Generate access token.
3735
*/
3836

39-
AbstractGrantType.prototype.generateAccessToken = function(client, user, scope) {
37+
AbstractGrantType.prototype.generateAccessToken = asyncfunction(client, user, scope) {
4038
if (this.model.generateAccessToken) {
41-
return promisify(this.model.generateAccessToken, 3).call(this.model, client, user, scope)
42-
.then(function(accessToken) {
43-
return accessToken || tokenUtil.generateRandomToken();
44-
});
39+
const accessToken = await this.model.generateAccessToken(client, user, scope);
40+
return accessToken || tokenUtil.generateRandomToken();
4541
}
4642

4743
return tokenUtil.generateRandomToken();
@@ -51,12 +47,10 @@ AbstractGrantType.prototype.generateAccessToken = function(client, user, scope)
5147
* Generate refresh token.
5248
*/
5349

54-
AbstractGrantType.prototype.generateRefreshToken = function(client, user, scope) {
50+
AbstractGrantType.prototype.generateRefreshToken = asyncfunction(client, user, scope) {
5551
if (this.model.generateRefreshToken) {
56-
return promisify(this.model.generateRefreshToken, 3).call(this.model, client, user, scope)
57-
.then(function(refreshToken) {
58-
return refreshToken || tokenUtil.generateRandomToken();
59-
});
52+
const refreshToken = await this.model.generateRefreshToken(client, user, scope);
53+
return refreshToken || tokenUtil.generateRandomToken();
6054
}
6155

6256
return tokenUtil.generateRandomToken();
@@ -93,16 +87,15 @@ AbstractGrantType.prototype.getScope = function(request) {
9387
/**
9488
* Validate requested scope.
9589
*/
96-
AbstractGrantType.prototype.validateScope = function(user, client, scope) {
90+
AbstractGrantType.prototype.validateScope = asyncfunction(user, client, scope) {
9791
if (this.model.validateScope) {
98-
return promisify(this.model.validateScope, 3).call(this.model, user, client, scope)
99-
.then(function (scope) {
100-
if (!scope) {
101-
throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
102-
}
103-
104-
return scope;
105-
});
92+
const validatedScope = await this.model.validateScope(user, client, scope);
93+
94+
if (!validatedScope) {
95+
throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
96+
}
97+
98+
return validatedScope;
10699
} else {
107100
return scope;
108101
}

‎lib/grant-types/authorization-code-grant-type.js‎

Lines changed: 92 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ const AbstractGrantType = require('./abstract-grant-type');
88
const InvalidArgumentError = require('../errors/invalid-argument-error');
99
const InvalidGrantError = require('../errors/invalid-grant-error');
1010
const InvalidRequestError = require('../errors/invalid-request-error');
11-
const Promise = require('bluebird');
12-
const promisify = require('promisify-any').use(Promise);
1311
const ServerError = require('../errors/server-error');
1412
const isFormat = require('@node-oauth/formats');
1513
const pkce = require('../pkce/pkce');
@@ -45,7 +43,7 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
4543
* @see https://tools.ietf.org/html/rfc6749#section-4.1.3
4644
*/
4745

48-
handle(request, client) {
46+
asynchandle(request, client) {
4947
if (!request) {
5048
throw new InvalidArgumentError('Missing parameter: `request`');
5149
}
@@ -54,96 +52,87 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
5452
throw new InvalidArgumentError('Missing parameter: `client`');
5553
}
5654

57-
return Promise.bind(this)
58-
.then(function () {
59-
return this.getAuthorizationCode(request, client);
60-
})
61-
.tap(function (code) {
62-
return this.validateRedirectUri(request, code);
63-
})
64-
.tap(function (code) {
65-
return this.revokeAuthorizationCode(code);
66-
})
67-
.then(function (code) {
68-
return this.saveToken(code.user, client, code.authorizationCode, code.scope);
69-
});
55+
const code = await this.getAuthorizationCode(request, client);
56+
await this.validateRedirectUri(request, code);
57+
await this.revokeAuthorizationCode(code);
58+
59+
return this.saveToken(code.user, client, code.authorizationCode, code.scope);
7060
}
7161

7262
/**
7363
* Get the authorization code.
7464
*/
7565

76-
getAuthorizationCode(request, client) {
66+
asyncgetAuthorizationCode(request, client) {
7767
if (!request.body.code) {
7868
throw new InvalidRequestError('Missing parameter: `code`');
7969
}
8070

8171
if (!isFormat.vschar(request.body.code)) {
8272
throw new InvalidRequestError('Invalid parameter: `code`');
8373
}
84-
return promisify(this.model.getAuthorizationCode, 1)
85-
.call(this.model, request.body.code)
86-
.then((code) => {
87-
if (!code) {
88-
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
89-
}
90-
91-
if (!code.client) {
92-
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object');
93-
}
94-
95-
if (!code.user) {
96-
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object');
97-
}
98-
99-
if (code.client.id !== client.id) {
100-
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
101-
}
102-
103-
if (!(code.expiresAt instanceof Date)) {
104-
throw new ServerError('Server error: `expiresAt` must be a Date instance');
105-
}
106-
107-
if (code.expiresAt < new Date()) {
108-
throw new InvalidGrantError('Invalid grant: authorization code has expired');
109-
}
110-
111-
if (code.redirectUri && !isFormat.uri(code.redirectUri)) {
112-
throw new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI');
113-
}
114-
115-
// optional: PKCE code challenge
116-
117-
if (code.codeChallenge) {
118-
if (!request.body.code_verifier) {
119-
throw new InvalidGrantError('Missing parameter: `code_verifier`');
120-
}
121-
122-
const hash = pkce.getHashForCodeChallenge({
123-
method: code.codeChallengeMethod,
124-
verifier: request.body.code_verifier
125-
});
126-
127-
if (!hash) {
128-
// notice that we assume that codeChallengeMethod is already
129-
// checked at an earlier stage when being read from
130-
// request.body.code_challenge_method
131-
throw new ServerError('Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property');
132-
}
133-
134-
if (code.codeChallenge !== hash) {
135-
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
136-
}
137-
}
138-
else {
139-
if (request.body.code_verifier) {
140-
// No code challenge but code_verifier was passed in.
141-
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
142-
}
143-
}
144-
145-
return code;
74+
75+
const code = await this.model.getAuthorizationCode(request.body.code);
76+
77+
if (!code) {
78+
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
79+
}
80+
81+
if (!code.client) {
82+
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object');
83+
}
84+
85+
if (!code.user) {
86+
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object');
87+
}
88+
89+
if (code.client.id !== client.id) {
90+
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
91+
}
92+
93+
if (!(code.expiresAt instanceof Date)) {
94+
throw new ServerError('Server error: `expiresAt` must be a Date instance');
95+
}
96+
97+
if (code.expiresAt < new Date()) {
98+
throw new InvalidGrantError('Invalid grant: authorization code has expired');
99+
}
100+
101+
if (code.redirectUri && !isFormat.uri(code.redirectUri)) {
102+
throw new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI');
103+
}
104+
105+
// optional: PKCE code challenge
106+
107+
if (code.codeChallenge) {
108+
if (!request.body.code_verifier) {
109+
throw new InvalidGrantError('Missing parameter: `code_verifier`');
110+
}
111+
112+
const hash = pkce.getHashForCodeChallenge({
113+
method: code.codeChallengeMethod,
114+
verifier: request.body.code_verifier
146115
});
116+
117+
if (!hash) {
118+
// notice that we assume that codeChallengeMethod is already
119+
// checked at an earlier stage when being read from
120+
// request.body.code_challenge_method
121+
throw new ServerError('Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property');
122+
}
123+
124+
if (code.codeChallenge !== hash) {
125+
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
126+
}
127+
}
128+
else {
129+
if (request.body.code_verifier) {
130+
// No code challenge but code_verifier was passed in.
131+
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
132+
}
133+
}
134+
135+
return code;
147136
}
148137

149138
/**
@@ -183,46 +172,38 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
183172
* @see https://tools.ietf.org/html/rfc6749#section-4.1.2
184173
*/
185174

186-
revokeAuthorizationCode(code) {
187-
return promisify(this.model.revokeAuthorizationCode, 1)
188-
.call(this.model, code)
189-
.then((status) => {
190-
if (!status) {
191-
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
192-
}
175+
async revokeAuthorizationCode(code) {
176+
const status = await this.model.revokeAuthorizationCode(code);
193177

194-
return code;
195-
});
178+
if (!status) {
179+
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
180+
}
181+
182+
return code;
196183
}
197184

198185

199186
/**
200187
* Save token.
201188
*/
202189

203-
saveToken(user, client, authorizationCode, scope) {
204-
const fns = [
205-
this.validateScope(user, client, scope),
206-
this.generateAccessToken(client, user, scope),
207-
this.generateRefreshToken(client, user, scope),
208-
this.getAccessTokenExpiresAt(),
209-
this.getRefreshTokenExpiresAt(),
210-
];
211-
212-
return Promise.all(fns)
213-
.bind(this)
214-
.spread(function (scope, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
215-
const token = {
216-
accessToken: accessToken,
217-
authorizationCode: authorizationCode,
218-
accessTokenExpiresAt: accessTokenExpiresAt,
219-
refreshToken: refreshToken,
220-
refreshTokenExpiresAt: refreshTokenExpiresAt,
221-
scope: scope,
222-
};
223-
224-
return promisify(this.model.saveToken, 3).call(this.model, token, client, user);
225-
});
190+
async saveToken(user, client, authorizationCode, scope) {
191+
const validatedScope = await this.validateScope(user, client, scope);
192+
const accessToken = await this.generateAccessToken(client, user, scope);
193+
const refreshToken = await this.generateRefreshToken(client, user, scope);
194+
const accessTokenExpiresAt = await this.getAccessTokenExpiresAt();
195+
const refreshTokenExpiresAt = await this.getRefreshTokenExpiresAt();
196+
197+
const token = {
198+
accessToken: accessToken,
199+
authorizationCode: authorizationCode,
200+
accessTokenExpiresAt: accessTokenExpiresAt,
201+
refreshToken: refreshToken,
202+
refreshTokenExpiresAt: refreshTokenExpiresAt,
203+
scope: validatedScope,
204+
};
205+
206+
return this.model.saveToken(token, client, user);
226207
}
227208
}
228209

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /