Comparing version 4.0.1 to 4.1.0
@@ -1,2 +0,2 @@ | ||
'use strict' | ||
'use strict'; | ||
@@ -11,6 +11,4 @@ /* | ||
; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; }; | ||
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } | ||
var hawk = { | ||
@@ -579,3 +577,3 @@ internals: {} | ||
var CryptoJS = CryptoJS || (function (h, r) { | ||
var CryptoJS = CryptoJS || function (h, r) { | ||
var k = {}, | ||
@@ -681,3 +679,3 @@ l = k.lib = {}, | ||
} });var u = k.algo = {};return k; | ||
})(Math); | ||
}(Math); | ||
(function () { | ||
@@ -684,0 +682,0 @@ var k = CryptoJS, |
@@ -149,3 +149,3 @@ 'use strict'; | ||
exports.authenticate = function (res, credentials, artifacts, options) { | ||
exports.authenticate = function (res, credentials, artifacts, options, callback) { | ||
@@ -155,2 +155,19 @@ artifacts = Hoek.clone(artifacts); | ||
let wwwAttributes = null; | ||
let serverAuthAttributes = null; | ||
const finalize = function (err) { | ||
if (callback) { | ||
const headers = { | ||
'www-authenticate': wwwAttributes, | ||
'server-authorization': serverAuthAttributes | ||
}; | ||
return callback(err, headers); | ||
} | ||
return !err; | ||
}; | ||
if (res.headers['www-authenticate']) { | ||
@@ -160,5 +177,6 @@ | ||
const wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); | ||
wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); | ||
if (wwwAttributes instanceof Error) { | ||
return false; | ||
wwwAttributes = null; | ||
return finalize(new Error('Invalid WWW-Authenticate header')); | ||
} | ||
@@ -171,3 +189,3 @@ | ||
if (tsm !== wwwAttributes.tsm) { | ||
return false; | ||
return finalize(new Error('Invalid server timestamp hash')); | ||
} | ||
@@ -182,16 +200,17 @@ } | ||
return true; | ||
return finalize(); | ||
} | ||
const attributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']); | ||
if (attributes instanceof Error) { | ||
return false; | ||
serverAuthAttributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']); | ||
if (serverAuthAttributes instanceof Error) { | ||
serverAuthAttributes = null; | ||
return finalize(new Error('Invalid Server-Authorization header')); | ||
} | ||
artifacts.ext = attributes.ext; | ||
artifacts.hash = attributes.hash; | ||
artifacts.ext = serverAuthAttributes.ext; | ||
artifacts.hash = serverAuthAttributes.hash; | ||
const mac = Crypto.calculateMac('response', credentials, artifacts); | ||
if (mac !== attributes.mac) { | ||
return false; | ||
if (mac !== serverAuthAttributes.mac) { | ||
return finalize(new Error('Bad response mac')); | ||
} | ||
@@ -202,11 +221,15 @@ | ||
return true; | ||
return finalize(); | ||
} | ||
if (!attributes.hash) { | ||
return false; | ||
if (!serverAuthAttributes.hash) { | ||
return finalize(new Error('Missing response hash attribute')); | ||
} | ||
const calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']); | ||
return (calculatedHash === attributes.hash); | ||
if (calculatedHash !== serverAuthAttributes.hash) { | ||
return finalize(new Error('Bad response payload mac')); | ||
} | ||
return finalize(); | ||
}; | ||
@@ -213,0 +236,0 @@ |
@@ -150,3 +150,3 @@ 'use strict'; | ||
if (!credentials) { | ||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, artifacts); | ||
return callback(Utils.unauthorized('Unknown credentials'), null, artifacts); | ||
} | ||
@@ -168,3 +168,3 @@ | ||
if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) { | ||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, artifacts); | ||
return callback(Utils.unauthorized('Bad mac'), credentials, artifacts); | ||
} | ||
@@ -178,3 +178,3 @@ | ||
if (!attributes.hash) { | ||
return callback(Boom.unauthorized('Missing required payload hash', 'Hawk'), credentials, artifacts); | ||
return callback(Utils.unauthorized('Missing required payload hash'), credentials, artifacts); | ||
} | ||
@@ -184,3 +184,3 @@ | ||
if (!Cryptiles.fixedTimeComparison(hash, attributes.hash)) { | ||
return callback(Boom.unauthorized('Bad payload hash', 'Hawk'), credentials, artifacts); | ||
return callback(Utils.unauthorized('Bad payload hash'), credentials, artifacts); | ||
} | ||
@@ -194,3 +194,3 @@ } | ||
if (err) { | ||
return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials, artifacts); | ||
return callback(Utils.unauthorized('Invalid nonce'), credentials, artifacts); | ||
} | ||
@@ -202,3 +202,3 @@ | ||
const tsm = Crypto.timestampMessage(credentials, options.localtimeOffsetMsec); | ||
return callback(Boom.unauthorized('Stale timestamp', 'Hawk', tsm), credentials, artifacts); | ||
return callback(Utils.unauthorized('Stale timestamp', tsm), credentials, artifacts); | ||
} | ||
@@ -339,3 +339,3 @@ | ||
if (!resource) { | ||
return callback(Boom.unauthorized(null, 'Hawk')); | ||
return callback(Utils.unauthorized()); | ||
} | ||
@@ -346,3 +346,3 @@ | ||
if (!resource[3]) { | ||
return callback(Boom.unauthorized('Empty bewit', 'Hawk')); | ||
return callback(Utils.unauthorized('Empty bewit')); | ||
} | ||
@@ -355,3 +355,3 @@ | ||
return callback(Boom.unauthorized('Invalid method', 'Hawk')); | ||
return callback(Utils.unauthorized('Invalid method')); | ||
} | ||
@@ -403,3 +403,3 @@ | ||
if (bewit.exp * 1000 <= now) { | ||
return callback(Boom.unauthorized('Access expired', 'Hawk'), null, bewit); | ||
return callback(Utils.unauthorized('Access expired'), null, bewit); | ||
} | ||
@@ -416,3 +416,3 @@ | ||
if (!credentials) { | ||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'), null, bewit); | ||
return callback(Utils.unauthorized('Unknown credentials'), null, bewit); | ||
} | ||
@@ -443,3 +443,3 @@ | ||
if (!Cryptiles.fixedTimeComparison(mac, bewit.mac)) { | ||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials, bewit); | ||
return callback(Utils.unauthorized('Bad mac'), credentials, bewit); | ||
} | ||
@@ -492,3 +492,3 @@ | ||
if (!credentials) { | ||
return callback(Boom.unauthorized('Unknown credentials', 'Hawk')); | ||
return callback(Utils.unauthorized('Unknown credentials')); | ||
} | ||
@@ -520,3 +520,3 @@ | ||
if (!Cryptiles.fixedTimeComparison(mac, authorization.mac)) { | ||
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials); | ||
return callback(Utils.unauthorized('Bad mac'), credentials); | ||
} | ||
@@ -528,3 +528,3 @@ | ||
if (!Cryptiles.fixedTimeComparison(hash, authorization.hash)) { | ||
return callback(Boom.unauthorized('Bad message hash', 'Hawk'), credentials); | ||
return callback(Utils.unauthorized('Bad message hash'), credentials); | ||
} | ||
@@ -537,3 +537,3 @@ | ||
if (err) { | ||
return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials); | ||
return callback(Utils.unauthorized('Invalid nonce'), credentials); | ||
} | ||
@@ -544,3 +544,3 @@ | ||
if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) { | ||
return callback(Boom.unauthorized('Stale timestamp'), credentials); | ||
return callback(Utils.unauthorized('Stale timestamp'), credentials); | ||
} | ||
@@ -547,0 +547,0 @@ |
@@ -167,4 +167,4 @@ 'use strict'; | ||
return Boom.unauthorized(message, 'Hawk', attributes); | ||
return Boom.unauthorized(message || null, 'Hawk', attributes); | ||
}; | ||
{ | ||
"name": "hawk", | ||
"description": "HTTP Hawk Authentication Scheme", | ||
"version": "4.0.1", | ||
"version": "4.1.0", | ||
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)", | ||
@@ -6,0 +6,0 @@ "repository": "git://github.com/hueniverse/hawk", |
@@ -210,2 +210,18 @@ 'use strict'; | ||
it('returns false on invalid header (callback)', (done) => { | ||
const res = { | ||
headers: { | ||
'server-authorization': 'Hawk mac="abc", bad="xyz"' | ||
} | ||
}; | ||
Hawk.client.authenticate(res, {}, null, null, (err) => { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid Server-Authorization header'); | ||
done(); | ||
}); | ||
}); | ||
it('returns false on invalid mac', (done) => { | ||
@@ -281,2 +297,124 @@ | ||
it('validates response payload', (done) => { | ||
const payload = 'some reply'; | ||
const res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="odsVGUq0rCoITaiNagW22REIpqkwP9zt5FyqqOW9Zj8=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
const credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
const artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1453070933', | ||
nonce: '3hOHpR', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: '/DitzeD66F2f7O535SERbX9p+oh9ZnNLqSNHG+c7/vs=', | ||
id: '123456' | ||
}; | ||
expect(Hawk.client.authenticate(res, credentials, artifacts, { payload: payload })).to.equal(true); | ||
done(); | ||
}); | ||
it('validates response payload (callback)', (done) => { | ||
const payload = 'some reply'; | ||
const res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="odsVGUq0rCoITaiNagW22REIpqkwP9zt5FyqqOW9Zj8=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
const credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
const artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1453070933', | ||
nonce: '3hOHpR', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: '/DitzeD66F2f7O535SERbX9p+oh9ZnNLqSNHG+c7/vs=', | ||
id: '123456' | ||
}; | ||
Hawk.client.authenticate(res, credentials, artifacts, { payload: payload }, (err, headers) => { | ||
expect(err).to.not.exist(); | ||
expect(headers).to.deep.equal({ | ||
'www-authenticate': null, | ||
'server-authorization': { | ||
mac: 'odsVGUq0rCoITaiNagW22REIpqkwP9zt5FyqqOW9Zj8=', | ||
hash: 'f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=', | ||
ext: 'response-specific' | ||
} | ||
}); | ||
done(); | ||
}); | ||
}); | ||
it('errors on invalid response payload', (done) => { | ||
const payload = 'wrong reply'; | ||
const res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="odsVGUq0rCoITaiNagW22REIpqkwP9zt5FyqqOW9Zj8=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
const credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
const artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1453070933', | ||
nonce: '3hOHpR', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: '/DitzeD66F2f7O535SERbX9p+oh9ZnNLqSNHG+c7/vs=', | ||
id: '123456' | ||
}; | ||
expect(Hawk.client.authenticate(res, credentials, artifacts, { payload: payload })).to.equal(false); | ||
done(); | ||
}); | ||
it('fails on invalid WWW-Authenticate header format', (done) => { | ||
@@ -283,0 +421,0 @@ |
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
400651
6051