Socket
Socket
Sign inDemoInstall

oauth2orize-koa

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

oauth2orize-koa - npm Package Compare versions

Comparing version 1.2.0 to 1.2.1

23

lib/errors/authorizationerror.js

@@ -14,11 +14,17 @@ /**

switch (code) {
case 'invalid_request': status = 400; break;
case 'unauthorized_client': status = 403; break;
case 'access_denied': status = 403; break;
case 'unsupported_response_type': status = 501; break;
case 'invalid_scope': status = 400; break;
case 'temporarily_unavailable': status = 503; break;
case 'invalid_request':
status = 400;break;
case 'unauthorized_client':
status = 403;break;
case 'access_denied':
status = 403;break;
case 'unsupported_response_type':
status = 501;break;
case 'invalid_scope':
status = 400;break;
case 'temporarily_unavailable':
status = 503;break;
}
}
OAuth2Error.call(this, message, code, uri, status);

@@ -34,6 +40,5 @@ Error.captureStackTrace(this, arguments.callee);

/**
* Expose `AuthorizationError`.
*/
module.exports = AuthorizationError;
module.exports = AuthorizationError;

@@ -19,6 +19,5 @@ /**

/**
* Expose `BadRequestError`.
*/
module.exports = BadRequestError;
module.exports = BadRequestError;

@@ -19,6 +19,5 @@ /**

/**
* Expose `ForbiddenError`.
*/
module.exports = ForbiddenError;
module.exports = ForbiddenError;

@@ -19,6 +19,5 @@ /**

/**
* Expose `OAuth2Error`.
*/
module.exports = OAuth2Error;
module.exports = OAuth2Error;

