http-auth-utils
Advanced tools
Comparing version 3.0.1 to 3.0.2
@@ -0,1 +1,10 @@ | ||
## [3.0.2](https://github.com/nfroidure/http-auth-utils/compare/v3.0.1...v3.0.2) (2021-12-15) | ||
### Bug Fixes | ||
* **src/utils.ts:** handle parsing non-quoted values in authenticate header ([772608e](https://github.com/nfroidure/http-auth-utils/commit/772608e037da2385e1f6ba5035146ab4d945af6b)), closes [#10](https://github.com/nfroidure/http-auth-utils/issues/10) | ||
## [3.0.1](https://github.com/nfroidure/http-auth-utils/compare/v3.0.0...v3.0.1) (2021-04-09) | ||
@@ -2,0 +11,0 @@ |
@@ -26,2 +26,10 @@ "use strict"; | ||
}); | ||
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' | ||
}); | ||
}); | ||
}); | ||
@@ -28,0 +36,0 @@ describe('buildWWWAuthenticateRest', () => { |
@@ -16,7 +16,19 @@ "use strict"; | ||
const SEPARATOR = ', '; | ||
const SEPARATOR_REGEXP = /", ?/; // FIXME: Create a real parser | ||
/* | ||
* Regular expression for matching the key-value pairs | ||
* \w+ = The key | ||
* = = The equal sign | ||
* ".*?" = Value option 1: A double-quoted value (using the non-greedy *? to stop at the first doublequote) | ||
* [^",]+ = Value option 2: A string without commas or double-quotes | ||
* (?=,|$) = 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 | ||
*/ | ||
const KEYVALUE_REGEXP = /\w+=(".*?"|[^",]+)(?=,|$)/g; // FIXME: Create a real parser | ||
function parseHTTPHeadersQuotedKeyValueSet(contents, authorizedKeys, requiredKeys = []) { | ||
const data = contents.split(SEPARATOR_REGEXP).map((part, partPosition, parts) => { | ||
part = parts.length - 1 === partPosition ? part : part + '"'; | ||
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); | ||
@@ -33,8 +45,16 @@ | ||
} | ||
/* | ||
* 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 | ||
*/ | ||
if (QUOTE !== value[0] || QUOTE !== value[value.length - 1]) { | ||
throw new _yerror.default('E_UNQUOTED_VALUE', valuePosition, name, value); | ||
} | ||
parsedValues[name] = value.substr(1, value.length - 2); | ||
parsedValues[name] = value.replace(/^"(.+(?="$))"$/, '$1'); | ||
return parsedValues; | ||
@@ -41,0 +61,0 @@ }, {}); |
@@ -21,10 +21,23 @@ "use strict"; | ||
}); | ||
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' | ||
}); | ||
}); | ||
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 fail with bad quoted value pair', () => { | ||
_assert.default.throws(() => (0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm=dsad', ['realm']), /E_UNQUOTED_VALUE/); | ||
test('should pass with non-quoted value pair', () => { | ||
(0, _neatequal.default)((0, _utils.parseHTTPHeadersQuotedKeyValueSet)('realm=dsad', ['realm']), { | ||
realm: 'dsad' | ||
}); | ||
}); | ||
@@ -31,0 +44,0 @@ }); |
{ | ||
"name": "http-auth-utils", | ||
"version": "3.0.1", | ||
"version": "3.0.2", | ||
"description": "Parse, build and deal with HTTP authorization headers.", | ||
@@ -143,3 +143,9 @@ "main": "dist/index", | ||
}, | ||
"contributors": [], | ||
"contributors": [ | ||
{ | ||
"name": "Jake Pruitt", | ||
"email": "jake.pruitt@datadoghq.com", | ||
"url": "https://github.com/jakepruitt" | ||
} | ||
], | ||
"files": [ | ||
@@ -146,0 +152,0 @@ "dist", |
@@ -683,4 +683,5 @@ [//]: # ( ) | ||
- [Nicolas Froidure](https://insertafter.com/en/index.html) | ||
- [Jake Pruitt](https://github.com/jakepruitt) | ||
# License | ||
[MIT](https://github.com/nfroidure/http-auth-utils/blob/master/LICENSE) |
@@ -29,2 +29,19 @@ import assert from 'assert'; | ||
}); | ||
it('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', | ||
}, | ||
); | ||
}); | ||
}); | ||
@@ -31,0 +48,0 @@ |
@@ -29,2 +29,21 @@ import assert from 'assert'; | ||
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', () => { | ||
@@ -37,6 +56,6 @@ assert.throws( | ||
test('should fail with bad quoted value pair', () => { | ||
test('should fail with half-quoted value pair', () => { | ||
assert.throws( | ||
() => parseHTTPHeadersQuotedKeyValueSet('realm="dsad"', []), | ||
/E_UNAUTHORIZED_KEY/, | ||
() => parseHTTPHeadersQuotedKeyValueSet('realm="uneven', ['realm']), | ||
/E_MALFORMED_QUOTEDKEYVALUE/, | ||
); | ||
@@ -47,6 +66,12 @@ }); | ||
assert.throws( | ||
() => parseHTTPHeadersQuotedKeyValueSet('realm=dsad', ['realm']), | ||
/E_UNQUOTED_VALUE/, | ||
() => parseHTTPHeadersQuotedKeyValueSet('realm="dsad"', []), | ||
/E_UNAUTHORIZED_KEY/, | ||
); | ||
}); | ||
test('should pass with non-quoted value pair', () => { | ||
neatequal(parseHTTPHeadersQuotedKeyValueSet('realm=dsad', ['realm']), { | ||
realm: 'dsad', | ||
}); | ||
}); | ||
}); | ||
@@ -53,0 +78,0 @@ |
@@ -6,4 +6,15 @@ import YError from 'yerror'; | ||
const SEPARATOR = ', '; | ||
const SEPARATOR_REGEXP = /", ?/; | ||
/* | ||
* Regular expression for matching the key-value pairs | ||
* \w+ = The key | ||
* = = The equal sign | ||
* ".*?" = Value option 1: A double-quoted value (using the non-greedy *? to stop at the first doublequote) | ||
* [^",]+ = Value option 2: A string without commas or double-quotes | ||
* (?=,|$) = 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 | ||
*/ | ||
const KEYVALUE_REGEXP = /\w+=(".*?"|[^",]+)(?=,|$)/g; | ||
// FIXME: Create a real parser | ||
@@ -15,6 +26,7 @@ export function parseHTTPHeadersQuotedKeyValueSet( | ||
): Record<string, string> { | ||
const data = contents | ||
.split(SEPARATOR_REGEXP) | ||
.map((part, partPosition, parts) => { | ||
part = parts.length - 1 === partPosition ? part : part + '"'; | ||
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); | ||
@@ -36,6 +48,14 @@ | ||
} | ||
if (QUOTE !== value[0] || QUOTE !== value[value.length - 1]) { | ||
throw new YError('E_UNQUOTED_VALUE', valuePosition, name, value); | ||
} | ||
parsedValues[name] = value.substr(1, value.length - 2); | ||
/* | ||
* 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; | ||
@@ -42,0 +62,0 @@ }, {}); |
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
327623
3962
687