Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

oauth2orize

Package Overview
Dependencies
Maintainers
1
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

oauth2orize - npm Package Compare versions

Comparing version 0.1.0 to 1.0.0

.jshintrc

12

lib/errors/authorizationerror.js

@@ -9,5 +9,7 @@ /**

switch (code) {
case 'invalid_client': status = 401; break;
case 'invalid_request': status = 400; break;
case 'unauthorized_client': status = 403; break;
case 'access_denied': status = 403; break;
case 'server_error': status = 500; break;
case 'unsupported_response_type': status = 501; break;
case 'invalid_scope': status = 400; break;
case 'temporarily_unavailable': status = 503; break;

@@ -20,7 +22,7 @@ }

this.name = 'AuthorizationError';
this.message = message || null;
this.message = message;
this.code = code || 'server_error';
this.uri = uri;
this.status = status || 400;
};
this.status = status || 500;
}

@@ -27,0 +29,0 @@ /**

@@ -10,4 +10,5 @@ /**

this.name = 'BadRequestError';
this.message = message || null;
};
this.message = message;
this.status = 400;
}

@@ -14,0 +15,0 @@ /**

@@ -5,3 +5,3 @@ /**

var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
, TokenError = require('../errors/tokenerror');

@@ -59,10 +59,10 @@

*/
module.exports = function authorizationCode(options, issue) {
module.exports = function(options, issue) {
if (typeof options == 'function') {
issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 authorizationCode exchange middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.authorizationCode exchange requires an issue callback'); }

@@ -72,3 +72,3 @@ var userProperty = options.userProperty || 'user';

return function authorization_code(req, res, next) {
if (!req.body) { return next(new Error('Request body not parsed. Use bodyParser middleware.')); }
if (!req.body) { return next(new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?')); }

@@ -78,24 +78,32 @@ // The 'user' property of `req` holds the authenticated user. In the case

var client = req[userProperty]
, code = req.body['code']
, redirectURI = req.body['redirect_uri'];
, code = req.body.code
, redirectURI = req.body.redirect_uri;
if (!code) { return next(new AuthorizationError('missing code parameter', 'invalid_request')); }
if (!code) { return next(new TokenError('Missing required parameter: code', 'invalid_request')); }
issue(client, code, redirectURI, function(err, accessToken, refreshToken, params) {
if (err) { return next(err); }
if (!accessToken) { return next(new AuthorizationError('invalid code', 'invalid_grant')); }
try {
issue(client, code, redirectURI, function(err, accessToken, refreshToken, params) {
if (err) { return next(err); }
if (!accessToken) { return next(new TokenError('Invalid authorization code', 'invalid_grant')); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
var tok = {};
tok['access_token'] = accessToken;
if (refreshToken) { tok['refresh_token'] = refreshToken; }
if (params) { utils.merge(tok, params); }
tok['token_type'] = tok['token_type'] || 'bearer';
var tok = {};
tok.access_token = accessToken;
if (refreshToken) { tok.refresh_token = refreshToken; }
if (params) { utils.merge(tok, params); }
tok.token_type = tok.token_type || 'Bearer';
var json = JSON.stringify(tok);
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
res.end(json);
});
}
}
var json = JSON.stringify(tok);
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
res.end(json);
});
} catch (ex) {
return next(ex);
}
};
};

@@ -5,3 +5,3 @@ /**

var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
, TokenError = require('../errors/tokenerror');

@@ -26,9 +26,10 @@

*
* done(err, accessToken, refreshToken, params)
* done(err, accessToken, [refreshToken], [params])
*
* `accessToken` is the access token that will be sent to the client. An
* optional `refreshToken` will be sent to the client, if the server chooses to
* implement support for this functionality. Any additional `params` will be
* included in the response. If an error occurs, `done` should be invoked with
* `err` set in idomatic Node.js fashion.
* implement support for this functionality (note that the spec says a refresh
* token should not be included). Any additional `params` will be included in
* the response. If an error occurs, `done` should be invoked with `err` set in
* idomatic Node.js fashion.
*

@@ -58,10 +59,10 @@ * Options:

*/
module.exports = function clientCredentials(options, issue) {
module.exports = function(options, issue) {
if (typeof options == 'function') {
issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 clientCredentials exchange middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.clientCredentials exchange requires an issue callback'); }

@@ -81,3 +82,3 @@ var userProperty = options.userProperty || 'user';

return function client_credentials(req, res, next) {
if (!req.body) { return next(new Error('Request body not parsed. Use bodyParser middleware.')); }
if (!req.body) { return next(new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?')); }

@@ -87,3 +88,3 @@ // The 'user' property of `req` holds the authenticated user. In the case

var client = req[userProperty]
, scope = req.body['scope'];
, scope = req.body.scope;

@@ -105,9 +106,13 @@ if (scope) {

if (err) { return next(err); }
if (!accessToken) { return next(new AuthorizationError('invalid client credentials', 'invalid_grant')); }
if (!accessToken) { return next(new TokenError('Invalid client credentials', 'invalid_grant')); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
var tok = {};
tok['access_token'] = accessToken;
if (refreshToken) { tok['refresh_token'] = refreshToken; }
tok.access_token = accessToken;
if (refreshToken) { tok.refresh_token = refreshToken; }
if (params) { utils.merge(tok, params); }
tok['token_type'] = tok['token_type'] || 'bearer';
tok.token_type = tok.token_type || 'Bearer';

@@ -121,9 +126,13 @@ var json = JSON.stringify(tok);

var arity = issue.length;
if (arity == 3) {
issue(client, scope, issued);
} else { // arity == 2
issue(client, issued);
try {
var arity = issue.length;
if (arity == 3) {
issue(client, scope, issued);
} else { // arity == 2
issue(client, issued);
}
} catch (ex) {
return next(ex);
}
}
}
};
};

@@ -5,3 +5,3 @@ /**

var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
, TokenError = require('../errors/tokenerror');

@@ -59,10 +59,10 @@

*/
module.exports = function password(options, issue) {
module.exports = function(options, issue) {
if (typeof options == 'function') {
issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 password exchange middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.password exchange requires an issue callback'); }

@@ -82,3 +82,3 @@ var userProperty = options.userProperty || 'user';

return function password(req, res, next) {
if (!req.body) { return next(new Error('Request body not parsed. Use bodyParser middleware.')); }
if (!req.body) { return next(new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?')); }

@@ -88,8 +88,8 @@ // The 'user' property of `req` holds the authenticated user. In the case

var client = req[userProperty]
, username = req.body['username']
, password = req.body['password']
, scope = req.body['scope'];
, username = req.body.username
, passwd = req.body.password
, scope = req.body.scope;
if (!username) { return next(new AuthorizationError('missing username parameter', 'invalid_request')); }
if (!password) { return next(new AuthorizationError('missing password parameter', 'invalid_request')); }
if (!username) { return next(new TokenError('Missing required parameter: username', 'invalid_request')); }
if (!passwd) { return next(new TokenError('Missing required parameter: password', 'invalid_request')); }

@@ -111,9 +111,13 @@ if (scope) {

if (err) { return next(err); }
if (!accessToken) { return next(new AuthorizationError('invalid resource owner credentials', 'invalid_grant')); }
if (!accessToken) { return next(new TokenError('Invalid resource owner credentials', 'invalid_grant')); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
var tok = {};
tok['access_token'] = accessToken;
if (refreshToken) { tok['refresh_token'] = refreshToken; }
tok.access_token = accessToken;
if (refreshToken) { tok.refresh_token = refreshToken; }
if (params) { utils.merge(tok, params); }
tok['token_type'] = tok['token_type'] || 'bearer';
tok.token_type = tok.token_type || 'Bearer';

@@ -127,9 +131,13 @@ var json = JSON.stringify(tok);

var arity = issue.length;
if (arity == 5) {
issue(client, username, password, scope, issued);
} else { // arity == 4
issue(client, username, password, issued);
try {
var arity = issue.length;
if (arity == 5) {
issue(client, username, passwd, scope, issued);
} else { // arity == 4
issue(client, username, passwd, issued);
}
} catch (ex) {
return next(ex);
}
}
}
};
};

@@ -5,3 +5,3 @@ /**

var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
, TokenError = require('../errors/tokenerror');

@@ -56,10 +56,10 @@

*/
module.exports = function refreshToken(options, issue) {
module.exports = function(options, issue) {
if (typeof options == 'function') {
issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 refreshToken exchange middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.refreshToken exchange requires an issue callback'); }

@@ -79,3 +79,3 @@ var userProperty = options.userProperty || 'user';

return function refresh_token(req, res, next) {
if (!req.body) { return next(new Error('Request body not parsed. Use bodyParser middleware.')); }
if (!req.body) { return next(new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?')); }

@@ -85,6 +85,6 @@ // The 'user' property of `req` holds the authenticated user. In the case

var client = req[userProperty]
, refreshToken = req.body['refresh_token']
, scope = req.body['scope'];
, refreshToken = req.body.refresh_token
, scope = req.body.scope;
if (!refreshToken) { return next(new AuthorizationError('missing refresh_token parameter', 'invalid_request')); }
if (!refreshToken) { return next(new TokenError('Missing required parameter: refresh_token', 'invalid_request')); }

@@ -106,9 +106,13 @@ if (scope) {

if (err) { return next(err); }
if (!accessToken) { return next(new AuthorizationError('invalid refresh token', 'invalid_grant')); }
if (!accessToken) { return next(new TokenError('Invalid refresh token', 'invalid_grant')); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
var tok = {};
tok['access_token'] = accessToken;
if (refreshToken) { tok['refresh_token'] = refreshToken; }
tok.access_token = accessToken;
if (refreshToken) { tok.refresh_token = refreshToken; }
if (params) { utils.merge(tok, params); }
tok['token_type'] = tok['token_type'] || 'bearer';
tok.token_type = tok.token_type || 'Bearer';

@@ -122,9 +126,13 @@ var json = JSON.stringify(tok);

var arity = issue.length;
if (arity == 4) {
issue(client, refreshToken, scope, issued);
} else { // arity == 3
issue(client, refreshToken, issued);
try {
var arity = issue.length;
if (arity == 4) {
issue(client, refreshToken, scope, issued);
} else { // arity == 3
issue(client, refreshToken, issued);
}
} catch (ex) {
return next(ex);
}
}
}
};
};

@@ -61,7 +61,7 @@ /**

issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 code grant middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.code grant requires an issue callback'); }

@@ -85,8 +85,8 @@ // For maximum flexibility, multiple scope spearators can optionally be

function request(req) {
var clientID = req.query['client_id']
, redirectURI = req.query['redirect_uri']
, scope = req.query['scope']
, state = req.query['state'];
var clientID = req.query.client_id
, redirectURI = req.query.redirect_uri
, scope = req.query.scope
, state = req.query.state;
if (!clientID) { throw new AuthorizationError('missing client_id parameter', 'invalid_request'); }
if (!clientID) { throw new AuthorizationError('Missing required parameter: client_id', 'invalid_request'); }

@@ -112,3 +112,3 @@ if (scope) {

state: state
}
};
}

@@ -124,8 +124,8 @@

function response(txn, res, next) {
if (!txn.redirectURI) { return next(new Error('No redirect URI available to send OAuth 2.0 response.')); }
if (!txn.redirectURI) { return next(new Error('Unable to issue redirect for OAuth 2.0 transaction')); }
if (!txn.res.allow) {
var parsed = url.parse(txn.redirectURI, true);
delete parsed.search;
parsed.query['error'] = 'access_denied';
if (txn.req && txn.req.state) { parsed.query['state'] = txn.req.state; }
parsed.query.error = 'access_denied';
if (txn.req && txn.req.state) { parsed.query.state = txn.req.state; }

@@ -138,8 +138,8 @@ var location = url.format(parsed);

if (err) { return next(err); }
if (!code) { return next(new AuthorizationError('authorization server denied request', 'access_denied')); }
if (!code) { return next(new AuthorizationError('Request denied by authorization server', 'access_denied')); }
var parsed = url.parse(txn.redirectURI, true);
delete parsed.search;
parsed.query['code'] = code;
if (txn.req && txn.req.state) { parsed.query['state'] = txn.req.state; }
parsed.query.code = code;
if (txn.req && txn.req.state) { parsed.query.state = txn.req.state; }

@@ -158,7 +158,11 @@ var location = url.format(parsed);

var arity = issue.length;
if (arity == 5) {
issue(txn.client, txn.req.redirectURI, txn.user, txn.res, issued);
} else { // arity == 4
issue(txn.client, txn.req.redirectURI, txn.user, issued);
try {
var arity = issue.length;
if (arity == 5) {
issue(txn.client, txn.req.redirectURI, txn.user, txn.res, issued);
} else { // arity == 4
issue(txn.client, txn.req.redirectURI, txn.user, issued);
}
} catch (ex) {
return next(ex);
}

@@ -176,2 +180,2 @@ }

return mod;
}
};

@@ -61,7 +61,7 @@ /**

issue = options;
options = null;
options = undefined;
}
options = options || {};
if (!issue) throw new Error('OAuth 2.0 token grant middleware requires an issue function.');
if (!issue) { throw new TypeError('oauth2orize.token grant requires an issue callback'); }

@@ -85,8 +85,8 @@ // For maximum flexibility, multiple scope spearators can optionally be

function request(req) {
var clientID = req.query['client_id']
, redirectURI = req.query['redirect_uri']
, scope = req.query['scope']
, state = req.query['state'];
var clientID = req.query.client_id
, redirectURI = req.query.redirect_uri
, scope = req.query.scope
, state = req.query.state;
if (!clientID) { throw new AuthorizationError('missing client_id parameter', 'invalid_request'); }
if (!clientID) { throw new AuthorizationError('Missing required parameter: client_id', 'invalid_request'); }

@@ -112,3 +112,3 @@ if (scope) {

state: state
}
};
}

@@ -124,7 +124,7 @@

function response(txn, res, next) {
if (!txn.redirectURI) { return next(new Error('No redirect URI available to send OAuth 2.0 response.')); }
if (!txn.redirectURI) { return next(new Error('Unable to issue redirect for OAuth 2.0 transaction')); }
if (!txn.res.allow) {
var err = {};
err['error'] = 'access_denied';
if (txn.req && txn.req.state) { err['state'] = txn.req.state; }
err.error = 'access_denied';
if (txn.req && txn.req.state) { err.state = txn.req.state; }

@@ -140,9 +140,9 @@ var parsed = url.parse(txn.redirectURI);

if (err) { return next(err); }
if (!accessToken) { return next(new AuthorizationError('authorization server denied request', 'access_denied')); }
if (!accessToken) { return next(new AuthorizationError('Request denied by authorization server', 'access_denied')); }
var tok = {};
tok['access_token'] = accessToken;
tok.access_token = accessToken;
if (params) { utils.merge(tok, params); }
tok['token_type'] = tok['token_type'] || 'bearer';
if (txn.req && txn.req.state) { tok['state'] = txn.req.state; }
tok.token_type = tok.token_type || 'Bearer';
if (txn.req && txn.req.state) { tok.state = txn.req.state; }

@@ -163,7 +163,11 @@ var parsed = url.parse(txn.redirectURI);

var arity = issue.length;
if (arity == 4) {
issue(txn.client, txn.user, txn.res, issued);
} else { // arity == 3
issue(txn.client, txn.user, issued);
try {
var arity = issue.length;
if (arity == 4) {
issue(txn.client, txn.user, txn.res, issued);
} else { // arity == 3
issue(txn.client, txn.user, issued);
}
} catch (ex) {
return next(ex);
}

@@ -181,2 +185,2 @@ }

return mod;
}
};

@@ -9,5 +9,2 @@ /**

// expose createServer() as the module
exports = module.exports = createServer;
/**

@@ -24,4 +21,7 @@ * Create an OAuth 2.0 server.

// expose createServer() as the module
exports = module.exports = createServer;
/**
* Expose `.createServer()` as module method.
* Export `.createServer()`.
*/

@@ -32,4 +32,9 @@ exports.createServer = createServer;

/**
* Auto-load bundled grant middleware.
* Export middleware.
*/
exports.errorHandler = require('./middleware/errorHandler');
/**
* Auto-load bundled grants.
*/
exports.grant = {};

@@ -45,2 +50,3 @@

// alias grants
exports.grant.authorizationCode = exports.grant.code;

@@ -50,3 +56,3 @@ exports.grant.implicit = exports.grant.token;

/**
* Auto-load bundled exchange middleware.
* Auto-load bundled exchanges.
*/

@@ -63,2 +69,9 @@ exports.exchange = {};

// alias exchanges
exports.exchange.code = exports.exchange.authorizationCode;
/**
* Export errors.
*/
exports.AuthorizationError = require('./errors/authorizationerror');
exports.TokenError = require('./errors/tokenerror');

@@ -5,4 +5,3 @@ /**

var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror')
, BadRequestError = require('../errors/badrequesterror');
, AuthorizationError = require('../errors/authorizationerror');

@@ -100,24 +99,28 @@

*/
module.exports = function authorization(server, options, validate) {
module.exports = function(server, options, validate, immediate) {
if (typeof options == 'function') {
immediate = validate;
validate = options;
options = {};
options = undefined;
}
options = options || {};
immediate = immediate || function (client, user, done) { return done(null, false); };
if (!server) throw new Error('OAuth 2.0 authorization middleware requires a server instance.');
if (!validate) throw new Error('OAuth 2.0 authorization middleware requires a validate function.');
if (!server) { throw new TypeError('oauth2orize.authorization middleware requires a server argument'); }
if (!validate) { throw new TypeError('oauth2orize.authorization middleware requires a validate function'); }
var lenTxnID = options.idLength || 8;
var key = options.sessionKey || 'authorize';
var lenTxnID = options.idLength || 8
, userProperty = options.userProperty || 'user'
, key = options.sessionKey || 'authorize';
return function authorization(req, res, next) {
if (!req.session) { return next(new Error('OAuth 2.0 server requires session support.')); }
if (!req.session) { return next(new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?')); }
var body = req.body || {}
, type = req.query['response_type'] || body['response_type'];
, type = req.query.response_type || body.response_type;
server._parse(type, req, function(err, areq) {
if (err) { return next(err); }
if (!areq || !Object.keys(areq).length || (Object.keys(areq).length == 1 && areq.type)) { return next(new AuthorizationError('invalid response type', 'unsupported_response_type')); }
if (!areq || !Object.keys(areq).length) { return next(new AuthorizationError('Missing required parameter: response_type', 'invalid_request')); }
if (Object.keys(areq).length == 1 && areq.type) { return next(new AuthorizationError('Unsupported response type: ' + type, 'unsupported_response_type')); }

@@ -129,52 +132,70 @@ function validated(err, client, redirectURI) {

req.oauth2 = {};
req.oauth2.client = client;
req.oauth2.redirectURI = redirectURI;
if (client) { req.oauth2.client = client; }
if (redirectURI) { req.oauth2.redirectURI = redirectURI; }
if (err) { return next(err); }
if (!client) { return next(new AuthorizationError('not authorized', 'unauthorized_client')); }
if (!client) { return next(new AuthorizationError('Unauthorized client', 'unauthorized_client')); }
req.oauth2.req = areq;
// TODO: Add an optional `immediate` callback, which can consult a
// pre-approved decision and respond immediately, along with the
// ability to fall back into "transaction" mode. Currently, this
// functionality can be achieved using later route middleware
// after `next()`ing, but this would optimize away the need to
// serialize the client into the session.
req.oauth2.user = req[userProperty];
// A dialog needs to be conducted to obtain the user's approval.
// Serialize a transaction to the session. The transaction will be
// restored (and removed) from the session when the user allows or
// denies the request.
server.serializeClient(client, function(err, obj) {
function immediated(err, allow, ares) {
if (err) { return next(err); }
var tid = utils.uid(lenTxnID);
req.oauth2.transactionID = tid;
var txn = {};
txn.protocol = 'oauth2';
txn.client = obj;
txn.redirectURI = redirectURI;
txn.req = areq;
// store transaction in session
var txns = req.session[key] = req.session[key] || {};
txns[tid] = txn;
if (allow) {
req.oauth2.res = ares || {};
req.oauth2.res.allow = true;
next();
});
server._respond(req.oauth2, res, function(err) {
if (err) { return next(err); }
return next(new AuthorizationError('Unsupported response type: ' + req.oauth2.req.type, 'unsupported_response_type'));
});
} else {
// A dialog needs to be conducted to obtain the user's approval.
// Serialize a transaction to the session. The transaction will be
// restored (and removed) from the session when the user allows or
// denies the request.
server.serializeClient(client, function(err, obj) {
if (err) { return next(err); }
var tid = utils.uid(lenTxnID);
req.oauth2.transactionID = tid;
var txn = {};
txn.protocol = 'oauth2';
txn.client = obj;
txn.redirectURI = redirectURI;
txn.req = areq;
// store transaction in session
var txns = req.session[key] = req.session[key] || {};
txns[tid] = txn;
next();
});
}
}
var arity = immediate.length;
if (arity == 4) {
immediate(req.oauth2.client, req.oauth2.user, req.oauth2.req.scope, immediated);
} else { // arity == 3
immediate(req.oauth2.client, req.oauth2.user, immediated);
}
}
var arity = validate.length;
if (arity == 3) {
validate(areq.clientID, areq.redirectURI, validated);
} else if (arity == 4) {
validate(areq.clientID, areq.redirectURI, areq.scope, validated);
} else if (arity == 5) {
validate(areq.clientID, areq.redirectURI, areq.scope, areq.type, validated);
} else { // arity == 2
validate(areq, validated);
try {
var arity = validate.length;
if (arity == 3) {
validate(areq.clientID, areq.redirectURI, validated);
} else if (arity == 4) {
validate(areq.clientID, areq.redirectURI, areq.scope, validated);
} else if (arity == 5) {
validate(areq.clientID, areq.redirectURI, areq.scope, areq.type, validated);
} else { // arity == 2
validate(areq, validated);
}
} catch (ex) {
return next(ex);
}
});
}
}
};
};
/**
* Module dependencies.
*/
var util = require('util')
, AuthorizationError = require('../errors/authorizationerror');
var AuthorizationError = require('../errors/authorizationerror')
, ForbiddenError = require('../errors/forbiddenerror');
/**
* Handle authorization descisions from resource owners.
* Handle authorization decisions from resource owners.
*

@@ -68,6 +68,6 @@ * Obtaining authorization via OAuth 2.0 consists of a sequence of discrete

*/
module.exports = function descision(server, options, parse) {
module.exports = function(server, options, parse) {
if (typeof options == 'function') {
parse = options;
options = {};
options = undefined;
}

@@ -77,3 +77,3 @@ options = options || {};

if (!server) throw new Error('OAuth 2.0 descision middleware requires a server instance.');
if (!server) { throw new TypeError('oauth2orize.decision middleware requires a server argument'); }

@@ -84,7 +84,7 @@ var cancelField = options.cancelField || 'cancel'

return function descision(req, res, next) {
if (!req.session) { return next(new Error('OAuth 2.0 server requires session support.')); }
if (!req.session[key]) { return next(new Error('Invalid OAuth 2.0 session key.')); }
if (!req.body) { return next(new Error('OAuth 2.0 server requires body parsing.')); }
if (!req.oauth2) { return next(new Error('OAuth 2.0 transaction not found.')); }
return function decision(req, res, next) {
if (!req.session) { return next(new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?')); }
if (!req.body) { return next(new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?')); }
if (!req.oauth2) { return next(new Error('OAuth2orize requires transaction support. Did you forget oauth2orize.transactionLoader(...)?')); }
if (!req.session[key]) { return next(new ForbiddenError('Unable to load OAuth 2.0 transactions from session')); }

@@ -109,10 +109,10 @@ parse(req, function(err, ares) {

res.end(chunk, encoding);
}
};
server._respond(req.oauth2, res, function(err) {
if (err) { return next(err); }
return next(new AuthorizationError('invalid response type', 'unsupported_response_type'));
return next(new AuthorizationError('Unsupported response type: ' + req.oauth2.req.type, 'unsupported_response_type'));
});
});
}
}
};
};
/**
* Module dependencies.
*/
var url = require('url');
var url = require('url')
, qs = require('querystring')
, UnorderedList = require('../unorderedlist');

@@ -44,10 +46,8 @@

*/
module.exports = function errorHandler(options) {
module.exports = function(options) {
options = options || {};
var mode = options.mode || 'direct';
var mode = options.mode || 'direct'
, fragment = options.fragment || ['token'];
// TODO: Error response should be added in the URL fragment, if the client is
// requesting an implicit token.
return function errorHandler(err, req, res, next) {

@@ -63,5 +63,5 @@ if (mode == 'direct') {

var e = {};
e['error'] = err.code || 'server_error';
if (err.message) { e['error_description'] = err.message; }
if (err.uri) { e['error_uri'] = err.uri; }
e.error = err.code || 'server_error';
if (err.message) { e.error_description = err.message; }
if (err.uri) { e.error_uri = err.uri; }

@@ -77,11 +77,31 @@ res.setHeader('Content-Type', 'application/json');

var redirectURI = req.oauth2.redirectURI;
var parsed = url.parse(redirectURI, true);
delete parsed.search;
parsed.query['error'] = err.code || 'server_error';
if (err.message) { parsed.query['error_description'] = err.message; }
if (err.uri) { parsed.query['error_uri'] = err.uri; }
if (req.oauth2.req && req.oauth2.req.state) { parsed.query['state'] = req.oauth2.req.state; }
var enc = 'query';
if (req.oauth2 && req.oauth2.req) {
var type = new UnorderedList(req.oauth2.req.type);
// In accordance with [OAuth 2.0 Multiple Response Type Encoding
// Practices - draft 08](http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html),
// if the response type contains any value that requires fragment
// encoding, the response will be fragment encoded.
if (type.containsAny(fragment)) { enc = 'fragment'; }
}
var location = url.format(parsed);
var redirectURI = req.oauth2.redirectURI
, uri = url.parse(redirectURI, true);
if (enc == 'fragment') {
var hash = {};
hash.error = err.code || 'server_error';
if (err.message) { hash.error_description = err.message; }
if (err.uri) { hash.error_uri = err.uri; }
if (req.oauth2.req && req.oauth2.req.state) { hash.state = req.oauth2.req.state; }
uri.hash = qs.stringify(hash);
} else {
delete uri.search;
uri.query.error = err.code || 'server_error';
if (err.message) { uri.query.error_description = err.message; }
if (err.uri) { uri.query.error_uri = err.uri; }
if (req.oauth2.req && req.oauth2.req.state) { uri.query.state = req.oauth2.req.state; }
}
var location = url.format(uri);
res.redirect(location);

@@ -91,3 +111,3 @@ } else {

}
}
}
};
};
/**
* Module dependencies.
*/
var AuthorizationError = require('../errors/authorizationerror');
var TokenError = require('../errors/tokenerror');

@@ -51,12 +51,12 @@

if (!server) throw new Error('OAuth 2.0 token middleware requires a server instance.');
if (!server) { throw new TypeError('oauth2orize.token middleware requires a server argument'); }
return function token(req, res, next) {
var type = req.body['grant_type'];
var type = req.body.grant_type;
server._exchange(type, req, res, function(err) {
if (err) { return next(err); }
return next(new AuthorizationError('invalid grant type', 'unsupported_grant_type'));
return next(new TokenError('Unsupported grant type: ' + type, 'unsupported_grant_type'));
});
}
}
};
};
/**
* Module dependencies.
*/
var util = require('util')
, AuthorizationError = require('../errors/authorizationerror');
var AuthorizationError = require('../errors/authorizationerror')
, BadRequestError = require('../errors/badrequesterror')
, ForbiddenError = require('../errors/forbiddenerror');

@@ -26,6 +27,6 @@

*/
module.exports = function transactionLoader(server, options) {
module.exports = function(server, options) {
options = options || {};
if (!server) throw new Error('OAuth 2.0 transactionLoader middleware requires a server instance.');
if (!server) { throw new TypeError('oauth2orize.transactionLoader middleware requires a server argument'); }

@@ -36,4 +37,4 @@ var field = options.transactionField || 'transaction_id'

return function transactionLoader(req, res, next) {
if (!req.session) { return next(new Error('OAuth 2.0 server requires session support.')); }
if (!req.session[key]) { return next(new Error('Invalid OAuth 2.0 session key.')); }
if (!req.session) { return next(new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?')); }
if (!req.session[key]) { return next(new ForbiddenError('Unable to load OAuth 2.0 transactions from session')); }

@@ -44,5 +45,5 @@ var query = req.query || {}

if (!tid) { return next(); }
if (!tid) { return next(new BadRequestError('Missing required parameter: ' + field)); }
var txn = req.session[key][tid];
if (!txn) { return next(); }
if (!txn) { return next(new ForbiddenError('Unable to load OAuth 2.0 transaction: ' + tid)); }

@@ -56,4 +57,4 @@ server.deserializeClient(txn.client, function(err, client) {

delete req.session[key][tid];
return next(new AuthorizationError('no longer authorized', 'unauthorized_client'));
};
return next(new AuthorizationError('Unauthorized client', 'unauthorized_client'));
}

@@ -67,3 +68,3 @@ req.oauth2 = {};

});
}
}
};
};
/**
* Module dependencies.
*/
var utils = require('./utils')
, UnorderedList = require('./unorderedlist')
var UnorderedList = require('./unorderedlist')
, authorization = require('./middleware/authorization')

@@ -11,2 +10,3 @@ , decision = require('./middleware/decision')

, errorHandler = require('./middleware/errorHandler')
, utils = require('./utils')
, debug = require('debug')('oauth2orize');

@@ -23,7 +23,7 @@

this._resHandlers = [];
this._exchangers = [];
this._exchanges = [];
this._serializers = [];
this._deserializers = [];
};
}

@@ -81,10 +81,10 @@ /**

if (phase == 'request') {
debug('register parser %s %s', type || '*', fn.name || 'anonymous');
debug('register request parser %s %s', type || '*', fn.name || 'anonymous');
this._reqParsers.push({ type: type, handle: fn });
} else if (phase == 'response') {
debug('register responder %s %s', type || '*', fn.name || 'anonymous');
debug('register response handler %s %s', type || '*', fn.name || 'anonymous');
this._resHandlers.push({ type: type, handle: fn });
}
return this;
}
};

@@ -118,5 +118,5 @@ /**

debug('register exchanger %s %s', type || '*', fn.name || 'anonymous');
this._exchangers.push({ type: type, handle: fn });
this._exchanges.push({ type: type, handle: fn });
return this;
}
};

@@ -131,3 +131,3 @@ /**

return authorization(this, options, validate);
}
};

@@ -140,7 +140,7 @@ /**

Server.prototype.decision = function(options, parse) {
if (options && options.loadTransaction == false) {
if (options && options.loadTransaction === false) {
return decision(this, options, parse);
}
return [transactionLoader(this, options), decision(this, options, parse)];
}
};

@@ -154,3 +154,3 @@ /**

return token(this, options);
}
};

@@ -164,3 +164,3 @@ /**

return errorHandler(options);
}
};

@@ -196,12 +196,12 @@ /**

if (!layer) {
return done(new Error('Failed to serialize client. Register serialization function using serializeClient().'));
return done(new Error('Failed to serialize client. Register serialization function using serializeClient().'));
}
try {
layer(client, function(e, o) { pass(i + 1, e, o); } )
} catch(e) {
return done(e);
layer(client, function(e, o) { pass(i + 1, e, o); } );
} catch (ex) {
return done(ex);
}
})(0);
}
};

@@ -242,12 +242,12 @@ /**

if (!layer) {
return done(new Error('Failed to deserialize client. Register deserialization function using deserializeClient().'));
return done(new Error('Failed to deserialize client. Register deserialization function using deserializeClient().'));
}
try {
layer(obj, function(e, c) { pass(i + 1, e, c); } )
} catch(e) {
return done(e);
layer(obj, function(e, c) { pass(i + 1, e, c); } );
} catch (ex) {
return done(ex);
}
})(0);
}
};

@@ -292,7 +292,7 @@

}
} catch(e) {
return cb(e);
} catch (ex) {
return cb(ex);
}
})(0);
}
};

@@ -325,8 +325,8 @@ /**

}
} catch (e) {
return cb(e);
} catch (ex) {
return cb(ex);
}
}
next();
}
};

@@ -343,3 +343,3 @@ /**

Server.prototype._exchange = function(type, req, res, cb) {
var stack = this._exchangers
var stack = this._exchanges
, idx = 0;

@@ -360,8 +360,8 @@

}
} catch (e) {
return cb(e);
} catch (ex) {
return cb(ex);
}
}
next();
}
};

@@ -368,0 +368,0 @@

@@ -22,3 +22,3 @@ /**

UnorderedList.prototype.equalTo = function(other) {
if (!other instanceof UnorderedList) {
if (!(other instanceof UnorderedList)) {
other = new UnorderedList(other);

@@ -35,5 +35,30 @@ }

return true;
}
};
/**
* Check if list contains `val`
*
* @param {String} val
* @return {Boolean}
* @api public
*/
UnorderedList.prototype.contains = function(val) {
return this._items.indexOf(val) != -1;
};
/**
* Check if list contains any element in `arr`
*
* @param {Array} arr
* @return {Boolean}
* @api public
*/
UnorderedList.prototype.containsAny = function(arr) {
for (var i = 0, len = arr.length; i < len; i++) {
if (this._items.indexOf(arr[i]) != -1) { return true; }
}
return false;
};
/**
* String representation of list.

@@ -46,3 +71,3 @@ *

return this._items.join(' ');
}
};

@@ -57,7 +82,7 @@ /**

return this._items.length;
}
};
/**
* Expose `UnorderedList`.
*/
*/
module.exports = UnorderedList;

@@ -1,62 +0,2 @@

/**
* Module dependencies.
*/
var crypto = require('crypto');
/**
* Merge object b with object a.
*
* var a = { foo: 'bar' }
* , b = { bar: 'baz' };
*
* utils.merge(a, b);
* // => { foo: 'bar', bar: 'baz' }
*
* @param {Object} a
* @param {Object} b
* @return {Object}
* @api private
*/
exports.merge = function(a, b){
if (a && b) {
for (var key in b) {
a[key] = b[key];
}
}
return a;
};
/**
* Return a unique identifier with the given `len`.
*
* utils.uid(10);
* // => "FDaS435D2z"
*
* @param {Number} len
* @return {String}
* @api private
*/
exports.uid = function(len) {
var buf = []
, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
, charlen = chars.length;
for (var i = 0; i < len; ++i) {
buf.push(chars[getRandomInt(0, charlen - 1)]);
}
return buf.join('');
};
/**
* Retrun a random int, used by `utils.uid()`
*
* @param {Number} min
* @param {Number} max
* @return {Number}
* @api private
*/
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
exports.merge = require('utils-merge');
exports.uid = require('uid2');
{
"name": "oauth2orize",
"version": "0.1.0",
"version": "1.0.0",
"description": "OAuth 2.0 authorization server toolkit for Node.js.",
"keywords": ["oauth", "oauth2", "connect", "express", "middleware", "http", "api"],
"keywords": [
"oauth",
"oauth2",
"auth",
"authz",
"authorization",
"connect",
"express",
"passport",
"middleware"
],
"repository": {

@@ -13,18 +23,31 @@ "type": "git",

},
"author": { "name": "Jared Hanson", "email": "jaredhanson@gmail.com", "url": "http://www.jaredhanson.net/" },
"licenses": [ {
"type": "MIT",
"url": "http://www.opensource.org/licenses/MIT"
} ],
"author": {
"name": "Jared Hanson",
"email": "jaredhanson@gmail.com",
"url": "http://www.jaredhanson.net/"
},
"licenses": [
{
"type": "MIT",
"url": "http://www.opensource.org/licenses/MIT"
}
],
"main": "./lib",
"dependencies": {
"uid2": "0.0.x",
"utils-merge": "1.x.x",
"debug": "0.7.x"
},
"devDependencies": {
"vows": "0.6.x"
"mocha": "1.x.x",
"chai": "1.x.x",
"chai-connect-middleware": "0.1.x",
"chai-oauth2orize-grant": "0.1.x"
},
"engines": {
"node": ">= 0.4.0"
},
"scripts": {
"test": "NODE_PATH=lib node_modules/.bin/vows test/*-test.js test/**/*-test.js"
},
"engines": { "node": ">= 0.4.0" }
"test": "node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js test/**/*.test.js"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc