Skip to content

Commit

Permalink
Merge branch 'master' of github.com:node-oauth/express-oauth-server
Browse files Browse the repository at this point in the history
  • Loading branch information
jankapunkt committed Jan 3, 2024
2 parents b7fbc11 + c58132f commit 1390685
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 154 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
node: [14, 16, 18]
node: [16, 18, 20]
steps:
- name: Checkout ${{ matrix.node }}
uses: actions/checkout@v3
Expand Down
263 changes: 117 additions & 146 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,173 +1,144 @@
'use strict';

/**
* Module dependencies.
*/
const NodeOAuthServer = require('@node-oauth/oauth2-server');
const { Request, Response } = require('@node-oauth/oauth2-server');
const InvalidArgumentError = require('@node-oauth/oauth2-server/lib/errors/invalid-argument-error');
const UnauthorizedRequestError = require('@node-oauth/oauth2-server/lib/errors/unauthorized-request-error');

var InvalidArgumentError = require('@node-oauth/oauth2-server/lib/errors/invalid-argument-error');
var NodeOAuthServer = require('@node-oauth/oauth2-server');
var Promise = require('bluebird');
var Request = require('@node-oauth/oauth2-server').Request;
var Response = require('@node-oauth/oauth2-server').Response;
var UnauthorizedRequestError = require('@node-oauth/oauth2-server/lib/errors/unauthorized-request-error');
class ExpressOAuthServer {
constructor(options) {
this.options = options || {};

/**
* Constructor.
*/
if (!this.options.model) {
throw new InvalidArgumentError('Missing parameter: `model`');
}
this.useErrorHandler = this.options.useErrorHandler === true;
this.continueMiddleware = this.options.continueMiddleware === true;

function ExpressOAuthServer(options) {
options = options || {};
delete this.options.useErrorHandler;
delete this.options.continueMiddleware;

if (!options.model) {
throw new InvalidArgumentError('Missing parameter: `model`');
this.server = new NodeOAuthServer(this.options);
}

this.useErrorHandler = options.useErrorHandler ? true : false;
delete options.useErrorHandler;

this.continueMiddleware = options.continueMiddleware ? true : false;
delete options.continueMiddleware;

this.server = new NodeOAuthServer(options);
}

/**
* Authentication Middleware.
*
* Returns a middleware that will validate a token.
*
* (See: https://tools.ietf.org/html/rfc6749#section-7)
*/
/**
* Authentication Middleware.
*
* Returns a middleware that will validate a token.
*
* (See: https://tools.ietf.org/html/rfc6749#section-7)
*/
authenticate(options) {
return async (req, res, next) => {
const request = new Request(req);
const response = new Response(res);
let token;
try {
token = await this.server.authenticate(request, response, options);
} catch (err) {
this._handleError(res, null, err, next);
return;
}
res.locals.oauth = { token };
return next();
}
}

ExpressOAuthServer.prototype.authenticate = function(options) {
var that = this;

return function(req, res, next) {
var request = new Request(req);
var response = new Response(res);
return Promise.bind(that)
.then(function() {
return this.server.authenticate(request, response, options);
})
.tap(function(token) {
res.locals.oauth = { token: token };
/**
* Authorization Middleware.
*
* Returns a middleware that will authorize a client to request tokens.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.1)
*/
authorize(options) {
return async (req, res, next) => {
const request = new Request(req);
const response = new Response(res);
let code;
try {
code = await this.server.authorize(request, response, options);
} catch (err) {
this._handleError(res, response, err, next);
return;
}
res.locals.oauth = { code };
if (this.continueMiddleware) {
next();
})
.catch(function(e) {
return handleError.call(this, e, req, res, null, next);
});
};
};

/**
* Authorization Middleware.
*
* Returns a middleware that will authorize a client to request tokens.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.1)
*/

ExpressOAuthServer.prototype.authorize = function(options) {
var that = this;

return function(req, res, next) {
var request = new Request(req);
var response = new Response(res);

return Promise.bind(that)
.then(function() {
return this.server.authorize(request, response, options);
})
.tap(function(code) {
res.locals.oauth = { code: code };
if (this.continueMiddleware) {
next();
}
})
.then(function() {
return handleResponse.call(this, req, res, response);
})
.catch(function(e) {
return handleError.call(this, e, req, res, response, next);
});
};
};

/**
* Grant Middleware.
*
* Returns middleware that will grant tokens to valid requests.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.2)
*/
}
return this._handleResponse(req, res, response);
}
}

ExpressOAuthServer.prototype.token = function(options) {
var that = this;

return function(req, res, next) {
var request = new Request(req);
var response = new Response(res);

return Promise.bind(that)
.then(function() {
return this.server.token(request, response, options);
})
.tap(function(token) {
res.locals.oauth = { token: token };
if (this.continueMiddleware) {
next();
}
})
.then(function() {
return handleResponse.call(this, req, res, response);
})
.catch(function(e) {
return handleError.call(this, e, req, res, response, next);
});
};
};

/**
* Handle response.
*/
var handleResponse = function(req, res, response) {

if (response.status === 302) {
var location = response.headers.location;
delete response.headers.location;
res.set(response.headers);
res.redirect(location);
} else {
res.set(response.headers);
res.status(response.status).send(response.body);
/**
* Authorization Middleware.
*
* Returns a middleware that will authorize a client to request tokens.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.1)
*/
token(options) {
return async (req, res, next) => {
const request = new Request(req);
const response = new Response(res);
let token;
try {
token = await this.server.token(request, response, options);
} catch (err) {
this._handleError(res, response, err, next);
return;
}
res.locals.oauth = { token };
if (this.continueMiddleware) {
next();
}
return this._handleResponse(req, res, response);
}
}
};

/**
* Handle error.
*/
/**
* Grant Middleware.
*
* Returns middleware that will grant tokens to valid requests.
*
* (See: https://tools.ietf.org/html/rfc6749#section-3.2)
*/
_handleResponse(req, res, oauthResponse) {
if (oauthResponse.status === 302) {
const location = oauthResponse.headers.location;
delete oauthResponse.headers.location;
res.set(oauthResponse.headers);
res.redirect(location);
return;
}
res.set(oauthResponse.headers);
res.status(oauthResponse.status).send(oauthResponse.body);
}

var handleError = function(e, req, res, response, next) {
/**
* Handles errors depending on the options of `this.useErrorHandler`.
* Either calls `next()` with the error (so the application can handle it), or returns immediately a response with the error.
*/
_handleError(res, oauthResponse, error, next) {
if (this.useErrorHandler) {
return next(error);
}

if (this.useErrorHandler === true) {
next(e);
} else {
if (response) {
res.set(response.headers);
if (oauthResponse) {
res.set(oauthResponse.headers);
}

res.status(e.code);
res.status(error.code || 500);

if (e instanceof UnauthorizedRequestError) {
if (error instanceof UnauthorizedRequestError) {
return res.send();
}

res.send({ error: e.name, error_description: e.message });
return res.send({ error: error.name, error_description: error.message });
}
};
}

/**
* Export constructor.
*/

module.exports = ExpressOAuthServer;
10 changes: 7 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "3.0.1",
"description": "OAuth provider for express",
"main": "index.js",
"typings": "index.d.ts",
"types": "index.d.ts",
"scripts": {
"lint": "npx eslint .",
"lint:fix": "npx eslint . --fix",
Expand Down Expand Up @@ -32,7 +32,6 @@
"license": "MIT",
"dependencies": {
"@node-oauth/oauth2-server": "^4.3.0",
"bluebird": "^3.7.2",
"express": "^4.18.2"
},
"devDependencies": {
Expand All @@ -45,6 +44,6 @@
"supertest": "^6.3.3"
},
"engines": {
"node": ">=0.11"
"node": ">=14.0.0"
}
}
2 changes: 1 addition & 1 deletion test/integration/index_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,7 @@ describe('ExpressOAuthServer', function() {

app.use(oauth.authorize());

request(app)
request(app.listen())
.post('/')
.expect({ error: 'invalid_argument', error_description: 'Invalid argument: model does not implement `getClient()`' })
.end(done);
Expand Down

0 comments on commit 1390685

Please sign in to comment.