http-auth-utils
Advanced tools
Comparing version 3.0.3 to 3.0.4
@@ -0,1 +1,5 @@ | ||
## [3.0.4](https://github.com/nfroidure/http-auth-utils/compare/v3.0.3...v3.0.4) (2022-09-01) | ||
## [3.0.3](https://github.com/nfroidure/http-auth-utils/compare/v3.0.2...v3.0.3) (2022-05-25) | ||
@@ -2,0 +6,0 @@ |
@@ -1,4 +0,4 @@ | ||
import BASIC from './mechanisms/basic'; | ||
import DIGEST from './mechanisms/digest'; | ||
import BEARER from './mechanisms/bearer'; | ||
import BASIC from './mechanisms/basic.js'; | ||
import DIGEST from './mechanisms/digest.js'; | ||
import BEARER from './mechanisms/bearer.js'; | ||
export declare type Mechanism = { | ||
@@ -5,0 +5,0 @@ type: string; |
@@ -1,44 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
Object.defineProperty(exports, "BASIC", { | ||
enumerable: true, | ||
get: function () { | ||
return _basic.default; | ||
} | ||
}); | ||
Object.defineProperty(exports, "BEARER", { | ||
enumerable: true, | ||
get: function () { | ||
return _bearer.default; | ||
} | ||
}); | ||
Object.defineProperty(exports, "DIGEST", { | ||
enumerable: true, | ||
get: function () { | ||
return _digest.default; | ||
} | ||
}); | ||
exports.buildAuthorizationHeader = buildAuthorizationHeader; | ||
exports.buildWWWAuthenticateHeader = buildWWWAuthenticateHeader; | ||
exports.mechanisms = void 0; | ||
exports.parseAuthorizationHeader = parseAuthorizationHeader; | ||
exports.parseWWWAuthenticateHeader = parseWWWAuthenticateHeader; | ||
var _yerror = _interopRequireDefault(require("yerror")); | ||
var _basic = _interopRequireDefault(require("./mechanisms/basic")); | ||
var _digest = _interopRequireDefault(require("./mechanisms/digest")); | ||
var _bearer = _interopRequireDefault(require("./mechanisms/bearer")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { YError } from 'yerror'; | ||
import BASIC from './mechanisms/basic.js'; | ||
import DIGEST from './mechanisms/digest.js'; | ||
import BEARER from './mechanisms/bearer.js'; | ||
/** | ||
* @module http-auth-utils | ||
*/ | ||
/** | ||
@@ -48,3 +12,3 @@ * Natively supported authentication mechanisms. | ||
*/ | ||
const mechanisms = [_basic.default, _digest.default, _bearer.default]; | ||
const mechanisms = [BASIC, DIGEST, BEARER]; | ||
/** | ||
@@ -55,5 +19,3 @@ * Basic authentication mechanism. | ||
*/ | ||
exports.mechanisms = mechanisms; | ||
_basic.default; | ||
BASIC; | ||
/** | ||
@@ -64,4 +26,3 @@ * Digest authentication mechanism. | ||
*/ | ||
_digest.default; | ||
DIGEST; | ||
/** | ||
@@ -72,5 +33,4 @@ * Bearer authentication mechanism. | ||
*/ | ||
_bearer.default; | ||
BEARER; | ||
export { BASIC, DIGEST, BEARER, mechanisms }; | ||
/** | ||
@@ -99,25 +59,19 @@ * Parse HTTP WWW-Authenticate header contents. | ||
*/ | ||
function parseWWWAuthenticateHeader(header, authMechanisms = mechanisms, { | ||
strict = true | ||
} = { | ||
strict: true | ||
}) { | ||
let result = null; | ||
authMechanisms.some(authMechanism => { | ||
if (0 === header.indexOf(authMechanism.type + ' ') || !strict && 0 === header.indexOf(authMechanism.type.toLowerCase() + ' ')) { | ||
result = { | ||
type: authMechanism.type, | ||
data: authMechanism.parseWWWAuthenticateRest(header.substr(authMechanism.type.length + 1)) | ||
}; | ||
return true; | ||
export function parseWWWAuthenticateHeader(header, authMechanisms = mechanisms, { strict = true } = { strict: true }) { | ||
let result = null; | ||
authMechanisms.some((authMechanism) => { | ||
if (0 === header.indexOf(authMechanism.type + ' ') || | ||
(!strict && 0 === header.indexOf(authMechanism.type.toLowerCase() + ' '))) { | ||
result = { | ||
type: authMechanism.type, | ||
data: authMechanism.parseWWWAuthenticateRest(header.substr(authMechanism.type.length + 1)), | ||
}; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
if (!result) { | ||
throw new YError('E_UNKNOWN_AUTH_MECHANISM', header); | ||
} | ||
return false; | ||
}); | ||
if (!result) { | ||
throw new _yerror.default('E_UNKNOWN_AUTH_MECHANISM', header); | ||
} | ||
return result; | ||
return result; | ||
} | ||
@@ -146,27 +100,19 @@ /** | ||
*/ | ||
function parseAuthorizationHeader(header, authMechanisms = mechanisms, { | ||
strict = true | ||
} = { | ||
strict: true | ||
}) { | ||
let result = null; | ||
authMechanisms.some(function (authMechanism) { | ||
if (0 === header.indexOf(authMechanism.type + ' ') || !strict && 0 === header.indexOf(authMechanism.type.toLowerCase() + ' ')) { | ||
result = { | ||
type: authMechanism.type, | ||
data: authMechanism.parseAuthorizationRest(header.substr(authMechanism.type.length + 1)) | ||
}; | ||
return true; | ||
export function parseAuthorizationHeader(header, authMechanisms = mechanisms, { strict = true } = { strict: true }) { | ||
let result = null; | ||
authMechanisms.some(function (authMechanism) { | ||
if (0 === header.indexOf(authMechanism.type + ' ') || | ||
(!strict && 0 === header.indexOf(authMechanism.type.toLowerCase() + ' '))) { | ||
result = { | ||
type: authMechanism.type, | ||
data: authMechanism.parseAuthorizationRest(header.substr(authMechanism.type.length + 1)), | ||
}; | ||
return true; | ||
} | ||
return false; | ||
}); | ||
if (result) { | ||
return result; | ||
} | ||
return false; | ||
}); | ||
if (result) { | ||
return result; | ||
} | ||
throw new _yerror.default('E_UNKNOWN_AUTH_MECHANISM', header); | ||
throw new YError('E_UNKNOWN_AUTH_MECHANISM', header); | ||
} | ||
@@ -189,6 +135,4 @@ /** | ||
*/ | ||
function buildWWWAuthenticateHeader(authMechanism, data) { | ||
return `${authMechanism.type} ${authMechanism.buildWWWAuthenticateRest(data)}`; | ||
export function buildWWWAuthenticateHeader(authMechanism, data) { | ||
return `${authMechanism.type} ${authMechanism.buildWWWAuthenticateRest(data)}`; | ||
} | ||
@@ -211,7 +155,5 @@ /** | ||
*/ | ||
function buildAuthorizationHeader(authMechanism, data) { | ||
return `${authMechanism.type} ${authMechanism.buildAuthorizationRest(data)}`; | ||
export function buildAuthorizationHeader(authMechanism, data) { | ||
return `${authMechanism.type} ${authMechanism.buildAuthorizationRest(data)}`; | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -1,141 +0,132 @@ | ||
"use strict"; | ||
var _assert = _interopRequireDefault(require("assert")); | ||
var _neatequal = _interopRequireDefault(require("neatequal")); | ||
var _index = require("./index"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import { parseWWWAuthenticateHeader, parseAuthorizationHeader, buildWWWAuthenticateHeader, buildAuthorizationHeader, mechanisms, BASIC, DIGEST, BEARER, } from './index.js'; | ||
describe('index', () => { | ||
describe('parseWWWAuthenticateHeader', () => { | ||
it('should parse Basic headers', () => { | ||
(0, _neatequal.default)((0, _index.parseWWWAuthenticateHeader)('Basic realm="test"'), { | ||
type: 'Basic', | ||
data: { | ||
realm: 'test' | ||
} | ||
}); | ||
(0, _neatequal.default)((0, _index.parseWWWAuthenticateHeader)('basic realm="test"', [_index.BASIC], { | ||
strict: false | ||
}), { | ||
type: 'Basic', | ||
data: { | ||
realm: 'test' | ||
} | ||
}); | ||
describe('parseWWWAuthenticateHeader', () => { | ||
test('should parse Basic headers', () => { | ||
neatequal(parseWWWAuthenticateHeader('Basic realm="test"'), { | ||
type: 'Basic', | ||
data: { | ||
realm: 'test', | ||
}, | ||
}); | ||
neatequal(parseWWWAuthenticateHeader('basic realm="test"', [BASIC], { | ||
strict: false, | ||
}), { | ||
type: 'Basic', | ||
data: { | ||
realm: 'test', | ||
}, | ||
}); | ||
}); | ||
test('should parse Bearer headers', () => { | ||
neatequal(parseWWWAuthenticateHeader('Bearer realm="test"', mechanisms), { | ||
type: 'Bearer', | ||
data: { | ||
realm: 'test', | ||
}, | ||
}); | ||
neatequal(parseWWWAuthenticateHeader('bearer realm="test"', mechanisms, { | ||
strict: false, | ||
}), { | ||
type: 'Bearer', | ||
data: { | ||
realm: 'test', | ||
}, | ||
}); | ||
}); | ||
test('should fail with unknown headers', () => { | ||
assert.throws(() => parseWWWAuthenticateHeader('Kikoolol realm="test"'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
}); | ||
}); | ||
it('should parse Bearer headers', () => { | ||
(0, _neatequal.default)((0, _index.parseWWWAuthenticateHeader)('Bearer realm="test"', _index.mechanisms), { | ||
type: 'Bearer', | ||
data: { | ||
realm: 'test' | ||
} | ||
}); | ||
(0, _neatequal.default)((0, _index.parseWWWAuthenticateHeader)('bearer realm="test"', _index.mechanisms, { | ||
strict: false | ||
}), { | ||
type: 'Bearer', | ||
data: { | ||
realm: 'test' | ||
} | ||
}); | ||
describe('parseAuthorizationHeader', () => { | ||
test('should parse Basic headers', () => { | ||
neatequal(parseAuthorizationHeader('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
type: 'Basic', | ||
data: { | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
}, | ||
}); | ||
neatequal(parseAuthorizationHeader('basic QWxpIEJhYmE6b3BlbiBzZXNhbWU=', [BASIC], { | ||
strict: false, | ||
}), { | ||
type: 'Basic', | ||
data: { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}, | ||
}, { strict: false }); | ||
neatequal(parseAuthorizationHeader('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU=', mechanisms), { | ||
type: 'Basic', | ||
data: { | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
}, | ||
}); | ||
neatequal(parseAuthorizationHeader('Basic bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), { | ||
type: 'Basic', | ||
data: { | ||
username: 'nicolas.froidure@simplifield.com', | ||
password: 'test', | ||
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==', | ||
}, | ||
}); | ||
}); | ||
test('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=', | ||
}, | ||
}); | ||
}); | ||
test('should fail with unknown headers', () => { | ||
assert.throws(() => parseAuthorizationHeader('Kikoolol ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
}); | ||
test('should fail with basic headers in strict mode', () => { | ||
assert.throws(() => parseAuthorizationHeader('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
assert.throws(() => parseAuthorizationHeader('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
assert.throws(() => parseAuthorizationHeader('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
}); | ||
}); | ||
it('should fail with unknown headers', () => { | ||
_assert.default.throws(() => (0, _index.parseWWWAuthenticateHeader)('Kikoolol realm="test"'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
describe('buildWWWAuthenticateHeader', () => { | ||
test('should build Basic headers', () => { | ||
assert.equal(buildWWWAuthenticateHeader(BASIC, { | ||
realm: 'test', | ||
}), 'Basic realm="test"'); | ||
}); | ||
test('should be reentrant', () => { | ||
assert.equal(buildWWWAuthenticateHeader(BASIC, parseWWWAuthenticateHeader('Basic realm="test"').data), 'Basic realm="test"'); | ||
}); | ||
}); | ||
}); | ||
describe('parseAuthorizationHeader', () => { | ||
it('should parse Basic headers', () => { | ||
(0, _neatequal.default)((0, _index.parseAuthorizationHeader)('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
type: 'Basic', | ||
data: { | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
} | ||
}); | ||
(0, _neatequal.default)((0, _index.parseAuthorizationHeader)('basic QWxpIEJhYmE6b3BlbiBzZXNhbWU=', [_index.BASIC], { | ||
strict: false | ||
}), { | ||
type: 'Basic', | ||
data: { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
} | ||
}, { | ||
strict: false | ||
}); | ||
(0, _neatequal.default)((0, _index.parseAuthorizationHeader)('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU=', _index.mechanisms), { | ||
type: 'Basic', | ||
data: { | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
} | ||
}); | ||
(0, _neatequal.default)((0, _index.parseAuthorizationHeader)('Basic bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), { | ||
type: 'Basic', | ||
data: { | ||
username: 'nicolas.froidure@simplifield.com', | ||
password: 'test', | ||
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==' | ||
} | ||
}); | ||
describe('buildAuthorizationHeader', () => { | ||
test('should build Basic headers', () => { | ||
assert.equal(buildAuthorizationHeader(BASIC, { | ||
username: 'John', | ||
password: 'R:U:kidding?', | ||
}), 'Basic Sm9objpSOlU6a2lkZGluZz8='); | ||
}); | ||
test('should be reentrant', () => { | ||
assert.equal(buildAuthorizationHeader(BASIC, parseAuthorizationHeader('Basic Sm9objpSOlU6a2lkZGluZz8=', [BASIC]) | ||
.data), 'Basic Sm9objpSOlU6a2lkZGluZz8='); | ||
}); | ||
}); | ||
it('should parse Basic headers with a ":" char in the password', () => { | ||
(0, _neatequal.default)((0, _index.parseAuthorizationHeader)('Basic Sm9objpSOlU6a2lkZGluZz8='), { | ||
type: 'Basic', | ||
data: { | ||
username: 'John', | ||
password: 'R:U:kidding?', | ||
hash: 'Sm9objpSOlU6a2lkZGluZz8=' | ||
} | ||
}); | ||
describe('mechanisms', () => { | ||
test('should export bot DIGEST and BASIC mechanisms', () => { | ||
assert.equal(mechanisms.length, 3); | ||
}); | ||
test('should export DIGEST BASIC and BEARER mechanisms', () => { | ||
assert(BASIC); | ||
assert(DIGEST); | ||
assert(BEARER); | ||
}); | ||
}); | ||
it('should fail with unknown headers', () => { | ||
_assert.default.throws(() => (0, _index.parseAuthorizationHeader)('Kikoolol ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
}); | ||
it('should fail with basic headers in strict mode', () => { | ||
_assert.default.throws(() => (0, _index.parseAuthorizationHeader)('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
_assert.default.throws(() => (0, _index.parseAuthorizationHeader)('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
_assert.default.throws(() => (0, _index.parseAuthorizationHeader)('basic ddd'), /E_UNKNOWN_AUTH_MECHANISM/); | ||
}); | ||
}); | ||
describe('buildWWWAuthenticateHeader', () => { | ||
it('should build Basic headers', () => { | ||
_assert.default.equal((0, _index.buildWWWAuthenticateHeader)(_index.BASIC, { | ||
realm: 'test' | ||
}), 'Basic realm="test"'); | ||
}); | ||
it('should be reentrant', () => { | ||
_assert.default.equal((0, _index.buildWWWAuthenticateHeader)(_index.BASIC, (0, _index.parseWWWAuthenticateHeader)('Basic realm="test"').data), 'Basic realm="test"'); | ||
}); | ||
}); | ||
describe('buildAuthorizationHeader', () => { | ||
it('should build Basic headers', () => { | ||
_assert.default.equal((0, _index.buildAuthorizationHeader)(_index.BASIC, { | ||
username: 'John', | ||
password: 'R:U:kidding?' | ||
}), 'Basic Sm9objpSOlU6a2lkZGluZz8='); | ||
}); | ||
it('should be reentrant', () => { | ||
_assert.default.equal((0, _index.buildAuthorizationHeader)(_index.BASIC, (0, _index.parseAuthorizationHeader)('Basic Sm9objpSOlU6a2lkZGluZz8=', [_index.BASIC]).data), 'Basic Sm9objpSOlU6a2lkZGluZz8='); | ||
}); | ||
}); | ||
describe('mechanisms', () => { | ||
it('should export bot DIGEST and BASIC mechanisms', () => { | ||
_assert.default.equal(_index.mechanisms.length, 3); | ||
}); | ||
it('should export DIGEST BASIC and BEARER mechanisms', () => { | ||
(0, _assert.default)(_index.BASIC); | ||
(0, _assert.default)(_index.DIGEST); | ||
(0, _assert.default)(_index.BEARER); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=index.test.js.map |
@@ -1,20 +0,8 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = void 0; | ||
var _yerror = _interopRequireDefault(require("yerror")); | ||
var _utils = require("../utils"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* @module http-auth-utils/mechanisms/basic | ||
*/ | ||
import { YError } from 'yerror'; | ||
import { parseHTTPHeadersQuotedKeyValueSet, buildHTTPHeadersQuotedKeyValueSet, } from '../utils.js'; | ||
const REQUIRED_WWW_AUTHENTICATE_KEYS = ['realm']; | ||
const AUTHORIZED_WWW_AUTHENTICATE_KEYS = REQUIRED_WWW_AUTHENTICATE_KEYS; | ||
/* Architecture Note #1.2: Basic mechanism | ||
@@ -25,3 +13,2 @@ | ||
*/ | ||
/** | ||
@@ -33,147 +20,129 @@ * Basic authentication mechanism. | ||
const BASIC = { | ||
/** | ||
* The Basic auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Basic', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
* realm: 'perlinpinpin' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return (0, _utils.parseHTTPHeadersQuotedKeyValueSet)(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* BASIC.buildWWWAuthenticateRest({ | ||
* realm: 'perlinpinpin' | ||
* }), | ||
* 'realm="perlinpinpin"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
return (0, _utils.buildHTTPHeadersQuotedKeyValueSet)(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
if (!rest) { | ||
throw new _yerror.default('E_EMPTY_AUTH'); | ||
} | ||
const { | ||
username, | ||
password | ||
} = BASIC.decodeHash(rest); | ||
return { | ||
hash: rest, | ||
username, | ||
password | ||
}; | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} content The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* BASIC.buildAuthorizationRest({ | ||
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* }), | ||
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest({ | ||
hash, | ||
username, | ||
password | ||
}) { | ||
if (username && password) { | ||
return BASIC.computeHash({ | ||
username, | ||
password | ||
}); | ||
} | ||
if (!hash) { | ||
throw new _yerror.default('E_NO_HASH'); | ||
} | ||
return hash; | ||
}, | ||
/** | ||
* Compute the Basic authentication hash from the given credentials. | ||
* @param {Object} credentials The credentials to encode {username, password}. | ||
* @return {String} The hash representing the credentials. | ||
* @example | ||
* assert.equal( | ||
* BASIC.computeHash({ | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* }), | ||
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* ); | ||
* @api public | ||
*/ | ||
computeHash: function computeHash({ | ||
username, | ||
password | ||
}) { | ||
return Buffer.from(username + ':' + password).toString('base64'); | ||
}, | ||
/** | ||
* Decode the Basic hash and return the corresponding credentials. | ||
* @param {String} hash The hash. | ||
* @return {Object} Object representing the credentials {username, password}. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
decodeHash: function decodeHash(hash) { | ||
const [username, ...passwordParts] = Buffer.from(hash, 'base64').toString().split(':'); | ||
return { | ||
username, | ||
password: passwordParts.join(':') | ||
}; | ||
} | ||
/** | ||
* The Basic auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Basic', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
* realm: 'perlinpinpin' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return parseHTTPHeadersQuotedKeyValueSet(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* BASIC.buildWWWAuthenticateRest({ | ||
* realm: 'perlinpinpin' | ||
* }), | ||
* 'realm="perlinpinpin"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
return buildHTTPHeadersQuotedKeyValueSet(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
if (!rest) { | ||
throw new YError('E_EMPTY_AUTH'); | ||
} | ||
const { username, password } = BASIC.decodeHash(rest); | ||
return { | ||
hash: rest, | ||
username, | ||
password, | ||
}; | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} content The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* BASIC.buildAuthorizationRest({ | ||
* hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* }), | ||
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest({ hash, username, password, }) { | ||
if (username && password) { | ||
return BASIC.computeHash({ | ||
username, | ||
password, | ||
}); | ||
} | ||
if (!hash) { | ||
throw new YError('E_NO_HASH'); | ||
} | ||
return hash; | ||
}, | ||
/** | ||
* Compute the Basic authentication hash from the given credentials. | ||
* @param {Object} credentials The credentials to encode {username, password}. | ||
* @return {String} The hash representing the credentials. | ||
* @example | ||
* assert.equal( | ||
* BASIC.computeHash({ | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* }), | ||
* 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
* ); | ||
* @api public | ||
*/ | ||
computeHash: function computeHash({ username, password, }) { | ||
return Buffer.from(username + ':' + password).toString('base64'); | ||
}, | ||
/** | ||
* Decode the Basic hash and return the corresponding credentials. | ||
* @param {String} hash The hash. | ||
* @return {Object} Object representing the credentials {username, password}. | ||
* @example | ||
* assert.deepEqual( | ||
* BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
* username: 'Ali Baba', | ||
* password: 'open sesame' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
decodeHash: function decodeHash(hash) { | ||
const [username, ...passwordParts] = Buffer.from(hash, 'base64') | ||
.toString() | ||
.split(':'); | ||
return { | ||
username, | ||
password: passwordParts.join(':'), | ||
}; | ||
}, | ||
}; | ||
var _default = BASIC; | ||
exports.default = _default; | ||
export default BASIC; | ||
//# sourceMappingURL=basic.js.map |
@@ -1,99 +0,93 @@ | ||
"use strict"; | ||
var _assert = _interopRequireDefault(require("assert")); | ||
var _neatequal = _interopRequireDefault(require("neatequal")); | ||
var _basic = _interopRequireDefault(require("./basic")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import BASIC from './basic.js'; | ||
describe('BASIC', () => { | ||
describe('type', () => { | ||
test('should be the basic auth prefix', () => { | ||
_assert.default.equal(_basic.default.type, 'Basic'); | ||
describe('type', () => { | ||
test('should be the basic auth prefix', () => { | ||
assert.equal(BASIC.type, 'Basic'); | ||
}); | ||
}); | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
(0, _neatequal.default)(_basic.default.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
realm: 'perlinpinpin' | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
neatequal(BASIC.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
realm: 'perlinpinpin', | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('buildWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
_assert.default.equal(_basic.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin' | ||
}), 'realm="perlinpinpin"'); | ||
describe('buildWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
assert.equal(BASIC.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
}), 'realm="perlinpinpin"'); | ||
}); | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
neatequal(BASIC.parseWWWAuthenticateRest(BASIC.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
})), { | ||
realm: 'perlinpinpin', | ||
}); | ||
}); | ||
}); | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
(0, _neatequal.default)(_basic.default.parseWWWAuthenticateRest(_basic.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin' | ||
})), { | ||
realm: 'perlinpinpin' | ||
}); | ||
describe('parseAuthorizationRest', () => { | ||
test('should work', () => { | ||
neatequal(BASIC.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}); | ||
neatequal(BASIC.parseAuthorizationRest('bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), { | ||
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==', | ||
username: 'nicolas.froidure@simplifield.com', | ||
password: 'test', | ||
}); | ||
}); | ||
test('should fail with empty rest', () => { | ||
assert.throws(() => BASIC.parseAuthorizationRest(''), /E_EMPTY_AUTH/); | ||
}); | ||
}); | ||
}); | ||
describe('parseAuthorizationRest', () => { | ||
test('should work', () => { | ||
(0, _neatequal.default)(_basic.default.parseAuthorizationRest('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
}); | ||
(0, _neatequal.default)(_basic.default.parseAuthorizationRest('bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA=='), { | ||
hash: 'bmljb2xhcy5mcm9pZHVyZUBzaW1wbGlmaWVsZC5jb206dGVzdA==', | ||
username: 'nicolas.froidure@simplifield.com', | ||
password: 'test' | ||
}); | ||
describe('buildAuthorizationRest', () => { | ||
test('should work with credentials', () => { | ||
assert.equal(BASIC.buildAuthorizationRest({ | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
}); | ||
test('should work with just the hash', () => { | ||
assert.equal(BASIC.buildAuthorizationRest({ | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
}); | ||
test('should fail with nothing at all', () => { | ||
assert.throws(() => BASIC.buildAuthorizationRest({}), /E_NO_HASH/); | ||
}); | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
neatequal(BASIC.parseAuthorizationRest(BASIC.buildAuthorizationRest({ | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
})), { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}); | ||
}); | ||
}); | ||
test('should fail with empty rest', () => { | ||
_assert.default.throws(() => _basic.default.parseAuthorizationRest(''), /E_EMPTY_AUTH/); | ||
describe('computeHash', () => { | ||
test('should work', () => { | ||
assert.equal(BASIC.computeHash({ | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
}); | ||
}); | ||
}); | ||
describe('buildAuthorizationRest', () => { | ||
test('should work with credentials', () => { | ||
_assert.default.equal(_basic.default.buildAuthorizationRest({ | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
describe('decodeHash', () => { | ||
test('should work', () => { | ||
neatequal(BASIC.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
username: 'Ali Baba', | ||
password: 'open sesame', | ||
}); | ||
}); | ||
}); | ||
test('should work with just the hash', () => { | ||
_assert.default.equal(_basic.default.buildAuthorizationRest({ | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=' | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
}); | ||
test('should fail with nothing at all', () => { | ||
_assert.default.throws(() => _basic.default.buildAuthorizationRest({}), /E_NO_HASH/); | ||
}); | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
(0, _neatequal.default)(_basic.default.parseAuthorizationRest(_basic.default.buildAuthorizationRest({ | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
})), { | ||
hash: 'QWxpIEJhYmE6b3BlbiBzZXNhbWU=', | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
}); | ||
}); | ||
}); | ||
describe('computeHash', () => { | ||
test('should work', () => { | ||
_assert.default.equal(_basic.default.computeHash({ | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
}), 'QWxpIEJhYmE6b3BlbiBzZXNhbWU='); | ||
}); | ||
}); | ||
describe('decodeHash', () => { | ||
test('should work', () => { | ||
(0, _neatequal.default)(_basic.default.decodeHash('QWxpIEJhYmE6b3BlbiBzZXNhbWU='), { | ||
username: 'Ali Baba', | ||
password: 'open sesame' | ||
}); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=basic.test.js.map |
@@ -1,21 +0,18 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = void 0; | ||
var _yerror = _interopRequireDefault(require("yerror")); | ||
var _utils = require("../utils"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* @module http-auth-utils/mechanisms/bearer | ||
*/ | ||
const AUTHORIZED_ERROR_CODES = ['invalid_request', 'invalid_token', 'insufficient_scope']; | ||
import { YError } from 'yerror'; | ||
import { parseHTTPHeadersQuotedKeyValueSet, buildHTTPHeadersQuotedKeyValueSet, } from '../utils.js'; | ||
const AUTHORIZED_ERROR_CODES = [ | ||
'invalid_request', | ||
'invalid_token', | ||
'insufficient_scope', | ||
]; | ||
const REQUIRED_WWW_AUTHENTICATE_KEYS = ['realm']; | ||
const AUTHORIZED_WWW_AUTHENTICATE_KEYS = [...REQUIRED_WWW_AUTHENTICATE_KEYS, 'scope', 'error', 'error_description']; | ||
const AUTHORIZED_WWW_AUTHENTICATE_KEYS = [ | ||
...REQUIRED_WWW_AUTHENTICATE_KEYS, | ||
'scope', | ||
'error', | ||
'error_description', | ||
]; | ||
/* Architecture Note #1.1: Bearer mechanism | ||
@@ -26,3 +23,2 @@ | ||
*/ | ||
/** | ||
@@ -34,100 +30,92 @@ * Bearer authentication mechanism. | ||
const BEARER = { | ||
/** | ||
* The Bearer auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Bearer', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* BEARER.parseWWWAuthenticateRest( | ||
* 'realm="testrealm@host.com", ' + | ||
* 'scope="openid profile email"' | ||
* ), { | ||
* realm: 'testrealm@host.com', | ||
* scope: 'openid profile email', | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return (0, _utils.parseHTTPHeadersQuotedKeyValueSet)(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, []); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* BEARER.buildWWWAuthenticateRest({ | ||
* realm: 'testrealm@host.com', | ||
* error: 'invalid_request', | ||
* error_description: 'The access token expired', | ||
* }), | ||
* 'realm="testrealm@host.com", ' + | ||
* 'error="invalid_request", ' + | ||
* 'error_description="The access token expired"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
if (data.error && -1 === AUTHORIZED_ERROR_CODES.indexOf(data.error)) { | ||
throw new _yerror.default('E_INVALID_ERROR', data.error, AUTHORIZED_ERROR_CODES); | ||
} | ||
return (0, _utils.buildHTTPHeadersQuotedKeyValueSet)(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, []); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* BEARER.parseAuthorizationRest('mF_9.B5f-4.1JqM'), { | ||
* hash: 'mF_9.B5f-4.1JqM', | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
if (!rest) { | ||
throw new _yerror.default('E_EMPTY_AUTH'); | ||
} | ||
return { | ||
hash: rest | ||
}; | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} content The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* BEARER.buildAuthorizationRest({ | ||
* hash: 'mF_9.B5f-4.1JqM' | ||
* }), | ||
* 'mF_9.B5f-4.1JqM==' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest({ | ||
hash | ||
}) { | ||
if (!hash) { | ||
throw new _yerror.default('E_NO_HASH'); | ||
} | ||
return hash; | ||
} | ||
/** | ||
* The Bearer auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Bearer', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* BEARER.parseWWWAuthenticateRest( | ||
* 'realm="testrealm@host.com", ' + | ||
* 'scope="openid profile email"' | ||
* ), { | ||
* realm: 'testrealm@host.com', | ||
* scope: 'openid profile email', | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return parseHTTPHeadersQuotedKeyValueSet(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, []); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* BEARER.buildWWWAuthenticateRest({ | ||
* realm: 'testrealm@host.com', | ||
* error: 'invalid_request', | ||
* error_description: 'The access token expired', | ||
* }), | ||
* 'realm="testrealm@host.com", ' + | ||
* 'error="invalid_request", ' + | ||
* 'error_description="The access token expired"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
if (data.error && | ||
-1 === | ||
AUTHORIZED_ERROR_CODES.indexOf(data.error)) { | ||
throw new YError('E_INVALID_ERROR', data.error, AUTHORIZED_ERROR_CODES); | ||
} | ||
return buildHTTPHeadersQuotedKeyValueSet(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, []); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* BEARER.parseAuthorizationRest('mF_9.B5f-4.1JqM'), { | ||
* hash: 'mF_9.B5f-4.1JqM', | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
if (!rest) { | ||
throw new YError('E_EMPTY_AUTH'); | ||
} | ||
return { | ||
hash: rest, | ||
}; | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} content The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* BEARER.buildAuthorizationRest({ | ||
* hash: 'mF_9.B5f-4.1JqM' | ||
* }), | ||
* 'mF_9.B5f-4.1JqM==' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest({ hash, }) { | ||
if (!hash) { | ||
throw new YError('E_NO_HASH'); | ||
} | ||
return hash; | ||
}, | ||
}; | ||
var _default = BEARER; | ||
exports.default = _default; | ||
export default BEARER; | ||
//# sourceMappingURL=bearer.js.map |
@@ -1,80 +0,76 @@ | ||
"use strict"; | ||
var _assert = _interopRequireDefault(require("assert")); | ||
var _neatequal = _interopRequireDefault(require("neatequal")); | ||
var _bearer = _interopRequireDefault(require("./bearer")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import BEARER from './bearer.js'; | ||
describe('BEARER', () => { | ||
describe('type', () => { | ||
it('should be the basic auth prefix', () => { | ||
_assert.default.equal(_bearer.default.type, 'Bearer'); | ||
describe('type', () => { | ||
test('should be the basic auth prefix', () => { | ||
assert.equal(BEARER.type, 'Bearer'); | ||
}); | ||
}); | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
(0, _neatequal.default)(_bearer.default.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
realm: 'perlinpinpin' | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
neatequal(BEARER.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
realm: 'perlinpinpin', | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('buildWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
_assert.default.equal(_bearer.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin' | ||
}), 'realm="perlinpinpin"'); | ||
describe('buildWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
assert.equal(BEARER.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
}), 'realm="perlinpinpin"'); | ||
}); | ||
test('should work with an error', () => { | ||
assert.equal(BEARER.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
error: 'invalid_request', | ||
error_description: 'The access token expired', | ||
}), 'realm="perlinpinpin", ' + | ||
'error="invalid_request", ' + | ||
'error_description="The access token expired"'); | ||
}); | ||
test('should fail with an unauthorized error', () => { | ||
assert.throws(() => BEARER.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
error: 'invalid_tacos', | ||
error_description: 'The tacos has been eaten yet', | ||
}), /E_INVALID_ERROR/); | ||
}); | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
neatequal(BEARER.parseWWWAuthenticateRest(BEARER.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
})), { | ||
realm: 'perlinpinpin', | ||
}); | ||
}); | ||
}); | ||
it('should work with an error', () => { | ||
_assert.default.equal(_bearer.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
error: 'invalid_request', | ||
error_description: 'The access token expired' | ||
}), 'realm="perlinpinpin", ' + 'error="invalid_request", ' + 'error_description="The access token expired"'); | ||
describe('parseAuthorizationRest', () => { | ||
test('should work', () => { | ||
neatequal(BEARER.parseAuthorizationRest('mF_9.B5f-4.1JqM'), { | ||
hash: 'mF_9.B5f-4.1JqM', | ||
}); | ||
}); | ||
test('should fail with empty rest', () => { | ||
assert.throws(() => BEARER.parseAuthorizationRest(''), /E_EMPTY_AUTH/); | ||
}); | ||
}); | ||
it('should fail with an unauthorized error', () => { | ||
_assert.default.throws(() => _bearer.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
error: 'invalid_tacos', | ||
error_description: 'The tacos has been eaten yet' | ||
}), /E_INVALID_ERROR/); | ||
describe('buildAuthorizationRest', () => { | ||
test('should work', () => { | ||
assert.equal(BEARER.buildAuthorizationRest({ | ||
hash: 'mF_9.B5f-4.1JqM', | ||
}), 'mF_9.B5f-4.1JqM'); | ||
}); | ||
test('should fail with nothing at all', () => { | ||
assert.throws(() => BEARER.buildAuthorizationRest({}), /E_NO_HASH/); | ||
}); | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
neatequal(BEARER.parseAuthorizationRest(BEARER.buildAuthorizationRest({ | ||
hash: 'mF_9.B5f-4.1JqM', | ||
})), { | ||
hash: 'mF_9.B5f-4.1JqM', | ||
}); | ||
}); | ||
}); | ||
it('should be the inverse of parseWWWAuthenticateRest', () => { | ||
(0, _neatequal.default)(_bearer.default.parseWWWAuthenticateRest(_bearer.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin' | ||
})), { | ||
realm: 'perlinpinpin' | ||
}); | ||
}); | ||
}); | ||
describe('parseAuthorizationRest', () => { | ||
it('should work', () => { | ||
(0, _neatequal.default)(_bearer.default.parseAuthorizationRest('mF_9.B5f-4.1JqM'), { | ||
hash: 'mF_9.B5f-4.1JqM' | ||
}); | ||
}); | ||
it('should fail with empty rest', () => { | ||
_assert.default.throws(() => _bearer.default.parseAuthorizationRest(''), /E_EMPTY_AUTH/); | ||
}); | ||
}); | ||
describe('buildAuthorizationRest', () => { | ||
it('should work', () => { | ||
_assert.default.equal(_bearer.default.buildAuthorizationRest({ | ||
hash: 'mF_9.B5f-4.1JqM' | ||
}), 'mF_9.B5f-4.1JqM'); | ||
}); | ||
it('should fail with nothing at all', () => { | ||
_assert.default.throws(() => _bearer.default.buildAuthorizationRest({}), /E_NO_HASH/); | ||
}); | ||
it('should be the inverse of parseAuthorizationRest', () => { | ||
(0, _neatequal.default)(_bearer.default.parseAuthorizationRest(_bearer.default.buildAuthorizationRest({ | ||
hash: 'mF_9.B5f-4.1JqM' | ||
})), { | ||
hash: 'mF_9.B5f-4.1JqM' | ||
}); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=bearer.test.js.map |
@@ -1,22 +0,30 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.default = void 0; | ||
var _utils = require("../utils"); | ||
var _crypto = _interopRequireDefault(require("crypto")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
/** | ||
* @module http-auth-utils/mechanisms/digest | ||
*/ | ||
import { parseHTTPHeadersQuotedKeyValueSet, buildHTTPHeadersQuotedKeyValueSet, } from '../utils.js'; | ||
import crypto from 'crypto'; | ||
const REQUIRED_WWW_AUTHENTICATE_KEYS = ['realm', 'nonce']; | ||
const AUTHORIZED_WWW_AUTHENTICATE_KEYS = [...REQUIRED_WWW_AUTHENTICATE_KEYS, 'domain', 'opaque', 'stale', 'algorithm', 'qop']; | ||
const REQUIRED_AUTHORIZATION_KEYS = ['username', 'realm', 'nonce', 'uri', 'response']; | ||
const AUTHORIZED_AUTHORIZATION_KEYS = [...REQUIRED_AUTHORIZATION_KEYS, 'algorithm', 'cnonce', 'opaque', 'qop', 'nc']; | ||
const AUTHORIZED_WWW_AUTHENTICATE_KEYS = [ | ||
...REQUIRED_WWW_AUTHENTICATE_KEYS, | ||
'domain', | ||
'opaque', | ||
'stale', | ||
'algorithm', | ||
'qop', | ||
]; | ||
const REQUIRED_AUTHORIZATION_KEYS = [ | ||
'username', | ||
'realm', | ||
'nonce', | ||
'uri', | ||
'response', | ||
]; | ||
const AUTHORIZED_AUTHORIZATION_KEYS = [ | ||
...REQUIRED_AUTHORIZATION_KEYS, | ||
'algorithm', | ||
'cnonce', | ||
'opaque', | ||
'qop', | ||
'nc', | ||
]; | ||
/* Architecture Note #1.3: Digest mechanism | ||
@@ -27,3 +35,2 @@ | ||
*/ | ||
/** | ||
@@ -36,162 +43,152 @@ * Digest authentication mechanism. | ||
const DIGEST = { | ||
/** | ||
* The Digest auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Digest', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* DIGEST.parseWWWAuthenticateRest( | ||
* 'realm="testrealm@host.com", ' + | ||
* 'qop="auth, auth-int", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' | ||
* ), { | ||
* realm: 'testrealm@host.com', | ||
* qop: 'auth, auth-int', | ||
* nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
* opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return (0, _utils.parseHTTPHeadersQuotedKeyValueSet)(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* DIGEST.buildWWWAuthenticateRest({ | ||
* realm: 'testrealm@host.com', | ||
* qop: 'auth, auth-int', | ||
* nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
* opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
* }), | ||
* 'realm="testrealm@host.com", ' + | ||
* 'qop="auth, auth-int", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
return (0, _utils.buildHTTPHeadersQuotedKeyValueSet)(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* DIGEST.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", | ||
* realm: 'testrealm@host.com', | ||
* nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093", | ||
* uri: "/dir/index.html", | ||
* qop: 'auth', | ||
* nc: '00000001', | ||
* cnonce: "0a4f113b", | ||
* response: "6629fae49393a05397450978507c4ef1", | ||
* opaque: "5ccc069c403ebaf9f0171e9517f40e41" | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
return (0, _utils.parseHTTPHeadersQuotedKeyValueSet)(rest, AUTHORIZED_AUTHORIZATION_KEYS, REQUIRED_AUTHORIZATION_KEYS); | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* DIGEST.buildAuthorizationRest({ | ||
* username: "Mufasa", | ||
* realm: 'testrealm@host.com', | ||
* nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093", | ||
* uri: "/dir/index.html", | ||
* qop: 'auth', | ||
* nc: '00000001', | ||
* cnonce: "0a4f113b", | ||
* response: "6629fae49393a05397450978507c4ef1", | ||
* opaque: "5ccc069c403ebaf9f0171e9517f40e41" | ||
* }), | ||
* 'username="Mufasa", ' + | ||
* 'realm="testrealm@host.com", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'uri="/dir/index.html", ' + | ||
* 'response="6629fae49393a05397450978507c4ef1", ' + | ||
* 'cnonce="0a4f113b", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + | ||
* 'qop="auth", ' + | ||
* 'nc="00000001"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest(data) { | ||
return (0, _utils.buildHTTPHeadersQuotedKeyValueSet)(data, AUTHORIZED_AUTHORIZATION_KEYS, REQUIRED_AUTHORIZATION_KEYS); | ||
}, | ||
/** | ||
* Compute the Digest authentication hash from the given credentials. | ||
* @param {Object} data The credentials to encode and other encoding details. | ||
* @return {String} The hash representing the credentials. | ||
* @example | ||
* 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' | ||
* ); | ||
* @api public | ||
*/ | ||
computeHash: function computeHash(data) { | ||
const ha1 = data.ha1 || _computeHash(data.algorithm, [data.username, data.realm, data.password].join(':')); | ||
const ha2 = _computeHash(data.algorithm, [data.method, data.uri].join(':')); | ||
return _computeHash(data.algorithm, [ha1, data.nonce, data.nc, data.cnonce, data.qop, ha2].join(':')); | ||
} | ||
/** | ||
* The Digest auth mechanism prefix. | ||
* @type {String} | ||
*/ | ||
type: 'Digest', | ||
/** | ||
* Parse the WWW Authenticate header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix). | ||
* @return {Object} Object representing the result of the parse operation. | ||
* @example | ||
* assert.deepEqual( | ||
* DIGEST.parseWWWAuthenticateRest( | ||
* 'realm="testrealm@host.com", ' + | ||
* 'qop="auth, auth-int", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' | ||
* ), { | ||
* realm: 'testrealm@host.com', | ||
* qop: 'auth, auth-int', | ||
* nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
* opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseWWWAuthenticateRest: function parseWWWAuthenticateRest(rest) { | ||
return parseHTTPHeadersQuotedKeyValueSet(rest, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Build the WWW Authenticate header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The built rest. | ||
* @example | ||
* assert.equal( | ||
* DIGEST.buildWWWAuthenticateRest({ | ||
* realm: 'testrealm@host.com', | ||
* qop: 'auth, auth-int', | ||
* nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
* opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
* }), | ||
* 'realm="testrealm@host.com", ' + | ||
* 'qop="auth, auth-int", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildWWWAuthenticateRest: function buildWWWAuthenticateRest(data) { | ||
return buildHTTPHeadersQuotedKeyValueSet(data, AUTHORIZED_WWW_AUTHENTICATE_KEYS, REQUIRED_WWW_AUTHENTICATE_KEYS); | ||
}, | ||
/** | ||
* Parse the Authorization header rest. | ||
* @param {String} rest The header rest (string after the authentication mechanism prefix).) | ||
* @return {Object} Object representing the result of the parse operation {hash}. | ||
* @example | ||
* assert.deepEqual( | ||
* DIGEST.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", | ||
* realm: 'testrealm@host.com', | ||
* nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093", | ||
* uri: "/dir/index.html", | ||
* qop: 'auth', | ||
* nc: '00000001', | ||
* cnonce: "0a4f113b", | ||
* response: "6629fae49393a05397450978507c4ef1", | ||
* opaque: "5ccc069c403ebaf9f0171e9517f40e41" | ||
* } | ||
* ); | ||
* @api public | ||
*/ | ||
parseAuthorizationRest: function parseAuthorizationRest(rest) { | ||
return parseHTTPHeadersQuotedKeyValueSet(rest, AUTHORIZED_AUTHORIZATION_KEYS, REQUIRED_AUTHORIZATION_KEYS); | ||
}, | ||
/** | ||
* Build the Authorization header rest. | ||
* @param {Object} data The content from wich to build the rest. | ||
* @return {String} The rest built. | ||
* @example | ||
* assert.equal( | ||
* DIGEST.buildAuthorizationRest({ | ||
* username: "Mufasa", | ||
* realm: 'testrealm@host.com', | ||
* nonce: "dcd98b7102dd2f0e8b11d0f600bfb0c093", | ||
* uri: "/dir/index.html", | ||
* qop: 'auth', | ||
* nc: '00000001', | ||
* cnonce: "0a4f113b", | ||
* response: "6629fae49393a05397450978507c4ef1", | ||
* opaque: "5ccc069c403ebaf9f0171e9517f40e41" | ||
* }), | ||
* 'username="Mufasa", ' + | ||
* 'realm="testrealm@host.com", ' + | ||
* 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
* 'uri="/dir/index.html", ' + | ||
* 'response="6629fae49393a05397450978507c4ef1", ' + | ||
* 'cnonce="0a4f113b", ' + | ||
* 'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + | ||
* 'qop="auth", ' + | ||
* 'nc="00000001"' | ||
* ); | ||
* @api public | ||
*/ | ||
buildAuthorizationRest: function buildAuthorizationRest(data) { | ||
return buildHTTPHeadersQuotedKeyValueSet(data, AUTHORIZED_AUTHORIZATION_KEYS, REQUIRED_AUTHORIZATION_KEYS); | ||
}, | ||
/** | ||
* Compute the Digest authentication hash from the given credentials. | ||
* @param {Object} data The credentials to encode and other encoding details. | ||
* @return {String} The hash representing the credentials. | ||
* @example | ||
* 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' | ||
* ); | ||
* @api public | ||
*/ | ||
computeHash: function computeHash(data) { | ||
const ha1 = data.ha1 || | ||
_computeHash(data.algorithm, [data.username, data.realm, data.password].join(':')); | ||
const ha2 = _computeHash(data.algorithm, [data.method, data.uri].join(':')); | ||
return _computeHash(data.algorithm, [ha1, data.nonce, data.nc, data.cnonce, data.qop, ha2].join(':')); | ||
}, | ||
}; | ||
function _computeHash(algorithm, str) { | ||
const hashsum = _crypto.default.createHash(algorithm); | ||
hashsum.update(str); | ||
return hashsum.digest('hex'); | ||
const hashsum = crypto.createHash(algorithm); | ||
hashsum.update(str); | ||
return hashsum.digest('hex'); | ||
} | ||
var _default = DIGEST; | ||
exports.default = _default; | ||
export default DIGEST; | ||
//# sourceMappingURL=digest.js.map |
@@ -1,127 +0,146 @@ | ||
"use strict"; | ||
var _assert = _interopRequireDefault(require("assert")); | ||
var _neatequal = _interopRequireDefault(require("neatequal")); | ||
var _digest = _interopRequireDefault(require("./digest")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import DIGEST from './digest.js'; | ||
describe('digest', () => { | ||
describe('type', () => { | ||
it('should be the digest auth prefix', () => { | ||
_assert.default.equal(_digest.default.type, 'Digest'); | ||
describe('type', () => { | ||
test('should be the digest auth prefix', () => { | ||
assert.equal(DIGEST.type, 'Digest'); | ||
}); | ||
}); | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
(0, _neatequal.default)(_digest.default.parseWWWAuthenticateRest('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}); | ||
describe('parseWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
neatequal(DIGEST.parseWWWAuthenticateRest('realm="testrealm@host.com", ' + | ||
'qop="auth, auth-int", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
'opaque="5ccc069c403ebaf9f0171e9517f40e41"'), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}); | ||
}); | ||
test('should handle non-quoted fields', () => { | ||
neatequal(DIGEST.parseWWWAuthenticateRest('realm="testrealm@host.com", ' + | ||
'qop=auth, ' + | ||
'algorithm=MD5, ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth', | ||
algorithm: 'MD5', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
}); | ||
}); | ||
}); | ||
it('should handle non-quoted fields', () => { | ||
(0, _neatequal.default)(_digest.default.parseWWWAuthenticateRest('realm="testrealm@host.com", ' + 'qop=auth, ' + 'algorithm=MD5, ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth', | ||
algorithm: 'MD5', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093' | ||
}); | ||
describe('buildWWWAuthenticateRest', () => { | ||
test('should work', () => { | ||
assert.equal(DIGEST.buildWWWAuthenticateRest({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}), 'realm="testrealm@host.com", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + | ||
'qop="auth, auth-int"'); | ||
}); | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
neatequal(DIGEST.parseWWWAuthenticateRest(DIGEST.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
})), { | ||
realm: 'perlinpinpin', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('buildWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
_assert.default.equal(_digest.default.buildWWWAuthenticateRest({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}), 'realm="testrealm@host.com", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + 'qop="auth, auth-int"'); | ||
describe('parseAuthorizationRest', () => { | ||
test('should work', () => { | ||
neatequal(DIGEST.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', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}); | ||
}); | ||
test('should fail with empty rest', () => { | ||
assert.throws(() => DIGEST.parseAuthorizationRest(''), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
}); | ||
it('should be the inverse of parseWWWAuthenticateRest', () => { | ||
(0, _neatequal.default)(_digest.default.parseWWWAuthenticateRest(_digest.default.buildWWWAuthenticateRest({ | ||
realm: 'perlinpinpin', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093' | ||
})), { | ||
realm: 'perlinpinpin', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093' | ||
}); | ||
describe('buildAuthorizationRest', () => { | ||
test('should work', () => { | ||
assert.equal(DIGEST.buildAuthorizationRest({ | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}), 'username="Mufasa", ' + | ||
'realm="testrealm@host.com", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
'uri="/dir/index.html", ' + | ||
'response="6629fae49393a05397450978507c4ef1", ' + | ||
'cnonce="0a4f113b", ' + | ||
'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + | ||
'qop="auth", ' + | ||
'nc="00000001"'); | ||
}); | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
neatequal(DIGEST.parseAuthorizationRest(DIGEST.buildAuthorizationRest({ | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
})), { | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('parseAuthorizationRest', () => { | ||
it('should work', () => { | ||
(0, _neatequal.default)(_digest.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', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}); | ||
describe('computeHash', () => { | ||
test('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'); | ||
}); | ||
}); | ||
it('should fail with empty rest', () => { | ||
_assert.default.throws(() => _digest.default.parseAuthorizationRest(''), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
}); | ||
describe('buildAuthorizationRest', () => { | ||
it('should work', () => { | ||
_assert.default.equal(_digest.default.buildAuthorizationRest({ | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}), 'username="Mufasa", ' + 'realm="testrealm@host.com", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'uri="/dir/index.html", ' + 'response="6629fae49393a05397450978507c4ef1", ' + 'cnonce="0a4f113b", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41", ' + 'qop="auth", ' + 'nc="00000001"'); | ||
}); | ||
it('should be the inverse of parseAuthorizationRest', () => { | ||
(0, _neatequal.default)(_digest.default.parseAuthorizationRest(_digest.default.buildAuthorizationRest({ | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
})), { | ||
username: 'Mufasa', | ||
realm: 'testrealm@host.com', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
uri: '/dir/index.html', | ||
qop: 'auth', | ||
nc: '00000001', | ||
cnonce: '0a4f113b', | ||
response: '6629fae49393a05397450978507c4ef1', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}); | ||
}); | ||
}); | ||
describe('computeHash', () => { | ||
it('should work', () => { | ||
_assert.default.equal(_digest.default.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'); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=digest.test.js.map |
@@ -1,13 +0,2 @@ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.buildHTTPHeadersQuotedKeyValueSet = buildHTTPHeadersQuotedKeyValueSet; | ||
exports.parseHTTPHeadersQuotedKeyValueSet = parseHTTPHeadersQuotedKeyValueSet; | ||
var _yerror = _interopRequireDefault(require("yerror")); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { YError } from 'yerror'; | ||
const QUOTE = '"'; | ||
@@ -26,61 +15,59 @@ const EQUAL = '='; | ||
*/ | ||
const KEYVALUE_REGEXP = /\w+=(".*?"|[^",]+)(?=,|$)/g; // FIXME: Create a real parser | ||
function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys, requiredKeys = []) { | ||
const matches = contents.trim().match(KEYVALUE_REGEXP); | ||
if (!matches) throw new _yerror.default('E_MALFORMED_QUOTEDKEYVALUE', contents); | ||
const data = matches.map((part, partPosition) => { | ||
const pair = part.split(EQUAL); | ||
if (2 !== pair.length) { | ||
throw new _yerror.default('E_MALFORMED_QUOTEDKEYVALUE', partPosition, part, pair.length); | ||
} | ||
return pair; | ||
}).reduce(function (parsedValues, [name, value], valuePosition) { | ||
if (-1 === authorizedKeys.indexOf(name)) { | ||
throw new _yerror.default('E_UNAUTHORIZED_KEY', valuePosition, name); | ||
} | ||
/* | ||
* Regular expression for stripping paired starting and ending double quotes off the value: | ||
* ^ = The beginning of the string | ||
* " = The first double quote | ||
* .+ = One or more characters of any kind | ||
* (?="$) = Zero-width (as in not captured) positive lookahead assertion. | ||
* The previous match will only be valid if it's followed by a " literal | ||
* or the end of the string | ||
* " = The ending double quote | ||
* $ = The end of the string | ||
*/ | ||
parsedValues[name] = value.replace(/^"(.+(?="$))"$/, '$1'); | ||
return parsedValues; | ||
}, {}); | ||
_checkRequiredKeys(requiredKeys, data); | ||
return data; | ||
const KEYVALUE_REGEXP = /\w+=(".*?"|[^",]+)(?=,|$)/g; | ||
// FIXME: Create a real parser | ||
export function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys, requiredKeys = []) { | ||
const matches = contents.trim().match(KEYVALUE_REGEXP); | ||
if (!matches) | ||
throw new YError('E_MALFORMED_QUOTEDKEYVALUE', contents); | ||
const data = matches | ||
.map((part, partPosition) => { | ||
const 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); | ||
} | ||
/* | ||
* Regular expression for stripping paired starting and ending double quotes off the value: | ||
* ^ = The beginning of the string | ||
* " = The first double quote | ||
* .+ = One or more characters of any kind | ||
* (?="$) = Zero-width (as in not captured) positive lookahead assertion. | ||
* The previous match will only be valid if it's followed by a " literal | ||
* or the end of the string | ||
* " = The ending double quote | ||
* $ = The end of the string | ||
*/ | ||
parsedValues[name] = value.replace(/^"(.+(?="$))"$/, '$1'); | ||
return parsedValues; | ||
}, {}); | ||
_checkRequiredKeys(requiredKeys, data); | ||
return data; | ||
} | ||
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; | ||
}, ''); | ||
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.default('E_REQUIRED_KEY', name); | ||
} | ||
}); | ||
requiredKeys.forEach((name) => { | ||
if ('undefined' === typeof data[name]) { | ||
throw new YError('E_REQUIRED_KEY', name); | ||
} | ||
}); | ||
} | ||
//# sourceMappingURL=utils.js.map |
@@ -1,68 +0,72 @@ | ||
"use strict"; | ||
var _assert = _interopRequireDefault(require("assert")); | ||
var _neatequal = _interopRequireDefault(require("neatequal")); | ||
var _utils = require("./utils"); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import { parseHTTPHeadersQuotedKeyValueSet, buildHTTPHeadersQuotedKeyValueSet, } from './utils.js'; | ||
describe('utils', () => { | ||
describe('parseHTTPHeadersQuotedKeyValueSet', () => { | ||
test('should work with good datas', () => { | ||
(0, _neatequal.default)((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce', 'opaque']), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}); | ||
describe('parseHTTPHeadersQuotedKeyValueSet', () => { | ||
test('should work with good datas', () => { | ||
neatequal(parseHTTPHeadersQuotedKeyValueSet('realm="testrealm@host.com", ' + | ||
'qop="auth, auth-int", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce', 'opaque']), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}); | ||
}); | ||
test('should work with parse-able non-quoted data', () => { | ||
neatequal(parseHTTPHeadersQuotedKeyValueSet('realm="testrealm@host.com", ' + | ||
'qop=auth, ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + | ||
'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce', 'opaque']), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}); | ||
}); | ||
test('should fail with bad quoted value pair', () => { | ||
assert.throws(() => parseHTTPHeadersQuotedKeyValueSet('realm', []), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
test('should fail with half-quoted value pair', () => { | ||
assert.throws(() => parseHTTPHeadersQuotedKeyValueSet('realm="uneven', ['realm']), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
test('should fail with bad quoted value pair', () => { | ||
assert.throws(() => parseHTTPHeadersQuotedKeyValueSet('realm="dsad"', []), /E_UNAUTHORIZED_KEY/); | ||
}); | ||
test('should pass with non-quoted value pair', () => { | ||
neatequal(parseHTTPHeadersQuotedKeyValueSet('realm=dsad', ['realm']), { | ||
realm: 'dsad', | ||
}); | ||
}); | ||
}); | ||
test('should work with parse-able non-quoted data', () => { | ||
(0, _neatequal.default)((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="testrealm@host.com", ' + 'qop=auth, ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093", ' + 'opaque="5ccc069c403ebaf9f0171e9517f40e41"', ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce', 'opaque']), { | ||
realm: 'testrealm@host.com', | ||
qop: 'auth', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}); | ||
describe('buildHTTPHeadersQuotedKeyValueSet', () => { | ||
test('should work with good datas', () => { | ||
assert.equal(buildHTTPHeadersQuotedKeyValueSet({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
}, ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce']), 'realm="testrealm@host.com", ' + | ||
'qop="auth, auth-int", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'); | ||
}); | ||
test('should work with unused keys', () => { | ||
assert.equal(buildHTTPHeadersQuotedKeyValueSet({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41', | ||
}, ['realm', 'qop', 'nonce']), 'realm="testrealm@host.com", ' + | ||
'qop="auth, auth-int", ' + | ||
'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'); | ||
}); | ||
test('should fail without required keys', () => { | ||
assert.throws(() => buildHTTPHeadersQuotedKeyValueSet({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
}, ['realm', 'qop', 'nonce'], ['realm', 'qop', 'nonce']), /E_REQUIRED_KEY/); | ||
}); | ||
}); | ||
test('should fail with bad quoted value pair', () => { | ||
_assert.default.throws(() => (0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm', []), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
test('should fail with half-quoted value pair', () => { | ||
_assert.default.throws(() => (0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="uneven', ['realm']), /E_MALFORMED_QUOTEDKEYVALUE/); | ||
}); | ||
test('should fail with bad quoted value pair', () => { | ||
_assert.default.throws(() => (0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm="dsad"', []), /E_UNAUTHORIZED_KEY/); | ||
}); | ||
test('should pass with non-quoted value pair', () => { | ||
(0, _neatequal.default)((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm=dsad', ['realm']), { | ||
realm: 'dsad' | ||
}); | ||
}); | ||
}); | ||
describe('buildHTTPHeadersQuotedKeyValueSet', () => { | ||
test('should work with good datas', () => { | ||
_assert.default.equal((0, _utils.buildHTTPHeadersQuotedKeyValueSet)({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093' | ||
}, ['realm', 'qop', 'nonce', 'opaque'], ['realm', 'qop', 'nonce']), 'realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'); | ||
}); | ||
test('should work with unused keys', () => { | ||
_assert.default.equal((0, _utils.buildHTTPHeadersQuotedKeyValueSet)({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int', | ||
nonce: 'dcd98b7102dd2f0e8b11d0f600bfb0c093', | ||
opaque: '5ccc069c403ebaf9f0171e9517f40e41' | ||
}, ['realm', 'qop', 'nonce']), 'realm="testrealm@host.com", ' + 'qop="auth, auth-int", ' + 'nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093"'); | ||
}); | ||
test('should fail without required keys', () => { | ||
_assert.default.throws(() => (0, _utils.buildHTTPHeadersQuotedKeyValueSet)({ | ||
realm: 'testrealm@host.com', | ||
qop: 'auth, auth-int' | ||
}, ['realm', 'qop', 'nonce'], ['realm', 'qop', 'nonce']), /E_REQUIRED_KEY/); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=utils.test.js.map |
{ | ||
"name": "http-auth-utils", | ||
"version": "3.0.3", | ||
"version": "3.0.4", | ||
"description": "Parse, build and deal with HTTP authorization headers.", | ||
"main": "dist/index", | ||
"module": "dist/index.mjs", | ||
"main": "dist/index.js", | ||
"types": "dist/index.d.ts", | ||
@@ -25,4 +24,3 @@ "metapak": { | ||
"eslint", | ||
"babel", | ||
"typescript", | ||
"tsesm", | ||
"jest", | ||
@@ -32,3 +30,3 @@ "jsdocs", | ||
"codeclimate", | ||
"travis" | ||
"ghactions" | ||
] | ||
@@ -38,7 +36,5 @@ }, | ||
"architecture": "jsarch 'src/**/*.ts' > ARCHITECTURE.md && git add ARCHITECTURE.md", | ||
"build": "rimraf -f 'dist' && tsc --outDir dist", | ||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md", | ||
"cli": "env NODE_ENV=${NODE_ENV:-cli}", | ||
"compile": "rimraf -f 'dist' && npm run compile:cjs && npm run compile:mjs", | ||
"compile:cjs": "babel --env-name=cjs --out-dir=dist --extensions '.ts,.js' --source-maps=true src", | ||
"compile:mjs": "babel --env-name=mjs --out-file-extension=.mjs --out-dir=dist --extensions '.ts,.js' --source-maps=true src", | ||
"cover": "npm run jest -- --coverage", | ||
@@ -48,10 +44,9 @@ "coveralls": "npm run cover && cat ./coverage/lcov.info | coveralls && rm -rf ./coverage", | ||
"doc": "echo \"# API\" > API.md; jsdoc2md 'dist/**/*.js' >> API.md && git add API.md", | ||
"jest": "NODE_ENV=test jest", | ||
"jest": "NODE_OPTIONS=--experimental-vm-modules NODE_ENV=test jest", | ||
"lint": "eslint 'src/**/*.ts'", | ||
"metapak": "metapak", | ||
"precz": "npm run compile && npm run types && npm t && npm run lint && npm run metapak -- -s && npm run doc && npm run architecture", | ||
"precz": "npm run build && npm t && npm run lint && npm run doc && npm run architecture && npm run metapak -- -s", | ||
"prettier": "prettier --write 'src/**/*.ts'", | ||
"preversion": "npm run compile && npm run types && npm t && npm run lint && npm run metapak -- -s && npm run doc && npm run architecture", | ||
"preversion": "npm run build && npm t && npm run lint && npm run doc && npm run architecture && npm run metapak -- -s", | ||
"test": "npm run jest", | ||
"types": "rimraf -f 'dist/**/*.d.ts' && tsc --project . --declaration --emitDeclarationOnly --outDir dist", | ||
"version": "npm run changelog" | ||
@@ -84,34 +79,28 @@ }, | ||
"devDependencies": { | ||
"@babel/cli": "^7.17.10", | ||
"@babel/core": "^7.18.2", | ||
"@babel/eslint-parser": "^7.18.2", | ||
"@babel/plugin-proposal-class-properties": "^7.17.12", | ||
"@babel/plugin-proposal-object-rest-spread": "^7.18.0", | ||
"@babel/preset-env": "^7.18.2", | ||
"@babel/preset-typescript": "^7.17.12", | ||
"@babel/register": "^7.17.7", | ||
"@types/jest": "^27.0.2", | ||
"@typescript-eslint/eslint-plugin": "^5.26.0", | ||
"@typescript-eslint/parser": "^5.26.0", | ||
"commitizen": "^4.2.4", | ||
"@typescript-eslint/eslint-plugin": "^5.36.0", | ||
"@typescript-eslint/parser": "^5.36.0", | ||
"commitizen": "^4.2.5", | ||
"conventional-changelog-cli": "^2.2.2", | ||
"coveralls": "^3.1.1", | ||
"cz-conventional-changelog": "^3.3.0", | ||
"eslint": "^8.16.0", | ||
"eslint-plugin-prettier": "^4.0.0", | ||
"jest": "^28.1.0", | ||
"jsarch": "^5.0.1", | ||
"esbuild": "^0.15.6", | ||
"esbuild-jest": "^0.5.0", | ||
"eslint": "^8.23.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-prettier": "^4.2.1", | ||
"jest": "^29.0.1", | ||
"jsarch": "^6.0.0", | ||
"jsdoc-to-markdown": "^7.1.1", | ||
"metapak": "^4.0.3", | ||
"metapak-nfroidure": "11.2.1", | ||
"metapak": "^4.0.4", | ||
"metapak-nfroidure": "12.3.0", | ||
"neatequal": "^1.0.0", | ||
"prettier": "^2.6.2", | ||
"prettier": "^2.7.1", | ||
"rimraf": "^3.0.2", | ||
"typescript": "^4.7.2" | ||
"typescript": "^4.8.2" | ||
}, | ||
"dependencies": { | ||
"yerror": "^6.0.2" | ||
"yerror": "^6.1.1" | ||
}, | ||
"engines": { | ||
"node": ">=12.19.0" | ||
"node": ">=16.15.0" | ||
}, | ||
@@ -130,14 +119,8 @@ "config": { | ||
"eslint-config-prettier", | ||
"eslint-plugin-prettier", | ||
"prettier", | ||
"@typescript-eslint/eslint-plugin", | ||
"@typescript-eslint/parser", | ||
"@babel/cli", | ||
"@babel/core", | ||
"@babel/register", | ||
"@babel/preset-env", | ||
"@babel/plugin-proposal-object-rest-spread", | ||
"@babel/preset-typescript", | ||
"@babel/plugin-proposal-class-properties", | ||
"babel-eslint", | ||
"babel-core", | ||
"typescript", | ||
"rimraf", | ||
"jest", | ||
@@ -166,2 +149,3 @@ "coveralls", | ||
"eslint:recommended", | ||
"plugin:prettier/recommended", | ||
"plugin:@typescript-eslint/eslint-recommended", | ||
@@ -172,3 +156,3 @@ "plugin:@typescript-eslint/recommended" | ||
"ecmaVersion": 2018, | ||
"sourceType": "module", | ||
"sourceType": "script", | ||
"modules": true | ||
@@ -211,3 +195,3 @@ }, | ||
"targets": { | ||
"node": "12.19.0" | ||
"node": "16.15.0" | ||
} | ||
@@ -258,2 +242,18 @@ } | ||
"<rootDir>/src" | ||
], | ||
"testEnvironment": "node", | ||
"transform": { | ||
"^.+\\.tsx?$": [ | ||
"esbuild-jest", | ||
{ | ||
"sourcemap": true, | ||
"format": "esm" | ||
} | ||
] | ||
}, | ||
"moduleNameMapper": { | ||
"(.+)\\.js": "$1" | ||
}, | ||
"extensionsToTreatAsEsm": [ | ||
".ts" | ||
] | ||
@@ -267,3 +267,4 @@ }, | ||
} | ||
} | ||
}, | ||
"type": "module" | ||
} |
@@ -11,3 +11,2 @@ [//]: # ( ) | ||
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/http-auth-utils/blob/master/LICENSE) | ||
[![Build status](https://travis-ci.com/nfroidure/http-auth-utils.svg?branch=master)](https://travis-ci.com/github/nfroidure/http-auth-utils) | ||
[![Coverage Status](https://coveralls.io/repos/github/nfroidure/http-auth-utils/badge.svg?branch=master)](https://coveralls.io/github/nfroidure/http-auth-utils?branch=master) | ||
@@ -54,29 +53,15 @@ | ||
* _static_ | ||
* [.mechanisms](#module_http-auth-utils.mechanisms) : <code>Object</code> | ||
* [.parseWWWAuthenticateHeader(header, [authMechanisms], [options])](#module_http-auth-utils.parseWWWAuthenticateHeader) ⇒ <code>Object</code> | ||
* [.parseAuthorizationHeader(header, [authMechanisms], [options])](#module_http-auth-utils.parseAuthorizationHeader) ⇒ <code>Object</code> | ||
* [.buildWWWAuthenticateHeader(authMechanism, The)](#module_http-auth-utils.buildWWWAuthenticateHeader) ⇒ <code>string</code> | ||
* [.buildAuthorizationHeader(authMechanism, The)](#module_http-auth-utils.buildAuthorizationHeader) ⇒ <code>string</code> | ||
* _inner_ | ||
* [~mechanisms](#module_http-auth-utils..mechanisms) : <code>Array</code> | ||
* [~parseWWWAuthenticateHeader(header, [authMechanisms], [options])](#module_http-auth-utils..parseWWWAuthenticateHeader) ⇒ <code>Object</code> | ||
* [~parseAuthorizationHeader(header, [authMechanisms], [options])](#module_http-auth-utils..parseAuthorizationHeader) ⇒ <code>Object</code> | ||
* [~buildWWWAuthenticateHeader(authMechanism, The)](#module_http-auth-utils..buildWWWAuthenticateHeader) ⇒ <code>string</code> | ||
* [~buildAuthorizationHeader(authMechanism, The)](#module_http-auth-utils..buildAuthorizationHeader) ⇒ <code>string</code> | ||
<a name="module_http-auth-utils.mechanisms"></a> | ||
<a name="module_http-auth-utils.parseWWWAuthenticateHeader"></a> | ||
### http-auth-utils.mechanisms : <code>Object</code> | ||
Basic authentication mechanism. | ||
**Kind**: static property of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**See**: [http-auth-utils/mechanisms/basic](#module_http-auth-utils/mechanisms/basic) | ||
<a name="module_http-auth-utils..mechanisms"></a> | ||
### http-auth-utils~mechanisms : <code>Array</code> | ||
Natively supported authentication mechanisms. | ||
**Kind**: inner constant of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
<a name="module_http-auth-utils..parseWWWAuthenticateHeader"></a> | ||
### http-auth-utils~parseWWWAuthenticateHeader(header, [authMechanisms], [options]) ⇒ <code>Object</code> | ||
### http-auth-utils.parseWWWAuthenticateHeader(header, [authMechanisms], [options]) ⇒ <code>Object</code> | ||
Parse HTTP WWW-Authenticate header contents. | ||
**Kind**: inner method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Kind**: static method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Returns**: <code>Object</code> - Result of the contents parse. | ||
@@ -103,8 +88,8 @@ **Api**: public | ||
``` | ||
<a name="module_http-auth-utils..parseAuthorizationHeader"></a> | ||
<a name="module_http-auth-utils.parseAuthorizationHeader"></a> | ||
### http-auth-utils~parseAuthorizationHeader(header, [authMechanisms], [options]) ⇒ <code>Object</code> | ||
### http-auth-utils.parseAuthorizationHeader(header, [authMechanisms], [options]) ⇒ <code>Object</code> | ||
Parse HTTP Authorization header contents. | ||
**Kind**: inner method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Kind**: static method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Returns**: <code>Object</code> - Result of the contents parse. | ||
@@ -131,8 +116,8 @@ **Api**: public | ||
``` | ||
<a name="module_http-auth-utils..buildWWWAuthenticateHeader"></a> | ||
<a name="module_http-auth-utils.buildWWWAuthenticateHeader"></a> | ||
### http-auth-utils~buildWWWAuthenticateHeader(authMechanism, The) ⇒ <code>string</code> | ||
### http-auth-utils.buildWWWAuthenticateHeader(authMechanism, The) ⇒ <code>string</code> | ||
Build HTTP WWW-Authenticate header value. | ||
**Kind**: inner method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Kind**: static method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Returns**: <code>string</code> - The header value. | ||
@@ -155,8 +140,8 @@ **Api**: public | ||
``` | ||
<a name="module_http-auth-utils..buildAuthorizationHeader"></a> | ||
<a name="module_http-auth-utils.buildAuthorizationHeader"></a> | ||
### http-auth-utils~buildAuthorizationHeader(authMechanism, The) ⇒ <code>string</code> | ||
### http-auth-utils.buildAuthorizationHeader(authMechanism, The) ⇒ <code>string</code> | ||
Build HTTP Authorization header value. | ||
**Kind**: inner method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Kind**: static method of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
**Returns**: <code>string</code> - The header value. | ||
@@ -179,2 +164,8 @@ **Api**: public | ||
``` | ||
<a name="module_http-auth-utils..mechanisms"></a> | ||
### http-auth-utils~mechanisms : <code>Array</code> | ||
Natively supported authentication mechanisms. | ||
**Kind**: inner constant of [<code>http-auth-utils</code>](#module_http-auth-utils) | ||
<a name="module_http-auth-utils/mechanisms/basic"></a> | ||
@@ -181,0 +172,0 @@ |
@@ -0,1 +1,2 @@ | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
@@ -12,7 +13,7 @@ import neatequal from 'neatequal'; | ||
BEARER, | ||
} from './index'; | ||
} from './index.js'; | ||
describe('index', () => { | ||
describe('parseWWWAuthenticateHeader', () => { | ||
it('should parse Basic headers', () => { | ||
test('should parse Basic headers', () => { | ||
neatequal(parseWWWAuthenticateHeader('Basic realm="test"'), { | ||
@@ -36,3 +37,3 @@ type: 'Basic', | ||
}); | ||
it('should parse Bearer headers', () => { | ||
test('should parse Bearer headers', () => { | ||
neatequal(parseWWWAuthenticateHeader('Bearer realm="test"', mechanisms), { | ||
@@ -57,3 +58,3 @@ type: 'Bearer', | ||
it('should fail with unknown headers', () => { | ||
test('should fail with unknown headers', () => { | ||
assert.throws( | ||
@@ -67,3 +68,3 @@ () => parseWWWAuthenticateHeader('Kikoolol realm="test"'), | ||
describe('parseAuthorizationHeader', () => { | ||
it('should parse Basic headers', () => { | ||
test('should parse Basic headers', () => { | ||
neatequal( | ||
@@ -127,3 +128,3 @@ parseAuthorizationHeader('Basic QWxpIEJhYmE6b3BlbiBzZXNhbWU='), | ||
it('should parse Basic headers with a ":" char in the password', () => { | ||
test('should parse Basic headers with a ":" char in the password', () => { | ||
neatequal(parseAuthorizationHeader('Basic Sm9objpSOlU6a2lkZGluZz8='), { | ||
@@ -139,3 +140,3 @@ type: 'Basic', | ||
it('should fail with unknown headers', () => { | ||
test('should fail with unknown headers', () => { | ||
assert.throws( | ||
@@ -147,3 +148,3 @@ () => parseAuthorizationHeader('Kikoolol ddd'), | ||
it('should fail with basic headers in strict mode', () => { | ||
test('should fail with basic headers in strict mode', () => { | ||
assert.throws( | ||
@@ -165,3 +166,3 @@ () => parseAuthorizationHeader('basic ddd'), | ||
describe('buildWWWAuthenticateHeader', () => { | ||
it('should build Basic headers', () => { | ||
test('should build Basic headers', () => { | ||
assert.equal( | ||
@@ -175,3 +176,3 @@ buildWWWAuthenticateHeader(BASIC, { | ||
it('should be reentrant', () => { | ||
test('should be reentrant', () => { | ||
assert.equal( | ||
@@ -188,3 +189,3 @@ buildWWWAuthenticateHeader( | ||
describe('buildAuthorizationHeader', () => { | ||
it('should build Basic headers', () => { | ||
test('should build Basic headers', () => { | ||
assert.equal( | ||
@@ -199,3 +200,3 @@ buildAuthorizationHeader(BASIC, { | ||
it('should be reentrant', () => { | ||
test('should be reentrant', () => { | ||
assert.equal( | ||
@@ -213,7 +214,7 @@ buildAuthorizationHeader( | ||
describe('mechanisms', () => { | ||
it('should export bot DIGEST and BASIC mechanisms', () => { | ||
test('should export bot DIGEST and BASIC mechanisms', () => { | ||
assert.equal(mechanisms.length, 3); | ||
}); | ||
it('should export DIGEST BASIC and BEARER mechanisms', () => { | ||
test('should export DIGEST BASIC and BEARER mechanisms', () => { | ||
assert(BASIC); | ||
@@ -220,0 +221,0 @@ assert(DIGEST); |
@@ -1,6 +0,6 @@ | ||
import YError from 'yerror'; | ||
import { YError } from 'yerror'; | ||
import BASIC from './mechanisms/basic'; | ||
import DIGEST from './mechanisms/digest'; | ||
import BEARER from './mechanisms/bearer'; | ||
import BASIC from './mechanisms/basic.js'; | ||
import DIGEST from './mechanisms/digest.js'; | ||
import BEARER from './mechanisms/bearer.js'; | ||
@@ -7,0 +7,0 @@ /* Architecture Note #1: Module structure |
@@ -0,4 +1,5 @@ | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import BASIC from './basic'; | ||
import BASIC from './basic.js'; | ||
@@ -5,0 +6,0 @@ describe('BASIC', () => { |
@@ -5,3 +5,3 @@ /** | ||
import YError from 'yerror'; | ||
import { YError } from 'yerror'; | ||
@@ -11,3 +11,3 @@ import { | ||
buildHTTPHeadersQuotedKeyValueSet, | ||
} from '../utils'; | ||
} from '../utils.js'; | ||
@@ -14,0 +14,0 @@ const REQUIRED_WWW_AUTHENTICATE_KEYS = ['realm']; |
@@ -0,8 +1,9 @@ | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import BEARER from './bearer'; | ||
import BEARER from './bearer.js'; | ||
describe('BEARER', () => { | ||
describe('type', () => { | ||
it('should be the basic auth prefix', () => { | ||
test('should be the basic auth prefix', () => { | ||
assert.equal(BEARER.type, 'Bearer'); | ||
@@ -13,3 +14,3 @@ }); | ||
describe('parseWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
neatequal(BEARER.parseWWWAuthenticateRest('realm="perlinpinpin"'), { | ||
@@ -22,3 +23,3 @@ realm: 'perlinpinpin', | ||
describe('buildWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
assert.equal( | ||
@@ -32,3 +33,3 @@ BEARER.buildWWWAuthenticateRest({ | ||
it('should work with an error', () => { | ||
test('should work with an error', () => { | ||
assert.equal( | ||
@@ -46,3 +47,3 @@ BEARER.buildWWWAuthenticateRest({ | ||
it('should fail with an unauthorized error', () => { | ||
test('should fail with an unauthorized error', () => { | ||
assert.throws( | ||
@@ -59,3 +60,3 @@ () => | ||
it('should be the inverse of parseWWWAuthenticateRest', () => { | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
neatequal( | ||
@@ -75,3 +76,3 @@ BEARER.parseWWWAuthenticateRest( | ||
describe('parseAuthorizationRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
neatequal(BEARER.parseAuthorizationRest('mF_9.B5f-4.1JqM'), { | ||
@@ -82,3 +83,3 @@ hash: 'mF_9.B5f-4.1JqM', | ||
it('should fail with empty rest', () => { | ||
test('should fail with empty rest', () => { | ||
assert.throws(() => BEARER.parseAuthorizationRest(''), /E_EMPTY_AUTH/); | ||
@@ -89,3 +90,3 @@ }); | ||
describe('buildAuthorizationRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
assert.equal( | ||
@@ -99,3 +100,3 @@ BEARER.buildAuthorizationRest({ | ||
it('should fail with nothing at all', () => { | ||
test('should fail with nothing at all', () => { | ||
assert.throws( | ||
@@ -107,3 +108,3 @@ () => BEARER.buildAuthorizationRest({} as any), | ||
it('should be the inverse of parseAuthorizationRest', () => { | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
neatequal( | ||
@@ -110,0 +111,0 @@ BEARER.parseAuthorizationRest( |
@@ -5,3 +5,3 @@ /** | ||
import YError from 'yerror'; | ||
import { YError } from 'yerror'; | ||
@@ -11,3 +11,3 @@ import { | ||
buildHTTPHeadersQuotedKeyValueSet, | ||
} from '../utils'; | ||
} from '../utils.js'; | ||
@@ -14,0 +14,0 @@ const AUTHORIZED_ERROR_CODES = [ |
@@ -0,8 +1,9 @@ | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
import neatequal from 'neatequal'; | ||
import DIGEST from './digest'; | ||
import DIGEST from './digest.js'; | ||
describe('digest', () => { | ||
describe('type', () => { | ||
it('should be the digest auth prefix', () => { | ||
test('should be the digest auth prefix', () => { | ||
assert.equal(DIGEST.type, 'Digest'); | ||
@@ -13,3 +14,3 @@ }); | ||
describe('parseWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
neatequal( | ||
@@ -31,3 +32,3 @@ DIGEST.parseWWWAuthenticateRest( | ||
it('should handle non-quoted fields', () => { | ||
test('should handle non-quoted fields', () => { | ||
neatequal( | ||
@@ -51,3 +52,3 @@ DIGEST.parseWWWAuthenticateRest( | ||
describe('buildWWWAuthenticateRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
assert.equal( | ||
@@ -67,3 +68,3 @@ DIGEST.buildWWWAuthenticateRest({ | ||
it('should be the inverse of parseWWWAuthenticateRest', () => { | ||
test('should be the inverse of parseWWWAuthenticateRest', () => { | ||
neatequal( | ||
@@ -85,3 +86,3 @@ DIGEST.parseWWWAuthenticateRest( | ||
describe('parseAuthorizationRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
neatequal( | ||
@@ -113,3 +114,3 @@ DIGEST.parseAuthorizationRest( | ||
it('should fail with empty rest', () => { | ||
test('should fail with empty rest', () => { | ||
assert.throws( | ||
@@ -123,3 +124,3 @@ () => DIGEST.parseAuthorizationRest(''), | ||
describe('buildAuthorizationRest', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
assert.equal( | ||
@@ -149,3 +150,3 @@ DIGEST.buildAuthorizationRest({ | ||
it('should be the inverse of parseAuthorizationRest', () => { | ||
test('should be the inverse of parseAuthorizationRest', () => { | ||
neatequal( | ||
@@ -181,3 +182,3 @@ DIGEST.parseAuthorizationRest( | ||
describe('computeHash', () => { | ||
it('should work', () => { | ||
test('should work', () => { | ||
assert.equal( | ||
@@ -184,0 +185,0 @@ DIGEST.computeHash({ |
@@ -8,3 +8,3 @@ /** | ||
buildHTTPHeadersQuotedKeyValueSet, | ||
} from '../utils'; | ||
} from '../utils.js'; | ||
@@ -11,0 +11,0 @@ import crypto from 'crypto'; |
@@ -0,1 +1,2 @@ | ||
import { describe, test } from '@jest/globals'; | ||
import assert from 'assert'; | ||
@@ -6,3 +7,3 @@ import neatequal from 'neatequal'; | ||
buildHTTPHeadersQuotedKeyValueSet, | ||
} from './utils'; | ||
} from './utils.js'; | ||
@@ -9,0 +10,0 @@ describe('utils', () => { |
@@ -1,2 +0,2 @@ | ||
import YError from 'yerror'; | ||
import { YError } from 'yerror'; | ||
@@ -3,0 +3,0 @@ const QUOTE = '"'; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
20
Yes
174203
44
3275
673
Updatedyerror@^6.1.1