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

@equisoft/oauth2orize-bearer-to-bearer

Package Overview
Dependencies
Maintainers
11
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@equisoft/oauth2orize-bearer-to-bearer - npm Package Compare versions

Comparing version 1.1.3 to 1.1.4-snapshot.20230111192632

.eslintrc.js

111

lib/oauth2orize-bearer-to-bearer/exchange.js

@@ -40,10 +40,12 @@ /**

*
* server.exchange('urn:ietf:params:oauth:grant-type:jwt-bearer', oauth2orize.exchange.jwtBearer(function(client, scope, assertion, done) {
* server.exchange(
* 'urn:ietf:params:oauth:grant-type:jwt-bearer',
* oauth2orize.exchange.jwtBearer(function(client, scope, assertion, done) {
* AccessToken.create(client, scope, function(err, accessToken) {
* if (err) { return done(err); }
* done(null, accessToken);
* });
* })
* );
*
* AccessToken.create(client, scope, function(err, accessToken) {
* if (err) { return done(err); }
* done(null, accessToken);
* });
* }));
*
* References:

@@ -60,58 +62,63 @@ * - [JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants](https://tools.ietf.org/html/rfc7523#section-2.1)

module.exports = (issue, options = {}) => {
if (!issue) throw new Error('OAuth 2.0 jwtBearer exchange middleware requires an issue function.');
if (!issue) throw new Error('OAuth 2.0 jwtBearer exchange middleware requires an issue function.');
const userProperty = options.userProperty || 'user';
const scopeSeparator = options.scopeSeparator || ' ';
const userProperty = options.userProperty || 'user';
const scopeSeparator = options.scopeSeparator || ' ';
return (req, res, next) => {
if (!req.body) {
return next(new Error('Request body not parsed. Use bodyParser middleware.'));
}
return (req, res, next) => {
if (!req.body) {
next(new Error('Request body not parsed. Use bodyParser middleware.'));
return;
}
// 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.
const client = req[userProperty];
const { assertion } = req.body;
let { scope } = req.body;
// 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.
const client = req[userProperty];
const { assertion } = req.body;
let { scope } = req.body;
if (!assertion) {
return next(new TokenError('missing assertion parameter', 'invalid_request'));
}
if (!assertion) {
next(new TokenError('missing assertion parameter', 'invalid_request'));
return;
}
if (scope) {
if (typeof scope !== 'string') {
return next(new TokenError('Invalid parameter: scope must be a string', 'invalid_request'));
}
scope = scope.split(scopeSeparator);
} else {
scope = [];
}
if (scope) {
if (typeof scope !== 'string') {
next(new TokenError('Invalid parameter: scope must be a string', 'invalid_request'));
return;
}
scope = scope.split(scopeSeparator);
} else {
scope = [];
}
function issued(err, accessToken, refreshToken = null, params = {}) {
if (err) {
return next(err);
}
if (!accessToken) {
return next(new TokenError('Invalid authorization code', 'invalid_grant'));
}
function issued(err, accessToken, refreshToken = null, params = {}) {
if (err) {
next(err);
return;
}
if (!accessToken) {
next(new TokenError('Invalid authorization code', 'invalid_grant'));
return;
}
const tok = {};
tok.access_token = accessToken;
if (refreshToken !== null) {
tok.refresh_token = refreshToken;
}
const tok = {};
tok.access_token = accessToken;
if (refreshToken !== null) {
tok.refresh_token = refreshToken;
}
utils.merge(tok, params);
utils.merge(tok, params);
tok.token_type = tok.token_type || 'Bearer';
tok.token_type = tok.token_type || 'Bearer';
const json = JSON.stringify(tok);
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
res.end(json);
}
const json = JSON.stringify(tok);
res.setHeader('Content-Type', 'application/json');
res.setHeader('Cache-Control', 'no-store');
res.setHeader('Pragma', 'no-cache');
res.end(json);
}
issue(client, scope, assertion, issued);
};
issue(client, scope, assertion, issued);
};
};

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

'use strict';
exports.JWTToBearer = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
exports.SAML2ToBearer = 'urn:ietf:params:oauth:grant-type:saml2-bearer';

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

'use strict';
/**

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

/**

@@ -13,0 +10,0 @@ * Exports

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

'use strict';
exports.merge = require('utils-merge');
{
"name": "@equisoft/oauth2orize-bearer-to-bearer",
"version": "1.1.3",
"version": "1.1.4-snapshot.20230111192632",
"description": "Bearer Token Exchange Middleware for OAuth2orize.",

@@ -38,23 +38,33 @@ "author": "Equisoft Inc.",

"dependencies": {
"oauth2orize": "^1.11.0",
"oauth2orize": "^1.11.1",
"utils-merge": "^1.0.1"
},
"devDependencies": {
"chai": "^4.1.2",
"eslint": "^6.8",
"eslint-config-airbnb": "^18.0.1",
"mocha": "^5.2.0",
"nyc": "^15.0",
"sinon": "^6.1.0",
"sinon-chai": "^3.2.0"
"@equisoft/eslint-config": "^3.0.3",
"@microsoft/eslint-formatter-sarif": "2.1.7",
"chai": "^4.3.7",
"eslint": "7.32.0",
"eslint-plugin-chai-friendly": "0.7.2",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-mocha": "10.1.0",
"mocha": "^10.2.0",
"mocha-junit-reporter": "2.1.0",
"nyc": "^15.1.0",
"sinon": "^15.0.1",
"sinon-chai": "^3.7.0"
},
"scripts": {
"test": "./node_modules/mocha/bin/mocha test",
"test:watch": "./node_modules/mocha/bin/mocha --watch test",
"test:coverage": "./node_modules/nyc/bin/nyc.js --reporter=lcov --reporter=text ./node_modules/mocha/bin/mocha test"
"test": "mocha test",
"test:watch": "mocha --watch test",
"test:ci": "NODE_ENV=test nyc -r clover --report-dir build/mocha/coverage mocha --reporter mocha-junit-reporter --reporter-options mochaFile=build/mocha/junit.xml --non-interactive --no-progress test",
"eslint": "eslint . --ext .js"
},
"engines": {
"node": ">=8.0.0"
"node": ">=12.0.0",
"yarn": ">=1.5.1"
},
"private": false
}
"publishConfig": {
"access": "public"
},
"packageManager": "yarn@3.3.1"
}

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

'use strict';
/* eslint-disable no-underscore-dangle */
const chai = require('chai');