@@ -14,11 +14,17 @@ /**

switch (code) {
case 'invalid_request': status = 400; break;
case 'invalid_client': status = 401; break;
case 'invalid_grant': status = 403; break;
case 'unauthorized_client': status = 403; break;
case 'unsupported_grant_type': status = 501; break;
case 'invalid_scope': status = 400; break;
case 'invalid_request':
status = 400;break;
case 'invalid_client':
status = 401;break;
case 'invalid_grant':
status = 403;break;
case 'unauthorized_client':
status = 403;break;
case 'unsupported_grant_type':
status = 501;break;
case 'invalid_scope':
status = 400;break;
}
}
OAuth2Error.call(this, message, code, uri, status);

@@ -34,6 +40,5 @@ Error.captureStackTrace(this, arguments.callee);

/**
* Expose `TokenError`.
*/
module.exports = TokenError;
module.exports = TokenError;

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var utils = require('../utils')
, TokenError = require('../errors/tokenerror');
var utils = require('../utils'),
TokenError = require('../errors/tokenerror');
/**

@@ -58,3 +59,3 @@ * Exchanges authorization codes for access tokens.

*/
module.exports = function(options, issue) {
module.exports = function (options, issue) {
if (typeof options == 'function') {

@@ -66,48 +67,67 @@ issue = options;

if (!issue) { throw new TypeError('oauth2orize.authorizationCode exchange requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.authorizationCode exchange requires an issue callback');
}
var userProperty = options.userProperty || 'user';
return async function authorization_code(ctx) {
const req = ctx.request;
if (!req.body) { throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?'); }
return function () {
var ref = _asyncToGenerator(function* (ctx) {
const req = ctx.request;
if (!req.body) {
throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?');
}
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty]
, code = req.body.code
, redirectURI = req.body.redirect_uri;
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty],
code = req.body.code,
redirectURI = req.body.redirect_uri;
if (!code) { throw new TokenError('Missing required parameter: code', 'invalid_request'); }
if (!code) {
throw new TokenError('Missing required parameter: code', 'invalid_request');
}
var arity = issue.length;
var result;
if (arity == 4) {
result = await issue(client, code, redirectURI, req.body);
} else { // arity == 3
result = await issue(client, code, redirectURI);
}
var arity = issue.length;
var result;
if (arity == 4) {
result = yield issue(client, code, redirectURI, req.body);
} else {
// arity == 3
result = yield issue(client, code, redirectURI);
}
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
if (!accessToken) { throw new TokenError('Invalid authorization code', 'invalid_grant'); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
if (!accessToken) {
throw 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);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
};
};
var json = JSON.stringify(tok);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
});
return function authorization_code(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var utils = require('../utils')
, TokenError = require('../errors/tokenerror');
var utils = require('../utils'),
TokenError = require('../errors/tokenerror');
/**

@@ -57,3 +58,3 @@ * Exchanges client credentials for access tokens.

*/
module.exports = function(options, issue) {
module.exports = function (options, issue) {
if (typeof options == 'function') {

@@ -65,3 +66,5 @@ issue = options;

if (!issue) { throw new TypeError('oauth2orize.clientCredentials exchange requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.clientCredentials exchange requires an issue callback');
}

@@ -77,59 +80,76 @@ var userProperty = options.userProperty || 'user';

if (!Array.isArray(separators)) {
separators = [ separators ];
separators = [separators];
}
return async function client_credentials(ctx) {
const req = ctx.request;
if (!req.body) { throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?'); }
return function () {
var ref = _asyncToGenerator(function* (ctx) {
const req = ctx.request;
if (!req.body) {
throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?');
}
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty]
, scope = req.body.scope;
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty],
scope = req.body.scope;
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
}
}
if (!Array.isArray(scope)) {
scope = [scope];
}
}
if (!Array.isArray(scope)) { scope = [ scope ]; }
}
var arity = issue.length;
var result;
if (arity == 3) {
result = await issue(client, scope, req.body);
} else if (arity == 2) {
result = await issue(client, scope);
} else { // arity == 1
result = await issue(client);
}
var arity = issue.length;
var result;
if (arity == 3) {
result = yield issue(client, scope, req.body);
} else if (arity == 2) {
result = yield issue(client, scope);
} else {
// arity == 1
result = yield issue(client);
}
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
if (!accessToken) { throw new TokenError('Invalid client credentials', 'invalid_grant'); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
if (!accessToken) {
throw 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; }
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);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
};
};
var json = JSON.stringify(tok);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
});
return function client_credentials(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var utils = require('../utils')
, TokenError = require('../errors/tokenerror');
var utils = require('../utils'),
TokenError = require('../errors/tokenerror');
/**

@@ -58,3 +59,3 @@ * Exchanges resource owner password credentials for access tokens.

*/
module.exports = function(options, issue) {
module.exports = function (options, issue) {
if (typeof options == 'function') {

@@ -66,3 +67,5 @@ issue = options;

if (!issue) { throw new TypeError('oauth2orize.password exchange requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.password exchange requires an issue callback');
}

@@ -78,65 +81,86 @@ var userProperty = options.userProperty || 'user';

if (!Array.isArray(separators)) {
separators = [ separators ];
separators = [separators];
}
return async function password(ctx) {
const req = ctx.request;
return function () {
var ref = _asyncToGenerator(function* (ctx) {
const req = ctx.request;
if (!req.body) { throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?'); }
if (!req.body) {
throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?');
}
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty]
, username = req.body.username
, passwd = req.body.password
, scope = req.body.scope;
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty],
username = req.body.username,
passwd = req.body.password,
scope = req.body.scope;
if (!username) { throw new TokenError('Missing required parameter: username', 'invalid_request'); }
if (!passwd) { throw new TokenError('Missing required parameter: password', 'invalid_request'); }
if (!username) {
throw new TokenError('Missing required parameter: username', 'invalid_request');
}
if (!passwd) {
throw new TokenError('Missing required parameter: password', 'invalid_request');
}
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
}
}
if (!Array.isArray(scope)) {
scope = [scope];
}
}
if (!Array.isArray(scope)) { scope = [ scope ]; }
}
var arity = issue.length;
var result;
if (arity == 5) {
result = await issue(client, username, passwd, scope, req.body);
} else if (arity == 4) {
result = await issue(client, username, passwd, scope);
} else { // arity == 3
result = await issue(client, username, passwd);
}
var arity = issue.length;
var result;
if (arity == 5) {
result = yield issue(client, username, passwd, scope, req.body);
} else if (arity == 4) {
result = yield issue(client, username, passwd, scope);
} else {
// arity == 3
result = yield issue(client, username, passwd);
}
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
var accessToken = result[0];
var refreshToken = result[1];
var params = result[2];
if (!accessToken) { throw new TokenError('Invalid resource owner credentials', 'invalid_grant'); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
if (!accessToken) {
throw 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; }
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);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
};
};
var json = JSON.stringify(tok);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
});
return function password(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var utils = require('../utils')
, TokenError = require('../errors/tokenerror');
var utils = require('../utils'),
TokenError = require('../errors/tokenerror');
/**

@@ -55,3 +56,3 @@ * Refresh previously issued access tokens.

*/
module.exports = function(options, issue) {
module.exports = function (options, issue) {
if (typeof options == 'function') {

@@ -63,3 +64,5 @@ issue = options;

if (!issue) { throw new TypeError('oauth2orize.refreshToken exchange requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.refreshToken exchange requires an issue callback');
}

@@ -75,60 +78,79 @@ var userProperty = options.userProperty || 'user';

if (!Array.isArray(separators)) {
separators = [ separators ];
separators = [separators];
}
return async function refresh_token(ctx) {
const req = ctx.request;
if (!req.body) { throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?'); }
return function () {
var ref = _asyncToGenerator(function* (ctx) {
const req = ctx.request;
if (!req.body) {
throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?');
}
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty]
, refreshToken = req.body.refresh_token
, scope = req.body.scope;
// The 'user' property of `req` holds the authenticated user. In the case
// of the token endpoint, the property will contain the OAuth 2.0 client.
var client = ctx.state[userProperty],
refreshToken = req.body.refresh_token,
scope = req.body.scope;
if (!refreshToken) { throw new TokenError('Missing required parameter: refresh_token', 'invalid_request'); }
if (!refreshToken) {
throw new TokenError('Missing required parameter: refresh_token', 'invalid_request');
}
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
if (scope) {
for (var i = 0, len = separators.length; i < len; i++) {
var separated = scope.split(separators[i]);
// only separate on the first matching separator. this allows for a sort
// of separator "priority" (ie, favor spaces then fallback to commas)
if (separated.length > 1) {
scope = separated;
break;
}
}
if (!Array.isArray(scope)) {
scope = [scope];
}
}
if (!Array.isArray(scope)) { scope = [ scope ]; }
}
var arity = issue.length;
var result;
if (arity == 3) {
result = await issue(client, refreshToken, scope);
} else { // arity == 2
result = await issue(client, refreshToken);
}
var arity = issue.length;
var result;
if (arity == 3) {
result = yield issue(client, refreshToken, scope);
} else {
// arity == 2
result = yield issue(client, refreshToken);
}
var accessToken = result[0];
refreshToken = result[1];
var params = result[2];
var accessToken = result[0];
refreshToken = result[1];
var params = result[2];
if (!accessToken) { throw new TokenError('Invalid refresh token', 'invalid_grant'); }
if (refreshToken && typeof refreshToken == 'object') {
params = refreshToken;
refreshToken = null;
}
if (!accessToken) {
throw 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; }
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);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
};
};
var json = JSON.stringify(tok);
ctx.set('Content-Type', 'application/json');
ctx.set('Cache-Control', 'no-store');
ctx.set('Pragma', 'no-cache');
ctx.body = json;
});
return function refresh_token(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -5,5 +5,7 @@ 'use strict';

*/
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
var AuthorizationError = require('../errors/authorizationerror');
/**

@@ -66,3 +68,5 @@ * Handles requests to obtain a grant in the form of an authorization code.

if (!issue) { throw new TypeError('oauth2orize.code grant requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.code grant requires an issue callback');
}

@@ -81,6 +85,5 @@ var modes = options.modes || {};

if (!Array.isArray(separators)) {
separators = [ separators ];
separators = [separators];
}
/* Parse requests that request `code` as `response_type`.

@@ -93,8 +96,10 @@ *

var clientID = ctx.query.client_id
, redirectURI = ctx.query.redirect_uri
, scope = ctx.query.scope
, state = ctx.query.state;
var clientID = ctx.query.client_id,
redirectURI = ctx.query.redirect_uri,
scope = ctx.query.scope,
state = ctx.query.state;
if (!clientID) { throw new AuthorizationError('Missing required parameter: client_id', 'invalid_request'); }
if (!clientID) {
throw new AuthorizationError('Missing required parameter: client_id', 'invalid_request');
}

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

if (!Array.isArray(scope)) { scope = [ scope ]; }
if (!Array.isArray(scope)) {
scope = [scope];
}
}

@@ -131,55 +138,69 @@

*/
async function response(ctx) {
const txn = ctx.state.oauth2;
var mode = 'query'
, respond;
if (txn.req && txn.req.responseMode) {
mode = txn.req.responseMode;
}
respond = modes[mode];
if (!respond) {
// http://lists.openid.net/pipermail/openid-specs-ab/Week-of-Mon-20140317/004680.html
throw new AuthorizationError('Unsupported response mode: ' + mode, 'unsupported_response_mode', null, 501);
}
if (respond && respond.validate) {
respond.validate(txn);
}
let response = function () {
var ref = _asyncToGenerator(function* (ctx) {
const txn = ctx.state.oauth2;
var mode = 'query',
respond;
if (txn.req && txn.req.responseMode) {
mode = txn.req.responseMode;
}
respond = modes[mode];
if (!txn.res.allow) {
var params = { error: 'access_denied' };
if (txn.req && txn.req.state) { params.state = txn.req.state; }
return respond(txn, ctx.response, params);
}
if (!respond) {
// http://lists.openid.net/pipermail/openid-specs-ab/Week-of-Mon-20140317/004680.html
throw new AuthorizationError('Unsupported response mode: ' + mode, 'unsupported_response_mode', null, 501);
}
if (respond && respond.validate) {
respond.validate(txn);
}
// NOTE: The `redirect_uri`, if present in the client's authorization
// request, must also be present in the subsequent request to exchange
// the authorization code for an access token. Acting as a verifier,
// the two values must be equal and serve to protect against certain
// types of attacks. More information can be found here:
//
// http://hueniverse.com/2011/06/oauth-2-0-redirection-uri-validation/
if (!txn.res.allow) {
var params = { error: 'access_denied' };
if (txn.req && txn.req.state) {
params.state = txn.req.state;
}
return respond(txn, ctx.response, params);
}
var arity = issue.length;
var code;
if (arity == 5) {
code = await issue(txn.client, txn.req.redirectURI, txn.user, txn.res, txn.req);
} else if (arity == 4) {
code = await issue(txn.client, txn.req.redirectURI, txn.user, txn.res);
} else { // arity == 3
code = await issue(txn.client, txn.req.redirectURI, txn.user);
}
// NOTE: The `redirect_uri`, if present in the client's authorization
// request, must also be present in the subsequent request to exchange
// the authorization code for an access token. Acting as a verifier,
// the two values must be equal and serve to protect against certain
// types of attacks. More information can be found here:
//
// http://hueniverse.com/2011/06/oauth-2-0-redirection-uri-validation/
if (!code) { throw new AuthorizationError('Request denied by authorization server', 'access_denied'); }
var arity = issue.length;
var code;
if (arity == 5) {
code = yield issue(txn.client, txn.req.redirectURI, txn.user, txn.res, txn.req);
} else if (arity == 4) {
code = yield issue(txn.client, txn.req.redirectURI, txn.user, txn.res);
} else {
// arity == 3
code = yield issue(txn.client, txn.req.redirectURI, txn.user);
}
params = { code: code };
if (txn.req && txn.req.state) { params.state = txn.req.state; }
if (!code) {
throw new AuthorizationError('Request denied by authorization server', 'access_denied');
}
respond(txn, ctx.response, params);
}
params = { code: code };
if (txn.req && txn.req.state) {
params.state = txn.req.state;
}
respond(txn, ctx.response, params);
});
return function response(_x) {
return ref.apply(this, arguments);
};
}();
/**
* Return `code` approval module.
*/
var mod = {};

@@ -190,2 +211,2 @@ mod.name = 'code';

return mod;
};
};

@@ -5,6 +5,8 @@ 'use strict';

*/
var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
var utils = require('../utils'),
AuthorizationError = require('../errors/authorizationerror');
/**

@@ -65,3 +67,5 @@ * Handles requests to obtain an implicit grant.

if (!issue) { throw new TypeError('oauth2orize.token grant requires an issue callback'); }
if (!issue) {
throw new TypeError('oauth2orize.token grant requires an issue callback');
}

@@ -80,6 +84,5 @@ var modes = options.modes || {};

if (!Array.isArray(separators)) {
separators = [ separators ];
separators = [separators];
}
/* Parse requests that request `token` as `response_type`.

@@ -91,8 +94,10 @@ *

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

@@ -110,3 +115,5 @@ if (scope) {

if (!Array.isArray(scope)) { scope = [ scope ]; }
if (!Array.isArray(scope)) {
scope = [scope];
}
}

@@ -129,57 +136,73 @@

*/
async function response(ctx) {
const txn = ctx.state.oauth2;
var mode = 'fragment'
, respond;
if (txn.req && txn.req.responseMode) {
mode = txn.req.responseMode;
}
respond = modes[mode];
if (!respond) {
// http://lists.openid.net/pipermail/openid-specs-ab/Week-of-Mon-20140317/004680.html
throw new AuthorizationError('Unsupported response mode: ' + mode, 'unsupported_response_mode', null, 501);
}
if (respond && respond.validate) {
respond.validate(txn);
}
let response = function () {
var ref = _asyncToGenerator(function* (ctx) {
const txn = ctx.state.oauth2;
var mode = 'fragment',
respond;
if (txn.req && txn.req.responseMode) {
mode = txn.req.responseMode;
}
respond = modes[mode];
if (!txn.res.allow) {
var params = { error: 'access_denied' };
if (txn.req && txn.req.state) { params.state = txn.req.state; }
return respond(txn, ctx.response, params);
}
if (!respond) {
// http://lists.openid.net/pipermail/openid-specs-ab/Week-of-Mon-20140317/004680.html
throw new AuthorizationError('Unsupported response mode: ' + mode, 'unsupported_response_mode', null, 501);
}
if (respond && respond.validate) {
respond.validate(txn);
}
// NOTE: In contrast to an authorization code grant, redirectURI is not
// passed as an argument to the issue callback because it is not used
// as a verifier in a subsequent token exchange. However, when
// issuing an implicit access tokens, an application must ensure that
// the redirection URI is registered, which can be done in the
// `validate` callback of `authorization` middleware.
if (!txn.res.allow) {
var params = { error: 'access_denied' };
if (txn.req && txn.req.state) {
params.state = txn.req.state;
}
return respond(txn, ctx.response, params);
}
var arity = issue.length;
var result;
if (arity == 3) {
result = await issue(txn.client, txn.user, txn.res);
} else { // arity == 2
result = await issue(txn.client, txn.user);
}
// NOTE: In contrast to an authorization code grant, redirectURI is not
// passed as an argument to the issue callback because it is not used
// as a verifier in a subsequent token exchange. However, when
// issuing an implicit access tokens, an application must ensure that
// the redirection URI is registered, which can be done in the
// `validate` callback of `authorization` middleware.
var accessToken = result[0];
params = result[1];
var arity = issue.length;
var result;
if (arity == 3) {
result = yield issue(txn.client, txn.user, txn.res);
} else {
// arity == 2
result = yield issue(txn.client, txn.user);
}
if (!accessToken) { throw new AuthorizationError('Request denied by authorization server', 'access_denied'); }
var accessToken = result[0];
params = result[1];
var tok = {};
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; }
return respond(txn, ctx.response, tok);
}
if (!accessToken) {
throw new AuthorizationError('Request denied by authorization server', 'access_denied');
}
var tok = {};
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;
}
return respond(txn, ctx.response, tok);
});
return function response(_x) {
return ref.apply(this, arguments);
};
}();
/**
* Return `token` approval module.
*/
var mod = {};

