Comparing version 2.3.1 to 3.0.0
@@ -13,3 +13,3 @@ // Load modules | ||
dh37fgj492je: { | ||
id: 'dh37fgj492je', // Required by Hawk.client.header | ||
id: 'dh37fgj492je', // Required by Hawk.client.header | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
@@ -16,0 +16,0 @@ algorithm: 'sha256', |
@@ -241,14 +241,14 @@ /* | ||
var attributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']); | ||
if (!attributes) { | ||
var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']); | ||
if (!wwwAttributes) { | ||
return false; | ||
} | ||
if (attributes.ts) { | ||
var tsm = hawk.crypto.calculateTsMac(attributes.ts, credentials); | ||
if (tsm !== attributes.tsm) { | ||
if (wwwAttributes.ts) { | ||
var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials); | ||
if (tsm !== wwwAttributes.tsm) { | ||
return false; | ||
} | ||
hawk.utils.setNtpOffset(attributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision | ||
hawk.utils.setNtpOffset(wwwAttributes.ts - Math.floor((new Date()).getTime() / 1000)); // Keep offset at 1 second precision | ||
} | ||
@@ -621,2 +621,3 @@ } | ||
// $lab:coverage:off$ | ||
/* eslint-disable */ | ||
@@ -643,2 +644,3 @@ // Based on: Crypto-JS v3.1.2 | ||
/* eslint-enable */ | ||
// $lab:coverage:on$ |
@@ -156,4 +156,4 @@ // Load modules | ||
var attributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); | ||
if (attributes instanceof Error) { | ||
var wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); | ||
if (wwwAttributes instanceof Error) { | ||
return false; | ||
@@ -164,5 +164,5 @@ } | ||
if (attributes.ts) { | ||
var tsm = Crypto.calculateTsMac(attributes.ts, credentials); | ||
if (tsm !== attributes.tsm) { | ||
if (wwwAttributes.ts) { | ||
var tsm = Crypto.calculateTsMac(wwwAttributes.ts, credentials); | ||
if (tsm !== wwwAttributes.tsm) { | ||
return false; | ||
@@ -169,0 +169,0 @@ } |
@@ -19,3 +19,3 @@ // Load modules | ||
req: node's HTTP request object or an object as follows: | ||
var request = { | ||
@@ -28,3 +28,3 @@ method: 'GET', | ||
}; | ||
credentialsFunc: required function to lookup the set of Hawk credentials based on the provided credentials id. | ||
@@ -34,12 +34,12 @@ The credentials include the MAC key, MAC algorithm, and other attributes (such as username) | ||
password in Basic authentication. | ||
var credentialsFunc = function (id, callback) { | ||
// Lookup credentials in database | ||
db.lookup(id, function (err, item) { | ||
if (err || !item) { | ||
return callback(err); | ||
} | ||
var credentials = { | ||
@@ -52,7 +52,7 @@ // Required | ||
}; | ||
return callback(null, credentials); | ||
}); | ||
}; | ||
options: { | ||
@@ -64,12 +64,12 @@ | ||
Only used when passed a node Http.ServerRequest object. | ||
nonceFunc: optional nonce validation function. The function signature is function(nonce, ts, callback) | ||
nonceFunc: optional nonce validation function. The function signature is function(key, nonce, ts, callback) | ||
where 'callback' must be called using the signature function(err). | ||
timestampSkewSec: optional number of seconds of permitted clock skew for incoming timestamps. Defaults to 60 seconds. | ||
Provides a +/- skew which means actual allowed window is double the number of seconds. | ||
localtimeOffsetMsec: optional local clock time offset express in a number of milliseconds (positive or negative). | ||
Defaults to 0. | ||
payload: optional payload for validation. The client calculates the hash value and includes it via the 'hash' | ||
@@ -93,6 +93,6 @@ header attribute. The server always ensures the value provided has been included in the request | ||
callback = Hoek.nextTick(callback); | ||
// Default options | ||
options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation | ||
options.nonceFunc = options.nonceFunc || internals.nonceFunc; | ||
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds | ||
@@ -191,3 +191,3 @@ | ||
options.nonceFunc(attributes.nonce, attributes.ts, function (err) { | ||
options.nonceFunc(credentials.key, attributes.nonce, attributes.ts, function (err) { | ||
@@ -335,3 +335,3 @@ if (err) { | ||
// 1 2 3 4 | ||
// 1 2 3 4 | ||
var resource = request.url.match(/^(\/.*)([\?&])bewit\=([^&$]*)(?:&(.+))?$/); | ||
@@ -456,6 +456,6 @@ if (!resource) { | ||
callback = Hoek.nextTick(callback); | ||
// Default options | ||
options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation | ||
options.nonceFunc = options.nonceFunc || internals.nonceFunc; | ||
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds | ||
@@ -468,3 +468,3 @@ | ||
// Validate authorization | ||
if (!authorization.id || | ||
@@ -475,4 +475,4 @@ !authorization.ts || | ||
!authorization.mac) { | ||
return callback(Boom.badRequest('Invalid authorization')) | ||
return callback(Boom.badRequest('Invalid authorization')); | ||
} | ||
@@ -528,3 +528,3 @@ | ||
options.nonceFunc(authorization.nonce, authorization.ts, function (err) { | ||
options.nonceFunc(credentials.key, authorization.nonce, authorization.ts, function (err) { | ||
@@ -547,1 +547,7 @@ if (err) { | ||
}; | ||
internals.nonceFunc = function (key, nonce, ts, nonceCallback) { | ||
return nonceCallback(); // No validation | ||
}; |
@@ -63,3 +63,3 @@ // Load modules | ||
} | ||
// Obtain host and port information | ||
@@ -161,6 +161,6 @@ | ||
exports.unauthorized = function (message) { | ||
exports.unauthorized = function (message, attributes) { | ||
return Boom.unauthorized(message, 'Hawk'); | ||
return Boom.unauthorized(message, 'Hawk', attributes); | ||
}; | ||
{ | ||
"name": "hawk", | ||
"description": "HTTP Hawk Authentication Scheme", | ||
"version": "2.3.1", | ||
"version": "3.0.0", | ||
"author": "Eran Hammer <eran@hammer.io> (http://hueniverse.com)", | ||
"contributors": [], | ||
"repository": "git://github.com/hueniverse/hawk", | ||
"main": "index", | ||
"main": "lib/index.js", | ||
"keywords": [ | ||
@@ -16,3 +16,3 @@ "http", | ||
"engines": { | ||
"node": ">=0.8.0" | ||
"node": ">=0.10.32" | ||
}, | ||
@@ -31,10 +31,6 @@ "browser": "./lib/browser.js", | ||
"scripts": { | ||
"test": "make test-cov" | ||
"test": "lab -a code -t 100 -L", | ||
"test-cov-html": "lab -a code -r html -o coverage.html" | ||
}, | ||
"licenses": [ | ||
{ | ||
"type": "BSD", | ||
"url": "http://github.com/hueniverse/hawk/raw/master/LICENSE" | ||
} | ||
] | ||
"license": "BSD-3-Clause" | ||
} |
@@ -6,6 +6,5 @@ ![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png) | ||
Current version: **2.3** | ||
Current version: **3.x** | ||
Note: 2.x is the same exact protocol as 1.1. The version increment reflects a change in the internal error format | ||
used by the module and used by the node API. | ||
Note: 3.x and 2.x are the same exact protocol as 1.1. The version increments reflect changes in the node API. | ||
@@ -12,0 +11,0 @@ [![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk) |
@@ -85,3 +85,3 @@ // Load modules | ||
describe('#bewit', function () { | ||
describe('bewit()', function () { | ||
@@ -520,3 +520,3 @@ it('returns a valid bewit value', function (done) { | ||
Browser.utils.setStorage(localStorage) | ||
Browser.utils.setStorage(localStorage); | ||
@@ -746,3 +746,3 @@ Browser.utils.setNtpOffset(60 * 60 * 1000); | ||
describe('#header', function () { | ||
describe('header()', function () { | ||
@@ -956,3 +956,3 @@ it('returns a valid authorization header (sha1)', function (done) { | ||
describe('#authenticate', function () { | ||
describe('authenticate()', function () { | ||
@@ -1126,3 +1126,3 @@ it('skips tsm validation when missing ts', function (done) { | ||
describe('#message', function () { | ||
describe('message()', function () { | ||
@@ -1278,3 +1278,3 @@ it('generates an authorization then successfully parse it', function (done) { | ||
describe('#authenticateTimestamp', function (done) { | ||
describe('authenticateTimestamp()', function (done) { | ||
@@ -1351,3 +1351,3 @@ it('validates a timestamp', function (done) { | ||
describe('#setStorage', function () { | ||
describe('setStorage()', function () { | ||
@@ -1368,17 +1368,25 @@ it('sets storage for the first time', function (done) { | ||
describe('#setNtpOffset', function (done) { | ||
describe('setNtpOffset()', function (done) { | ||
it('catches localStorage errors', function (done) { | ||
it('catches localStorage errors', { parallel: false }, function (done) { | ||
var orig = Browser.utils.storage.setItem; | ||
var error = console.error; | ||
var consoleOrig = console.error; | ||
var count = 0; | ||
console.error = function () { if (count++ === 2) { console.error = error; } }; | ||
console.error = function () { | ||
if (count++ === 2) { | ||
console.error = consoleOrig; | ||
} | ||
}; | ||
Browser.utils.storage.setItem = function () { | ||
Browser.utils.storage.setItem = orig; | ||
throw new Error() | ||
throw new Error(); | ||
}; | ||
expect(function () { | ||
Browser.utils.setNtpOffset(100); | ||
@@ -1391,3 +1399,3 @@ }).not.to.throw(); | ||
describe('#parseAuthorizationHeader', function (done) { | ||
describe('parseAuthorizationHeader()', function (done) { | ||
@@ -1431,3 +1439,3 @@ it('returns null on missing header', function (done) { | ||
describe('#parseUri', function () { | ||
describe('parseUri()', function () { | ||
@@ -1449,6 +1457,6 @@ it('returns empty port when unknown scheme', function (done) { | ||
var str = "https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=url"; | ||
var base64str = "aHR0cHM6Ly93d3cuZ29vZ2xlLmNhL3dlYmhwP3NvdXJjZWlkPWNocm9tZS1pbnN0YW50Jmlvbj0xJmVzcHY9MiZpZT1VVEYtOCNxPXVybA"; | ||
var str = 'https://www.google.ca/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=url'; | ||
var base64str = 'aHR0cHM6Ly93d3cuZ29vZ2xlLmNhL3dlYmhwP3NvdXJjZWlkPWNocm9tZS1pbnN0YW50Jmlvbj0xJmVzcHY9MiZpZT1VVEYtOCNxPXVybA'; | ||
describe('#base64urlEncode', function () { | ||
describe('base64urlEncode()', function () { | ||
@@ -1460,6 +1468,4 @@ it('should base64 URL-safe decode a string', function (done) { | ||
}); | ||
}); | ||
}); | ||
}); |
@@ -22,423 +22,420 @@ // Load modules | ||
describe('Hawk', function () { | ||
describe('Client', function () { | ||
describe('client', function () { | ||
describe('header()', function () { | ||
describe('#header', function () { | ||
it('returns a valid authorization header (sha1)', function (done) { | ||
it('returns a valid authorization header (sha1)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var header = Hawk.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('http://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="bsvY3IfUllw6V5rvk4tStEvpBhE=", ext="Bazinga!", mac="qbf1ZPG/r/e06F4ht+T77LXi5vw="'); | ||
done(); | ||
}); | ||
it('returns a valid authorization header (sha256)', function (done) { | ||
it('returns a valid authorization header (sha256)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", ext="Bazinga!", mac="q1CwFoSHzPZSkbIvl0oYlD+91rBUEvFk763nMjMndj8="'); | ||
done(); | ||
}); | ||
it('returns a valid authorization header (no ext)', function (done) { | ||
it('returns a valid authorization header (no ext)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
it('returns a valid authorization header (null ext)', function (done) { | ||
it('returns a valid authorization header (null ext)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain', ext: null }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain', ext: null }).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
it('returns a valid authorization header (empty payload)', function (done) { | ||
it('returns a valid authorization header (empty payload)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: '', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id=\"123456\", ts=\"1353809207\", nonce=\"Ygvqdz\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", mac=\"U5k16YEzn3UnBHKeBzsDXn067Gu3R4YaY6xOt9PYRZM=\"'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: '', contentType: 'text/plain' }).field; | ||
expect(header).to.equal('Hawk id=\"123456\", ts=\"1353809207\", nonce=\"Ygvqdz\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", mac=\"U5k16YEzn3UnBHKeBzsDXn067Gu3R4YaY6xOt9PYRZM=\"'); | ||
done(); | ||
}); | ||
it('returns a valid authorization header (pre hashed payload)', function (done) { | ||
it('returns a valid authorization header (pre hashed payload)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var options = { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }; | ||
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', options).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
var options = { credentials: credentials, timestamp: 1353809207, nonce: 'Ygvqdz', payload: 'something to write about', contentType: 'text/plain' }; | ||
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', options).field; | ||
expect(header).to.equal('Hawk id="123456", ts="1353809207", nonce="Ygvqdz", hash="2QfCt3GuY9HQnHWyWD3wX68ZOKbynqlfYmuO2ZBRqtY=", mac="HTgtd0jPI6E4izx8e4OHdO36q00xFCU0FolNq3RiCYs="'); | ||
done(); | ||
}); | ||
it('errors on missing uri', function (done) { | ||
it('errors on missing uri', function (done) { | ||
var header = Hawk.client.header('', 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('', 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
it('errors on invalid uri', function (done) { | ||
it('errors on invalid uri', function (done) { | ||
var header = Hawk.client.header(4, 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header(4, 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
it('errors on missing method', function (done) { | ||
it('errors on missing method', function (done) { | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', ''); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', ''); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
it('errors on invalid method', function (done) { | ||
it('errors on invalid method', function (done) { | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 5); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 5); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
it('errors on missing options', function (done) { | ||
it('errors on missing options', function (done) { | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST'); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid argument type'); | ||
done(); | ||
}); | ||
it('errors on invalid credentials (id)', function (done) { | ||
it('errors on invalid credentials (id)', function (done) { | ||
var credentials = { | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
key: '2983d45yun89q', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
it('errors on missing credentials', function (done) { | ||
it('errors on missing credentials', function (done) { | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
it('errors on invalid credentials', function (done) { | ||
it('errors on invalid credentials', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha256' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Invalid credential object'); | ||
done(); | ||
}); | ||
it('errors on invalid algorithm', function (done) { | ||
it('errors on invalid algorithm', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'hmac-sha-0' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'hmac-sha-0' | ||
}; | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('https://example.net/somewhere/over/the/rainbow', 'POST', { credentials: credentials, payload: 'something, anything!', ext: 'Bazinga!', timestamp: 1353809207 }); | ||
expect(header.field).to.equal(''); | ||
expect(header.err).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
}); | ||
describe('#authenticate', function () { | ||
describe('authenticate()', function () { | ||
it('returns false on invalid header', function (done) { | ||
it('returns false on invalid header', function (done) { | ||
var res = { | ||
headers: { | ||
'server-authorization': 'Hawk mac="abc", bad="xyz"' | ||
} | ||
}; | ||
var res = { | ||
headers: { | ||
'server-authorization': 'Hawk mac="abc", bad="xyz"' | ||
} | ||
}; | ||
expect(Hawk.client.authenticate(res, {})).to.equal(false); | ||
done(); | ||
}); | ||
expect(Hawk.client.authenticate(res, {})).to.equal(false); | ||
done(); | ||
}); | ||
it('returns false on invalid mac', function (done) { | ||
it('returns false on invalid mac', function (done) { | ||
var res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
var res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="_IJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1362336900', | ||
nonce: 'eb5S_L', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', | ||
id: '123456' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1362336900', | ||
nonce: 'eb5S_L', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', | ||
id: '123456' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(false); | ||
done(); | ||
}); | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(false); | ||
done(); | ||
}); | ||
it('returns true on ignoring hash', function (done) { | ||
it('returns true on ignoring hash', function (done) { | ||
var res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
var res = { | ||
headers: { | ||
'content-type': 'text/plain', | ||
'server-authorization': 'Hawk mac="XIJRsMl/4oL+nn+vKoeVZPdCHXB4yJkNnBbTbHFZUYE=", hash="f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=", ext="response-specific"' | ||
} | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1362336900', | ||
nonce: 'eb5S_L', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', | ||
id: '123456' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1362336900', | ||
nonce: 'eb5S_L', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
app: undefined, | ||
dlg: undefined, | ||
mac: 'BlmSe8K+pbKIb6YsZCnt4E1GrYvY1AaYayNR82dGpIk=', | ||
id: '123456' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true); | ||
done(); | ||
}); | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true); | ||
done(); | ||
}); | ||
it('fails on invalid WWW-Authenticate header format', function (done) { | ||
it('fails on invalid WWW-Authenticate header format', function (done) { | ||
var header = 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(false); | ||
done(); | ||
}); | ||
var header = 'Hawk ts="1362346425875", tsm="PhwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", x="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(false); | ||
done(); | ||
}); | ||
it('fails on invalid WWW-Authenticate header format', function (done) { | ||
it('fails on invalid WWW-Authenticate header format', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var header = 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, credentials)).to.equal(false); | ||
done(); | ||
}); | ||
var header = 'Hawk ts="1362346425875", tsm="hwayS28vtnn3qbv0mqRBYSXebN/zggEtucfeZ620Zo=", error="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, credentials)).to.equal(false); | ||
done(); | ||
}); | ||
it('skips tsm validation when missing ts', function (done) { | ||
it('skips tsm validation when missing ts', function (done) { | ||
var header = 'Hawk error="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(true); | ||
done(); | ||
}); | ||
var header = 'Hawk error="Stale timestamp"'; | ||
expect(Hawk.client.authenticate({ headers: { 'www-authenticate': header } }, {})).to.equal(true); | ||
done(); | ||
}); | ||
}); | ||
describe('#message', function () { | ||
describe('message()', function () { | ||
it('generates authorization', function (done) { | ||
it('generates authorization', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.exist(); | ||
expect(auth.ts).to.equal(1353809207); | ||
expect(auth.nonce).to.equal('abc123'); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.exist(); | ||
expect(auth.ts).to.equal(1353809207); | ||
expect(auth.nonce).to.equal('abc123'); | ||
done(); | ||
}); | ||
it('errors on invalid host', function (done) { | ||
it('errors on invalid host', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message(5, 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message(5, 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on invalid port', function (done) { | ||
it('errors on invalid port', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', '80', 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', '80', 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on missing host', function (done) { | ||
it('errors on missing host', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 0, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 0, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on null message', function (done) { | ||
it('errors on null message', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, null, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, null, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on missing message', function (done) { | ||
it('errors on missing message', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, undefined, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, undefined, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on invalid message', function (done) { | ||
it('errors on invalid message', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, 5, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, 5, { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on missing options', function (done) { | ||
it('errors on missing options', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman'); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman'); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on invalid credentials (id)', function (done) { | ||
it('errors on invalid credentials (id)', function (done) { | ||
var credentials = { | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
key: '2983d45yun89q', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('errors on invalid credentials (key)', function (done) { | ||
it('errors on invalid credentials (key)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha1' | ||
}; | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha1' | ||
}; | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 80, 'I am the boodyman', { credentials: credentials, timestamp: 1353809207, nonce: 'abc123' }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); |
@@ -21,67 +21,51 @@ // Load modules | ||
describe('Hawk', function () { | ||
describe('Crypto', function () { | ||
describe('Crypto', function () { | ||
describe('generateNormalizedString()', function () { | ||
describe('#generateNormalizedString', function () { | ||
it('should return a valid normalized string', function (done) { | ||
it('should return a valid normalized string', function (done) { | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080 | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\n\n'); | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
credentials: { | ||
key: 'dasdfasdf', | ||
algorithm: 'sha256' | ||
}, | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080 | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\n\n'); | ||
done(); | ||
}); | ||
done(); | ||
}); | ||
it('should return a valid normalized string (ext)', function (done) { | ||
it('should return a valid normalized string (ext)', function (done) { | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080, | ||
ext: 'this is some app data' | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\nthis is some app data\n'); | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
credentials: { | ||
key: 'dasdfasdf', | ||
algorithm: 'sha256' | ||
}, | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080, | ||
ext: 'this is some app data' | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\n\nthis is some app data\n'); | ||
done(); | ||
}); | ||
done(); | ||
}); | ||
it('should return a valid normalized string (payload + ext)', function (done) { | ||
it('should return a valid normalized string (payload + ext)', function (done) { | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080, | ||
hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=', | ||
ext: 'this is some app data' | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\nU4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=\nthis is some app data\n'); | ||
expect(Hawk.crypto.generateNormalizedString('header', { | ||
credentials: { | ||
key: 'dasdfasdf', | ||
algorithm: 'sha256' | ||
}, | ||
ts: 1357747017, | ||
nonce: 'k3k4j5', | ||
method: 'GET', | ||
resource: '/resource/something', | ||
host: 'example.com', | ||
port: 8080, | ||
hash: 'U4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=', | ||
ext: 'this is some app data' | ||
})).to.equal('hawk.1.header\n1357747017\nk3k4j5\nGET\n/resource/something\nexample.com\n8080\nU4MKKSmiVxk37JCCrAVIjV/OhB3y+NdwoCr6RShbVkE=\nthis is some app data\n'); | ||
done(); | ||
}); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
@@ -22,75 +22,72 @@ // Load modules | ||
describe('Hawk', function () { | ||
describe('README', function () { | ||
describe('README', function () { | ||
describe('core', function () { | ||
describe('core', function () { | ||
var credentials = { | ||
id: 'dh37fgj492je', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256' | ||
}; | ||
var credentials = { | ||
id: 'dh37fgj492je', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256' | ||
}; | ||
var options = { | ||
credentials: credentials, | ||
timestamp: 1353832234, | ||
nonce: 'j4h3g2', | ||
ext: 'some-app-ext-data' | ||
}; | ||
var options = { | ||
credentials: credentials, | ||
timestamp: 1353832234, | ||
nonce: 'j4h3g2', | ||
ext: 'some-app-ext-data' | ||
}; | ||
it('should generate a header protocol example', function (done) { | ||
it('should generate a header protocol example', function (done) { | ||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', options).field; | ||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', options).field; | ||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="'); | ||
done(); | ||
}); | ||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", ext="some-app-ext-data", mac="6R4rV5iE+NPoym+WwjeHzjAGXUtLNIxmo1vpMofpLAE="'); | ||
done(); | ||
it('should generate a normalized string protocol example', function (done) { | ||
var normalized = Hawk.crypto.generateNormalizedString('header', { | ||
credentials: credentials, | ||
ts: options.timestamp, | ||
nonce: options.nonce, | ||
method: 'GET', | ||
resource: '/resource?a=1&b=2', | ||
host: 'example.com', | ||
port: 8000, | ||
ext: options.ext | ||
}); | ||
it('should generate a normalized string protocol example', function (done) { | ||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nGET\n/resource?a=1&b=2\nexample.com\n8000\n\nsome-app-ext-data\n'); | ||
done(); | ||
}); | ||
var normalized = Hawk.crypto.generateNormalizedString('header', { | ||
credentials: credentials, | ||
ts: options.timestamp, | ||
nonce: options.nonce, | ||
method: 'GET', | ||
resource: '/resource?a=1&b=2', | ||
host: 'example.com', | ||
port: 8000, | ||
ext: options.ext | ||
}); | ||
var payloadOptions = Hoek.clone(options); | ||
payloadOptions.payload = 'Thank you for flying Hawk'; | ||
payloadOptions.contentType = 'text/plain'; | ||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nGET\n/resource?a=1&b=2\nexample.com\n8000\n\nsome-app-ext-data\n'); | ||
done(); | ||
}); | ||
it('should generate a header protocol example (with payload)', function (done) { | ||
var payloadOptions = Hoek.clone(options); | ||
payloadOptions.payload = 'Thank you for flying Hawk'; | ||
payloadOptions.contentType = 'text/plain'; | ||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'POST', payloadOptions).field; | ||
it('should generate a header protocol example (with payload)', function (done) { | ||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="'); | ||
done(); | ||
}); | ||
var header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'POST', payloadOptions).field; | ||
it('should generate a normalized string protocol example (with payload)', function (done) { | ||
expect(header).to.equal('Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", hash="Yi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=", ext="some-app-ext-data", mac="aSe1DERmZuRl3pI36/9BdZmnErTw3sNzOOAUlfeKjVw="'); | ||
done(); | ||
var normalized = Hawk.crypto.generateNormalizedString('header', { | ||
credentials: credentials, | ||
ts: options.timestamp, | ||
nonce: options.nonce, | ||
method: 'POST', | ||
resource: '/resource?a=1&b=2', | ||
host: 'example.com', | ||
port: 8000, | ||
hash: Hawk.crypto.calculatePayloadHash(payloadOptions.payload, credentials.algorithm, payloadOptions.contentType), | ||
ext: options.ext | ||
}); | ||
it('should generate a normalized string protocol example (with payload)', function (done) { | ||
var normalized = Hawk.crypto.generateNormalizedString('header', { | ||
credentials: credentials, | ||
ts: options.timestamp, | ||
nonce: options.nonce, | ||
method: 'POST', | ||
resource: '/resource?a=1&b=2', | ||
host: 'example.com', | ||
port: 8000, | ||
hash: Hawk.crypto.calculatePayloadHash(payloadOptions.payload, credentials.algorithm, payloadOptions.contentType), | ||
ext: options.ext | ||
}); | ||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nPOST\n/resource?a=1&b=2\nexample.com\n8000\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\nsome-app-ext-data\n'); | ||
done(); | ||
}); | ||
expect(normalized).to.equal('hawk.1.header\n1353832234\nj4h3g2\nPOST\n/resource?a=1&b=2\nexample.com\n8000\nYi9LfIIFRtBEPt74PVmbTF/xVAwPn7ub15ePICfgnuY=\nsome-app-ext-data\n'); | ||
done(); | ||
}); | ||
@@ -97,0 +94,0 @@ }); |
1675
test/server.js
@@ -6,2 +6,3 @@ // Load modules | ||
var Hawk = require('../lib'); | ||
var Hoek = require('hoek'); | ||
var Lab = require('lab'); | ||
@@ -23,670 +24,1079 @@ | ||
describe('Hawk', function () { | ||
describe('Server', function () { | ||
describe('server', function () { | ||
var credentialsFunc = function (id, callback) { | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'steve' | ||
}; | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'steve' | ||
return callback(null, credentials); | ||
}; | ||
describe('authenticate()', function () { | ||
it('parses a valid authentication header (sha1)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' | ||
}; | ||
return callback(null, credentials); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
describe('#authenticate', function () { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
it('parses a valid authentication header (sha1)', function (done) { | ||
it('parses a valid authentication header (sha256)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/1?b=1&a=2', | ||
host: 'example.com', | ||
port: 8000, | ||
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
it('parses a valid authentication header (host override)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example1.com:8080', | ||
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' | ||
}; | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
it('parses a valid authentication header (sha256)', function (done) { | ||
it('parses a valid authentication header (host port override)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/1?b=1&a=2', | ||
host: 'example.com', | ||
port: 8000, | ||
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example1.com:80', | ||
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
it('parses a valid authentication header (host override)', function (done) { | ||
it('parses a valid authentication header (POST with payload)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on missing hash', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/1?b=1&a=2', | ||
host: 'example.com', | ||
port: 8000, | ||
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing required payload hash'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on a stale timestamp', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Stale timestamp'); | ||
var header = err.output.headers['WWW-Authenticate']; | ||
var ts = header.match(/^Hawk ts\=\"(\d+)\"\, tsm\=\"([^\"]+)\"\, error=\"Stale timestamp\"$/); | ||
var now = Hawk.utils.now(); | ||
expect(parseInt(ts[1], 10) * 1000).to.be.within(now - 1000, now + 1000); | ||
var res = { | ||
headers: { | ||
host: 'example1.com:8080', | ||
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' | ||
'www-authenticate': header | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true); | ||
done(); | ||
}); | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
it('errors on a replay', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"' | ||
}; | ||
var memoryCache = {}; | ||
var options = { | ||
localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(), | ||
nonceFunc: function (key, nonce, ts, callback) { | ||
if (memoryCache[key + nonce]) { | ||
return callback(new Error()); | ||
} | ||
memoryCache[key + nonce] = true; | ||
return callback(); | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid nonce'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('parses a valid authentication header (host port override)', function (done) { | ||
it('does not error on nonce collision if keys differ', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example1.com:80', | ||
authorization: 'Hawk id="1", ts="1353788437", nonce="k3j4h2", mac="zy79QQ5/EYFmQqutVnYb73gAc/U=", ext="hello"' | ||
var reqSteve = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"' | ||
}; | ||
var reqBob = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="456", ts="1353788437", nonce="k3j4h2", mac="LXfmTnRzrLd9TD7yfH+4se46Bx6AHyhpM94hLCiNia4=", ext="hello"' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
'123': { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'steve' | ||
}, | ||
'456': { | ||
id: id, | ||
key: 'xrunpaw3489ruxnpa98w4rxnwerxhqb98rpaxn39848', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'bob' | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { host: 'example.com', port: 8080, localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
return callback(null, credentials[id]); | ||
}; | ||
var memoryCache = {}; | ||
var options = { | ||
localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(), | ||
nonceFunc: function (key, nonce, ts, callback) { | ||
if (memoryCache[key + nonce]) { | ||
return callback(new Error()); | ||
} | ||
memoryCache[key + nonce] = true; | ||
return callback(); | ||
} | ||
}; | ||
Hawk.server.authenticate(reqSteve, credentialsFunc, options, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
Hawk.server.authenticate(reqBob, credentialsFunc, options, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(credentials.user).to.equal('bob'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('parses a valid authentication header (POST with payload)', function (done) { | ||
it('errors on an invalid authentication header: wrong scheme', function (done) { | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123456", ts="1357926341", nonce="1AwuJD", hash="qAiXIVv+yjDATneWxZP2YCTa9aHRgQdnH9b3Wc+o3dg=", ext="some-app-data", mac="UeYcj5UoTVaAWXNvJfLVia7kU3VabxCqrccXP8sUGC4="' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Basic asdasdasdasd' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1357926341000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
it('errors on missing hash', function (done) { | ||
it('errors on an invalid authentication header: no scheme', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/1?b=1&a=2', | ||
host: 'example.com', | ||
port: 8000, | ||
authorization: 'Hawk id="dh37fgj492je", ts="1353832234", nonce="j4h3g2", mac="m8r1rHbXN6NgO+KIIhjO7sFRyd78RNGVUwehe8Cp2dU=", ext="some-app-data"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: '!@#' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { payload: 'body', localtimeOffsetMsec: 1353832234000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing required payload hash'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid header syntax'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on a stale timestamp', function (done) { | ||
it('errors on an missing authorization header', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123456", ts="1362337299", nonce="UzmxSs", ext="some-app-data", mac="wnNUxchvvryMH2RxckTdZ/gY3ijzvccx4keVvELC61w="' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Stale timestamp'); | ||
var header = err.output.headers['WWW-Authenticate']; | ||
var ts = header.match(/^Hawk ts\=\"(\d+)\"\, tsm\=\"([^\"]+)\"\, error=\"Stale timestamp\"$/); | ||
var now = Hawk.utils.now(); | ||
expect(parseInt(ts[1], 10) * 1000).to.be.within(now - 1000, now + 1000); | ||
expect(err).to.exist(); | ||
expect(err.isMissing).to.equal(true); | ||
done(); | ||
}); | ||
}); | ||
var res = { | ||
headers: { | ||
'www-authenticate': header | ||
} | ||
}; | ||
it('errors on an missing host header', function (done) { | ||
expect(Hawk.client.authenticate(res, credentials, artifacts)).to.equal(true); | ||
done(); | ||
}); | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on a replay', function (done) { | ||
it('errors on an missing authorization attribute (id)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="bXx7a7p1h9QYQNZ8x7QhvDQym8ACgab4m3lVSFn4DBw=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var memoryCache = {}; | ||
var options = { | ||
localtimeOffsetMsec: 1353788437000 - Hawk.utils.now(), | ||
nonceFunc: function (nonce, ts, callback) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
if (memoryCache[nonce]) { | ||
return callback(new Error()); | ||
} | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
}); | ||
memoryCache[nonce] = true; | ||
return callback(); | ||
} | ||
}; | ||
it('errors on an missing authorization attribute (ts)', function (done) { | ||
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, options, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid nonce'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization attribute (nonce)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an invalid authentication header: wrong scheme', function (done) { | ||
it('errors on an missing authorization attribute (mac)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Basic asdasdasdasd' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.not.exist(); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an invalid authentication header: no scheme', function (done) { | ||
it('errors on an unknown authorization attribute', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: '!@#' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid header syntax'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown attribute: x'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization header', function (done) { | ||
it('errors on an bad authorization header format', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123\\", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, {}, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.isMissing).to.equal(true); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad header format'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing host header', function (done) { | ||
it('errors on an bad authorization attribute value', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="\t", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad attribute value: id'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization attribute (id)', function (done) { | ||
it('errors on an empty authorization attribute value', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad attribute value: id'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization attribute (ts)', function (done) { | ||
it('errors on duplicated authorization attribute key', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", id="456", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Duplicate attribute: id'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization attribute (nonce)', function (done) { | ||
it('errors on an invalid authorization header format', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid header syntax'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an missing authorization attribute (mac)', function (done) { | ||
it('errors on an bad host header (missing host)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: ':8080', | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an unknown authorization attribute', function (done) { | ||
it('errors on an bad host header (pad port)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", x="3", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com:something', | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown attribute: x'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an bad authorization header format', function (done) { | ||
it('errors on credentialsFunc error', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123\\", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
var credentialsFunc = function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad header format'); | ||
done(); | ||
}); | ||
return callback(new Error('Unknown user')); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown user'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an bad authorization attribute value', function (done) { | ||
it('errors on credentialsFunc error (with credentials)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="\t", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
var credentialsFunc = function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad attribute value: id'); | ||
done(); | ||
}); | ||
return callback(new Error('Unknown user'), { some: 'value' }); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown user'); | ||
expect(credentials.some).to.equal('value'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an empty authorization attribute value', function (done) { | ||
it('errors on missing credentials', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
var credentialsFunc = function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad attribute value: id'); | ||
done(); | ||
}); | ||
return callback(null, null); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown credentials'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on duplicated authorization attribute key', function (done) { | ||
it('errors on invalid credentials (id)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", id="456", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
return callback(null, credentials); | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Duplicate attribute: id'); | ||
done(); | ||
}); | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an invalid authorization header format', function (done) { | ||
it('errors on invalid credentials (key)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk' | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
id: '23434d3q4d5345d', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
return callback(null, credentials); | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid header syntax'); | ||
done(); | ||
}); | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an bad host header (missing host)', function (done) { | ||
it('errors on unknown credentials algorithm', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: ':8080', | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'hmac-sha-0', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
return callback(null, credentials); | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
done(); | ||
}); | ||
}); | ||
it('errors on an bad host header (pad port)', function (done) { | ||
it('errors on unknown bad mac', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com:something', | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
} | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
return callback(null, credentials); | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad mac'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on credentialsFunc error', function (done) { | ||
describe('header()', function () { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
it('generates header', function (done) { | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
return callback(new Error('Unknown user')); | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"'); | ||
done(); | ||
}); | ||
it('generates header (empty payload)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var header = Hawk.server.header(credentials, artifacts, { payload: '', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal('Hawk mac=\"i8/kUBDx0QF+PpCtW860kkV/fa9dbwEoe/FpGUXowf0=\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", ext=\"response-specific\"'); | ||
done(); | ||
}); | ||
it('generates header (pre calculated hash)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var options = { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }; | ||
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); | ||
var header = Hawk.server.header(credentials, artifacts, options); | ||
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"'); | ||
done(); | ||
}); | ||
it('generates header (null ext)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: null }); | ||
expect(header).to.equal('Hawk mac=\"6PrybJTJs20jsgBw5eilXpcytD8kUbaIKNYXL+6g0ns=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\"'); | ||
done(); | ||
}); | ||
it('errors on missing artifacts', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var header = Hawk.server.header(credentials, null, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
it('errors on invalid artifacts', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var header = Hawk.server.header(credentials, 5, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
it('errors on missing credentials', function (done) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var header = Hawk.server.header(null, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
it('errors on invalid credentials (key)', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
it('errors on invalid algorithm', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'x', | ||
user: 'steve' | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
}); | ||
describe('authenticateMessage()', function () { | ||
it('errors on invalid authorization (ts)', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.ts; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown user'); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on credentialsFunc error (with credentials)', function (done) { | ||
it('errors on invalid authorization (nonce)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentialsFunc = function (id, callback) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.nonce; | ||
return callback(new Error('Unknown user'), { some: 'value' }); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown user'); | ||
expect(credentials.some).to.equal('value'); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on missing credentials', function (done) { | ||
it('errors on invalid authorization (hash)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentialsFunc = function (id, callback) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.hash; | ||
return callback(null, null); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown credentials'); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on invalid credentials (id)', function (done) { | ||
it('errors with credentials', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentialsFunc = function (id, callback) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, function (id, callback) { | ||
return callback(null, credentials); | ||
}; | ||
callback(new Error('something'), { some: 'value' }); | ||
}, {}, function (err, credentials) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
expect(err.message).to.equal('something'); | ||
expect(credentials.some).to.equal('value'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on invalid credentials (key)', function (done) { | ||
it('errors on nonce collision', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentialsFunc = function (id, callback) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { | ||
nonceFunc: function (key, nonce, ts, nonceCallback) { | ||
var credentials = { | ||
id: '23434d3q4d5345d', | ||
user: 'steve' | ||
}; | ||
nonceCallback(true); | ||
} | ||
}, function (err, credentials) { | ||
return callback(null, credentials); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
expect(err.message).to.equal('Invalid nonce'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on unknown credentials algorithm', function (done) { | ||
var credentialsFunc = function (id, callback) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcUyW6EEgUH4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'steve' | ||
}; | ||
var credentialsFunc = function (id, callback) { | ||
return callback(null, credentials); | ||
}; | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'hmac-sha-0', | ||
user: 'steve' | ||
}; | ||
it('should generate an authorization then successfully parse it', function (done) { | ||
return callback(null, credentials); | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
expect(err.output.payload.message).to.equal('An internal server error occurred'); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on unknown bad mac', function (done) { | ||
it('should fail authorization on mismatching host', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Hawk id="123", ts="1353788437", nonce="k3j4h2", mac="/qwS4UjfVWMcU4jlr7T/wuKe3dKijvTvSos=", ext="hello"' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentialsFunc = function (id, callback) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var credentials = { | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
return callback(null, credentials); | ||
}; | ||
Hawk.server.authenticate(req, credentialsFunc, { localtimeOffsetMsec: 1353788437000 - Hawk.utils.now() }, function (err, credentials, artifacts) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad mac'); | ||
expect(err.message).to.equal('Bad mac'); | ||
done(); | ||
@@ -697,292 +1107,211 @@ }); | ||
describe('#header', function () { | ||
it('should fail authorization on stale timestamp', function (done) { | ||
it('generates header', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials) { | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"'); | ||
done(); | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Stale timestamp'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('generates header (empty payload)', function (done) { | ||
it('overrides timestampSkewSec', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials, localtimeOffsetMsec: 100000 }); | ||
expect(auth).to.exist(); | ||
var header = Hawk.server.header(credentials, artifacts, { payload: '', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal('Hawk mac=\"i8/kUBDx0QF+PpCtW860kkV/fa9dbwEoe/FpGUXowf0=\", hash=\"q/t+NNAkQZNlq/aAD6PlexImwQTxwgT2MahfTa9XRLA=\", ext=\"response-specific\"'); | ||
done(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { timestampSkewSec: 500 }, function (err, credentials) { | ||
expect(err).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('generates header (pre calculated hash)', function (done) { | ||
it('should fail authorization on invalid authorization', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
delete auth.id; | ||
var options = { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }; | ||
options.hash = Hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); | ||
var header = Hawk.server.header(credentials, artifacts, options); | ||
expect(header).to.equal('Hawk mac=\"n14wVJK4cOxAytPUMc5bPezQzuJGl5n7MYXhFQgEKsE=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\", ext=\"response-specific\"'); | ||
done(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('generates header (null ext)', function (done) { | ||
it('should fail authorization on bad hash', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: null }); | ||
expect(header).to.equal('Hawk mac=\"6PrybJTJs20jsgBw5eilXpcytD8kUbaIKNYXL+6g0ns=\", hash=\"f9cDF/TDm7TkYRLnGwRMfeDzT6LixQVLvrIKhh0vgmM=\"'); | ||
done(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Bad message hash'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on missing artifacts', function (done) { | ||
it('should fail authorization on nonce error', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var header = Hawk.server.header(credentials, null, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
it('errors on invalid artifacts', function (done) { | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { | ||
nonceFunc: function (key, nonce, ts, callback) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
callback(new Error('kaboom')); | ||
} | ||
}, function (err, credentials) { | ||
var header = Hawk.server.header(credentials, 5, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid nonce'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on missing credentials', function (done) { | ||
it('should fail authorization on credentials error', function (done) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var header = Hawk.server.header(null, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
it('errors on invalid credentials (key)', function (done) { | ||
var errFunc = function (id, callback) { | ||
var credentials = { | ||
id: '123456', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
callback(new Error('kablooey')); | ||
}; | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('kablooey'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on invalid algorithm', function (done) { | ||
it('should fail authorization on missing credentials', function (done) { | ||
var credentials = { | ||
id: '123456', | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'x', | ||
user: 'steve' | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var artifacts = { | ||
method: 'POST', | ||
host: 'example.com', | ||
port: '8080', | ||
resource: '/resource/4?filter=a', | ||
ts: '1398546787', | ||
nonce: 'xUwusx', | ||
hash: 'nJjkVtBE5Y/Bk38Aiokwn0jiJxt/0S2WRSUwWLCf5xk=', | ||
ext: 'some-app-data', | ||
mac: 'dvIvMThwi28J61Jc3P0ryAhuKpanU63GXdx6hkmQkJA=', | ||
id: '123456' | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var errFunc = function (id, callback) { | ||
callback(); | ||
}; | ||
var header = Hawk.server.header(credentials, artifacts, { payload: 'some reply', contentType: 'text/plain', ext: 'response-specific' }); | ||
expect(header).to.equal(''); | ||
done(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown credentials'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('#authenticateMessage', function () { | ||
it('should fail authorization on invalid credentials', function (done) { | ||
it('errors on invalid authorization (ts)', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.ts; | ||
var errFunc = function (id, callback) { | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
callback(null, {}); | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on invalid authorization (nonce)', function (done) { | ||
it('should fail authorization on invalid credentials algorithm', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.nonce; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
var errFunc = function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
callback(null, { key: '123', algorithm: '456' }); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('errors on invalid authorization (hash)', function (done) { | ||
it('should fail on missing host', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
delete auth.hash; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
it('errors with credentials', function (done) { | ||
it('should fail on missing credentials', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', {}); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
it('should fail on invalid algorithm', function (done) { | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, function (id, callback) { callback(new Error('something'), { some: 'value' }); }, {}, function (err, credentials) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('something'); | ||
expect(credentials.some).to.equal('value'); | ||
done(); | ||
}); | ||
}); | ||
var creds = Hoek.clone(credentials); | ||
creds.algorithm = 'blah'; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
describe('#authenticatePayloadHash', function () { | ||
describe('authenticatePayloadHash()', function () { | ||
it('checks payload hash', function (done) { | ||
it('checks payload hash', function (done) { | ||
expect(Hawk.server.authenticatePayloadHash('abcdefg', { hash: 'abcdefg' })).to.equal(true); | ||
expect(Hawk.server.authenticatePayloadHash('1234567', { hash: 'abcdefg' })).to.equal(false); | ||
done(); | ||
}); | ||
expect(Hawk.server.authenticatePayloadHash('abcdefg', { hash: 'abcdefg' })).to.equal(true); | ||
expect(Hawk.server.authenticatePayloadHash('1234567', { hash: 'abcdefg' })).to.equal(false); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
845
test/uri.js
@@ -24,74 +24,30 @@ // Load modules | ||
describe('Hawk', function () { | ||
describe('Uri', function () { | ||
describe('Uri', function () { | ||
var credentialsFunc = function (id, callback) { | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
return callback(null, credentials); | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: 'sha256', | ||
user: 'steve' | ||
}; | ||
it('should generate a bewit then successfully authenticate it', function (done) { | ||
return callback(null, credentials); | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2', | ||
host: 'example.com', | ||
port: 80 | ||
}; | ||
it('should generate a bewit then successfully authenticate it', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2', | ||
host: 'example.com', | ||
port: 80 | ||
}; | ||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100, ext: 'some-app-data' }); | ||
req.url += '&bewit=' + bewit; | ||
credentialsFunc('123456', function (err, credentials) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100, ext: 'some-app-data' }); | ||
req.url += '&bewit=' + bewit; | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should generate a bewit then successfully authenticate it (no ext)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2', | ||
host: 'example.com', | ||
port: 80 | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100 }); | ||
req.url += '&bewit=' + bewit; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully authenticate a request (last param)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
@@ -105,12 +61,18 @@ | ||
}); | ||
}); | ||
it('should successfully authenticate a request (first param)', function (done) { | ||
it('should generate a bewit then successfully authenticate it (no ext)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ&a=1&b=2', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2', | ||
host: 'example.com', | ||
port: 80 | ||
}; | ||
credentialsFunc('123456', function (err, credentials) { | ||
var bewit = Hawk.uri.getBewit('http://example.com/resource/4?a=1&b=2', { credentials: credentials, ttlSec: 60 * 60 * 24 * 365 * 100 }); | ||
req.url += '&bewit=' + bewit; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
@@ -120,325 +82,378 @@ | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should successfully authenticate a request (only param)', function (done) { | ||
it('should successfully authenticate a request (last param)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on multiple authentication', function (done) { | ||
it('should successfully authenticate a request (first param)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Basic asdasdasdasd' | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2MjFcMzFjMmNkbUJFd1NJRVZDOVkva1NFb2c3d3YrdEVNWjZ3RXNmOGNHU2FXQT1cc29tZS1hcHAtZGF0YQ&a=1&b=2', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Multiple authentications'); | ||
done(); | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on method other than GET', function (done) { | ||
it('should successfully authenticate a request (only param)', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
var exp = Math.floor(Hawk.utils.now() / 1000) + 60; | ||
var ext = 'some-app-data'; | ||
var mac = Hawk.crypto.calculateMac('bewit', credentials, { | ||
timestamp: exp, | ||
nonce: '', | ||
method: req.method, | ||
resource: req.url, | ||
host: req.host, | ||
port: req.port, | ||
ext: ext | ||
}); | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
expect(attributes.ext).to.equal('some-app-data'); | ||
done(); | ||
}); | ||
}); | ||
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + ext; | ||
it('should fail on multiple authentication', function (done) { | ||
req.url += '&bewit=' + Hoek.base64urlEncode(bewit); | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MTE0ODQ2NDFcZm1CdkNWT3MvcElOTUUxSTIwbWhrejQ3UnBwTmo4Y1VrSHpQd3Q5OXJ1cz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080, | ||
authorization: 'Basic asdasdasdasd' | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid method'); | ||
done(); | ||
}); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Multiple authentications'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on invalid host header', function (done) { | ||
it('should fail on method other than GET', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
headers: { | ||
host: 'example.com:something' | ||
} | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var exp = Math.floor(Hawk.utils.now() / 1000) + 60; | ||
var ext = 'some-app-data'; | ||
var mac = Hawk.crypto.calculateMac('bewit', credentials, { | ||
timestamp: exp, | ||
nonce: '', | ||
method: req.method, | ||
resource: req.url, | ||
host: req.host, | ||
port: req.port, | ||
ext: ext | ||
}); | ||
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + ext; | ||
req.url += '&bewit=' + Hoek.base64urlEncode(bewit); | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
expect(err.output.payload.message).to.equal('Invalid method'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on empty bewit', function (done) { | ||
it('should fail on invalid host header', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
headers: { | ||
host: 'example.com:something' | ||
} | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Empty bewit'); | ||
expect(err.isMissing).to.not.exist(); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid Host header'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on invalid bewit', function (done) { | ||
it('should fail on empty bewit', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=*', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid bewit encoding'); | ||
expect(err.isMissing).to.not.exist(); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Empty bewit'); | ||
expect(err.isMissing).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on missing bewit', function (done) { | ||
it('should fail on invalid bewit', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=*', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.not.exist(); | ||
expect(err.isMissing).to.equal(true); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid bewit encoding'); | ||
expect(err.isMissing).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on invalid bewit structure', function (done) { | ||
it('should fail on missing bewit', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=abc', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid bewit structure'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.not.exist(); | ||
expect(err.isMissing).to.equal(true); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on empty bewit attribute', function (done) { | ||
it('should fail on invalid bewit structure', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=YVxcY1xk', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=abc', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing bewit attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Invalid bewit structure'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on missing bewit id attribute', function (done) { | ||
it('should fail on empty bewit attribute', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=XDQ1NTIxNDc2MjJcK0JFbFhQMXhuWjcvd1Nrbm1ldGhlZm5vUTNHVjZNSlFVRHk4NWpTZVJ4VT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=YVxcY1xk', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing bewit attributes'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing bewit attributes'); | ||
done(); | ||
}); | ||
it('should fail on expired access', function (done) { | ||
}); | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDEzNTY0MTg1ODNcWk1wZlMwWU5KNHV0WHpOMmRucTRydEk3NXNXTjFjeWVITTcrL0tNZFdVQT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
it('should fail on missing bewit id attribute', function (done) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=XDQ1NTIxNDc2MjJcK0JFbFhQMXhuWjcvd1Nrbm1ldGhlZm5vUTNHVjZNSlFVRHk4NWpTZVJ4VT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Access expired'); | ||
done(); | ||
}); | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Missing bewit attributes'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on credentials function error', function (done) { | ||
it('should fail on expired access', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?a=1&b=2&bewit=MTIzNDU2XDEzNTY0MTg1ODNcWk1wZlMwWU5KNHV0WHpOMmRucTRydEk3NXNXTjFjeWVITTcrL0tNZFdVQT1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(Hawk.error.badRequest('Boom')); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, credentialsFunc, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Boom'); | ||
done(); | ||
}); | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Access expired'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on credentials function error with credentials', function (done) { | ||
it('should fail on credentials function error', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(Hawk.error.badRequest('Boom'), { some: 'value' }); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Boom'); | ||
expect(credentials.some).to.equal('value'); | ||
done(); | ||
}); | ||
callback(Hawk.error.badRequest('Boom')); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Boom'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on null credentials function response', function (done) { | ||
it('should fail on credentials function error with credentials', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(null, null); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown credentials'); | ||
done(); | ||
}); | ||
callback(Hawk.error.badRequest('Boom'), { some: 'value' }); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Boom'); | ||
expect(credentials.some).to.equal('value'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on invalid credentials function response', function (done) { | ||
it('should fail on null credentials function response', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(null, {}); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
done(); | ||
}); | ||
callback(null, null); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Unknown credentials'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on invalid credentials function response (unknown algorithm)', function (done) { | ||
it('should fail on invalid credentials function response', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(null, { key: 'xxx', algorithm: 'xxx' }); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
callback(null, {}); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on expired access', function (done) { | ||
it('should fail on invalid credentials function response (unknown algorithm)', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { callback(null, { key: 'xxx', algorithm: 'sha256' }); }, {}, function (err, credentials, attributes) { | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad mac'); | ||
done(); | ||
}); | ||
callback(null, { key: 'xxx', algorithm: 'xxx' }); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
}); | ||
describe('#getBewit', function () { | ||
it('should fail on expired access', function (done) { | ||
var req = { | ||
method: 'GET', | ||
url: '/resource/4?bewit=MTIzNDU2XDQ1MDk5OTE3MTlcTUE2eWkwRWRwR0pEcWRwb0JkYVdvVDJrL0hDSzA1T0Y3MkhuZlVmVy96Zz1cc29tZS1hcHAtZGF0YQ', | ||
host: 'example.com', | ||
port: 8080 | ||
}; | ||
Hawk.uri.authenticate(req, function (id, callback) { | ||
callback(null, { key: 'xxx', algorithm: 'sha256' }); | ||
}, {}, function (err, credentials, attributes) { | ||
expect(err).to.exist(); | ||
expect(err.output.payload.message).to.equal('Bad mac'); | ||
done(); | ||
}); | ||
}); | ||
describe('getBewit()', function () { | ||
it('returns a valid bewit value', function (done) { | ||
@@ -592,3 +607,247 @@ | ||
}); | ||
describe('authenticateMessage()', function () { | ||
var credentialsFunc = function (id, callback) { | ||
var credentials = { | ||
id: id, | ||
key: 'werxhqb98rpaxn39848xrunpaw3489ruxnpa98w4rxn', | ||
algorithm: (id === '1' ? 'sha1' : 'sha256'), | ||
user: 'steve' | ||
}; | ||
return callback(null, credentials); | ||
}; | ||
it('should generate an authorization then successfully parse it', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.not.exist(); | ||
expect(credentials.user).to.equal('steve'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on mismatching host', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example1.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Bad mac'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on stale timestamp', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { localtimeOffsetMsec: 100000 }, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Stale timestamp'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('overrides timestampSkewSec', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials, localtimeOffsetMsec: 100000 }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { timestampSkewSec: 500 }, function (err, credentials) { | ||
expect(err).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on invalid authorization', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
delete auth.id; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid authorization'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on bad hash', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message1', auth, credentialsFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Bad message hash'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on nonce error', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, credentialsFunc, { | ||
nonceFunc: function (key, nonce, ts, callback) { | ||
callback(new Error('kaboom')); | ||
} | ||
}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid nonce'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on credentials error', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var errFunc = function (id, callback) { | ||
callback(new Error('kablooey')); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('kablooey'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on missing credentials', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var errFunc = function (id, callback) { | ||
callback(); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown credentials'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on invalid credentials', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var errFunc = function (id, callback) { | ||
callback(null, {}); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Invalid credentials'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail authorization on invalid credentials algorithm', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.exist(); | ||
var errFunc = function (id, callback) { | ||
callback(null, { key: '123', algorithm: '456' }); | ||
}; | ||
Hawk.server.authenticateMessage('example.com', 8080, 'some message', auth, errFunc, {}, function (err, credentials) { | ||
expect(err).to.exist(); | ||
expect(err.message).to.equal('Unknown algorithm'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
it('should fail on missing host', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var auth = Hawk.client.message(null, 8080, 'some message', { credentials: credentials }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
it('should fail on missing credentials', function (done) { | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', {}); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
it('should fail on invalid algorithm', function (done) { | ||
credentialsFunc('123456', function (err, credentials) { | ||
var creds = Hoek.clone(credentials); | ||
creds.algorithm = 'blah'; | ||
var auth = Hawk.client.message('example.com', 8080, 'some message', { credentials: creds }); | ||
expect(auth).to.not.exist(); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
@@ -22,100 +22,101 @@ // Load modules | ||
describe('Hawk', function () { | ||
describe('Utils', function () { | ||
describe('Utils', function () { | ||
describe('parseHost()', function () { | ||
describe('#parseHost', function () { | ||
it('returns port 80 for non tls node request', function (done) { | ||
it('returns port 80 for non tls node request', function (done) { | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com', | ||
'content-type': 'text/plain;x=y' | ||
} | ||
}; | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com', | ||
'content-type': 'text/plain;x=y' | ||
} | ||
}; | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(80); | ||
done(); | ||
}); | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(80); | ||
done(); | ||
}); | ||
it('returns port 443 for non tls node request', function (done) { | ||
it('returns port 443 for non tls node request', function (done) { | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: 'example.com', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); | ||
done(); | ||
}); | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); | ||
done(); | ||
}); | ||
it('returns port 443 for non tls node request (IPv6)', function (done) { | ||
it('returns port 443 for non tls node request (IPv6)', function (done) { | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: '[123:123:123]', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: '[123:123:123]', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); | ||
done(); | ||
}); | ||
expect(Hawk.utils.parseHost(req, 'Host').port).to.equal(443); | ||
done(); | ||
}); | ||
it('parses IPv6 headers', function (done) { | ||
it('parses IPv6 headers', function (done) { | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: '[123:123:123]:8000', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
var req = { | ||
method: 'POST', | ||
url: '/resource/4?filter=a', | ||
headers: { | ||
host: '[123:123:123]:8000', | ||
'content-type': 'text/plain;x=y' | ||
}, | ||
connection: { | ||
encrypted: true | ||
} | ||
}; | ||
var host = Hawk.utils.parseHost(req, 'Host'); | ||
expect(host.port).to.equal('8000'); | ||
expect(host.name).to.equal('[123:123:123]'); | ||
done(); | ||
}); | ||
var host = Hawk.utils.parseHost(req, 'Host'); | ||
expect(host.port).to.equal('8000'); | ||
expect(host.name).to.equal('[123:123:123]'); | ||
done(); | ||
}); | ||
}); | ||
describe('#version', function () { | ||
describe('version()', function () { | ||
it('returns the correct package version number', function (done) { | ||
it('returns the correct package version number', function (done) { | ||
expect(Hawk.utils.version()).to.equal(Package.version); | ||
done(); | ||
}); | ||
expect(Hawk.utils.version()).to.equal(Package.version); | ||
done(); | ||
}); | ||
}); | ||
describe('#unauthorized', function () { | ||
describe('unauthorized()', function () { | ||
it('returns a hawk 401', function (done) { | ||
it('returns a hawk 401', function (done) { | ||
expect(Hawk.utils.unauthorized('kaboom').output.headers['WWW-Authenticate']).to.equal('Hawk error="kaboom"'); | ||
done(); | ||
}); | ||
expect(Hawk.utils.unauthorized('kaboom').output.headers['WWW-Authenticate']).to.equal('Hawk error="kaboom"'); | ||
done(); | ||
}); | ||
it('supports attributes', function (done) { | ||
expect(Hawk.utils.unauthorized('kaboom', { a: 'b' }).output.headers['WWW-Authenticate']).to.equal('Hawk a="b", error="kaboom"'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
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
353313
4985
24
635