@@ -17,269 +16,273 @@ const sinonChai = require('sinon-chai');

function setUpBearerToBearerExchangeMiddleware(options, issue) {
bearerToBearerExchange = bearerToBearer(issue, options);
bearerToBearerExchange = bearerToBearer(issue, options);
}
function getDefaultIssueFunction() {
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t');
}
return done(new Error('something is wrong'));
};
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t');
}
return done(new Error('something is wrong'));
};
}
function getIssueReturningRefreshTokenFunction() {
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t', 'R3fr3SHs3cr1t');
}
return done(new Error('something is wrong'));
};
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t', 'R3fr3SHs3cr1t');
}
return done(new Error('something is wrong'));
};
}
function getIssueMergingCustomParamsFunction(params) {
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t', null, params);
}
return done(new Error('something is wrong'));
};
return (client, scope, jwt, done) => {
if (client.id === 'c123' && jwt === 'header.claimSet.signature') {
return done(null, 's3cr1t', null, params);
}
return done(new Error('something is wrong'));
};
}
describe('exchange middleware', () => {
it('should return a function', () => {
const jwtBearerFunction = bearerToBearer(() => {
it('should return a function', () => {
const jwtBearerFunction = bearerToBearer(() => {
});
expect(jwtBearerFunction).to.be.a('Function');
});
expect(jwtBearerFunction).to.be.a('Function');
});
describe('Request Validation', () => {
beforeEach(() => {
res = new mock.Response();
setUpBearerToBearerExchangeMiddleware({}, getDefaultIssueFunction());
});
describe('Request Validation', () => {
beforeEach(() => {
res = new mock.Response();
setUpBearerToBearerExchangeMiddleware({}, getDefaultIssueFunction());
});
it('Should throw TokenError if no assertion is found', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = {};
it('Should throw TokenError if no assertion is found', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = {};
function next(err) {
expect(err).to.be.an.instanceof(TokenError);
expect(err.status).to.equal(400);
expect(err.code).to.eql('invalid_request');
expect(err.message).to.eql('missing assertion parameter');
done();
}
function next(err) {
expect(err).to.be.an.instanceof(TokenError);
expect(err.status).to.equal(400);
expect(err.code).to.eql('invalid_request');
expect(err.message).to.eql('missing assertion parameter');
done();
}
bearerToBearerExchange(req, res, next);
});
bearerToBearerExchange(req, res, next);
});
it('Should throw TokenError if scope parameter is not a string', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope: {} };
it('Should throw TokenError if scope parameter is not a string', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope: {} };
function next(err) {
expect(err).to.be.an.instanceof(TokenError);
expect(err.status).to.equal(400);
expect(err.code).to.eql('invalid_request');
expect(err.message).to.eql('Invalid parameter: scope must be a string');
done();
}
function next(err) {
expect(err).to.be.an.instanceof(TokenError);
expect(err.status).to.equal(400);
expect(err.code).to.eql('invalid_request');
expect(err.message).to.eql('Invalid parameter: scope must be a string');
done();
}
bearerToBearerExchange(req, res, next);
});
bearerToBearerExchange(req, res, next);
});
it('Should use userProperty configuration to get client', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.userOptional = { id: 'c12345', name: 'Example Optional' };
req.body = { assertion: 'header.claimSet.signature' };
it('Should use userProperty configuration to get client', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.userOptional = { id: 'c12345', name: 'Example Optional' };
req.body = { assertion: 'header.claimSet.signature' };
setUpBearerToBearerExchangeMiddleware({}, (client) => {
expect(client).to.deep.equal({ id: 'c123', name: 'Example' });
return done();
});
setUpBearerToBearerExchangeMiddleware({}, (client) => {
expect(client).to.deep.equal({ id: 'c123', name: 'Example' });
return done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should modify userProperty configuration from options to get client', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.userOptional = { id: 'c12345', name: 'Example Optional' };
req.body = { assertion: 'header.claimSet.signature' };
it('Should modify userProperty configuration from options to get client', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.userOptional = { id: 'c12345', name: 'Example Optional' };
req.body = { assertion: 'header.claimSet.signature' };
setUpBearerToBearerExchangeMiddleware({ userProperty: 'userOptional' }, (client) => {
expect(client).to.deep.equal({ id: 'c12345', name: 'Example Optional' });
done();
});
setUpBearerToBearerExchangeMiddleware({ userProperty: 'userOptional' }, (client) => {
expect(client).to.deep.equal({ id: 'c12345', name: 'Example Optional' });
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should use scopeSeparator configuration to split scope', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope:'scope1:read scope2:write scope3' };
it('Should use scopeSeparator configuration to split scope', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope: 'scope1:read scope2:write scope3' };
setUpBearerToBearerExchangeMiddleware({}, (client, scope) => {
expect(scope).to.deep.equal(['scope1:read', 'scope2:write', 'scope3']);
done();
});
setUpBearerToBearerExchangeMiddleware({}, (client, scope) => {
expect(scope).to.deep.equal(['scope1:read', 'scope2:write', 'scope3']);
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should use scopeSeparator configuration to split scope', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope:'scope1:read.scope2:write.scope3' };
it('Should use scopeSeparator configuration to split scope', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope: 'scope1:read.scope2:write.scope3' };
setUpBearerToBearerExchangeMiddleware({ scopeSeparator:':' }, (client, scope) => {
expect(scope).to.deep.equal(['scope1', 'read.scope2', 'write.scope3']);
done();
});
setUpBearerToBearerExchangeMiddleware({ scopeSeparator: ':' }, (client, scope) => {
expect(scope).to.deep.equal(['scope1', 'read.scope2', 'write.scope3']);
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should send empty array if no scope is in body', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
it('Should send empty array if no scope is in body', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
setUpBearerToBearerExchangeMiddleware({ scopeSeparator:':' }, (client, scope) => {
expect(scope).to.deep.equal([]);
done();
});
setUpBearerToBearerExchangeMiddleware({ scopeSeparator: ':' }, (client, scope) => {
expect(scope).to.deep.equal([]);
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should send empty array if scope is an empty string', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope:'' };
it('Should send empty array if scope is an empty string', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature', scope: '' };
setUpBearerToBearerExchangeMiddleware({ scopeSeparator:':' }, (client, scope) => {
// eslint-disable-next-line no-unused-expressions
expect(scope).to.be.empty;
done();
});
setUpBearerToBearerExchangeMiddleware({ scopeSeparator: ':' }, (client, scope) => {
// eslint-disable-next-line no-unused-expressions
expect(scope).to.be.empty;
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('Should give back assertion as is from body', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
it('Should give back assertion as is from body', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
setUpBearerToBearerExchangeMiddleware({}, (client, scope, assertion) => {
expect(assertion).to.equal('header.claimSet.signature');
done();
});
setUpBearerToBearerExchangeMiddleware({}, (client, scope, assertion) => {
expect(assertion).to.equal('header.claimSet.signature');
done();
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
});
});
describe('Response', () => {
beforeEach(() => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
describe('Response', () => {
beforeEach(() => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = { assertion: 'header.claimSet.signature' };
res = new mock.Response();
res = new mock.Response();
setUpBearerToBearerExchangeMiddleware({}, getDefaultIssueFunction());
});
setUpBearerToBearerExchangeMiddleware({}, getDefaultIssueFunction());
});
it('Should not send response if error is sent to issued function', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = {};
it('Should not send response if error is sent to issued function', (done) => {
req = new mock.Request();
req.user = { id: 'c123', name: 'Example' };
req.body = {};
res.end = () => {
done(new Error('Shouldn\'t have call end() of response'));
};
res.end = () => {
done(new Error('Shouldn\'t have call end() of response'));
};
function next(err) {
expect(err).to.be.an.instanceof(Error);
done();
}
function next(err) {
expect(err).to.be.an.instanceof(Error);
done();
}
bearerToBearerExchange(req, res, next);
});
bearerToBearerExchange(req, res, next);
});
it('should set Content-Type header to application/json', (done) => {
res.end = () => {
expect(res._headers['Content-Type']).to.eql('application/json');
done();
};
it('should set Content-Type header to application/json', (done) => {
res.end = () => {
expect(res._headers['Content-Type']).to.eql('application/json');
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should set Cache-Control header to no-store', (done) => {
res.end = () => {
expect(res._headers['Cache-Control']).to.eql('no-store');
done();
};
it('should set Cache-Control header to no-store', (done) => {
res.end = () => {
expect(res._headers['Cache-Control']).to.eql('no-store');
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should set Pragma header to no-cache', (done) => {
res.end = () => {
expect(res._headers.Pragma).to.eql('no-cache');
done();
};
it('should set Pragma header to no-cache', (done) => {
res.end = () => {
expect(res._headers.Pragma).to.eql('no-cache');
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should set access token in response', (done) => {
res.done = () => {
expect(res._data).to.eql('{"access_token":"s3cr1t","token_type":"Bearer"}');
done();
};
it('should set access token in response', (done) => {
res.done = () => {
expect(res._data).to.eql('{"access_token":"s3cr1t","token_type":"Bearer"}');
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should set refresh token in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueReturningRefreshTokenFunction());
res.done = () => {
expect(res._data).to.eql('{"access_token":"s3cr1t","refresh_token":"R3fr3SHs3cr1t","token_type":"Bearer"}');
done();
};
it('should set refresh token in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueReturningRefreshTokenFunction());
res.done = () => {
expect(res._data).to.eql(
'{"access_token":"s3cr1t","refresh_token":"R3fr3SHs3cr1t","token_type":"Bearer"}',
);
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should merge custom params in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueMergingCustomParamsFunction({ test: 'testValue' }));
res.done = () => {
expect(res._data).to.eql('{"access_token":"s3cr1t","test":"testValue","token_type":"Bearer"}');
done();
};
it('should merge custom params in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueMergingCustomParamsFunction({ test: 'testValue' }));
res.done = () => {
expect(res._data).to.eql('{"access_token":"s3cr1t","test":"testValue","token_type":"Bearer"}');
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
it('should overwrite params while merging custom params in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueMergingCustomParamsFunction({
access_token: 'overwrite.access.token',
test: 'testValue',
}));
res.done = () => {
expect(res._data).to.eql('{"access_token":"overwrite.access.token","test":"testValue","token_type":"Bearer"}');
done();
};
it('should overwrite params while merging custom params in response', (done) => {
setUpBearerToBearerExchangeMiddleware({}, getIssueMergingCustomParamsFunction({
access_token: 'overwrite.access.token',
test: 'testValue',
}));
res.done = () => {
expect(res._data).to.eql(
'{"access_token":"overwrite.access.token","test":"testValue","token_type":"Bearer"}',
);
done();
};
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
bearerToBearerExchange(req, res, (err) => { if (err) done(err); });
});
});
});
});

@@ -1,18 +0,22 @@

function Request() {
/* eslint-disable no-underscore-dangle,max-classes-per-file */
class Request {
}
function Response() {
this._headers = {};
this._data = '';
}
class Response {
constructor() {
this._headers = {};
this._data = '';
}
Response.prototype.setHeader = function(name, value) {
this._headers[name] = value;
};
setHeader(name, value) {
this._headers[name] = value;
}
Response.prototype.end = function(data, encoding) {
this._data += data;
if (this.done) { this.done(); }
};
// eslint-disable-next-line no-unused-vars
end(data, encoding) {
this._data += data;
if (this.done) { this.done(); }
}
}
module.exports ={Request, Response}
module.exports = { Request, Response };
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