@@ -190,2 +213,2 @@ mod.name = 'token';

return mod;
};
};
/**
* Module dependencies.
*/
var fs = require('fs')
, path = require('path')
, Server = require('./server');
var fs = require('fs'),
path = require('path'),
Server = require('./server');
/**

@@ -28,3 +27,2 @@ * Create an OAuth 2.0 server.

/**

@@ -39,7 +37,9 @@ * Export middleware.

exports.grant = {};
fs.readdirSync(__dirname + '/grant').forEach(function(filename) {
fs.readdirSync(__dirname + '/grant').forEach(function (filename) {
if (/\.js$/.test(filename)) {
var name = path.basename(filename, '.js');
var load = function () { return require('./grant/' + name); };
var load = function () {
return require('./grant/' + name);
};
exports.grant.__defineGetter__(name, load);

@@ -57,7 +57,9 @@ }

exports.exchange = {};
fs.readdirSync(__dirname + '/exchange').forEach(function(filename) {
fs.readdirSync(__dirname + '/exchange').forEach(function (filename) {
if (/\.js$/.test(filename)) {
var name = path.basename(filename, '.js');
var load = function () { return require('./exchange/' + name); };
var load = function () {
return require('./exchange/' + name);
};
exports.exchange.__defineGetter__(name, load);

@@ -75,2 +77,2 @@ }

exports.AuthorizationError = require('./errors/authorizationerror');
exports.TokenError = require('./errors/tokenerror');
exports.TokenError = require('./errors/tokenerror');

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var utils = require('../utils')
, AuthorizationError = require('../errors/authorizationerror');
var utils = require('../utils'),
AuthorizationError = require('../errors/authorizationerror');
/**

@@ -98,3 +99,3 @@ * Handle authorization requests from OAuth 2.0 clients.

*/
module.exports = function(server, options, validate, immediate) {
module.exports = function (server, options, validate, immediate) {
if (typeof options == 'function') {

@@ -106,115 +107,144 @@ immediate = validate;

options = options || {};
immediate = immediate || function () { return false; };
immediate = immediate || function () {
return false;
};
if (!server) { throw new TypeError('oauth2orize.authorization middleware requires a server argument'); }
if (!validate) { throw new TypeError('oauth2orize.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
, userProperty = options.userProperty || 'user'
, key = options.sessionKey || 'authorize';
var lenTxnID = options.idLength || 8,
userProperty = options.userProperty || 'user',
key = options.sessionKey || 'authorize';
return async function authorization(ctx) {
if (!ctx.session) { throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?'); }
return function () {
var ref = _asyncToGenerator(function* (ctx) {
if (!ctx.session) {
throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?');
}
var body = ctx.request.body || {}
, type = ctx.query.response_type || body.response_type;
var body = ctx.request.body || {},
type = ctx.query.response_type || body.response_type;
var areq = await server._parse(type, ctx);
if (!areq || !Object.keys(areq).length) { throw new AuthorizationError('Missing required parameter: response_type', 'invalid_request'); }
if (Object.keys(areq).length == 1 && areq.type) { throw new AuthorizationError('Unsupported response type: ' + type, 'unsupported_response_type'); }
var areq = yield server._parse(type, ctx);
if (!areq || !Object.keys(areq).length) {
throw new AuthorizationError('Missing required parameter: response_type', 'invalid_request');
}
if (Object.keys(areq).length == 1 && areq.type) {
throw new AuthorizationError('Unsupported response type: ' + type, 'unsupported_response_type');
}
var arity = validate.length;
var response;
try {
if (arity == 2) {
response = await validate(areq.clientID, areq.redirectURI);
} else if (arity == 3) {
response = await validate(areq.clientID, areq.redirectURI, areq.scope);
} else if (arity == 4) {
response = await validate(areq.clientID, areq.redirectURI, areq.scope, areq.type);
} else { // arity == 1
response = await validate(areq);
var arity = validate.length;
var response;
try {
if (arity == 2) {
response = yield validate(areq.clientID, areq.redirectURI);
} else if (arity == 3) {
response = yield validate(areq.clientID, areq.redirectURI, areq.scope);
} else if (arity == 4) {
response = yield validate(areq.clientID, areq.redirectURI, areq.scope, areq.type);
} else {
// arity == 1
response = yield validate(areq);
}
} catch (err) {
// Set properties *before* throwing due to error. The presence of a
// redirectURI being provided, even under error conditions, indicates
// that the client should be informed of the error via a redirect.
ctx.state.oauth2 = {};
if (err.client) {
ctx.state.oauth2.client = err.client;
}
if (err.redirectURI) {
ctx.state.oauth2.redirectURI = err.redirectURI;
}
throw err;
}
} catch (err) {
// Set properties *before* throwing due to error. The presence of a
// redirectURI being provided, even under error conditions, indicates
// that the client should be informed of the error via a redirect.
ctx.state.oauth2 = {};
if (err.client) { ctx.state.oauth2.client = err.client; }
if (err.redirectURI) { ctx.state.oauth2.redirectURI = err.redirectURI; }
throw err;
}
var client = response[0];
var redirectURI = response[1];
var client = response[0];
var redirectURI = response[1];
ctx.state.oauth2 = {};
if (client) { ctx.state.oauth2.client = client; }
if (redirectURI) { ctx.state.oauth2.redirectURI = redirectURI; }
ctx.state.oauth2 = {};
if (client) {
ctx.state.oauth2.client = client;
}
if (redirectURI) {
ctx.state.oauth2.redirectURI = redirectURI;
}
if (!client) {
throw new AuthorizationError('Unauthorized client', 'unauthorized_client');
}
if (!client) { throw new AuthorizationError('Unauthorized client', 'unauthorized_client'); }
ctx.state.oauth2.req = areq;
ctx.state.oauth2.user = ctx.state[userProperty];
ctx.state.oauth2.req = areq;
ctx.state.oauth2.user = ctx.state[userProperty];
arity = immediate.length;
if (arity == 3) {
response = yield immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope);
} else if (arity == 4) {
response = yield immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope, ctx.state.oauth2.req.type);
} else if (arity == 5) {
response = yield immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope, ctx.state.oauth2.req.type, ctx.state.oauth2.req);
} else {
// arity == 2
response = yield immediate(ctx.state.oauth2.client, ctx.state.oauth2.user);
}
arity = immediate.length;
if (arity == 3) {
response = await immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope);
} else if (arity == 4) {
response = await immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope, ctx.state.oauth2.req.type);
} else if (arity == 5) {
response = await immediate(ctx.state.oauth2.client, ctx.state.oauth2.user, ctx.state.oauth2.req.scope, ctx.state.oauth2.req.type, ctx.state.oauth2.req);
} else { // arity == 2
response = await immediate(ctx.state.oauth2.client, ctx.state.oauth2.user);
}
var allow = response[0];
var info = response[1];
var locals = response[2];
var allow = response[0];
var info = response[1];
var locals = response[2];
if (allow) {
ctx.state.oauth2.res = info || {};
ctx.state.oauth2.res.allow = true;
if (allow) {
ctx.state.oauth2.res = info || {};
ctx.state.oauth2.res.allow = true;
yield server._respond(ctx, function () {
throw new AuthorizationError('Unsupported response type: ' + ctx.state.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.
var obj = yield server.serializeClient(client);
await server._respond(ctx, function() {
throw new AuthorizationError('Unsupported response type: ' + ctx.state.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.
var obj = await server.serializeClient(client);
var tid = utils.uid(lenTxnID);
ctx.state.oauth2.transactionID = tid;
// Add info and locals to `ctx.state.oauth2`, where they will be
// available to the next middleware. Since this is a
// non-immediate response, the next middleware's responsibility is
// to prompt the user to allow or deny access. `info` and
// `locals` are passed along as they may be of assistance when
// rendering the prompt.
//
// Note that `info` is also serialized into the transaction, where
// it can further be utilized in the `decision` middleware after
// the user submits the prompt's form. As such, `info` should be
// a normal JSON object, so that it can be correctly serialized
// into the session. `locals` is only carried through to the
// middleware chain for the current request, so it may contain
// instantiated classes that don't serialize cleanly.
ctx.state.oauth2.info = info;
ctx.state.oauth2.locals = locals;
var tid = utils.uid(lenTxnID);
ctx.state.oauth2.transactionID = tid;
// Add info and locals to `ctx.state.oauth2`, where they will be
// available to the next middleware. Since this is a
// non-immediate response, the next middleware's responsibility is
// to prompt the user to allow or deny access. `info` and
// `locals` are passed along as they may be of assistance when
// rendering the prompt.
//
// Note that `info` is also serialized into the transaction, where
// it can further be utilized in the `decision` middleware after
// the user submits the prompt's form. As such, `info` should be
// a normal JSON object, so that it can be correctly serialized
// into the session. `locals` is only carried through to the
// middleware chain for the current request, so it may contain
// instantiated classes that don't serialize cleanly.
ctx.state.oauth2.info = info;
ctx.state.oauth2.locals = locals;
var txn = {};
txn.protocol = 'oauth2';
txn.client = obj;
txn.redirectURI = redirectURI;
txn.req = areq;
txn.info = info;
// store transaction in session
var txns = ctx.session[key] = ctx.session[key] || {};
txns[tid] = txn;
}
});
var txn = {};
txn.protocol = 'oauth2';
txn.client = obj;
txn.redirectURI = redirectURI;
txn.req = areq;
txn.info = info;
// store transaction in session
var txns = ctx.session[key] = ctx.session[key] || {};
txns[tid] = txn;
}
};
};
return function authorization(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,8 +1,9 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var AuthorizationError = require('../errors/authorizationerror')
, ForbiddenError = require('../errors/forbiddenerror');
var AuthorizationError = require('../errors/authorizationerror'),
ForbiddenError = require('../errors/forbiddenerror');
/**

@@ -68,3 +69,3 @@ * Handle authorization decisions from resource owners.

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

@@ -75,40 +76,59 @@ parse = options;

options = options || {};
parse = parse || function() {};
parse = parse || function () {};
if (!server) { throw new TypeError('oauth2orize.decision middleware requires a server argument'); }
if (!server) {
throw new TypeError('oauth2orize.decision middleware requires a server argument');
}
var cancelField = options.cancelField || 'cancel'
, userProperty = options.userProperty || 'user'
, key = options.sessionKey || 'authorize';
var cancelField = options.cancelField || 'cancel',
userProperty = options.userProperty || 'user',
key = options.sessionKey || 'authorize';
return async function decision(ctx, next) {
if (!ctx.session) { throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?'); }
if (!ctx.request.body) { throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?'); }
if (!ctx.state.oauth2) { throw new Error('OAuth2orize requires transaction support. Did you forget oauth2orize.transactionLoader(...)?'); }
if (!ctx.session[key]) { throw new ForbiddenError('Unable to load OAuth 2.0 transactions from session'); }
return function () {
var ref = _asyncToGenerator(function* (ctx, next) {
if (!ctx.session) {
throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?');
}
if (!ctx.request.body) {
throw new Error('OAuth2orize requires body parsing. Did you forget app.use(express.bodyParser())?');
}
if (!ctx.state.oauth2) {
throw new Error('OAuth2orize requires transaction support. Did you forget oauth2orize.transactionLoader(...)?');
}
if (!ctx.session[key]) {
throw new ForbiddenError('Unable to load OAuth 2.0 transactions from session');
}
const ares = await parse(ctx);
const ares = yield parse(ctx);
var tid = ctx.state.oauth2.transactionID;
ctx.state.oauth2.user = ctx.state[userProperty];
ctx.state.oauth2.res = ares || {};
var tid = ctx.state.oauth2.transactionID;
ctx.state.oauth2.user = ctx.state[userProperty];
ctx.state.oauth2.res = ares || {};
if (ctx.state.oauth2.res.allow === undefined) {
if (!ctx.request.body[cancelField]) { ctx.state.oauth2.res.allow = true; }
else { ctx.state.oauth2.res.allow = false; }
}
if (ctx.state.oauth2.res.allow === undefined) {
if (!ctx.request.body[cancelField]) {
ctx.state.oauth2.res.allow = true;
} else {
ctx.state.oauth2.res.allow = false;
}
}
try {
await server._respond(ctx, function() {
throw new AuthorizationError('Unsupported response type: ' + ctx.state.oauth2.req.type, 'unsupported_response_type');
});
try {
yield server._respond(ctx, function () {
throw new AuthorizationError('Unsupported response type: ' + ctx.state.oauth2.req.type, 'unsupported_response_type');
});
await next();
} finally {
// Delete the transaction once we are done
if (ctx.session[key]) {
delete ctx.session[key][tid];
yield next();
} finally {
// Delete the transaction once we are done
if (ctx.session[key]) {
delete ctx.session[key][tid];
}
}
}
};
};
});
return function decision(_x, _x2) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,1 +1,3 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**

@@ -6,3 +8,2 @@ * Module dependencies.

/**

@@ -45,8 +46,8 @@ * Handles errors encountered in OAuth 2.0 endpoints.

*/
module.exports = function(options) {
module.exports = function (options) {
options = options || {};
var mode = options.mode || 'direct'
, fragment = options.fragment || ['token']
, modes = options.modes || {};
var mode = options.mode || 'direct',
fragment = options.fragment || ['token'],
modes = options.modes || {};

@@ -60,59 +61,85 @@ if (!modes.query) {

return async function errorHandler(ctx, next) {
return function () {
var ref = _asyncToGenerator(function* (ctx, next) {
try {
await next();
} catch (err) {
if (mode == 'direct') {
if (err.status) { ctx.status = err.status; }
if (!ctx.status || ctx.status < 400) { ctx.status = 500; }
try {
yield next();
} catch (err) {
if (mode == 'direct') {
if (err.status) {
ctx.status = err.status;
}
if (!ctx.status || ctx.status < 400) {
ctx.status = 500;
}
if (ctx.status == 401) {
// TODO: set WWW-Authenticate header
}
if (ctx.status == 401) {
// TODO: set WWW-Authenticate header
}
var e = {};
e.error = err.code || 'server_error';
if (err.message) { e.error_description = err.message; }
if (err.uri) { e.error_uri = err.uri; }
var e = {};
e.error = err.code || 'server_error';
if (err.message) {
e.error_description = err.message;
}
if (err.uri) {
e.error_uri = err.uri;
}
ctx.set('Content-Type', 'application/json');
ctx.body = JSON.stringify(e);
ctx.app.emit('error', err, ctx);
} else if (mode == 'indirect') {
// If the redirectURI for this OAuth 2.0 transaction is invalid, the user
// agent will not be redirected and the client will not be informed. `next`
// immediately into the application's error handler, so a message can be
// displayed to the user.
if (!ctx.state.oauth2 || !ctx.state.oauth2.redirectURI) { throw err; }
ctx.set('Content-Type', 'application/json');
ctx.body = JSON.stringify(e);
ctx.app.emit('error', err, ctx);
} else if (mode == 'indirect') {
// If the redirectURI for this OAuth 2.0 transaction is invalid, the user
// agent will not be redirected and the client will not be informed. `next`
// immediately into the application's error handler, so a message can be
// displayed to the user.
if (!ctx.state.oauth2 || !ctx.state.oauth2.redirectURI) {
throw err;
}
var enc = 'query';
if (ctx.state.oauth2.req) {
var type = new UnorderedList(ctx.state.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'; }
if (ctx.state.oauth2.req.responseMode) {
// Encode the response using the requested mode, if specified.
enc = ctx.state.oauth2.req.responseMode;
var enc = 'query';
if (ctx.state.oauth2.req) {
var type = new UnorderedList(ctx.state.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';
}
if (ctx.state.oauth2.req.responseMode) {
// Encode the response using the requested mode, if specified.
enc = ctx.state.oauth2.req.responseMode;
}
}
}
var respond = modes[enc]
, params = {};
var respond = modes[enc],
params = {};
if (!respond) { throw err; }
if (!respond) {
throw err;
}
params.error = err.code || 'server_error';
if (err.message) { params.error_description = err.message; }
if (err.uri) { params.error_uri = err.uri; }
if (ctx.state.oauth2.req && ctx.state.oauth2.req.state) { params.state = ctx.state.oauth2.req.state; }
respond(ctx.state.oauth2, ctx.response, params);
} else {
throw err;
params.error = err.code || 'server_error';
if (err.message) {
params.error_description = err.message;
}
if (err.uri) {
params.error_uri = err.uri;
}
if (ctx.state.oauth2.req && ctx.state.oauth2.req.state) {
params.state = ctx.state.oauth2.req.state;
}
respond(ctx.state.oauth2, ctx.response, params);
} else {
throw err;
}
}
}
};
};
});
return function errorHandler(_x, _x2) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,1 +1,3 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**

@@ -6,3 +8,2 @@ * Module dependencies.

/**

@@ -52,11 +53,19 @@ * Exchanges authorization grants for access tokens.

if (!server) { throw new TypeError('oauth2orize.token middleware requires a server argument'); }
if (!server) {
throw new TypeError('oauth2orize.token middleware requires a server argument');
}
return async function token(ctx) {
var type = ctx.request.body.grant_type;
return function () {
var ref = _asyncToGenerator(function* (ctx) {
var type = ctx.request.body.grant_type;
await server._exchange(type, ctx, function() {
throw new TokenError('Unsupported grant type: ' + type, 'unsupported_grant_type');
yield server._exchange(type, ctx, function () {
throw new TokenError('Unsupported grant type: ' + type, 'unsupported_grant_type');
});
});
};
};
return function token(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -0,9 +1,10 @@

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
/**
* Module dependencies.
*/
var AuthorizationError = require('../errors/authorizationerror')
, BadRequestError = require('../errors/badrequesterror')
, ForbiddenError = require('../errors/forbiddenerror');
var AuthorizationError = require('../errors/authorizationerror'),
BadRequestError = require('../errors/badrequesterror'),
ForbiddenError = require('../errors/forbiddenerror');
/**

@@ -27,38 +28,54 @@ * Loads an OAuth 2.0 authorization transaction from the session.

*/
module.exports = function(server, options) {
module.exports = function (server, options) {
options = options || {};
if (!server) { throw new TypeError('oauth2orize.transactionLoader middleware requires a server argument'); }
if (!server) {
throw new TypeError('oauth2orize.transactionLoader middleware requires a server argument');
}
var field = options.transactionField || 'transaction_id'
, key = options.sessionKey || 'authorize';
var field = options.transactionField || 'transaction_id',
key = options.sessionKey || 'authorize';
return async function transactionLoader(ctx) {
if (!ctx.session) { throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?'); }
if (!ctx.session[key]) { throw new ForbiddenError('Unable to load OAuth 2.0 transactions from session'); }
return function () {
var ref = _asyncToGenerator(function* (ctx) {
if (!ctx.session) {
throw new Error('OAuth2orize requires session support. Did you forget app.use(express.session(...))?');
}
if (!ctx.session[key]) {
throw new ForbiddenError('Unable to load OAuth 2.0 transactions from session');
}
var query = ctx.query || {}
, body = ctx.request.body || {}
, tid = query[field] || body[field];
var query = ctx.query || {},
body = ctx.request.body || {},
tid = query[field] || body[field];
if (!tid) { throw new BadRequestError('Missing required parameter: ' + field); }
var txn = ctx.session[key][tid];
if (!txn) { throw new ForbiddenError('Unable to load OAuth 2.0 transaction: ' + tid); }
if (!tid) {
throw new BadRequestError('Missing required parameter: ' + field);
}
var txn = ctx.session[key][tid];
if (!txn) {
throw new ForbiddenError('Unable to load OAuth 2.0 transaction: ' + tid);
}
const client = await server.deserializeClient(txn.client);
if (!client) {
// At the time the request was initiated, the client was validated.
// Since then, however, it has been invalidated. The transaction will
// be invalidated and no response will be sent to the client.
delete ctx.session[key][tid];
throw new AuthorizationError('Unauthorized client', 'unauthorized_client');
}
const client = yield server.deserializeClient(txn.client);
if (!client) {
// At the time the request was initiated, the client was validated.
// Since then, however, it has been invalidated. The transaction will
// be invalidated and no response will be sent to the client.
delete ctx.session[key][tid];
throw new AuthorizationError('Unauthorized client', 'unauthorized_client');
}
ctx.state.oauth2 = {};
ctx.state.oauth2.transactionID = tid;
ctx.state.oauth2.client = client;
ctx.state.oauth2.redirectURI = txn.redirectURI;
ctx.state.oauth2.req = txn.req;
ctx.state.oauth2.info = txn.info;
};
};
ctx.state.oauth2 = {};
ctx.state.oauth2.transactionID = tid;
ctx.state.oauth2.client = client;
ctx.state.oauth2.redirectURI = txn.redirectURI;
ctx.state.oauth2.req = txn.req;
ctx.state.oauth2.info = txn.info;
});
return function transactionLoader(_x) {
return ref.apply(this, arguments);
};
}();
};

@@ -1,3 +0,3 @@

var url = require('url')
, qs = require('querystring');
var url = require('url'),
qs = require('querystring');

@@ -16,5 +16,6 @@ /**

exports.validate = function(txn) {
if (!txn.redirectURI) { throw new Error('Unable to issue redirect for OAuth 2.0 transaction'); }
};
exports.validate = function (txn) {
if (!txn.redirectURI) {
throw new Error('Unable to issue redirect for OAuth 2.0 transaction');
}
};

@@ -18,4 +18,6 @@ var url = require('url');

exports.validate = function(txn) {
if (!txn.redirectURI) { throw new Error('Unable to issue redirect for OAuth 2.0 transaction'); }
};
exports.validate = function (txn) {
if (!txn.redirectURI) {
throw new Error('Unable to issue redirect for OAuth 2.0 transaction');
}
};

@@ -5,13 +5,15 @@ 'use strict';

*/
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { return step("next", value); }, function (err) { return step("throw", err); }); } } return step("next"); }); }; }
var compose = require('koa-compose');
var UnorderedList = require('./unorderedlist')
, authorization = require('./middleware/authorization')
, decision = require('./middleware/decision')
, transactionLoader = require('./middleware/transactionLoader')
, token = require('./middleware/token')
, errorHandler = require('./middleware/errorHandler')
, utils = require('./utils')
, debug = require('debug')('oauth2orize');
var UnorderedList = require('./unorderedlist'),
authorization = require('./middleware/authorization'),
decision = require('./middleware/decision'),
transactionLoader = require('./middleware/transactionLoader'),
token = require('./middleware/token'),
errorHandler = require('./middleware/errorHandler'),
utils = require('./utils'),
debug = require('debug')('oauth2orize');
/**

@@ -57,8 +59,12 @@ * `Server` constructor.

*/
Server.prototype.grant = function(type, phase, fn) {
Server.prototype.grant = function (type, phase, fn) {
if (typeof type == 'object') {
// sig: grant(mod)
var mod = type;
if (mod.request) { this.grant(mod.name, 'request', mod.request); }
if (mod.response) { this.grant(mod.name, 'response', mod.response); }
if (mod.request) {
this.grant(mod.name, 'request', mod.request);
}
if (mod.response) {
this.grant(mod.name, 'response', mod.response);
}
return this;

@@ -69,4 +75,8 @@ }

var mod = phase;
if (mod.request) { this.grant(type, 'request', mod.request); }
if (mod.response) { this.grant(type, 'response', mod.response); }
if (mod.request) {
this.grant(type, 'request', mod.request);
}
if (mod.response) {
this.grant(type, 'response', mod.response);
}
return this;

@@ -80,4 +90,8 @@ }

}
if (type === '*') { type = null; }
if (type) { type = new UnorderedList(type); }
if (type === '*') {
type = null;
}
if (type) {
type = new UnorderedList(type);
}

@@ -113,3 +127,3 @@ if (phase == 'request') {

*/
Server.prototype.exchange = function(type, fn) {
Server.prototype.exchange = function (type, fn) {
if (typeof type == 'function') {

@@ -119,3 +133,5 @@ fn = type;

}
if (type === '*') { type = null; }
if (type === '*') {
type = null;
}

@@ -132,4 +148,3 @@ debug('register exchanger %s %s', type || '*', fn.name || 'anonymous');

*/
Server.prototype.authorize =
Server.prototype.authorization = function(options, validate, immediate) {
Server.prototype.authorize = Server.prototype.authorization = function (options, validate, immediate) {
return authorization(this, options, validate, immediate);

@@ -143,3 +158,3 @@ };

*/
Server.prototype.decision = function(options, parse) {
Server.prototype.decision = function (options, parse) {
if (options && options.loadTransaction === false) {

@@ -156,3 +171,3 @@ return decision(this, options, parse);

*/
Server.prototype.token = function(options) {
Server.prototype.token = function (options) {
return token(this, options);

@@ -166,3 +181,3 @@ };

*/
Server.prototype.errorHandler = function(options) {
Server.prototype.errorHandler = function (options) {
return errorHandler(options);

@@ -182,27 +197,33 @@ };

*/
Server.prototype.serializeClient = async function(fn) {
if (typeof fn === 'function') {
return this._serializers.push(fn);
}
Server.prototype.serializeClient = function () {
var ref = _asyncToGenerator(function* (fn) {
if (typeof fn === 'function') {
return this._serializers.push(fn);
}
// private implementation that traverses the chain of serializers, attempting
// to serialize a client
var client = fn;
// private implementation that traverses the chain of serializers, attempting
// to serialize a client
var client = fn;
var stack = this._serializers;
var stack = this._serializers;
for (var i = 0; ; i++) {
let layer = stack[i];
for (var i = 0;; i++) {
let layer = stack[i];
if (!layer) {
throw new Error('Failed to serialize client. Register serialization function using serializeClient().');
}
if (!layer) {
throw new Error('Failed to serialize client. Register serialization function using serializeClient().');
}
let obj = await layer(client);
if (obj) {
return obj;
let obj = yield layer(client);
if (obj) {
return obj;
}
}
}
};
});
return function (_x) {
return ref.apply(this, arguments);
};
}();
/**

@@ -221,30 +242,35 @@ * Registers a function used to deserialize client objects out of the session.

*/
Server.prototype.deserializeClient = async function(fn) {
if (typeof fn === 'function') {
return this._deserializers.push(fn);
}
Server.prototype.deserializeClient = function () {
var ref = _asyncToGenerator(function* (fn) {
if (typeof fn === 'function') {
return this._deserializers.push(fn);
}
// private implementation that traverses the chain of deserializers,
// attempting to deserialize a client
var obj = fn;
// private implementation that traverses the chain of deserializers,
// attempting to deserialize a client
var obj = fn;
var stack = this._deserializers;
var stack = this._deserializers;
for (var i = 0; ; i++) {
let layer = stack[i];
if (!layer) {
throw new Error('Failed to deserialize client. Register deserialization function using deserializeClient().');
}
for (var i = 0;; i++) {
let layer = stack[i];
if (!layer) {
throw new Error('Failed to deserialize client. Register deserialization function using deserializeClient().');
}
let client = await layer(obj);
// a valid client existed when establishing the session, but that client has
// since been deauthorized
if (client === null || client === false) {
return false;
} else if (client) {
return client;
let client = yield layer(obj);
// a valid client existed when establishing the session, but that client has
// since been deauthorized
if (client === null || client === false) {
return false;
} else if (client) {
return client;
}
}
}
};
});
return function (_x2) {
return ref.apply(this, arguments);
};
}();

@@ -259,20 +285,30 @@ /**

*/
Server.prototype._parse = async function(type, ctx) {
var ultype = new UnorderedList(type)
, stack = this._reqParsers
, areq = {};
Server.prototype._parse = function () {
var ref = _asyncToGenerator(function* (type, ctx) {
var ultype = new UnorderedList(type),
stack = this._reqParsers,
areq = {};
if (type) { areq.type = type; }
if (type) {
areq.type = type;
}
for (var i = 0; ; i++) {
let layer = stack[i];
if (!layer) { return areq; }
debug('parse:%s', layer.handle.name || 'anonymous');
if (layer.type === null || layer.type.equalTo(ultype)) {
let o = await layer.handle(ctx);
utils.merge(areq, o);
for (var i = 0;; i++) {
let layer = stack[i];
if (!layer) {
return areq;
}
debug('parse:%s', layer.handle.name || 'anonymous');
if (layer.type === null || layer.type.equalTo(ultype)) {
let o = yield layer.handle(ctx);
utils.merge(areq, o);
}
}
}
};
});
return function (_x3, _x4) {
return ref.apply(this, arguments);
};
}();
/**

@@ -285,7 +321,7 @@ * Respond to authorization transaction using registered grant middleware.

*/
Server.prototype._respond = function(ctx, notHandled) {
Server.prototype._respond = function (ctx, notHandled) {
var ultype = new UnorderedList(ctx.state.oauth2.req.type);
var stack = this._resHandlers.filter(function(layer) {
var stack = this._resHandlers.filter(function (layer) {
return layer.type === null || layer.type.equalTo(ultype);
}).map((layer) => layer.handle);
}).map(layer => layer.handle);

@@ -305,11 +341,16 @@ var composed = compose(stack);

*/
Server.prototype._exchange = async function(type, ctx, notHandled) {
var stack = this._exchanges.filter(function(layer) {
return layer.type === null || layer.type === type;
}).map((layer) => layer.handle);
Server.prototype._exchange = function () {
var ref = _asyncToGenerator(function* (type, ctx, notHandled) {
var stack = this._exchanges.filter(function (layer) {
return layer.type === null || layer.type === type;
}).map(layer => layer.handle);
var composed = compose(stack);
return composed(ctx, notHandled);
};
var composed = compose(stack);
return composed(ctx, notHandled);
});
return function (_x5, _x6, _x7) {
return ref.apply(this, arguments);
};
}();

@@ -319,2 +360,2 @@ /**

*/
exports = module.exports = Server;
exports = module.exports = Server;

@@ -21,8 +21,10 @@ /**

*/
UnorderedList.prototype.equalTo = function(other) {
UnorderedList.prototype.equalTo = function (other) {
if (!(other instanceof UnorderedList)) {
other = new UnorderedList(other);
}
if (this.length != other.length) { return false; }
if (this.length != other.length) {
return false;
}
for (var i = 0, len = this._items.length; i < len; i++) {

@@ -44,3 +46,3 @@ var item = this._items[i];

*/
UnorderedList.prototype.contains = function(val) {
UnorderedList.prototype.contains = function (val) {
return this._items.indexOf(val) != -1;

@@ -56,5 +58,7 @@ };

*/
UnorderedList.prototype.containsAny = function(arr) {
UnorderedList.prototype.containsAny = function (arr) {
for (var i = 0, len = arr.length; i < len; i++) {
if (this._items.indexOf(arr[i]) != -1) { return true; }
if (this._items.indexOf(arr[i]) != -1) {
return true;
}
}

@@ -70,3 +74,3 @@ return false;

*/
UnorderedList.prototype.toString = function() {
UnorderedList.prototype.toString = function () {
return this._items.join(' ');

@@ -81,3 +85,3 @@ };

*/
UnorderedList.prototype._length = function() {
UnorderedList.prototype._length = function () {
return this._items.length;

@@ -89,2 +93,2 @@ };

*/
module.exports = UnorderedList;
module.exports = UnorderedList;
exports.merge = require('utils-merge');
exports.uid = require('uid2');
exports.uid = require('uid2');
{
"name": "oauth2orize-koa",
"version": "1.2.0",
"version": "1.2.1",
"description": "OAuth 2.0 authorization server toolkit for Node.js.",

@@ -40,2 +40,3 @@ "keywords": [

"devDependencies": {
"babel-cli": "^6.4.5",
"babel-eslint": "^4.1.6",

@@ -52,4 +53,7 @@ "babel-preset-stage-3": "^6.3.13",

"scripts": {
"version": "node_modules/.bin/babel src --out-dir lib",
"postversion": "git push && git push --tags",
"pretest": "node_modules/.bin/babel src --out-dir lib",
"test": "node_modules/.bin/mocha --reporter spec --require test/bootstrap/node test/*.test.js test/**/*.test.js"
}
}
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