Socket
Socket
Sign inDemoInstall

hawk

Package Overview
Dependencies
Maintainers
1
Versions
85
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.13.1 to 0.14.0

test/message.js

0

example/usage.js

@@ -0,0 +0,0 @@ // Load modules

115

lib/browser.js

@@ -19,33 +19,33 @@ /*

// Generate an Authorization header for a given request
hawk.client = {
/*
uri: 'http://example.com/resource?a=b'
method: HTTP verb (e.g. 'GET', 'POST')
options: {
// Generate an Authorization header for a given request
// Required
/*
uri: 'http://example.com/resource?a=b'
method: HTTP verb (e.g. 'GET', 'POST')
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
// Optional
ext: 'application-specific', // Application specific data sent via the ext attribute
timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds
nonce: '2334f34f', // A pre-generated nonce
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
contentType: 'application/json', // Payload content-type (ignored if hash provided)
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
app: '24s23423f34dx', // Oz application id
dlg: '234sz34tww3sd' // Oz delegated-by application id
}
*/
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
// Optional
ext: 'application-specific', // Application specific data sent via the ext attribute
timestamp: Date.now() / 1000, // A pre-calculated timestamp in seconds
nonce: '2334f34f', // A pre-generated nonce
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
payload: '{"some":"payload"}', // UTF-8 encoded string for body hash generation (ignored if hash provided)
contentType: 'application/json', // Payload content-type (ignored if hash provided)
hash: 'U4MKKSmiVxk37JCCrAVIjV=', // Pre-calculated payload hash
app: '24s23423f34dx', // Oz application id
dlg: '234sz34tww3sd' // Oz delegated-by application id
}
*/
hawk.client = {
header: function (uri, method, options) {

@@ -216,2 +216,57 @@

return (calculatedHash === attributes.hash);
},
message: function (host, port, message, options) {
// Validate inputs
if (!host || typeof host !== 'string' ||
!port || typeof port !== 'number' ||
message === null || message === undefined || typeof message !== 'string' ||
!options || typeof options !== 'object') {
return null;
}
// Application time
var timestamp = options.timestamp || Math.floor((hawk.utils.now() + (options.localtimeOffsetMsec || 0)) / 1000)
// Validate credentials
var credentials = options.credentials;
if (!credentials ||
!credentials.id ||
!credentials.key ||
!credentials.algorithm) {
// Invalid credential object
return null;
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return null;
}
// Calculate signature
var artifacts = {
ts: timestamp,
nonce: options.nonce || hawk.utils.randomString(6),
host: host,
port: port,
hash: hawk.crypto.calculatePayloadHash(message, credentials.algorithm)
};
// Construct authorization
var result = {
id: credentials.id,
ts: artifacts.ts,
nonce: artifacts.nonce,
hash: artifacts.hash,
mac: hawk.crypto.calculateMac('message', credentials, artifacts)
};
return result;
}

@@ -240,4 +295,4 @@ };

options.nonce + '\n' +
options.method.toUpperCase() + '\n' +
options.resource + '\n' +
(options.method || '').toUpperCase() + '\n' +
(options.resource || '') + '\n' +
options.host.toLowerCase() + '\n' +

@@ -244,0 +299,0 @@ options.port + '\n' +

@@ -286,1 +286,83 @@ // Load modules

// Generate an authorization string for a message
/*
host: 'example.com',
port: 8000,
message: '{"some":"payload"}', // UTF-8 encoded string for body hash generation
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
// Optional
timestamp: Date.now(), // A pre-calculated timestamp
nonce: '2334f34f', // A pre-generated nonce
localtimeOffsetMsec: 400, // Time offset to sync with server time (ignored if timestamp provided)
}
*/
exports.message = function (host, port, message, options) {
// Validate inputs
if (!host || typeof host !== 'string' ||
!port || typeof port !== 'number' ||
message === null || message === undefined || typeof message !== 'string' ||
!options || typeof options !== 'object') {
return null;
}
// Application time
var timestamp = options.timestamp || Math.floor((Utils.now() + (options.localtimeOffsetMsec || 0)) / 1000)
// Validate credentials
var credentials = options.credentials;
if (!credentials ||
!credentials.id ||
!credentials.key ||
!credentials.algorithm) {
// Invalid credential object
return null;
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return null;
}
// Calculate signature
var artifacts = {
ts: timestamp,
nonce: options.nonce || Cryptiles.randomString(6),
host: host,
port: port,
hash: Crypto.calculatePayloadHash(message, credentials.algorithm)
};
// Construct authorization
var result = {
id: credentials.id,
ts: artifacts.ts,
nonce: artifacts.nonce,
hash: artifacts.hash,
mac: Crypto.calculateMac('message', credentials, artifacts)
};
return result;
};

