Skip to content

Commit

Permalink
breaking(deps): remove bluebird and promisify-any
Browse files Browse the repository at this point in the history
  • Loading branch information
jankapunkt committed Jun 9, 2023
1 parent 9fd04f6 commit 126ceff
Show file tree
Hide file tree
Showing 25 changed files with 574 additions and 1,002 deletions.
2 changes: 1 addition & 1 deletion .mocharc.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
recursive: true
reporter: "spec"
retries: 1
retries: 0
slow: 20
timeout: 2000
ui: "bdd"
Expand Down
35 changes: 14 additions & 21 deletions lib/grant-types/abstract-grant-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

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

Expand Down Expand Up @@ -36,12 +34,10 @@ function AbstractGrantType(options) {
* Generate access token.
*/

AbstractGrantType.prototype.generateAccessToken = function(client, user, scope) {
AbstractGrantType.prototype.generateAccessToken = async function(client, user, scope) {
if (this.model.generateAccessToken) {
return promisify(this.model.generateAccessToken, 3).call(this.model, client, user, scope)
.then(function(accessToken) {
return accessToken || tokenUtil.generateRandomToken();
});
const accessToken = await this.model.generateAccessToken(client, user, scope);
return accessToken || tokenUtil.generateRandomToken();
}

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

AbstractGrantType.prototype.generateRefreshToken = function(client, user, scope) {
AbstractGrantType.prototype.generateRefreshToken = async function(client, user, scope) {
if (this.model.generateRefreshToken) {
return promisify(this.model.generateRefreshToken, 3).call(this.model, client, user, scope)
.then(function(refreshToken) {
return refreshToken || tokenUtil.generateRandomToken();
});
const refreshToken = await this.model.generateRefreshToken(client, user, scope);
return refreshToken || tokenUtil.generateRandomToken();
}

return tokenUtil.generateRandomToken();
Expand Down Expand Up @@ -93,16 +87,15 @@ AbstractGrantType.prototype.getScope = function(request) {
/**
* Validate requested scope.
*/
AbstractGrantType.prototype.validateScope = function(user, client, scope) {
AbstractGrantType.prototype.validateScope = async function(user, client, scope) {
if (this.model.validateScope) {
return promisify(this.model.validateScope, 3).call(this.model, user, client, scope)
.then(function (scope) {
if (!scope) {
throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
}

return scope;
});
const validatedScope = await this.model.validateScope(user, client, scope);

if (!validatedScope) {
throw new InvalidScopeError('Invalid scope: Requested scope is invalid');
}

return validatedScope;
} else {
return scope;
}
Expand Down
203 changes: 92 additions & 111 deletions lib/grant-types/authorization-code-grant-type.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ const AbstractGrantType = require('./abstract-grant-type');
const InvalidArgumentError = require('../errors/invalid-argument-error');
const InvalidGrantError = require('../errors/invalid-grant-error');
const InvalidRequestError = require('../errors/invalid-request-error');
const Promise = require('bluebird');
const promisify = require('promisify-any').use(Promise);
const ServerError = require('../errors/server-error');
const isFormat = require('@node-oauth/formats');
const pkce = require('../pkce/pkce');
Expand Down Expand Up @@ -45,7 +43,7 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
* @see https://tools.ietf.org/html/rfc6749#section-4.1.3
*/

handle(request, client) {
async handle(request, client) {
if (!request) {
throw new InvalidArgumentError('Missing parameter: `request`');
}
Expand All @@ -54,96 +52,87 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
throw new InvalidArgumentError('Missing parameter: `client`');
}

return Promise.bind(this)
.then(function () {
return this.getAuthorizationCode(request, client);
})
.tap(function (code) {
return this.validateRedirectUri(request, code);
})
.tap(function (code) {
return this.revokeAuthorizationCode(code);
})
.then(function (code) {
return this.saveToken(code.user, client, code.authorizationCode, code.scope);
});
const code = await this.getAuthorizationCode(request, client);
await this.validateRedirectUri(request, code);
await this.revokeAuthorizationCode(code);

return this.saveToken(code.user, client, code.authorizationCode, code.scope);
}

/**
* Get the authorization code.
*/

getAuthorizationCode(request, client) {
async getAuthorizationCode(request, client) {
if (!request.body.code) {
throw new InvalidRequestError('Missing parameter: `code`');
}

if (!isFormat.vschar(request.body.code)) {
throw new InvalidRequestError('Invalid parameter: `code`');
}
return promisify(this.model.getAuthorizationCode, 1)
.call(this.model, request.body.code)
.then((code) => {
if (!code) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}

if (!code.client) {
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object');
}

if (!code.user) {
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object');
}

if (code.client.id !== client.id) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}

if (!(code.expiresAt instanceof Date)) {
throw new ServerError('Server error: `expiresAt` must be a Date instance');
}

if (code.expiresAt < new Date()) {
throw new InvalidGrantError('Invalid grant: authorization code has expired');
}

if (code.redirectUri && !isFormat.uri(code.redirectUri)) {
throw new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI');
}

// optional: PKCE code challenge

if (code.codeChallenge) {
if (!request.body.code_verifier) {
throw new InvalidGrantError('Missing parameter: `code_verifier`');
}

const hash = pkce.getHashForCodeChallenge({
method: code.codeChallengeMethod,
verifier: request.body.code_verifier
});

if (!hash) {
// notice that we assume that codeChallengeMethod is already
// checked at an earlier stage when being read from
// request.body.code_challenge_method
throw new ServerError('Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property');
}

if (code.codeChallenge !== hash) {
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
}
}
else {
if (request.body.code_verifier) {
// No code challenge but code_verifier was passed in.
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
}
}

return code;

const code = await this.model.getAuthorizationCode(request.body.code);

if (!code) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}

if (!code.client) {
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `client` object');
}

if (!code.user) {
throw new ServerError('Server error: `getAuthorizationCode()` did not return a `user` object');
}

if (code.client.id !== client.id) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}

if (!(code.expiresAt instanceof Date)) {
throw new ServerError('Server error: `expiresAt` must be a Date instance');
}

if (code.expiresAt < new Date()) {
throw new InvalidGrantError('Invalid grant: authorization code has expired');
}

if (code.redirectUri && !isFormat.uri(code.redirectUri)) {
throw new InvalidGrantError('Invalid grant: `redirect_uri` is not a valid URI');
}

// optional: PKCE code challenge

if (code.codeChallenge) {
if (!request.body.code_verifier) {
throw new InvalidGrantError('Missing parameter: `code_verifier`');
}

const hash = pkce.getHashForCodeChallenge({
method: code.codeChallengeMethod,
verifier: request.body.code_verifier
});

if (!hash) {
// notice that we assume that codeChallengeMethod is already
// checked at an earlier stage when being read from
// request.body.code_challenge_method
throw new ServerError('Server error: `getAuthorizationCode()` did not return a valid `codeChallengeMethod` property');
}

if (code.codeChallenge !== hash) {
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
}
}
else {
if (request.body.code_verifier) {
// No code challenge but code_verifier was passed in.
throw new InvalidGrantError('Invalid grant: code verifier is invalid');
}
}

return code;
}

/**
Expand Down Expand Up @@ -183,46 +172,38 @@ class AuthorizationCodeGrantType extends AbstractGrantType {
* @see https://tools.ietf.org/html/rfc6749#section-4.1.2
*/

revokeAuthorizationCode(code) {
return promisify(this.model.revokeAuthorizationCode, 1)
.call(this.model, code)
.then((status) => {
if (!status) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}
async revokeAuthorizationCode(code) {
const status = await this.model.revokeAuthorizationCode(code);

return code;
});
if (!status) {
throw new InvalidGrantError('Invalid grant: authorization code is invalid');
}

return code;
}


/**
* Save token.
*/

saveToken(user, client, authorizationCode, scope) {
const fns = [
this.validateScope(user, client, scope),
this.generateAccessToken(client, user, scope),
this.generateRefreshToken(client, user, scope),
this.getAccessTokenExpiresAt(),
this.getRefreshTokenExpiresAt(),
];

return Promise.all(fns)
.bind(this)
.spread(function (scope, accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt) {
const token = {
accessToken: accessToken,
authorizationCode: authorizationCode,
accessTokenExpiresAt: accessTokenExpiresAt,
refreshToken: refreshToken,
refreshTokenExpiresAt: refreshTokenExpiresAt,
scope: scope,
};

return promisify(this.model.saveToken, 3).call(this.model, token, client, user);
});
async saveToken(user, client, authorizationCode, scope) {
const validatedScope = await this.validateScope(user, client, scope);
const accessToken = await this.generateAccessToken(client, user, scope);
const refreshToken = await this.generateRefreshToken(client, user, scope);
const accessTokenExpiresAt = await this.getAccessTokenExpiresAt();
const refreshTokenExpiresAt = await this.getRefreshTokenExpiresAt();

const token = {
accessToken: accessToken,
authorizationCode: authorizationCode,
accessTokenExpiresAt: accessTokenExpiresAt,
refreshToken: refreshToken,
refreshTokenExpiresAt: refreshTokenExpiresAt,
scope: validatedScope,
};

return this.model.saveToken(token, client, user);
}
}

Expand Down
Loading

0 comments on commit 126ceff

Please sign in to comment.