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

http-auth-utils

Package Overview
Dependencies
Maintainers
1
Versions
23
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

http-auth-utils - npm Package Compare versions

Comparing version 0.0.2 to 1.0.0

.babelrc

64

dist/index.js
'use strict';
Object.defineProperty(exports, '__esModule', {
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mecanisms = exports.BEARER = exports.DIGEST = exports.BASIC = undefined;
exports.parseWWWAuthenticateHeader = parseWWWAuthenticateHeader;
exports.parseAuthorizationHeader = parseAuthorizationHeader;
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _yerror = require('yerror');

@@ -13,6 +14,16 @@

var _mecanismsBasic = require('./mecanisms/basic');
var _basic = require('./mecanisms/basic');
var _mecanismsBasic2 = _interopRequireDefault(_mecanismsBasic);
var _basic2 = _interopRequireDefault(_basic);
var _digest = require('./mecanisms/digest');
var _digest2 = _interopRequireDefault(_digest);
var _bearer = require('./mecanisms/bearer');
var _bearer2 = _interopRequireDefault(_bearer);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**

@@ -22,6 +33,2 @@ * @module http-auth-utils

var _mecanismsDigest = require('./mecanisms/digest');
var _mecanismsDigest2 = _interopRequireDefault(_mecanismsDigest);
/**

@@ -32,3 +39,3 @@ * Basic authentication mecanism.

*/
exports.BASIC = _mecanismsBasic2['default'];
exports.BASIC = _basic2.default;

@@ -40,11 +47,20 @@ /**

*/
exports.DIGEST = _mecanismsDigest2['default'];
exports.DIGEST = _digest2.default;
/**
* Bearer authentication mecanism.
* @type {Object}
* @see {@link module:http-auth-utils/mecanisms/digest}
*/
exports.BEARER = _bearer2.default;
/**
* Natively supported authentication mecanisms.
* @type {Array}
*/
var mecanisms = [_mecanismsBasic2['default'], _mecanismsDigest2['default']];
exports.mecanisms = mecanisms;
var mecanisms = exports.mecanisms = [_basic2.default, _digest2.default, _bearer2.default];
/**

@@ -67,6 +83,7 @@ * Parse HTTP WWW-Authenticate header contents.

*/
var parseWWWAuthenticateHeader = function parseWWWAuthenticateHeader(header) {
var authMecanisms = arguments[1] === undefined ? mecanisms : arguments[1];
function parseWWWAuthenticateHeader(header) {
var authMecanisms = arguments.length <= 1 || arguments[1] === undefined ? mecanisms : arguments[1];
var result = null;
authMecanisms.some(function (authMecanism) {

@@ -83,6 +100,5 @@ if (0 === header.indexOf(authMecanism.type + ' ')) {

}
throw new _yerror2['default']('E_UNKNOWN_AUTH_MECANISM', header);
};
throw new _yerror2.default('E_UNKNOWN_AUTH_MECANISM', header);
}
exports.parseWWWAuthenticateHeader = parseWWWAuthenticateHeader;
/**

@@ -92,3 +108,3 @@ * Parse HTTP Authorization header contents.

* @param {string} header The Authorization header contents
* @param {Array} [authMecanisms=[BASIC, DIGEST]] Allow providing custom authentication mecanisms.
* @param {Array} [authMecanisms=[BASIC, DIGEST, BEARER]] Allow custom authentication mecanisms.
* @return {Object} Result of the contents parse.

@@ -106,6 +122,7 @@ * @api public

*/
var parseAuthorizationHeader = function parseAuthorizationHeader(header) {
var authMecanisms = arguments[1] === undefined ? mecanisms : arguments[1];
function parseAuthorizationHeader(header) {
var authMecanisms = arguments.length <= 1 || arguments[1] === undefined ? mecanisms : arguments[1];
var result = null;
authMecanisms.some(function (authMecanism) {

@@ -122,4 +139,3 @@ if (0 === header.indexOf(authMecanism.type + ' ')) {

}
throw new _yerror2['default']('E_UNKNOWN_AUTH_MECANISM', header);
};
exports.parseAuthorizationHeader = parseAuthorizationHeader;
throw new _yerror2.default('E_UNKNOWN_AUTH_MECANISM', header);
}
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _assert = require('assert');

@@ -15,2 +13,4 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('index', function () {

@@ -21,3 +21,3 @@

it('should parse Basic headers', function () {
(0, _neatequal2['default'])((0, _index.parseWWWAuthenticateHeader)('Basic realm="test"'), {
(0, _neatequal2.default)((0, _index.parseWWWAuthenticateHeader)('Basic realm="test"'), {
type: 'Basic',

@@ -34,11 +34,30 @@ data: {

it('should parse Basic headers', function () {
(0, _neatequal2['default'])((0, _index.parseAuthorizationHeader)('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
(0, _neatequal2.default)((0, _index.parseAuthorizationHeader)('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
type: 'Basic',
data: {
username: 'Aladdin',
username: 'Ali Baba',
password: 'open sesame',
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
}
});
(0, _neatequal2.default)((0, _index.parseAuthorizationHeader)('Basic bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), {
type: 'Basic',
data: {
username: 'nicolas.froidure@simplifield.com',
password: 'test',
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='
}
});
});
it('should parse Basic headers with a ":" char in the password', function () {
(0, _neatequal2.default)((0, _index.parseAuthorizationHeader)('Basic Sm9objpSOlU6a2lkZGluZz8='), {
type: 'Basic',
data: {
username: 'John',
password: 'R:U:kidding?',
hash: 'Sm9objpSOlU6a2lkZGluZz8='
}
});
});
});

@@ -49,10 +68,11 @@

it('should export bot DIGEST and BASIC mecanisms', function () {
_assert2['default'].equal(_index.mecanisms.length, 2);
_assert2.default.equal(_index.mecanisms.length, 3);
});
it('should export bot DIGEST and BASIC mecanisms', function () {
(0, _assert2['default'])(_index.BASIC);
(0, _assert2['default'])(_index.DIGEST);
it('should export DIGEST BASIC and BEARER mecanisms', function () {
(0, _assert2.default)(_index.BASIC);
(0, _assert2.default)(_index.DIGEST);
(0, _assert2.default)(_index.BEARER);
});
});
});

@@ -1,14 +0,7 @@

/**
* @module http-auth-utils/mecanisms/basic
*/
'use strict';
Object.defineProperty(exports, '__esModule', {
Object.defineProperty(exports, "__esModule", {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }
var _yerror = require('yerror');

@@ -20,2 +13,8 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); } /**
* @module http-auth-utils/mecanisms/basic
*/
var AUTHORIZED_WWW_AUTHENTICATE_KEYS = ['realm'];

@@ -38,3 +37,3 @@

* Parse the WWW Authenticate header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).
* @param {String} rest The header rest (string after the authentication mecanism prefix).
* @return {Object} Object representing the result of the parse operation.

@@ -55,3 +54,3 @@ * @example

* Build the WWW Authenticate header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The built rest.

@@ -73,9 +72,9 @@ * @example

* Parse the Authorization header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).)
* @param {String} rest The header rest (string after the authentication mecanism prefix).)
* @return {Object} Object representing the result of the parse operation {hash}.
* @example
* assert.deepEqual(
* BASIC.parseAuthorizationRest('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
* hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
* username: 'Aladdin',
* BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
* username: 'Ali Baba',
* password: 'open sesame'

@@ -88,3 +87,3 @@ * }

if (!rest) {
throw new _yerror2['default']('E_EMPTY_AUTH');
throw new _yerror2.default('E_EMPTY_AUTH');
}

@@ -97,2 +96,3 @@

return {

@@ -112,5 +112,5 @@ hash: rest,

* BASIC.buildAuthorizationRest({
* hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* }),
* 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* );

@@ -120,3 +120,3 @@ * @api public

buildAuthorizationRest: function buildAuthorizationRest() {
var _ref = arguments[0] === undefined ? {} : arguments[0];
var _ref = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];

@@ -131,3 +131,3 @@ var hash = _ref.hash;

if (!hash) {
throw new _yerror2['default']('E_NO_HASH');
throw new _yerror2.default('E_NO_HASH');
}

@@ -144,6 +144,6 @@ return hash;

* BASIC.computeHash({
* username: 'Aladdin',
* username: 'Ali Baba',
* password: 'open sesame'
* }),
* 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* );

@@ -165,4 +165,4 @@ * @api public

* assert.deepEqual(
* BASIC.decodeHash('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
* username: 'Aladdin',
* BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
* username: 'Ali Baba',
* password: 'open sesame'

@@ -176,10 +176,11 @@ * }

var _toString$split2 = _slicedToArray(_toString$split, 2);
var _toString$split2 = _toArray(_toString$split);
var username = _toString$split2[0];
var password = _toString$split2[1];
var passwordParts = _toString$split2.slice(1);
return {
username: username,
password: password
password: passwordParts.join(':')
};

@@ -189,3 +190,2 @@ }

exports['default'] = BASIC;
module.exports = exports['default'];
exports.default = BASIC;
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _assert = require('assert');

@@ -17,2 +15,4 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('BASIC', function () {

@@ -23,3 +23,3 @@

it('should be the basic auth prefix', function () {
_assert2['default'].equal(_basic2['default'].type, 'Basic');
_assert2.default.equal(_basic2.default.type, 'Basic');
});

@@ -31,3 +31,3 @@ });

it('should work', function () {
(0, _neatequal2['default'])(_basic2['default'].parseWWWAuthenticateRest('realm="perlinpinpin"'), {
(0, _neatequal2.default)(_basic2.default.parseWWWAuthenticateRest('realm="perlinpinpin"'), {
realm: 'perlinpinpin'

@@ -41,3 +41,3 @@ });

it('should work', function () {
_assert2['default'].equal(_basic2['default'].buildWWWAuthenticateRest({
_assert2.default.equal(_basic2.default.buildWWWAuthenticateRest({
realm: 'perlinpinpin'

@@ -48,3 +48,3 @@ }), 'realm="perlinpinpin"');

it('should be the inverse of parseWWWAuthenticateRest', function () {
(0, _neatequal2['default'])(_basic2['default'].parseWWWAuthenticateRest(_basic2['default'].buildWWWAuthenticateRest({
(0, _neatequal2.default)(_basic2.default.parseWWWAuthenticateRest(_basic2.default.buildWWWAuthenticateRest({
realm: 'perlinpinpin'

@@ -60,7 +60,12 @@ })), {

it('should work', function () {
(0, _neatequal2['default'])(_basic2['default'].parseAuthorizationRest('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
(0, _neatequal2.default)(_basic2.default.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame'
});
(0, _neatequal2.default)(_basic2.default.parseAuthorizationRest('bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), {
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==',
username: 'nicolas.froidure@simplifield.com',
password: 'test'
});
});

@@ -72,22 +77,22 @@ });

it('should work with credentials', function () {
_assert2['default'].equal(_basic2['default'].buildAuthorizationRest({
username: 'Aladdin',
_assert2.default.equal(_basic2.default.buildAuthorizationRest({
username: 'Ali Baba',
password: 'open sesame'
}), 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=');
});
it('should work with just the hash', function () {
_assert2['default'].equal(_basic2['default'].buildAuthorizationRest({
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
}), 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
_assert2.default.equal(_basic2.default.buildAuthorizationRest({
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=');
});
it('should be the inverse of parseAuthorizationRest', function () {
(0, _neatequal2['default'])(_basic2['default'].parseAuthorizationRest(_basic2['default'].buildAuthorizationRest({
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
(0, _neatequal2.default)(_basic2.default.parseAuthorizationRest(_basic2.default.buildAuthorizationRest({
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame'
})), {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame'

@@ -101,6 +106,6 @@ });

it('should work', function () {
_assert2['default'].equal(_basic2['default'].computeHash({
username: 'Aladdin',
_assert2.default.equal(_basic2.default.computeHash({
username: 'Ali Baba',
password: 'open sesame'
}), 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==');
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=');
});

@@ -112,4 +117,4 @@ });

it('should work', function () {
(0, _neatequal2['default'])(_basic2['default'].decodeHash('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
username: 'Aladdin',
(0, _neatequal2.default)(_basic2.default.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
username: 'Ali Baba',
password: 'open sesame'

@@ -116,0 +121,0 @@ });

@@ -1,13 +0,7 @@

/**
* @module http-auth-utils/mecanisms/digest
*/
'use strict';
Object.defineProperty(exports, '__esModule', {
Object.defineProperty(exports, "__esModule", {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _utils = require('../utils');

@@ -19,2 +13,8 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* @module http-auth-utils/mecanisms/digest
*/
var AUTHORIZED_WWW_AUTHENTICATE_KEYS = ['realm', 'domain', 'qop', 'nonce', 'opaque', 'stale', 'algorithm'];

@@ -39,3 +39,3 @@ var AUTHORIZED_AUTHORIZATION_KEYS = ['username', 'realm', 'nonce', 'uri', 'response', 'algorithm', 'cnonce', 'opaque', 'qop', 'nc'];

* Parse the WWW Authenticate header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).
* @param {String} rest The header rest (string after the authentication mecanism prefix).
* @return {Object} Object representing the result of the parse operation.

@@ -64,3 +64,3 @@ * @example

* Build the WWW Authenticate header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The built rest.

@@ -88,3 +88,3 @@ * @example

* Parse the Authorization header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).)
* @param {String} rest The header rest (string after the authentication mecanism prefix).)
* @return {Object} Object representing the result of the parse operation {hash}.

@@ -123,3 +123,3 @@ * @example

* Build the Authorization header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The rest built.

@@ -157,3 +157,3 @@ * @example

* Compute the Digest authentication hash from the given credentials.
* @param {Object} credentials The credentials to encode and other encoding details.
* @param {Object} data The credentials to encode and other encoding details.
* @return {String} The hash representing the credentials.

@@ -181,2 +181,3 @@ * @example

var ha2 = _computeHash(data.algorithm, [data.method, data.uri].join(':'));
return _computeHash(data.algorithm, [ha1, data.nonce, data.nc, data.cnonce, data.qop, ha2].join(':'));

@@ -187,3 +188,4 @@ }

function _computeHash(algorithm, str) {
var hashsum = _crypto2['default'].createHash(algorithm);
var hashsum = _crypto2.default.createHash(algorithm);
hashsum.update(str);

@@ -193,3 +195,2 @@ return hashsum.digest('hex');

exports['default'] = DIGEST;
module.exports = exports['default'];
exports.default = DIGEST;
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _assert = require('assert');

@@ -17,2 +15,4 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('digest', function () {

@@ -23,3 +23,3 @@

it('should be the digest auth prefix', function () {
_assert2['default'].equal(_digest2['default'].type, 'Digest');
_assert2.default.equal(_digest2.default.type, 'Digest');
});

@@ -31,3 +31,3 @@ });

it('should work', function () {
(0, _neatequal2['default'])(_digest2['default'].parseWWWAuthenticateRest('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), {
(0, _neatequal2.default)(_digest2.default.parseWWWAuthenticateRest('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), {
realm: 'testrealm@host.com',

@@ -44,3 +44,3 @@ qop: 'auth, auth-int',

it('should work', function () {
_assert2['default'].equal(_digest2['default'].buildWWWAuthenticateRest({
_assert2.default.equal(_digest2.default.buildWWWAuthenticateRest({
realm: 'testrealm@host.com',

@@ -54,3 +54,3 @@ qop: 'auth, auth-int',

it('should be the inverse of parseWWWAuthenticateRest', function () {
(0, _neatequal2['default'])(_digest2['default'].parseWWWAuthenticateRest(_digest2['default'].buildWWWAuthenticateRest({
(0, _neatequal2.default)(_digest2.default.parseWWWAuthenticateRest(_digest2.default.buildWWWAuthenticateRest({
realm: 'perlinpinpin'

@@ -66,3 +66,3 @@ })), {

it('should work', function () {
(0, _neatequal2['default'])(_digest2['default'].parseAuthorizationRest('username="Mufasa",' + 'realm="testrealm@host.com",' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",' + 'uri="/dir/index.html",' + 'qop="auth",' + 'nc="00000001",' + 'cnonce="0a4f113b",' + 'response="6629fae49393a05397450978507c4ef1",' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), {
(0, _neatequal2.default)(_digest2.default.parseAuthorizationRest('username="Mufasa",' + 'realm="testrealm@host.com",' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",' + 'uri="/dir/index.html",' + 'qop="auth",' + 'nc="00000001",' + 'cnonce="0a4f113b",' + 'response="6629fae49393a05397450978507c4ef1",' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), {
username: 'Mufasa',

@@ -84,3 +84,3 @@ realm: 'testrealm@host.com',

it('should work', function () {
_assert2['default'].equal(_digest2['default'].buildAuthorizationRest({
_assert2.default.equal(_digest2.default.buildAuthorizationRest({
username: 'Mufasa',

@@ -99,3 +99,3 @@ realm: 'testrealm@host.com',

it('should be the inverse of parseAuthorizationRest', function () {
(0, _neatequal2['default'])(_digest2['default'].parseAuthorizationRest(_digest2['default'].buildAuthorizationRest({
(0, _neatequal2.default)(_digest2.default.parseAuthorizationRest(_digest2.default.buildAuthorizationRest({
username: 'Mufasa',

@@ -127,3 +127,3 @@ realm: 'testrealm@host.com',

it('should work', function () {
_assert2['default'].equal(_digest2['default'].computeHash({
_assert2.default.equal(_digest2.default.computeHash({
username: 'Mufasa',

@@ -130,0 +130,0 @@ realm: 'testrealm@host.com',

'use strict';
Object.defineProperty(exports, '__esModule', {
Object.defineProperty(exports, "__esModule", {
value: true
});
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _slicedToArray(arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }
exports.parseHTTPHeadersQuotedKeyValueSet = parseHTTPHeadersQuotedKeyValueSet;
exports.buildHTTPHeadersQuotedKeyValueSet = buildHTTPHeadersQuotedKeyValueSet;

@@ -15,2 +16,4 @@ var _yerror = require('yerror');

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var QUOTE = '"';

@@ -22,10 +25,10 @@ var EQUAL = '=';

// FIXME: Create a real parser
var parseHTTPHeadersQuotedKeyValueSet = function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys) {
var requiredKeys = arguments[2] === undefined ? [] : arguments[2];
function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys) {
var requiredKeys = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
return contents.split(SEPARATOR_REGEXP).map(function (part, partPosition, parts) {
var data = contents.split(SEPARATOR_REGEXP).map(function (part, partPosition, parts) {
part = parts.length - 1 === partPosition ? part : part + '"';
var pair = part.split(EQUAL);
if (2 !== pair.length) {
throw new _yerror2['default']('E_MALFORMED_QUOTEDKEYVALUE', partPosition, part, pair.length);
throw new _yerror2.default('E_MALFORMED_QUOTEDKEYVALUE', partPosition, part, pair.length);
}

@@ -40,6 +43,6 @@ return pair;

if (-1 === authorizedKeys.indexOf(name)) {
throw new _yerror2['default']('E_UNAUTHORIZED_KEY', valuePosition, name);
throw new _yerror2.default('E_UNAUTHORIZED_KEY', valuePosition, name);
}
if (QUOTE !== value[0] || QUOTE !== value[value.length - 1]) {
throw new _yerror2['default']('E_UNQUOTED_VALUE', valuePosition, name, value);
throw new _yerror2.default('E_UNQUOTED_VALUE', valuePosition, name, value);
}

@@ -49,15 +52,26 @@ parsedValues[name] = value.substr(1, value.length - 2);

}, {});
};
exports.parseHTTPHeadersQuotedKeyValueSet = parseHTTPHeadersQuotedKeyValueSet;
var buildHTTPHeadersQuotedKeyValueSet = function buildHTTPHeadersQuotedKeyValueSet(data, authorizedKeys) {
var requiredKeys = arguments[2] === undefined ? [] : arguments[2];
_checkRequiredKeys(requiredKeys, data);
return data;
}
function buildHTTPHeadersQuotedKeyValueSet(data, authorizedKeys) {
var requiredKeys = arguments.length <= 2 || arguments[2] === undefined ? [] : arguments[2];
_checkRequiredKeys(requiredKeys, data);
return authorizedKeys.reduce(function (contents, key) {
if (data[key]) {
return contents + (contents ? ', ' : '') + key + EQUAL + QUOTE + data[key] + QUOTE;
return contents + (contents ? SEPARATOR : '') + key + EQUAL + QUOTE + data[key] + QUOTE;
}
return contents;
}, '');
};
exports.buildHTTPHeadersQuotedKeyValueSet = buildHTTPHeadersQuotedKeyValueSet;
}
function _checkRequiredKeys(requiredKeys, data) {
requiredKeys.forEach(function (name) {
if ('undefined' !== typeof data[name]) {
throw new _yerror2.default('E_REQUIRED_KEY', name);
}
});
}
'use strict';
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var _assert = require('assert');

@@ -15,2 +13,4 @@

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
describe('utils', function () {

@@ -21,3 +21,3 @@

it('should work with good datas', function () {
(0, _neatequal2['default'])((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque']), {
(0, _neatequal2.default)((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque']), {
realm: 'testrealm@host.com',

@@ -34,3 +34,3 @@ qop: 'auth, auth-int',

it('should work with good datas', function () {
_assert2['default'].equal((0, _utils.buildHTTPHeadersQuotedKeyValueSet)({
_assert2.default.equal((0, _utils.buildHTTPHeadersQuotedKeyValueSet)({
realm: 'testrealm@host.com',

@@ -37,0 +37,0 @@ qop: 'auth, auth-int',

{
"name": "http-auth-utils",
"version": "0.0.2",
"version": "1.0.0",
"description": "Parse, build and deal with HTTP auth headers.",
"main": "dist/index.js",
"scripts": {
"test": "mocha --compilers js:babel/register src/**/*.mocha.js src/*.mocha.js",
"test": "mocha --compilers js:babel-register src/**/*.mocha.js src/*.mocha.js src/**/*.mocha.js",
"compile": "babel src --out-dir=dist",
"prepublish": "npm run compile",
"prelink": "npm run compile",
"cli": "env NPM_CLI=1"
"cli": "env NPM_CLI=1",
"lint": "eslint src/*.js src/**/*.js",
"preversion": "npm run compile && npm run lint && npm test",
"doc": "cat src/index.js | jsdoc2md > API.md",
"coveralls": "istanbul cover _mocha --report lcovonly -- --compilers js:babel-register src/*.mocha.js src/**/*.mocha.js -R spec -t 5000 && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage",
"cover": "istanbul cover --report html _mochai-- --compilers js:babel-register src/*.mocha.js src/**/*.mocha.js -R spec -t 5000"
},

@@ -33,3 +36,9 @@ "keywords": [

"devDependencies": {
"babel": "^5.2.15",
"babel-cli": "^6.4.0",
"babel-preset-es2015": "^6.3.13",
"babel-register": "^6.4.3",
"coveralls": "^2.11.11",
"eslint": "^3.1.1",
"eslint-config-simplifield": "^3.0.0",
"istanbul": "^1.0.0-alpha.2",
"jsdoc-to-markdown": "^1.1.1",

@@ -36,0 +45,0 @@ "mocha": "^2.2.4",

@@ -6,2 +6,10 @@ # http-auth-utils

[![NPM version](https://img.shields.io/npm/v/http-auth-utils.svg)](https://www.npmjs.com/package/http-auth-utils)
[![Build Status](https://travis-ci.org/nfroidure/http-auth-utils.svg?branch=master)](https://travis-ci.org/nfroidure/http-auth-utils)
[![Dependency Status](https://david-dm.org/nfroidure/http-auth-utils.svg)](https://david-dm.org/nfroidure/http-auth-utils)
[![devDependency Status](https://david-dm.org/nfroidure/http-auth-utils/dev-status.svg)](https://david-dm.org/nfroidure/http-auth-utils#info=devDependencies)
[![Coverage Status](https://coveralls.io/repos/nfroidure/http-auth-utils/badge.svg?branch=master)](https://coveralls.io/r/nfroidure/http-auth-utils?branch=master)
[![Code Climate](https://codeclimate.com/github/nfroidure/http-auth-utils/badges/gpa.svg)](https://codeclimate.com/github/nfroidure/http-auth-utils)
[![Dependency Status](https://dependencyci.com/github/nfroidure/http-auth-utils/badge)](https://dependencyci.com/github/nfroidure/http-auth-utils)
This library is intended to be framework agnostic and could be used either on

@@ -92,6 +100,6 @@ the server and the client side.

assert.equal(
parseAuthorizationHeader('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
parseAuthorizationHeader('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
type: 'Basic',
data: {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
}

@@ -191,4 +199,4 @@ }

assert.deepEqual(
BASIC.parseAuthorizationRest('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
}

@@ -213,5 +221,5 @@ );

BASIC.buildAuthorizationRest({
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
}),
'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
);

@@ -235,6 +243,6 @@ ```

BASIC.computeHash({
username: 'Aladdin',
username: 'Ali Baba',
password: 'open sesame'
}),
'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
);

@@ -257,4 +265,4 @@ ```

assert.deepEqual(
BASIC.decodeHash('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
username: 'Aladdin',
BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
username: 'Ali Baba',
password: 'open sesame'

@@ -261,0 +269,0 @@ }

import YError from 'yerror';
import BASIC from './mecanisms/basic';
import DIGEST from './mecanisms/digest';
import BEARER from './mecanisms/bearer';
/**

@@ -8,4 +11,2 @@ * @module http-auth-utils

import DIGEST from './mecanisms/digest';
/**

@@ -16,3 +17,3 @@ * Basic authentication mecanism.

*/
export {BASIC as BASIC};
export { BASIC as BASIC };

@@ -24,9 +25,16 @@ /**

*/
export {DIGEST as DIGEST};
export { DIGEST as DIGEST };
/**
* Bearer authentication mecanism.
* @type {Object}
* @see {@link module:http-auth-utils/mecanisms/digest}
*/
export { BEARER as BEARER };
/**
* Natively supported authentication mecanisms.
* @type {Array}
*/
export const mecanisms = [BASIC, DIGEST];
export const mecanisms = [BASIC, DIGEST, BEARER];

@@ -50,20 +58,20 @@ /**

*/
export const parseWWWAuthenticateHeader =
function parseWWWAuthenticateHeader(header, authMecanisms = mecanisms) {
let result = null;
authMecanisms.some(function(authMecanism) {
if(0 === header.indexOf(authMecanism.type + ' ')) {
result = {
type: authMecanism.type,
data: authMecanism.parseWWWAuthenticateRest(
header.substr(authMecanism.type.length + 1)
)
};
}
});
if(result) {
return result;
export function parseWWWAuthenticateHeader(header, authMecanisms = mecanisms) {
let result = null;
authMecanisms.some((authMecanism) => {
if(0 === header.indexOf(authMecanism.type + ' ')) {
result = {
type: authMecanism.type,
data: authMecanism.parseWWWAuthenticateRest(
header.substr(authMecanism.type.length + 1)
),
};
}
throw new YError('E_UNKNOWN_AUTH_MECANISM', header);
};
});
if(result) {
return result;
}
throw new YError('E_UNKNOWN_AUTH_MECANISM', header);
}

@@ -74,3 +82,3 @@ /**

* @param {string} header The Authorization header contents
* @param {Array} [authMecanisms=[BASIC, DIGEST]] Allow providing custom authentication mecanisms.
* @param {Array} [authMecanisms=[BASIC, DIGEST, BEARER]] Allow custom authentication mecanisms.
* @return {Object} Result of the contents parse.

@@ -88,19 +96,19 @@ * @api public

*/
export const parseAuthorizationHeader =
function parseAuthorizationHeader(header, authMecanisms = mecanisms) {
let result = null;
authMecanisms.some(function(authMecanism) {
if(0 === header.indexOf(authMecanism.type + ' ')) {
result = {
type: authMecanism.type,
data: authMecanism.parseAuthorizationRest(
header.substr(authMecanism.type.length + 1)
)
};
}
});
if(result) {
return result;
export function parseAuthorizationHeader(header, authMecanisms = mecanisms) {
let result = null;
authMecanisms.some(function(authMecanism) {
if(0 === header.indexOf(authMecanism.type + ' ')) {
result = {
type: authMecanism.type,
data: authMecanism.parseAuthorizationRest(
header.substr(authMecanism.type.length + 1)
),
};
}
throw new YError('E_UNKNOWN_AUTH_MECANISM', header);
};
});
if(result) {
return result;
}
throw new YError('E_UNKNOWN_AUTH_MECANISM', header);
}

@@ -8,10 +8,11 @@ import assert from 'assert';

BASIC,
DIGEST
DIGEST,
BEARER,
} from './index';
describe('index', function() {
describe('index', () => {
describe('parseWWWAuthenticateHeader', function() {
describe('parseWWWAuthenticateHeader', () => {
it('should parse Basic headers', function() {
it('should parse Basic headers', () => {
neatequal(

@@ -21,4 +22,4 @@ parseWWWAuthenticateHeader('Basic realm="test"'), {

data: {
realm: 'test'
}
realm: 'test',
},
}

@@ -30,31 +31,55 @@ );

describe('parseAuthorizationHeader', function() {
describe('parseAuthorizationHeader', () => {
it('should parse Basic headers', function() {
it('should parse Basic headers', () => {
neatequal(
parseAuthorizationHeader('Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
parseAuthorizationHeader('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
type: 'Basic',
data: {
username: 'Aladdin',
password: 'open sesame',
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
}
username: 'Ali Baba',
password: 'open sesame',
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
},
}
);
neatequal(
parseAuthorizationHeader('Basic bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), {
type: 'Basic',
data: {
username: 'nicolas.froidure@simplifield.com',
password: 'test',
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==',
},
}
);
});
it('should parse Basic headers with a ":" char in the password', () => {
neatequal(
parseAuthorizationHeader('Basic Sm9objpSOlU6a2lkZGluZz8='), {
type: 'Basic',
data: {
username: 'John',
password: 'R:U:kidding?',
hash: 'Sm9objpSOlU6a2lkZGluZz8=',
},
}
);
});
});
describe('mecanisms', function() {
describe('mecanisms', () => {
it('should export bot DIGEST and BASIC mecanisms', function() {
it('should export bot DIGEST and BASIC mecanisms', () => {
assert.equal(
mecanisms.length,
2
3
);
});
it('should export bot DIGEST and BASIC mecanisms', function() {
it('should export DIGEST BASIC and BEARER mecanisms', () => {
assert(BASIC);
assert(DIGEST);
assert(BEARER);
});

@@ -61,0 +86,0 @@

/**
* @module http-auth-utils/mecanisms/basic
*/
import YError from 'yerror';

@@ -8,3 +9,3 @@

parseHTTPHeadersQuotedKeyValueSet,
buildHTTPHeadersQuotedKeyValueSet
buildHTTPHeadersQuotedKeyValueSet,
} from '../utils';

@@ -29,3 +30,3 @@

* Parse the WWW Authenticate header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).
* @param {String} rest The header rest (string after the authentication mecanism prefix).
* @return {Object} Object representing the result of the parse operation.

@@ -46,3 +47,3 @@ * @example

* Build the WWW Authenticate header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The built rest.

@@ -64,9 +65,9 @@ * @example

* Parse the Authorization header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).)
* @param {String} rest The header rest (string after the authentication mecanism prefix).)
* @return {Object} Object representing the result of the parse operation {hash}.
* @example
* assert.deepEqual(
* BASIC.parseAuthorizationRest('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
* hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
* username: 'Aladdin',
* BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
* username: 'Ali Baba',
* password: 'open sesame'

@@ -81,7 +82,8 @@ * }

}
let {username, password} = BASIC.decodeHash(rest);
const { username, password } = BASIC.decodeHash(rest);
return {
hash: rest,
username,
password
password,
};

@@ -97,11 +99,11 @@ },

* BASIC.buildAuthorizationRest({
* hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* }),
* 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* );
* @api public
*/
buildAuthorizationRest: function buildAuthorizationRest({hash, username, password} = {}) {
buildAuthorizationRest: function buildAuthorizationRest({ hash, username, password } = {}) {
if(username && password) {
return BASIC.computeHash({username, password});
return BASIC.computeHash({ username, password });
}

@@ -121,10 +123,10 @@ if(!hash) {

* BASIC.computeHash({
* username: 'Aladdin',
* username: 'Ali Baba',
* password: 'open sesame'
* }),
* 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
* );
* @api public
*/
computeHash: function computeHash({username, password}) {
computeHash: function computeHash({ username, password }) {
return (new Buffer(username + ':' + password)).toString('base64');

@@ -139,4 +141,4 @@ },

* assert.deepEqual(
* BASIC.decodeHash('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
* username: 'Aladdin',
* BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
* username: 'Ali Baba',
* password: 'open sesame'

@@ -148,10 +150,10 @@ * }

decodeHash: function decodeHash(hash) {
let [username, password] = ((new Buffer(hash, 'base64')).toString()).split(':');
let [username, ...passwordParts] = ((new Buffer(hash, 'base64')).toString()).split(':');
return {
username,
password
password: passwordParts.join(':'),
};
}
},
};
export default BASIC;

@@ -5,7 +5,7 @@ import assert from 'assert';

describe('BASIC', function() {
describe('BASIC', () => {
describe('type', function() {
describe('type', () => {
it('should be the basic auth prefix', function() {
it('should be the basic auth prefix', () => {
assert.equal(BASIC.type, 'Basic');

@@ -16,8 +16,8 @@ });

describe('parseWWWAuthenticateRest', function() {
describe('parseWWWAuthenticateRest', () => {
it('should work', function() {
it('should work', () => {
neatequal(
BASIC.parseWWWAuthenticateRest('realm="perlinpinpin"'), {
realm: 'perlinpinpin'
realm: 'perlinpinpin',
}

@@ -29,8 +29,8 @@ );

describe('buildWWWAuthenticateRest', function() {
describe('buildWWWAuthenticateRest', () => {
it('should work', function() {
it('should work', () => {
assert.equal(
BASIC.buildWWWAuthenticateRest({
realm: 'perlinpinpin'
realm: 'perlinpinpin',
}),

@@ -41,11 +41,12 @@ 'realm="perlinpinpin"'

it('should be the inverse of parseWWWAuthenticateRest', function() {
it('should be the inverse of parseWWWAuthenticateRest', () => {
neatequal(
BASIC.parseWWWAuthenticateRest(
BASIC.buildWWWAuthenticateRest({
realm: 'perlinpinpin'
realm: 'perlinpinpin',
})
), {
realm: 'perlinpinpin'
});
realm: 'perlinpinpin',
}
);
});

@@ -55,12 +56,19 @@

describe('parseAuthorizationRest', function() {
describe('parseAuthorizationRest', () => {
it('should work', function() {
it('should work', () => {
neatequal(
BASIC.parseAuthorizationRest('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
password: 'open sesame'
BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame',
}
);
neatequal(
BASIC.parseAuthorizationRest('bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), {
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==',
username: 'nicolas.froidure@simplifield.com',
password: 'test',
}
);
});

@@ -70,36 +78,37 @@

describe('buildAuthorizationRest', function() {
describe('buildAuthorizationRest', () => {
it('should work with credentials', function() {
it('should work with credentials', () => {
assert.equal(
BASIC.buildAuthorizationRest({
username: 'Aladdin',
password: 'open sesame'
username: 'Ali Baba',
password: 'open sesame',
}),
'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
);
});
it('should work with just the hash', function() {
it('should work with just the hash', () => {
assert.equal(
BASIC.buildAuthorizationRest({
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
}),
'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
);
});
it('should be the inverse of parseAuthorizationRest', function() {
it('should be the inverse of parseAuthorizationRest', () => {
neatequal(
BASIC.parseAuthorizationRest(
BASIC.buildAuthorizationRest({
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
password: 'open sesame'
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame',
})
), {
hash: 'QWxhZGRpbjpvcGVuIHNlc2FtZQ==',
username: 'Aladdin',
password: 'open sesame'
});
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=',
username: 'Ali Baba',
password: 'open sesame',
}
);
});

@@ -109,26 +118,26 @@

describe('computeHash', function() {
describe('computeHash', () => {
it('should work', function() {
assert.equal(
BASIC.computeHash({
username: 'Aladdin',
password: 'open sesame'
}),
'QWxhZGRpbjpvcGVuIHNlc2FtZQ=='
);
});
it('should work', () => {
assert.equal(
BASIC.computeHash({
username: 'Ali Baba',
password: 'open sesame',
}),
'QWxpIEJhYmE6b3BlbiBzZXNhbWU='
);
});
});
describe('decodeHash', function() {
describe('decodeHash', () => {
it('should work', function() {
neatequal(
BASIC.decodeHash('QWxhZGRpbjpvcGVuIHNlc2FtZQ=='), {
username: 'Aladdin',
password: 'open sesame'
}
);
});
it('should work', () => {
neatequal(
BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), {
username: 'Ali Baba',
password: 'open sesame',
}
);
});

@@ -135,0 +144,0 @@ });

@@ -7,3 +7,3 @@ /**

parseHTTPHeadersQuotedKeyValueSet,
buildHTTPHeadersQuotedKeyValueSet
buildHTTPHeadersQuotedKeyValueSet,
} from '../utils';

@@ -14,7 +14,7 @@

const AUTHORIZED_WWW_AUTHENTICATE_KEYS = [
'realm', 'domain', 'qop', 'nonce', 'opaque', 'stale', 'algorithm'
'realm', 'domain', 'qop', 'nonce', 'opaque', 'stale', 'algorithm',
];
const AUTHORIZED_AUTHORIZATION_KEYS = [
'username', 'realm', 'nonce', 'uri', 'response', 'algorithm', 'cnonce',
'opaque', 'qop', 'nc'
'opaque', 'qop', 'nc',
];

@@ -38,3 +38,3 @@

* Parse the WWW Authenticate header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).
* @param {String} rest The header rest (string after the authentication mecanism prefix).
* @return {Object} Object representing the result of the parse operation.

@@ -63,3 +63,3 @@ * @example

* Build the WWW Authenticate header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The built rest.

@@ -87,3 +87,3 @@ * @example

* Parse the Authorization header rest.
* @param {String} rest The header rest (string got after removing the authentication mecanism prefix).)
* @param {String} rest The header rest (string after the authentication mecanism prefix).)
* @return {Object} Object representing the result of the parse operation {hash}.

@@ -122,3 +122,3 @@ * @example

* Build the Authorization header rest.
* @param {Object} content The content from wich to build the rest.
* @param {Object} data The content from wich to build the rest.
* @return {String} The rest built.

@@ -156,3 +156,3 @@ * @example

* Compute the Digest authentication hash from the given credentials.
* @param {Object} credentials The credentials to encode and other encoding details.
* @param {Object} data The credentials to encode and other encoding details.
* @return {String} The hash representing the credentials.

@@ -178,16 +178,18 @@ * @example

computeHash: function computeHash(data) {
let ha1 = data.ha1 || _computeHash(data.algorithm, [
data.username, data.realm, data.password
const ha1 = data.ha1 || _computeHash(data.algorithm, [
data.username, data.realm, data.password,
].join(':'));
let ha2 = _computeHash(data.algorithm, [
data.method, data.uri
const ha2 = _computeHash(data.algorithm, [
data.method, data.uri,
].join(':'));
return _computeHash(data.algorithm, [
ha1, data.nonce, data.nc, data.cnonce, data.qop, ha2
ha1, data.nonce, data.nc, data.cnonce, data.qop, ha2,
].join(':'));
}
},
};
function _computeHash(algorithm, str) {
let hashsum = crypto.createHash(algorithm);
const hashsum = crypto.createHash(algorithm);
hashsum.update(str);

@@ -194,0 +196,0 @@ return hashsum.digest('hex');

@@ -5,7 +5,7 @@ import assert from 'assert';

describe('digest', function() {
describe('digest', () => {
describe('type', function() {
describe('type', () => {
it('should be the digest auth prefix', function() {
it('should be the digest auth prefix', () => {
assert.equal(DIGEST.type, 'Digest');

@@ -16,5 +16,5 @@ });

describe('parseWWWAuthenticateRest', function() {
describe('parseWWWAuthenticateRest', () => {
it('should work', function() {
it('should work', () => {
neatequal(

@@ -30,3 +30,3 @@ DIGEST.parseWWWAuthenticateRest(

nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
opaque: '5ccc069c403ebaf9f0171e9517f40e41'
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}

@@ -38,5 +38,5 @@ );

describe('buildWWWAuthenticateRest', function() {
describe('buildWWWAuthenticateRest', () => {
it('should work', function() {
it('should work', () => {
assert.equal(

@@ -47,3 +47,3 @@ DIGEST.buildWWWAuthenticateRest({

nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
opaque: '5ccc069c403ebaf9f0171e9517f40e41'
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}),

@@ -57,11 +57,12 @@ 'realm="testrealm@host.com", ' +

it('should be the inverse of parseWWWAuthenticateRest', function() {
it('should be the inverse of parseWWWAuthenticateRest', () => {
neatequal(
DIGEST.parseWWWAuthenticateRest(
DIGEST.buildWWWAuthenticateRest({
realm: 'perlinpinpin'
realm: 'perlinpinpin',
})
), {
realm: 'perlinpinpin'
});
realm: 'perlinpinpin',
}
);
});

@@ -71,5 +72,5 @@

describe('parseAuthorizationRest', function() {
describe('parseAuthorizationRest', () => {
it('should work', function() {
it('should work', () => {
neatequal(

@@ -87,11 +88,11 @@ DIGEST.parseAuthorizationRest(

), {
username: "Mufasa",
username: 'Mufasa',
realm: 'testrealm@host.com',
nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri: "/dir/index.html",
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
uri: '/dir/index.html',
qop: 'auth',
nc: '00000001',
cnonce: "0a4f113b",
response: "6629fae49393a05397450978507c4ef1",
opaque: "5ccc069c403ebaf9f0171e9517f40e41"
cnonce: '0a4f113b',
response: '6629fae49393a05397450978507c4ef1',
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}

@@ -103,16 +104,16 @@ );

describe('buildAuthorizationRest', function() {
describe('buildAuthorizationRest', () => {
it('should work', function() {
it('should work', () => {
assert.equal(
DIGEST.buildAuthorizationRest({
username: "Mufasa",
username: 'Mufasa',
realm: 'testrealm@host.com',
nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri: "/dir/index.html",
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
uri: '/dir/index.html',
qop: 'auth',
nc: '00000001',
cnonce: "0a4f113b",
response: "6629fae49393a05397450978507c4ef1",
opaque: "5ccc069c403ebaf9f0171e9517f40e41"
cnonce: '0a4f113b',
response: '6629fae49393a05397450978507c4ef1',
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}),

@@ -131,27 +132,28 @@ 'username="Mufasa", ' +

it('should be the inverse of parseAuthorizationRest', function() {
it('should be the inverse of parseAuthorizationRest', () => {
neatequal(
DIGEST.parseAuthorizationRest(
DIGEST.buildAuthorizationRest({
username: "Mufasa",
username: 'Mufasa',
realm: 'testrealm@host.com',
nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri: "/dir/index.html",
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
uri: '/dir/index.html',
qop: 'auth',
nc: '00000001',
cnonce: "0a4f113b",
response: "6629fae49393a05397450978507c4ef1",
opaque: "5ccc069c403ebaf9f0171e9517f40e41"
cnonce: '0a4f113b',
response: '6629fae49393a05397450978507c4ef1',
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
})
), {
username: "Mufasa",
username: 'Mufasa',
realm: 'testrealm@host.com',
nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093",
uri: "/dir/index.html",
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
uri: '/dir/index.html',
qop: 'auth',
nc: '00000001',
cnonce: "0a4f113b",
response: "6629fae49393a05397450978507c4ef1",
opaque: "5ccc069c403ebaf9f0171e9517f40e41"
});
cnonce: '0a4f113b',
response: '6629fae49393a05397450978507c4ef1',
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}
);
});

@@ -161,24 +163,24 @@

describe('computeHash', function() {
describe('computeHash', () => {
it('should work', function() {
assert.equal(
DIGEST.computeHash({
username: 'Mufasa',
realm: 'testrealm@host.com',
password: 'Circle Of Life',
method: 'GET',
uri: '/dir/index.html',
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
nc: '00000001',
cnonce: '0a4f113b',
qop: 'auth',
algorithm: 'md5'
}),
'6629fae49393a05397450978507c4ef1'
);
});
it('should work', () => {
assert.equal(
DIGEST.computeHash({
username: 'Mufasa',
realm: 'testrealm@host.com',
password: 'Circle Of Life',
method: 'GET',
uri: '/dir/index.html',
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
nc: '00000001',
cnonce: '0a4f113b',
qop: 'auth',
algorithm: 'md5',
}),
'6629fae49393a05397450978507c4ef1'
);
});
});
});
});

@@ -9,32 +9,43 @@ import YError from 'yerror';

// FIXME: Create a real parser
export const parseHTTPHeadersQuotedKeyValueSet =
function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys, requiredKeys = []) {
return contents.split(SEPARATOR_REGEXP).map(function(part, partPosition, parts) {
part = parts.length - 1 === partPosition ? part : part + '"';
let pair = part.split(EQUAL);
if(2 !== pair.length) {
throw new YError('E_MALFORMED_QUOTEDKEYVALUE', partPosition, part, pair.length);
}
return pair;
}).reduce(function(parsedValues, [name, value], valuePosition) {
if(-1 === authorizedKeys.indexOf(name)) {
throw new YError('E_UNAUTHORIZED_KEY', valuePosition, name);
}
if(QUOTE !== value[0] || QUOTE !== value[value.length - 1]) {
throw new YError('E_UNQUOTED_VALUE', valuePosition, name, value);
}
parsedValues[name] = value.substr(1, value.length - 2);
return parsedValues;
}, {});
};
export function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys, requiredKeys = []) {
const data = contents.split(SEPARATOR_REGEXP).map((part, partPosition, parts) => {
part = parts.length - 1 === partPosition ? part : part + '"';
let pair = part.split(EQUAL);
if(2 !== pair.length) {
throw new YError('E_MALFORMED_QUOTEDKEYVALUE', partPosition, part, pair.length);
}
return pair;
}).reduce(function(parsedValues, [name, value], valuePosition) {
if(-1 === authorizedKeys.indexOf(name)) {
throw new YError('E_UNAUTHORIZED_KEY', valuePosition, name);
}
if(QUOTE !== value[0] || QUOTE !== value[value.length - 1]) {
throw new YError('E_UNQUOTED_VALUE', valuePosition, name, value);
}
parsedValues[name] = value.substr(1, value.length - 2);
return parsedValues;
}, {});
export const buildHTTPHeadersQuotedKeyValueSet =
function buildHTTPHeadersQuotedKeyValueSet(data, authorizedKeys, requiredKeys = []) {
return authorizedKeys.reduce(function(contents, key) {
if(data[key]) {
return contents + (contents ? ', ' : '') + key + EQUAL +
QUOTE + data[key] + QUOTE;
}
return contents;
}, '');
};
_checkRequiredKeys(requiredKeys, data);
return data;
}
export function buildHTTPHeadersQuotedKeyValueSet(data, authorizedKeys, requiredKeys = []) {
_checkRequiredKeys(requiredKeys, data);
return authorizedKeys.reduce(function(contents, key) {
if(data[key]) {
return contents + (contents ? SEPARATOR : '') + key + EQUAL +
QUOTE + data[key] + QUOTE;
}
return contents;
}, '');
}
function _checkRequiredKeys(requiredKeys, data) {
requiredKeys.forEach((name) => {
if('undefined' !== typeof data[name]) {
throw new YError('E_REQUIRED_KEY', name);
}
});
}

@@ -5,10 +5,10 @@ import assert from 'assert';

parseHTTPHeadersQuotedKeyValueSet,
buildHTTPHeadersQuotedKeyValueSet
buildHTTPHeadersQuotedKeyValueSet,
} from './utils';
describe('utils', function() {
describe('utils', () => {
describe('parseHTTPHeadersQuotedKeyValueSet', function() {
describe('parseHTTPHeadersQuotedKeyValueSet', () => {
it('should work with good datas', function() {
it('should work with good datas', () => {
neatequal(parseHTTPHeadersQuotedKeyValueSet(

@@ -24,3 +24,3 @@ 'realm="testrealm@host.com", ' +

nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
opaque: '5ccc069c403ebaf9f0171e9517f40e41'
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
});

@@ -31,5 +31,5 @@ });

describe('buildHTTPHeadersQuotedKeyValueSet', function() {
describe('buildHTTPHeadersQuotedKeyValueSet', () => {
it('should work with good datas', function() {
it('should work with good datas', () => {
assert.equal(buildHTTPHeadersQuotedKeyValueSet({

@@ -39,3 +39,3 @@ realm: 'testrealm@host.com',

nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093',
opaque: '5ccc069c403ebaf9f0171e9517f40e41'
opaque: '5ccc069c403ebaf9f0171e9517f40e41',
}, ['realm', 'qop', 'nonce', 'opaque']),

@@ -51,2 +51,2 @@ 'realm="testrealm@host.com", ' +

});
});
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