@@ -60,4 +60,4 @@ // Load modules

options.nonce + '\n' +
options.method.toUpperCase() + '\n' +
options.resource + '\n' +
(options.method || '').toUpperCase() + '\n' +
(options.resource || '') + '\n' +
options.host.toLowerCase() + '\n' +

@@ -64,0 +64,0 @@ options.port + '\n' +

@@ -292,3 +292,3 @@ // Load modules

/*
* Arguments and options are the same as index.js with the exception that the only supported options are:
* Arguments and options are the same as authenticate() with the exception that the only supported options are:
* 'hostHeaderName', 'localtimeOffsetMsec'

@@ -426,1 +426,98 @@ */

};
/*
* options are the same as authenticate() with the exception that the only supported options are:
* 'nonceFunc', 'timestampSkewSec', 'localtimeOffsetMsec'
*/
exports.authenticateMessage = function (host, port, message, authorization, credentialsFunc, options, callback) {
callback = Utils.nextTick(callback);
// Default options
options.nonceFunc = options.nonceFunc || function (nonce, ts, nonceCallback) { return nonceCallback(); }; // No validation
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds
// Application time
var now = Utils.now() + (options.localtimeOffsetMsec || 0); // Measure now before any other processing
// Validate authorization
if (!authorization.id ||
!authorization.ts ||
!authorization.nonce ||
!authorization.hash ||
!authorization.mac) {
return callback(Boom.badRequest('Invalid authorization'))
}
// Fetch Hawk credentials
credentialsFunc(authorization.id, function (err, credentials) {
if (err) {
return callback(err, credentials || null);
}
if (!credentials) {
return callback(Boom.unauthorized('Unknown credentials', 'Hawk'));
}
if (!credentials.key ||
!credentials.algorithm) {
return callback(Boom.internal('Invalid credentials'), credentials);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return callback(Boom.internal('Unknown algorithm'), credentials);
}
// Construct artifacts container
var artifacts = {
ts: authorization.ts,
nonce: authorization.nonce,
host: host,
port: port,
hash: authorization.hash
};
// Calculate MAC
var mac = Crypto.calculateMac('message', credentials, artifacts);
if (!Cryptiles.fixedTimeComparison(mac, authorization.mac)) {
return callback(Boom.unauthorized('Bad mac', 'Hawk'), credentials);
}
// Check payload hash
var hash = Crypto.calculatePayloadHash(message, credentials.algorithm);
if (!Cryptiles.fixedTimeComparison(hash, authorization.hash)) {
return callback(Boom.unauthorized('Bad message hash', 'Hawk'), credentials);
}
// Check nonce
options.nonceFunc(authorization.nonce, authorization.ts, function (err) {
if (err) {
return callback(Boom.unauthorized('Invalid nonce', 'Hawk'), credentials);
}
// Check timestamp staleness
if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
return callback(Boom.unauthorized('Stale timestamp'), credentials);
}
// Successful authentication
return callback(null, credentials);
});
});
};

@@ -0,0 +0,0 @@ // Load modules

{
"name": "hawk",
"description": "HTTP Hawk Authentication Scheme",
"version": "0.13.1",
"version": "0.14.0",
"author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)",

@@ -19,3 +19,3 @@ "contributors": [],

"dependencies": {
"hoek": "0.8.x",
"hoek": "0.9.x",
"boom": "0.4.x",

@@ -22,0 +22,0 @@ "cryptiles": "0.2.x",

@@ -6,3 +6,3 @@ ![hawk Logo](https://raw.github.com/hueniverse/hawk/master/images/hawk.png)

Current version: **0.13**
Current version: **0.14**

@@ -9,0 +9,0 @@ [![Build Status](https://secure.travis-ci.org/hueniverse/hawk.png)](http://travis-ci.org/hueniverse/hawk)

// Load modules
var Lab = require('lab');
var Hoek = require('hoek');
var Hawk = require('../lib');

@@ -683,2 +684,49 @@ var Browser = require('../lib/browser');

});
describe('#message', function () {
it('should generate an authorization then successfully parse it', function (done) {
credentialsFunc('123456', function (err, credentials) {
var auth = Browser.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 on missing host', function (done) {
credentialsFunc('123456', function (err, credentials) {
var auth = Browser.client.message(null, 8080, 'some message', { credentials: credentials });
expect(auth).to.not.exist;
done();
});
});
it('should fail on missing credentials', function (done) {
var auth = Browser.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 = Browser.client.message('example.com', 8080, 'some message', { credentials: creds });
expect(auth).to.not.exist;
done();
});
});
});
});

@@ -685,0 +733,0 @@

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

@@ -0,0 +0,0 @@ // Load modules

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc