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

hawk - npm Package Compare versions

Comparing version 6.0.2 to 7.0.0

794

dist/browser.js

@@ -1,793 +0,1 @@

'use strict';
/*
HTTP Hawk Authentication Scheme
Copyright (c) 2012-2016, Eran Hammer <eran@hammer.io>
BSD Licensed
*/
// Declare namespace
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
var hawk = {
internals: {}
};
hawk.client = {
// Generate an Authorization header for a given request
/*
uri: 'http://example.com/resource?a=b' or object generated by hawk.utils.parseUri()
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
}
*/
header: function header(uri, method, options) {
var result = {
field: '',
artifacts: {}
};
// Validate inputs
if (!uri || typeof uri !== 'string' && (typeof uri === 'undefined' ? 'undefined' : _typeof(uri)) !== 'object' || !method || typeof method !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
result.err = 'Invalid argument type';
return result;
}
// Application time
var timestamp = options.timestamp || hawk.utils.nowSec(options.localtimeOffsetMsec);
// Validate credentials
var credentials = options.credentials;
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
result.err = 'Invalid credentials object';
return result;
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
result.err = 'Unknown algorithm';
return result;
}
// Parse URI
if (typeof uri === 'string') {
uri = hawk.utils.parseUri(uri);
}
// Calculate signature
var artifacts = {
ts: timestamp,
nonce: options.nonce || hawk.utils.randomString(6),
method: method,
resource: uri.resource,
host: uri.host,
port: uri.port,
hash: options.hash,
ext: options.ext,
app: options.app,
dlg: options.dlg
};
result.artifacts = artifacts;
// Calculate payload hash
if (!artifacts.hash && (options.payload || options.payload === '')) {
artifacts.hash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType);
}
var mac = hawk.crypto.calculateMac('header', credentials, artifacts);
// Construct header
var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed
var header = 'Hawk id="' + credentials.id + '", ts="' + artifacts.ts + '", nonce="' + artifacts.nonce + (artifacts.hash ? '", hash="' + artifacts.hash : '') + (hasExt ? '", ext="' + hawk.utils.escapeHeaderAttribute(artifacts.ext) : '') + '", mac="' + mac + '"';
if (artifacts.app) {
header += ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
}
result.field = header;
return result;
},
// Generate a bewit value for a given URI
/*
uri: 'http://example.com/resource?a=b'
options: {
// Required
credentials: {
id: 'dh37fgj492je',
key: 'aoijedoaijsdlaksjdl',
algorithm: 'sha256' // 'sha1', 'sha256'
},
ttlSec: 60 * 60, // TTL in seconds
// Optional
ext: 'application-specific', // Application specific data sent via the ext attribute
localtimeOffsetMsec: 400 // Time offset to sync with server time
};
*/
bewit: function bewit(uri, options) {
// Validate inputs
if (!uri || typeof uri !== 'string' || !options || (typeof options === 'undefined' ? 'undefined' : _typeof(options)) !== 'object' || !options.ttlSec) {
return '';
}
options.ext = options.ext === null || options.ext === undefined ? '' : options.ext; // Zero is valid value
// Application time
var now = hawk.utils.nowSec(options.localtimeOffsetMsec);
// Validate credentials
var credentials = options.credentials;
if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
return '';
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return '';
}
// Parse URI
uri = hawk.utils.parseUri(uri);
// Calculate signature
var exp = now + options.ttlSec;
var mac = hawk.crypto.calculateMac('bewit', credentials, {
ts: exp,
nonce: '',
method: 'GET',
resource: uri.resource, // Maintain trailing '?' and query params
host: uri.host,
port: uri.port,
ext: options.ext
});
// Construct bewit: id\exp\mac\ext
var bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext;
return hawk.utils.base64urlEncode(bewit);
},
// Validate server response
/*
request: object created via 'new XMLHttpRequest()' after response received or fetch API 'Response'
artifacts: object received from header().artifacts
options: {
payload: optional payload received
required: specifies if a Server-Authorization header is required. Defaults to 'false'
}
*/
authenticate: function authenticate(request, credentials, artifacts, options) {
options = options || {};
var getHeader = function getHeader(name) {
// Fetch API or plain headers
if (request.headers) {
return typeof request.headers.get === 'function' ? request.headers.get(name) : request.headers[name];
}
// XMLHttpRequest
return request.getResponseHeader ? request.getResponseHeader(name) : request.getHeader(name);
};
var wwwAuthenticate = getHeader('www-authenticate');
if (wwwAuthenticate) {
// Parse HTTP WWW-Authenticate header
var wwwAttributes = hawk.utils.parseAuthorizationHeader(wwwAuthenticate, ['ts', 'tsm', 'error']);
if (!wwwAttributes) {
return false;
}
if (wwwAttributes.ts) {
var tsm = hawk.crypto.calculateTsMac(wwwAttributes.ts, credentials);
if (tsm !== wwwAttributes.tsm) {
return false;
}
hawk.utils.setNtpSecOffset(wwwAttributes.ts - Math.floor(Date.now() / 1000)); // Keep offset at 1 second precision
}
}
// Parse HTTP Server-Authorization header
var serverAuthorization = getHeader('server-authorization');
if (!serverAuthorization && !options.required) {
return true;
}
var attributes = hawk.utils.parseAuthorizationHeader(serverAuthorization, ['mac', 'ext', 'hash']);
if (!attributes) {
return false;
}
var modArtifacts = {
ts: artifacts.ts,
nonce: artifacts.nonce,
method: artifacts.method,
resource: artifacts.resource,
host: artifacts.host,
port: artifacts.port,
hash: attributes.hash,
ext: attributes.ext,
app: artifacts.app,
dlg: artifacts.dlg
};
var mac = hawk.crypto.calculateMac('response', credentials, modArtifacts);
if (mac !== attributes.mac) {
return false;
}
if (!options.payload && options.payload !== '') {
return true;
}
if (!attributes.hash) {
return false;
}
var calculatedHash = hawk.crypto.calculatePayloadHash(options.payload, credentials.algorithm, getHeader('content-type'));
return calculatedHash === attributes.hash;
},
message: function message(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 === 'undefined' ? 'undefined' : _typeof(options)) !== 'object') {
return null;
}
// Application time
var timestamp = options.timestamp || hawk.utils.nowSec(options.localtimeOffsetMsec);
// 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;
},
authenticateTimestamp: function authenticateTimestamp(message, credentials, updateClock) {
// updateClock defaults to true
var tsm = hawk.crypto.calculateTsMac(message.ts, credentials);
if (tsm !== message.tsm) {
return false;
}
if (updateClock !== false) {
hawk.utils.setNtpSecOffset(message.ts - Math.floor(Date.now() / 1000)); // Keep offset at 1 second precision
}
return true;
}
};
hawk.crypto = {
headerVersion: '1',
algorithms: ['sha1', 'sha256'],
calculateMac: function calculateMac(type, credentials, options) {
var normalized = hawk.crypto.generateNormalizedString(type, options);
var hmac = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()](normalized, credentials.key);
return hmac.toString(CryptoJS.enc.Base64);
},
generateNormalizedString: function generateNormalizedString(type, options) {
var normalized = 'hawk.' + hawk.crypto.headerVersion + '.' + type + '\n' + options.ts + '\n' + options.nonce + '\n' + (options.method || '').toUpperCase() + '\n' + (options.resource || '') + '\n' + options.host.toLowerCase() + '\n' + options.port + '\n' + (options.hash || '') + '\n';
if (options.ext) {
normalized += options.ext.replace('\\', '\\\\').replace('\n', '\\n');
}
normalized += '\n';
if (options.app) {
normalized += options.app + '\n' + (options.dlg || '') + '\n';
}
return normalized;
},
calculatePayloadHash: function calculatePayloadHash(payload, algorithm, contentType) {
var hash = CryptoJS.algo[algorithm.toUpperCase()].create();
hash.update('hawk.' + hawk.crypto.headerVersion + '.payload\n');
hash.update(hawk.utils.parseContentType(contentType) + '\n');
hash.update(payload);
hash.update('\n');
return hash.finalize().toString(CryptoJS.enc.Base64);
},
calculateTsMac: function calculateTsMac(ts, credentials) {
var hash = CryptoJS['Hmac' + credentials.algorithm.toUpperCase()]('hawk.' + hawk.crypto.headerVersion + '.ts\n' + ts + '\n', credentials.key);
return hash.toString(CryptoJS.enc.Base64);
}
};
// localStorage compatible interface
hawk.internals.LocalStorage = function () {
this._cache = {};
this.length = 0;
this.getItem = function (key) {
return this._cache.hasOwnProperty(key) ? String(this._cache[key]) : null;
};
this.setItem = function (key, value) {
this._cache[key] = String(value);
this.length = Object.keys(this._cache).length;
};
this.removeItem = function (key) {
delete this._cache[key];
this.length = Object.keys(this._cache).length;
};
this.clear = function () {
this._cache = {};
this.length = 0;
};
this.key = function (i) {
return Object.keys(this._cache)[i || 0];
};
};
hawk.utils = {
storage: new hawk.internals.LocalStorage(),
setStorage: function setStorage(storage) {
var ntpOffset = hawk.utils.storage.getItem('hawk_ntp_offset');
hawk.utils.storage = storage;
if (ntpOffset) {
hawk.utils.setNtpSecOffset(ntpOffset);
}
},
setNtpSecOffset: function setNtpSecOffset(offset) {
try {
hawk.utils.storage.setItem('hawk_ntp_offset', offset);
} catch (err) {
console.error('[hawk] could not write to storage.');
console.error(err);
}
},
getNtpSecOffset: function getNtpSecOffset() {
var offset = hawk.utils.storage.getItem('hawk_ntp_offset');
if (!offset) {
return 0;
}
return parseInt(offset, 10);
},
now: function now(localtimeOffsetMsec) {
return Date.now() + (localtimeOffsetMsec || 0) + hawk.utils.getNtpSecOffset() * 1000;
},
nowSec: function nowSec(localtimeOffsetMsec) {
return Math.floor(hawk.utils.now(localtimeOffsetMsec) / 1000);
},
escapeHeaderAttribute: function escapeHeaderAttribute(attribute) {
return attribute.replace(/\\/g, '\\\\').replace(/\"/g, '\\"');
},
parseContentType: function parseContentType(header) {
if (!header) {
return '';
}
return header.split(';')[0].replace(/^\s+|\s+$/g, '').toLowerCase();
},
parseAuthorizationHeader: function parseAuthorizationHeader(header, keys) {
if (!header) {
return null;
}
var headerParts = header.match(/^(\w+)(?:\s+(.*))?$/); // Header: scheme[ something]
if (!headerParts) {
return null;
}
var scheme = headerParts[1];
if (scheme.toLowerCase() !== 'hawk') {
return null;
}
var attributesString = headerParts[2];
if (!attributesString) {
return null;
}
var attributes = {};
var verify = attributesString.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g, function ($0, $1, $2) {
// Check valid attribute names
if (keys.indexOf($1) === -1) {
return;
}
// Allowed attribute value characters: !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9
if ($2.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/) === null) {
return;
}
// Check for duplicates
if (attributes.hasOwnProperty($1)) {
return;
}
attributes[$1] = $2;
return '';
});
if (verify !== '') {
return null;
}
return attributes;
},
randomString: function randomString(size) {
var randomSource = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var len = randomSource.length;
var result = [];
for (var i = 0; i < size; ++i) {
result[i] = randomSource[Math.floor(Math.random() * len)];
}
return result.join('');
},
// 1 2 3 4
uriRegex: /^([^:]+)\:\/\/(?:[^@/]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/, // scheme://credentials@host:port/resource#fragment
parseUri: function parseUri(input) {
var parts = input.match(hawk.utils.uriRegex);
if (!parts) {
return { host: '', port: '', resource: '' };
}
var scheme = parts[1].toLowerCase();
var uri = {
host: parts[2],
port: parts[3] || (scheme === 'http' ? '80' : scheme === 'https' ? '443' : ''),
resource: parts[4]
};
return uri;
},
base64urlEncode: function base64urlEncode(value) {
var wordArray = CryptoJS.enc.Utf8.parse(value);
var encoded = CryptoJS.enc.Base64.stringify(wordArray);
return encoded.replace(/\+/g, '-').replace(/\//g, '_').replace(/\=/g, '');
}
};
// $lab:coverage:off$
/* eslint-disable */
// Based on: Crypto-JS v3.1.2
// Copyright (c) 2009-2013, Jeff Mott. All rights reserved.
// http://code.google.com/p/crypto-js/
// http://code.google.com/p/crypto-js/wiki/License
var CryptoJS = CryptoJS || function (h, r) {
var k = {},
l = k.lib = {},
n = function n() {},
f = l.Base = { extend: function extend(a) {
n.prototype = this;var b = new n();a && b.mixIn(a);b.hasOwnProperty("init") || (b.init = function () {
b.$super.init.apply(this, arguments);
});b.init.prototype = b;b.$super = this;return b;
}, create: function create() {
var a = this.extend();a.init.apply(a, arguments);return a;
}, init: function init() {}, mixIn: function mixIn(a) {
for (var _b in a) {
a.hasOwnProperty(_b) && (this[_b] = a[_b]);
}a.hasOwnProperty("toString") && (this.toString = a.toString);
}, clone: function clone() {
return this.init.prototype.extend(this);
} },
j = l.WordArray = f.extend({ init: function init(a, b) {
a = this.words = a || [];this.sigBytes = b != r ? b : 4 * a.length;
}, toString: function toString(a) {
return (a || s).stringify(this);
}, concat: function concat(a) {
var b = this.words,
d = a.words,
c = this.sigBytes;a = a.sigBytes;this.clamp();if (c % 4) for (var e = 0; e < a; e++) {
b[c + e >>> 2] |= (d[e >>> 2] >>> 24 - 8 * (e % 4) & 255) << 24 - 8 * ((c + e) % 4);
} else if (65535 < d.length) for (var _e = 0; _e < a; _e += 4) {
b[c + _e >>> 2] = d[_e >>> 2];
} else b.push.apply(b, d);this.sigBytes += a;return this;
}, clamp: function clamp() {
var a = this.words,
b = this.sigBytes;a[b >>> 2] &= 4294967295 << 32 - 8 * (b % 4);a.length = h.ceil(b / 4);
}, clone: function clone() {
var a = f.clone.call(this);a.words = this.words.slice(0);return a;
}, random: function random(a) {
for (var _b2 = [], d = 0; d < a; d += 4) {
_b2.push(4294967296 * h.random() | 0);
}return new j.init(b, a);
} }),
m = k.enc = {},
s = m.Hex = { stringify: function stringify(a) {
var b = a.words;a = a.sigBytes;for (var d = [], c = 0; c < a; c++) {
var e = b[c >>> 2] >>> 24 - 8 * (c % 4) & 255;d.push((e >>> 4).toString(16));d.push((e & 15).toString(16));
}return d.join("");
}, parse: function parse(a) {
for (var b = a.length, d = [], c = 0; c < b; c += 2) {
d[c >>> 3] |= parseInt(a.substr(c, 2), 16) << 24 - 4 * (c % 8);
}return new j.init(d, b / 2);
} },
p = m.Latin1 = { stringify: function stringify(a) {
var b = a.words;a = a.sigBytes;for (var d = [], c = 0; c < a; c++) {
d.push(String.fromCharCode(b[c >>> 2] >>> 24 - 8 * (c % 4) & 255));
}return d.join("");
}, parse: function parse(a) {
for (var b = a.length, d = [], c = 0; c < b; c++) {
d[c >>> 2] |= (a.charCodeAt(c) & 255) << 24 - 8 * (c % 4);
}return new j.init(d, b);
} },
t = m.Utf8 = { stringify: function stringify(a) {
try {
return decodeURIComponent(escape(p.stringify(a)));
} catch (b) {
throw Error("Malformed UTF-8 data");
}
}, parse: function parse(a) {
return p.parse(unescape(encodeURIComponent(a)));
} },
q = l.BufferedBlockAlgorithm = f.extend({ reset: function reset() {
this._data = new j.init();this._nDataBytes = 0;
}, _append: function _append(a) {
"string" == typeof a && (a = t.parse(a));this._data.concat(a);this._nDataBytes += a.sigBytes;
}, _process: function _process(a) {
var b = this._data,
d = b.words,
c = b.sigBytes,
e = this.blockSize,
f = c / (4 * e),
f = a ? h.ceil(f) : h.max((f | 0) - this._minBufferSize, 0);a = f * e;c = h.min(4 * a, c);if (a) {
for (var g = 0; g < a; g += e) {
this._doProcessBlock(d, g);
}g = d.splice(0, a);b.sigBytes -= c;
}return new j.init(g, c);
}, clone: function clone() {
var a = f.clone.call(this);a._data = this._data.clone();return a;
}, _minBufferSize: 0 });l.Hasher = q.extend({ cfg: f.extend(), init: function init(a) {
this.cfg = this.cfg.extend(a);this.reset();
}, reset: function reset() {
q.reset.call(this);this._doReset();
}, update: function update(a) {
this._append(a);this._process();return this;
}, finalize: function finalize(a) {
a && this._append(a);return this._doFinalize();
}, blockSize: 16, _createHelper: function _createHelper(a) {
return function (b, d) {
return new a.init(d).finalize(b);
};
}, _createHmacHelper: function _createHmacHelper(a) {
return function (b, d) {
return new u.HMAC.init(a, d).finalize(b);
};
} });var u = k.algo = {};return k;
}(Math);
(function () {
var k = CryptoJS,
b = k.lib,
m = b.WordArray,
l = b.Hasher,
d = [],
b = k.algo.SHA1 = l.extend({ _doReset: function _doReset() {
this._hash = new m.init([1732584193, 4023233417, 2562383102, 271733878, 3285377520]);
}, _doProcessBlock: function _doProcessBlock(n, p) {
for (var a = this._hash.words, e = a[0], f = a[1], h = a[2], j = a[3], b = a[4], c = 0; 80 > c; c++) {
if (16 > c) d[c] = n[p + c] | 0;else {
var g = d[c - 3] ^ d[c - 8] ^ d[c - 14] ^ d[c - 16];d[c] = g << 1 | g >>> 31;
}g = (e << 5 | e >>> 27) + b + d[c];g = 20 > c ? g + ((f & h | ~f & j) + 1518500249) : 40 > c ? g + ((f ^ h ^ j) + 1859775393) : 60 > c ? g + ((f & h | f & j | h & j) - 1894007588) : g + ((f ^ h ^ j) - 899497514);b = j;j = h;h = f << 30 | f >>> 2;f = e;e = g;
}a[0] = a[0] + e | 0;a[1] = a[1] + f | 0;a[2] = a[2] + h | 0;a[3] = a[3] + j | 0;a[4] = a[4] + b | 0;
}, _doFinalize: function _doFinalize() {
var b = this._data,
d = b.words,
a = 8 * this._nDataBytes,
e = 8 * b.sigBytes;d[e >>> 5] |= 128 << 24 - e % 32;d[(e + 64 >>> 9 << 4) + 14] = Math.floor(a / 4294967296);d[(e + 64 >>> 9 << 4) + 15] = a;b.sigBytes = 4 * d.length;this._process();return this._hash;
}, clone: function clone() {
var b = l.clone.call(this);b._hash = this._hash.clone();return b;
} });k.SHA1 = l._createHelper(b);k.HmacSHA1 = l._createHmacHelper(b);
})();
(function (k) {
for (var g = CryptoJS, h = g.lib, v = h.WordArray, j = h.Hasher, h = g.algo, s = [], t = [], u = function u(q) {
return 4294967296 * (q - (q | 0)) | 0;
}, l = 2, b = 0; 64 > b;) {
var d;a: {
d = l;for (var w = k.sqrt(d), r = 2; r <= w; r++) {
if (!(d % r)) {
d = !1;break a;
}
}d = !0;
}d && (8 > b && (s[b] = u(k.pow(l, 0.5))), t[b] = u(k.pow(l, 1 / 3)), b++);l++;
}var n = [],
h = h.SHA256 = j.extend({ _doReset: function _doReset() {
this._hash = new v.init(s.slice(0));
}, _doProcessBlock: function _doProcessBlock(q, h) {
for (var a = this._hash.words, c = a[0], d = a[1], b = a[2], k = a[3], f = a[4], g = a[5], j = a[6], l = a[7], e = 0; 64 > e; e++) {
if (16 > e) n[e] = q[h + e] | 0;else {
var m = n[e - 15],
p = n[e - 2];n[e] = ((m << 25 | m >>> 7) ^ (m << 14 | m >>> 18) ^ m >>> 3) + n[e - 7] + ((p << 15 | p >>> 17) ^ (p << 13 | p >>> 19) ^ p >>> 10) + n[e - 16];
}m = l + ((f << 26 | f >>> 6) ^ (f << 21 | f >>> 11) ^ (f << 7 | f >>> 25)) + (f & g ^ ~f & j) + t[e] + n[e];p = ((c << 30 | c >>> 2) ^ (c << 19 | c >>> 13) ^ (c << 10 | c >>> 22)) + (c & d ^ c & b ^ d & b);l = j;j = g;g = f;f = k + m | 0;k = b;b = d;d = c;c = m + p | 0;
}a[0] = a[0] + c | 0;a[1] = a[1] + d | 0;a[2] = a[2] + b | 0;a[3] = a[3] + k | 0;a[4] = a[4] + f | 0;a[5] = a[5] + g | 0;a[6] = a[6] + j | 0;a[7] = a[7] + l | 0;
}, _doFinalize: function _doFinalize() {
var d = this._data,
b = d.words,
a = 8 * this._nDataBytes,
c = 8 * d.sigBytes;b[c >>> 5] |= 128 << 24 - c % 32;b[(c + 64 >>> 9 << 4) + 14] = k.floor(a / 4294967296);b[(c + 64 >>> 9 << 4) + 15] = a;d.sigBytes = 4 * b.length;this._process();return this._hash;
}, clone: function clone() {
var b = j.clone.call(this);b._hash = this._hash.clone();return b;
} });g.SHA256 = j._createHelper(h);g.HmacSHA256 = j._createHmacHelper(h);
})(Math);
(function () {
var c = CryptoJS,
k = c.enc.Utf8;c.algo.HMAC = c.lib.Base.extend({ init: function init(a, b) {
a = this._hasher = new a.init();"string" == typeof b && (b = k.parse(b));var c = a.blockSize,
e = 4 * c;b.sigBytes > e && (b = a.finalize(b));b.clamp();for (var f = this._oKey = b.clone(), g = this._iKey = b.clone(), h = f.words, j = g.words, d = 0; d < c; d++) {
h[d] ^= 1549556828, j[d] ^= 909522486;
}f.sigBytes = g.sigBytes = e;this.reset();
}, reset: function reset() {
var a = this._hasher;a.reset();a.update(this._iKey);
}, update: function update(a) {
this._hasher.update(a);return this;
}, finalize: function finalize(a) {
var b = this._hasher;a = b.finalize(a);b.reset();return b.finalize(this._oKey.clone().concat(a));
} });
})();
(function () {
var h = CryptoJS,
j = h.lib.WordArray;h.enc.Base64 = { stringify: function stringify(b) {
var e = b.words,
f = b.sigBytes,
c = this._map;b.clamp();b = [];for (var a = 0; a < f; a += 3) {
for (var d = (e[a >>> 2] >>> 24 - 8 * (a % 4) & 255) << 16 | (e[a + 1 >>> 2] >>> 24 - 8 * ((a + 1) % 4) & 255) << 8 | e[a + 2 >>> 2] >>> 24 - 8 * ((a + 2) % 4) & 255, g = 0; 4 > g && a + 0.75 * g < f; g++) {
b.push(c.charAt(d >>> 6 * (3 - g) & 63));
}
}if (e = c.charAt(64)) for (; b.length % 4;) {
b.push(e);
}return b.join("");
}, parse: function parse(b) {
var e = b.length,
f = this._map,
c = f.charAt(64);c && (c = b.indexOf(c), -1 != c && (e = c));for (var c = [], a = 0, d = 0; d < e; d++) {
if (d % 4) {
var g = f.indexOf(b.charAt(d - 1)) << 2 * (d % 4),
h = f.indexOf(b.charAt(d)) >>> 6 - 2 * (d % 4);c[a >>> 2] |= (g | h) << 24 - 8 * (a % 4);a++;
}
}return j.create(c, a);
}, _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=" };
})();
hawk.crypto.utils = CryptoJS;
// Export if used as a module
if (typeof module !== 'undefined' && module.exports) {
module.exports = hawk;
}
/* eslint-enable */
// $lab:coverage:on$
'use strict';var _typeof='function'==typeof Symbol&&'symbol'==typeof Symbol.iterator?function(c){return typeof c}:function(c){return c&&'function'==typeof Symbol&&c.constructor===Symbol&&c!==Symbol.prototype?'symbol':typeof c},hawk={internals:{}};hawk.client={header:function(c,d,e){if(!c||'string'!=typeof c&&'object'!==('undefined'==typeof c?'undefined':_typeof(c))||!d||'string'!=typeof d||!e||'object'!==('undefined'==typeof e?'undefined':_typeof(e)))throw new Error('Invalid argument type');var f=e.timestamp||hawk.utils.nowSec(e.localtimeOffsetMsec),g=e.credentials;if(!g||!g.id||!g.key||!g.algorithm)throw new Error('Invalid credentials');if(-1===hawk.crypto.algorithms.indexOf(g.algorithm))throw new Error('Unknown algorithm');'string'==typeof c&&(c=hawk.utils.parseUri(c));var h={ts:f,nonce:e.nonce||hawk.utils.randomString(6),method:d,resource:c.resource,host:c.host,port:c.port,hash:e.hash,ext:e.ext,app:e.app,dlg:e.dlg};!h.hash&&(e.payload||''===e.payload)&&(h.hash=hawk.crypto.calculatePayloadHash(e.payload,g.algorithm,e.contentType));var i=hawk.crypto.calculateMac('header',g,h),j=null!==h.ext&&void 0!==h.ext&&''!==h.ext,k='Hawk id="'+g.id+'", ts="'+h.ts+'", nonce="'+h.nonce+(h.hash?'", hash="'+h.hash:'')+(j?'", ext="'+hawk.utils.escapeHeaderAttribute(h.ext):'')+'", mac="'+i+'"';return h.app&&(k+=', app="'+h.app+(h.dlg?'", dlg="'+h.dlg:'')+'"'),{artifacts:h,header:k}},bewit:function(c,d){if(!c||'string'!=typeof c||!d||'object'!==('undefined'==typeof d?'undefined':_typeof(d))||!d.ttlSec)throw new Error('Invalid inputs');d.ext=null===d.ext||d.ext===void 0?'':d.ext;var e=hawk.utils.nowSec(d.localtimeOffsetMsec),f=d.credentials;if(!f||!f.id||!f.key||!f.algorithm)throw new Error('Invalid credentials');if(-1===hawk.crypto.algorithms.indexOf(f.algorithm))throw new Error('Unknown algorithm');c=hawk.utils.parseUri(c);var g=e+d.ttlSec,h=hawk.crypto.calculateMac('bewit',f,{ts:g,nonce:'',method:'GET',resource:c.resource,host:c.host,port:c.port,ext:d.ext}),i=f.id+'\\'+g+'\\'+h+'\\'+d.ext;return hawk.utils.base64urlEncode(i)},authenticate:function authenticate(c,d,e,f){f=f||{};var g=function(d){return c.headers?'function'==typeof c.headers.get?c.headers.get(d):c.headers[d]:c.getResponseHeader?c.getResponseHeader(d):c.getHeader(d)},h=g('www-authenticate');if(h){var n=hawk.utils.parseAuthorizationHeader(h,['ts','tsm','error']);if(!n)return!1;if(n.ts){var o=hawk.crypto.calculateTsMac(n.ts,d);if(o!==n.tsm)return!1;hawk.utils.setNtpSecOffset(n.ts-Math.floor(Date.now()/1e3))}}var i=g('server-authorization');if(!i&&!f.required)return!0;var j=hawk.utils.parseAuthorizationHeader(i,['mac','ext','hash']);if(!j)return!1;var k={ts:e.ts,nonce:e.nonce,method:e.method,resource:e.resource,host:e.host,port:e.port,hash:j.hash,ext:j.ext,app:e.app,dlg:e.dlg},l=hawk.crypto.calculateMac('response',d,k);if(l!==j.mac)return!1;if(!f.payload&&''!==f.payload)return!0;if(!j.hash)return!1;var m=hawk.crypto.calculatePayloadHash(f.payload,d.algorithm,g('content-type'));return m===j.hash},message:function message(c,d,e,f){if(!c||'string'!=typeof c||!d||'number'!=typeof d||null===e||e===void 0||'string'!=typeof e||!f||'object'!==('undefined'==typeof f?'undefined':_typeof(f)))throw new Error('Invalid inputs');var g=f.timestamp||hawk.utils.nowSec(f.localtimeOffsetMsec),h=f.credentials;if(!h||!h.id||!h.key||!h.algorithm)throw new Error('Invalid credentials');if(-1===hawk.crypto.algorithms.indexOf(h.algorithm))throw new Error('Unknown algorithm');var i={ts:g,nonce:f.nonce||hawk.utils.randomString(6),host:c,port:d,hash:hawk.crypto.calculatePayloadHash(e,h.algorithm)},j={id:h.id,ts:i.ts,nonce:i.nonce,hash:i.hash,mac:hawk.crypto.calculateMac('message',h,i)};return j},authenticateTimestamp:function authenticateTimestamp(c,d,e){var f=hawk.crypto.calculateTsMac(c.ts,d);return!(f!==c.tsm)&&(!1!==e&&hawk.utils.setNtpSecOffset(c.ts-Math.floor(Date.now()/1e3)),!0)}},hawk.crypto={headerVersion:'1',algorithms:['sha1','sha256'],calculateMac:function calculateMac(c,d,e){var f=hawk.crypto.generateNormalizedString(c,e),g=CryptoJS['Hmac'+d.algorithm.toUpperCase()](f,d.key);return g.toString(CryptoJS.enc.Base64)},generateNormalizedString:function generateNormalizedString(c,d){var e='hawk.'+hawk.crypto.headerVersion+'.'+c+'\n'+d.ts+'\n'+d.nonce+'\n'+(d.method||'').toUpperCase()+'\n'+(d.resource||'')+'\n'+d.host.toLowerCase()+'\n'+d.port+'\n'+(d.hash||'')+'\n';return d.ext&&(e+=d.ext.replace('\\','\\\\').replace('\n','\\n')),e+='\n',d.app&&(e+=d.app+'\n'+(d.dlg||'')+'\n'),e},calculatePayloadHash:function calculatePayloadHash(c,d,e){var f=CryptoJS.algo[d.toUpperCase()].create();return f.update('hawk.'+hawk.crypto.headerVersion+'.payload\n'),f.update(hawk.utils.parseContentType(e)+'\n'),f.update(c),f.update('\n'),f.finalize().toString(CryptoJS.enc.Base64)},calculateTsMac:function calculateTsMac(c,d){var e=CryptoJS['Hmac'+d.algorithm.toUpperCase()]('hawk.'+hawk.crypto.headerVersion+'.ts\n'+c+'\n',d.key);return e.toString(CryptoJS.enc.Base64)}},hawk.internals.LocalStorage=function(){this._cache={},this.length=0,this.getItem=function(c){return this._cache.hasOwnProperty(c)?this._cache[c]+'':null},this.setItem=function(c,d){this._cache[c]=d+'',this.length=Object.keys(this._cache).length},this.removeItem=function(c){delete this._cache[c],this.length=Object.keys(this._cache).length},this.clear=function(){this._cache={},this.length=0},this.key=function(c){return Object.keys(this._cache)[c||0]}},hawk.utils={storage:new hawk.internals.LocalStorage,setStorage:function setStorage(c){var d=hawk.utils.storage.getItem('hawk_ntp_offset');hawk.utils.storage=c,d&&hawk.utils.setNtpSecOffset(d)},setNtpSecOffset:function setNtpSecOffset(c){try{hawk.utils.storage.setItem('hawk_ntp_offset',c)}catch(c){console.error('[hawk] could not write to storage.'),console.error(c)}},getNtpSecOffset:function getNtpSecOffset(){var c=hawk.utils.storage.getItem('hawk_ntp_offset');return c?parseInt(c,10):0},now:function now(c){return Date.now()+(c||0)+1e3*hawk.utils.getNtpSecOffset()},nowSec:function nowSec(c){return Math.floor(hawk.utils.now(c)/1e3)},escapeHeaderAttribute:function escapeHeaderAttribute(c){return c.replace(/\\/g,'\\\\').replace(/\"/g,'\\"')},parseContentType:function parseContentType(c){return c?c.split(';')[0].replace(/^\s+|\s+$/g,'').toLowerCase():''},parseAuthorizationHeader:function parseAuthorizationHeader(c,d){if(!c)return null;var e=c.match(/^(\w+)(?:\s+(.*))?$/);if(!e)return null;var f=e[1];if('hawk'!==f.toLowerCase())return null;var g=e[2];if(!g)return null;var h={},i=g.replace(/(\w+)="([^"\\]*)"\s*(?:,\s*|$)/g,function(c,e,f){if(-1!==d.indexOf(e))return null===f.match(/^[ \w\!#\$%&'\(\)\*\+,\-\.\/\:;<\=>\?@\[\]\^`\{\|\}~]+$/)||h.hasOwnProperty(e)?void 0:(h[e]=f,'')});return''===i?h:null},randomString:function randomString(c){for(var d='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789',e=d.length,f=[],g=0;g<c;++g)f[g]=d[Math.floor(Math.random()*e)];return result.join('')},uriRegex:/^([^:]+)\:\/\/(?:[^@/]*@)?([^\/:]+)(?:\:(\d+))?([^#]*)(?:#.*)?$/,parseUri:function parseUri(c){var d=c.match(hawk.utils.uriRegex);if(!d)return{host:'',port:'',resource:''};var e=d[1].toLowerCase(),f={host:d[2],port:d[3]||('http'===e?'80':'https'===e?'443':''),resource:d[4]};return f},base64urlEncode:function base64urlEncode(c){var d=CryptoJS.enc.Utf8.parse(c),e=CryptoJS.enc.Base64.stringify(d);return e.replace(/\+/g,'-').replace(/\//g,'_').replace(/\=/g,'')}};var CryptoJS=CryptoJS||function(i,c){var d={},e=d.lib={},g=function(){},h=e.Base={extend:function extend(c){g.prototype=this;var d=new g;return c&&d.mixIn(c),d.hasOwnProperty('init')||(d.init=function(){d.$super.init.apply(this,arguments)}),d.init.prototype=d,d.$super=this,d},create:function create(){var c=this.extend();return c.init.apply(c,arguments),c},init:function init(){},mixIn:function mixIn(c){for(var d in c)c.hasOwnProperty(d)&&(this[d]=c[d]);c.hasOwnProperty('toString')&&(this.toString=c.toString)},clone:function clone(){return this.init.prototype.extend(this)}},k=e.WordArray=h.extend({init:function init(d,e){d=this.words=d||[],this.sigBytes=e==c?4*d.length:e},toString:function toString(c){return(c||j).stringify(this)},concat:function concat(f){var g=this.words,h=f.words,d=this.sigBytes;if(f=f.sigBytes,this.clamp(),d%4)for(var c=0;c<f;c++)g[d+c>>>2]|=(255&h[c>>>2]>>>24-8*(c%4))<<24-8*((d+c)%4);else if(65535<h.length)for(var e=0;e<f;e+=4)g[d+e>>>2]=h[e>>>2];else g.push.apply(g,h);return this.sigBytes+=f,this},clamp:function clamp(){var c=this.words,d=this.sigBytes;c[d>>>2]&=4294967295<<32-8*(d%4),c.length=i.ceil(d/4)},clone:function clone(){var c=h.clone.call(this);return c.words=this.words.slice(0),c},random:function random(c){for(var e=[],f=0;f<c;f+=4)e.push(0|4294967296*i.random());return new k.init(b,c)}}),f=d.enc={},j=f.Hex={stringify:function stringify(f){var g=f.words;f=f.sigBytes;for(var h,e=[],d=0;d<f;d++)h=255&g[d>>>2]>>>24-8*(d%4),e.push((h>>>4).toString(16)),e.push((15&h).toString(16));return e.join('')},parse:function parse(e){for(var f=e.length,g=[],d=0;d<f;d+=2)g[d>>>3]|=parseInt(e.substr(d,2),16)<<24-4*(d%8);return new k.init(g,f/2)}},l=f.Latin1={stringify:function stringify(e){var f=e.words;e=e.sigBytes;for(var g=[],d=0;d<e;d++)g.push(String.fromCharCode(255&f[d>>>2]>>>24-8*(d%4)));return g.join('')},parse:function parse(e){for(var f=e.length,g=[],d=0;d<f;d++)g[d>>>2]|=(255&e.charCodeAt(d))<<24-8*(d%4);return new k.init(g,f)}},m=f.Utf8={stringify:function stringify(c){try{return decodeURIComponent(escape(l.stringify(c)))}catch(c){throw Error('Malformed UTF-8 data')}},parse:function parse(c){return l.parse(unescape(encodeURIComponent(c)))}},n=e.BufferedBlockAlgorithm=h.extend({reset:function reset(){this._data=new k.init,this._nDataBytes=0},_append:function _append(c){'string'==typeof c&&(c=m.parse(c)),this._data.concat(c),this._nDataBytes+=c.sigBytes},_process:function _process(h){var j=this._data,l=j.words,d=j.sigBytes,c=this.blockSize,e=d/(4*c),e=h?i.ceil(e):i.max((0|e)-this._minBufferSize,0);if(h=e*c,d=i.min(4*h,d),h){for(var f=0;f<h;f+=c)this._doProcessBlock(l,f);f=l.splice(0,h),j.sigBytes-=d}return new k.init(f,d)},clone:function clone(){var c=h.clone.call(this);return c._data=this._data.clone(),c},_minBufferSize:0});e.Hasher=n.extend({cfg:h.extend(),init:function init(c){this.cfg=this.cfg.extend(c),this.reset()},reset:function reset(){n.reset.call(this),this._doReset()},update:function update(c){return this._append(c),this._process(),this},finalize:function finalize(c){return c&&this._append(c),this._doFinalize()},blockSize:16,_createHelper:function _createHelper(c){return function(e,f){return new c.init(f).finalize(e)}},_createHmacHelper:function _createHmacHelper(c){return function(e,f){return new o.HMAC.init(c,f).finalize(e)}}});var o=d.algo={};return d}(Math);(function(){var c=CryptoJS,e=c.lib,f=e.WordArray,g=e.Hasher,i=[],e=c.algo.SHA1=g.extend({_doReset:function _doReset(){this._hash=new f.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function _doProcessBlock(d,k){for(var l=this._hash.words,m=l[0],e=l[1],n=l[2],h=l[3],j=l[4],o=0;80>o;o++){if(16>o)i[o]=0|d[k+o];else{var c=i[o-3]^i[o-8]^i[o-14]^i[o-16];i[o]=c<<1|c>>>31}c=(m<<5|m>>>27)+j+i[o],c=20>o?c+((e&n|~e&h)+1518500249):40>o?c+((e^n^h)+1859775393):60>o?c+((e&n|e&h|n&h)-1894007588):c+((e^n^h)-899497514),j=h,h=n,n=e<<30|e>>>2,e=m,m=c}l[0]=0|l[0]+m,l[1]=0|l[1]+e,l[2]=0|l[2]+n,l[3]=0|l[3]+h,l[4]=0|l[4]+j},_doFinalize:function _doFinalize(){var c=this._data,f=c.words,d=8*this._nDataBytes,g=8*c.sigBytes;return f[g>>>5]|=128<<24-g%32,f[(g+64>>>9<<4)+14]=Math.floor(d/4294967296),f[(g+64>>>9<<4)+15]=d,c.sigBytes=4*f.length,this._process(),this._hash},clone:function clone(){var c=g.clone.call(this);return c._hash=this._hash.clone(),c}});c.SHA1=g._createHelper(e),c.HmacSHA1=g._createHmacHelper(e)})(),function(e){for(var c=CryptoJS,f=c.lib,g=f.WordArray,h=f.Hasher,f=c.algo,i=[],o=[],j=function(c){return 0|4294967296*(c-(0|c))},k=2,l=0;64>l;){var m;a:{m=k;for(var d=e.sqrt(m),p=2;p<=d;p++)if(!(m%p)){m=!1;break a}m=!0}m&&(8>l&&(i[l]=j(e.pow(k,0.5))),o[l]=j(e.pow(k,1/3)),l++),k++}var r=[],f=f.SHA256=h.extend({_doReset:function _doReset(){this._hash=new g.init(i.slice(0))},_doProcessBlock:function _doProcessBlock(i,n){for(var h=this._hash.words,q=h[0],c=h[1],d=h[2],s=h[3],k=h[4],t=h[5],g=h[6],j=h[7],l=0;64>l;l++){if(16>l)r[l]=0|i[n+l];else{var e=r[l-15],m=r[l-2];r[l]=((e<<25|e>>>7)^(e<<14|e>>>18)^e>>>3)+r[l-7]+((m<<15|m>>>17)^(m<<13|m>>>19)^m>>>10)+r[l-16]}e=j+((k<<26|k>>>6)^(k<<21|k>>>11)^(k<<7|k>>>25))+(k&t^~k&g)+o[l]+r[l],m=((q<<30|q>>>2)^(q<<19|q>>>13)^(q<<10|q>>>22))+(q&c^q&d^c&d),j=g,g=t,t=k,k=0|s+e,s=d,d=c,c=q,q=0|e+m}h[0]=0|h[0]+q,h[1]=0|h[1]+c,h[2]=0|h[2]+d,h[3]=0|h[3]+s,h[4]=0|h[4]+k,h[5]=0|h[5]+t,h[6]=0|h[6]+g,h[7]=0|h[7]+j},_doFinalize:function _doFinalize(){var f=this._data,d=f.words,g=8*this._nDataBytes,h=8*f.sigBytes;return d[h>>>5]|=128<<24-h%32,d[(h+64>>>9<<4)+14]=e.floor(g/4294967296),d[(h+64>>>9<<4)+15]=g,f.sigBytes=4*d.length,this._process(),this._hash},clone:function clone(){var c=h.clone.call(this);return c._hash=this._hash.clone(),c}});c.SHA256=h._createHelper(f),c.HmacSHA256=h._createHmacHelper(f)}(Math),function(){var d=CryptoJS,i=d.enc.Utf8;d.algo.HMAC=d.lib.Base.extend({init:function init(k,l){k=this._hasher=new k.init,'string'==typeof l&&(l=i.parse(l));var m=k.blockSize,c=4*m;l.sigBytes>c&&(l=k.finalize(l)),l.clamp();for(var e=this._oKey=l.clone(),f=this._iKey=l.clone(),g=e.words,h=f.words,j=0;j<m;j++)g[j]^=1549556828,h[j]^=909522486;e.sigBytes=f.sigBytes=c,this.reset()},reset:function reset(){var c=this._hasher;c.reset(),c.update(this._iKey)},update:function update(c){return this._hasher.update(c),this},finalize:function finalize(c){var d=this._hasher;return c=d.finalize(c),d.reset(),d.finalize(this._oKey.clone().concat(c))}})}(),function(){var c=CryptoJS,i=c.lib.WordArray;c.enc.Base64={stringify:function stringify(h){var i=h.words,e=h.sigBytes,f=this._map;h.clamp(),h=[];for(var c=0;c<e;c+=3)for(var j=(255&i[c>>>2]>>>24-8*(c%4))<<16|(255&i[c+1>>>2]>>>24-8*((c+1)%4))<<8|255&i[c+2>>>2]>>>24-8*((c+2)%4),d=0;4>d&&c+0.75*d<e;d++)h.push(f.charAt(63&j>>>6*(3-d)));if(i=f.charAt(64))for(;h.length%4;)h.push(i);return h.join('')},parse:function parse(j){var k=j.length,e=this._map,f=e.charAt(64);f&&(f=j.indexOf(f),-1!=f&&(k=f));for(var f=[],c=0,l=0;l<k;l++)if(l%4){var d=e.indexOf(j.charAt(l-1))<<2*(l%4),g=e.indexOf(j.charAt(l))>>>6-2*(l%4);f[c>>>2]|=(d|g)<<24-8*(c%4),c++}return i.create(f,c)},_map:'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='}}(),hawk.crypto.utils=CryptoJS,'undefined'!=typeof module&&module.exports&&(module.exports=hawk);

35

lib/browser.js

@@ -5,3 +5,3 @@ 'use strict';

HTTP Hawk Authentication Scheme
Copyright (c) 2012-2016, Eran Hammer <eran@hammer.io>
Copyright (c) 2012-2017, Eran Hammer <eran@hammer.io>
BSD Licensed

@@ -51,7 +51,2 @@ */

const result = {
field: '',
artifacts: {}
};
// Validate inputs

@@ -63,4 +58,3 @@

result.err = 'Invalid argument type';
return result;
throw new Error('Invalid argument type');
}

@@ -80,9 +74,7 @@

result.err = 'Invalid credentials object';
return result;
throw new Error('Invalid credentials');
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
result.err = 'Unknown algorithm';
return result;
throw new Error('Unknown algorithm');
}

@@ -111,4 +103,2 @@

result.artifacts = artifacts;
// Calculate payload hash

@@ -139,5 +129,3 @@

result.field = header;
return result;
return { artifacts, header };
},

@@ -177,3 +165,3 @@

return '';
throw new Error('Invalid inputs');
}

@@ -195,7 +183,7 @@

return '';
throw new Error('Invalid credentials');
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return '';
throw new Error('Unknown algorithm');
}

@@ -329,3 +317,3 @@

return null;
throw new Error('Invalid inputs');
}

@@ -345,8 +333,7 @@

// Invalid credential object
return null;
throw new Error('Invalid credentials');
}
if (hawk.crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return null;
throw new Error('Unknown algorithm');
}

@@ -353,0 +340,0 @@

@@ -6,3 +6,5 @@ 'use strict';

const Url = require('url');
const Hoek = require('hoek');
const Cryptiles = require('cryptiles');

@@ -49,7 +51,2 @@ const Crypto = require('./crypto');

const result = {
field: '',
artifacts: {}
};
// Validate inputs

@@ -61,4 +58,3 @@

result.err = 'Invalid argument type';
return result;
throw new Error('Invalid argument type');
}

@@ -78,9 +74,7 @@

result.err = 'Invalid credential object';
return result;
throw new Error('Invalid credentials');
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
result.err = 'Unknown algorithm';
return result;
throw new Error('Unknown algorithm');
}

@@ -109,4 +103,2 @@

result.artifacts = artifacts;
// Calculate payload hash

@@ -126,16 +118,14 @@

let header = 'Hawk id="' + credentials.id +
'", ts="' + artifacts.ts +
'", nonce="' + artifacts.nonce +
(artifacts.hash ? '", hash="' + artifacts.hash : '') +
(hasExt ? '", ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) : '') +
'", mac="' + mac + '"';
'", ts="' + artifacts.ts +
'", nonce="' + artifacts.nonce +
(artifacts.hash ? '", hash="' + artifacts.hash : '') +
(hasExt ? '", ext="' + Hoek.escapeHeaderAttribute(artifacts.ext) : '') +
'", mac="' + mac + '"';
if (artifacts.app) {
header = header + ', app="' + artifacts.app +
(artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
(artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"';
}
result.field = header;
return result;
return { header, artifacts };
};

@@ -155,24 +145,8 @@

exports.authenticate = function (res, credentials, artifacts, options, callback) {
exports.authenticate = function (res, credentials, artifacts, options = {}) {
artifacts = Hoek.clone(artifacts);
options = options || {};
let wwwAttributes = null;
let serverAuthAttributes = null;
const result = { headers: {} };
const finalize = function (err) {
if (callback) {
const headers = {
'www-authenticate': wwwAttributes,
'server-authorization': serverAuthAttributes
};
return callback(err, headers);
}
return !err;
};
if (res.headers['www-authenticate']) {

@@ -182,8 +156,11 @@

wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
if (wwwAttributes instanceof Error) {
wwwAttributes = null;
return finalize(new Error('Invalid WWW-Authenticate header'));
try {
var wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']);
}
catch (err) {
throw new Error('Invalid WWW-Authenticate header');
}
result.headers['www-authenticate'] = wwwAttributes;
// Validate server timestamp (not used to update clock since it is done via the SNPT client)

@@ -194,3 +171,3 @@

if (tsm !== wwwAttributes.tsm) {
return finalize(new Error('Invalid server timestamp hash'));
throw Object.assign(new Error('Invalid server timestamp hash'), result);
}

@@ -205,11 +182,14 @@ }

return finalize();
return result;
}
serverAuthAttributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
if (serverAuthAttributes instanceof Error) {
serverAuthAttributes = null;
return finalize(new Error('Invalid Server-Authorization header'));
try {
var serverAuthAttributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']);
}
catch (err) {
throw Object.assign(new Error('Invalid Server-Authorization header'), result);
}
result.headers['server-authorization'] = serverAuthAttributes;
artifacts.ext = serverAuthAttributes.ext;

@@ -220,3 +200,3 @@ artifacts.hash = serverAuthAttributes.hash;

if (mac !== serverAuthAttributes.mac) {
return finalize(new Error('Bad response mac'));
throw Object.assign(new Error('Bad response mac'), result);
}

@@ -227,7 +207,7 @@

return finalize();
return result;
}
if (!serverAuthAttributes.hash) {
return finalize(new Error('Missing response hash attribute'));
throw Object.assign(new Error('Missing response hash attribute'), result);
}

@@ -237,6 +217,6 @@

if (calculatedHash !== serverAuthAttributes.hash) {
return finalize(new Error('Bad response payload mac'));
throw Object.assign(new Error('Bad response payload mac'), result);
}
return finalize();
return result;
};

@@ -277,3 +257,3 @@

return '';
throw new Error('Invalid inputs');
}

@@ -295,7 +275,7 @@

return '';
throw new Error('Invalid credentials');
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return '';
throw new Error('Unknown algorithm');
}

@@ -353,3 +333,3 @@

exports.message = function (host, port, message, options) {
exports.message = function (host, port, message, options = {}) {

@@ -361,5 +341,5 @@ // Validate inputs

message === null || message === undefined || typeof message !== 'string' ||
!options || typeof options !== 'object') {
typeof options !== 'object') {
return null;
throw new Error('Invalid inputs');
}

@@ -379,8 +359,7 @@

// Invalid credential object
return null;
throw new Error('Invalid credentials');
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return null;
throw new Error('Unknown algorithm');
}

@@ -387,0 +366,0 @@

@@ -7,2 +7,3 @@ 'use strict';

const Url = require('url');
const Utils = require('./utils');

@@ -130,1 +131,12 @@

};
exports.fixedTimeComparison = function (a, b) {
try {
return Crypto.timingSafeEqual(new Buffer(a), new Buffer(b));
}
catch (err) {
return false;
}
};

@@ -5,3 +5,2 @@ 'use strict';

exports.error = exports.Error = require('boom');
exports.sntp = require('sntp');

@@ -18,2 +17,1 @@

};

@@ -7,3 +7,3 @@ 'use strict';

const Hoek = require('hoek');
const Cryptiles = require('cryptiles');
const Crypto = require('./crypto');

@@ -36,21 +36,20 @@ const Utils = require('./utils');

const credentialsFunc = function (id, callback) {
const credentialsFunc = async function (id) {
// Lookup credentials in database
db.lookup(id, function (err, item) {
if (err || !item) {
return callback(err);
}
const item = await db.lookup(id); // Can throw errors
if (!item) {
return null;
}
const credentials = {
// Required
key: item.key,
algorithm: item.algorithm,
// Application specific
user: item.user
};
const credentials = {
// Required
key: item.key,
algorithm: item.algorithm,
// Application specific
user: item.user
};
return callback(null, credentials);
});
return credentials;
};

@@ -65,4 +64,4 @@

nonceFunc: optional nonce validation function. The function signature is function(key, nonce, ts, callback)
where 'callback' must be called using the signature function(err).
nonceFunc: optional nonce validation function. The function signature is `async function(key, nonce, ts)`
and it must return no value for success or throw an error for invalid state.

@@ -81,3 +80,3 @@ timestampSkewSec: optional number of seconds of permitted clock skew for incoming timestamps. Defaults to 60 seconds.

of authentication, the authenticatePayload() method can be used by passing it the credentials and
attributes.hash returned in the authenticate callback.
attributes.hash returned from authenticate().

@@ -88,12 +87,9 @@ host: optional host name override. Only used when passed a node request object.

callback: function (err, credentials, artifacts) { }
Return value: { credentials, artifacts } or throws an error.
*/
exports.authenticate = function (req, credentialsFunc, options, callback) {
exports.authenticate = async function (req, credentialsFunc, options = {}) {
callback = Hoek.nextTick(callback);
// Default options
options.nonceFunc = options.nonceFunc || internals.nonceFunc;
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds

@@ -108,5 +104,2 @@

const request = Utils.parseRequest(req, options);
if (request instanceof Error) {
return callback(Boom.badRequest(request.message));
}

@@ -116,5 +109,2 @@ // Parse HTTP Authorization header

const attributes = Utils.parseAuthorizationHeader(request.authorization);
if (attributes instanceof Error) {
return callback(attributes);
}

@@ -145,3 +135,3 @@ // Construct artifacts container

return callback(Boom.badRequest('Missing attributes'), null, artifacts);
throw Object.assign(Boom.badRequest('Missing attributes'), { artifacts });
}

@@ -151,64 +141,68 @@

credentialsFunc(attributes.id, (err, credentials) => {
try {
var credentials = await credentialsFunc(attributes.id);
}
catch (err) {
throw Object.assign(err, { artifacts });
}
if (err) {
return callback(err, credentials || null, artifacts);
}
if (!credentials) {
throw Object.assign(Utils.unauthorized('Unknown credentials'), { artifacts });
}
if (!credentials) {
return callback(Utils.unauthorized('Unknown credentials'), null, artifacts);
}
const result = { credentials, artifacts };
if (!credentials.key ||
!credentials.algorithm) {
if (!credentials.key ||
!credentials.algorithm) {
return callback(Boom.internal('Invalid credentials'), credentials, artifacts);
}
throw Object.assign(Boom.internal('Invalid credentials'), result);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return callback(Boom.internal('Unknown algorithm'), credentials, artifacts);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
throw Object.assign(Boom.internal('Unknown algorithm'), result);
}
// Calculate MAC
// Calculate MAC
const mac = Crypto.calculateMac('header', credentials, artifacts);
if (!Cryptiles.fixedTimeComparison(mac, attributes.mac)) {
return callback(Utils.unauthorized('Bad mac'), credentials, artifacts);
}
const mac = Crypto.calculateMac('header', credentials, artifacts);
if (!Crypto.fixedTimeComparison(mac, attributes.mac)) {
throw Object.assign(Utils.unauthorized('Bad mac'), result);
}
// Check payload hash
// Check payload hash
if (options.payload ||
options.payload === '') {
if (options.payload ||
options.payload === '') {
if (!attributes.hash) {
return callback(Utils.unauthorized('Missing required payload hash'), credentials, artifacts);
}
if (!attributes.hash) {
throw Object.assign(Utils.unauthorized('Missing required payload hash'), result);
}
const hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.contentType);
if (!Cryptiles.fixedTimeComparison(hash, attributes.hash)) {
return callback(Utils.unauthorized('Bad payload hash'), credentials, artifacts);
}
const hash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, request.contentType);
if (!Crypto.fixedTimeComparison(hash, attributes.hash)) {
throw Object.assign(Utils.unauthorized('Bad payload hash'), result);
}
}
// Check nonce
// Check nonce
options.nonceFunc(credentials.key, attributes.nonce, attributes.ts, (err) => {
if (options.nonceFunc) {
try {
await options.nonceFunc(credentials.key, attributes.nonce, attributes.ts);
}
catch (err) {
throw Object.assign(Utils.unauthorized('Invalid nonce'), result);
}
}
if (err) {
return callback(Utils.unauthorized('Invalid nonce'), credentials, artifacts);
}
// Check timestamp staleness
// Check timestamp staleness
if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
const tsm = Crypto.timestampMessage(credentials, options.localtimeOffsetMsec);
throw Object.assign(Utils.unauthorized('Stale timestamp', tsm), result);
}
if (Math.abs((attributes.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
const tsm = Crypto.timestampMessage(credentials, options.localtimeOffsetMsec);
return callback(Utils.unauthorized('Stale timestamp', tsm), credentials, artifacts);
}
// Successful authentication
// Successful authentication
return callback(null, credentials, artifacts);
});
});
return result;
};

@@ -221,5 +215,7 @@

payload: raw request payload
credentials: from authenticate callback
artifacts: from authenticate callback
credentials: from authenticate()
artifacts: from authenticate()
contentType: req.headers['content-type']
Return value: { credentials, artifacts } or throws an error.
*/

@@ -230,3 +226,5 @@

const calculatedHash = Crypto.calculatePayloadHash(payload, credentials.algorithm, contentType);
return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash);
if (!Crypto.fixedTimeComparison(calculatedHash, artifacts.hash)) {
throw Object.assign(Utils.unauthorized('Bad payload hash'), { credentials, artifacts });
}
};

@@ -239,3 +237,5 @@

calculatedHash: the payload hash calculated using Crypto.calculatePayloadHash()
artifacts: from authenticate callback
artifacts: from authenticate()
Return value: { artifacts } or throws an error.
*/

@@ -245,3 +245,5 @@

return Cryptiles.fixedTimeComparison(calculatedHash, artifacts.hash);
if (!Crypto.fixedTimeComparison(calculatedHash, artifacts.hash)) {
throw Object.assign(Utils.unauthorized('Bad payload hash'), { artifacts });
}
};

@@ -308,3 +310,3 @@

let header = 'Hawk mac="' + mac + '"' +
(artifacts.hash ? ', hash="' + artifacts.hash + '"' : '');
(artifacts.hash ? ', hash="' + artifacts.hash + '"' : '');

@@ -332,6 +334,4 @@ if (artifacts.ext !== null &&

exports.authenticateBewit = function (req, credentialsFunc, options, callback) {
exports.authenticateBewit = async function (req, credentialsFunc, options = {}) {
callback = Hoek.nextTick(callback);
// Application time

@@ -344,5 +344,2 @@

const request = Utils.parseRequest(req, options);
if (request instanceof Error) {
return callback(Boom.badRequest(request.message));
}

@@ -352,3 +349,3 @@ // Extract bewit

if (request.url.length > Utils.limits.maxMatchLength) {
return callback(Boom.badRequest('Resource path exceeds max length'));
throw Boom.badRequest('Resource path exceeds max length');
}

@@ -358,3 +355,3 @@

if (!resource) {
return callback(Utils.unauthorized());
throw Utils.unauthorized();
}

@@ -365,3 +362,3 @@

if (!resource[3]) {
return callback(Utils.unauthorized('Empty bewit'));
throw Utils.unauthorized('Empty bewit');
}

@@ -374,3 +371,3 @@

return callback(Utils.unauthorized('Invalid method'));
throw Utils.unauthorized('Invalid method');
}

@@ -381,3 +378,3 @@

if (request.authorization) {
return callback(Boom.badRequest('Multiple authentications'));
throw Boom.badRequest('Multiple authentications');
}

@@ -387,6 +384,8 @@

const bewitString = Hoek.base64urlDecode(resource[3]);
if (bewitString instanceof Error) {
return callback(Boom.badRequest('Invalid bewit encoding'));
try {
var bewitString = Hoek.base64urlDecode(resource[3]);
}
catch (err) {
throw Boom.badRequest('Invalid bewit encoding');
}

@@ -397,3 +396,3 @@ // Bewit format: id\exp\mac\ext ('\' is used because it is a reserved header attribute character)

if (bewitParts.length !== 4) {
return callback(Boom.badRequest('Invalid bewit structure'));
throw Boom.badRequest('Invalid bewit structure');
}

@@ -412,3 +411,3 @@

return callback(Boom.badRequest('Missing bewit attributes'));
throw Boom.badRequest('Missing bewit attributes');
}

@@ -426,3 +425,3 @@

if (bewit.exp * 1000 <= now) {
return callback(Utils.unauthorized('Access expired'), null, bewit);
throw Object.assign(Utils.unauthorized('Access expired'), { bewit });
}

@@ -432,42 +431,44 @@

credentialsFunc(bewit.id, (err, credentials) => {
try {
var credentials = await credentialsFunc(bewit.id);
}
catch (err) {
throw Object.assign(err, { bewit });
}
if (err) {
return callback(err, credentials || null, bewit.ext);
}
if (!credentials) {
throw Object.assign(Utils.unauthorized('Unknown credentials'), { bewit });
}
if (!credentials) {
return callback(Utils.unauthorized('Unknown credentials'), null, bewit);
}
const result = { credentials, attributes: bewit };
if (!credentials.key ||
!credentials.algorithm) {
if (!credentials.key ||
!credentials.algorithm) {
return callback(Boom.internal('Invalid credentials'), credentials, bewit);
}
throw Object.assign(Boom.internal('Invalid credentials'), result);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return callback(Boom.internal('Unknown algorithm'), credentials, bewit);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
throw Object.assign(Boom.internal('Unknown algorithm'), result);
}
// Calculate MAC
// Calculate MAC
const mac = Crypto.calculateMac('bewit', credentials, {
ts: bewit.exp,
nonce: '',
method: 'GET',
resource: url,
host: request.host,
port: request.port,
ext: bewit.ext
});
const mac = Crypto.calculateMac('bewit', credentials, {
ts: bewit.exp,
nonce: '',
method: 'GET',
resource: url,
host: request.host,
port: request.port,
ext: bewit.ext
});
if (!Cryptiles.fixedTimeComparison(mac, bewit.mac)) {
return callback(Utils.unauthorized('Bad mac'), credentials, bewit);
}
if (!Crypto.fixedTimeComparison(mac, bewit.mac)) {
throw Object.assign(Utils.unauthorized('Bad mac'), result);
}
// Successful authentication
// Successful authentication
return callback(null, credentials, bewit);
});
return result;
};

@@ -481,9 +482,6 @@

exports.authenticateMessage = function (host, port, message, authorization, credentialsFunc, options, callback) {
exports.authenticateMessage = async function (host, port, message, authorization, credentialsFunc, options = {}) {
callback = Hoek.nextTick(callback);
// Default options
options.nonceFunc = options.nonceFunc || internals.nonceFunc;
options.timestampSkewSec = options.timestampSkewSec || 60; // 60 seconds

@@ -503,3 +501,3 @@

return callback(Boom.badRequest('Invalid authorization'));
throw Boom.badRequest('Invalid authorization');
}

@@ -509,71 +507,63 @@

credentialsFunc(authorization.id, (err, credentials) => {
const credentials = await credentialsFunc(authorization.id);
if (!credentials) {
throw Utils.unauthorized('Unknown credentials');
}
if (err) {
return callback(err, credentials || null);
}
const result = { credentials };
if (!credentials) {
return callback(Utils.unauthorized('Unknown credentials'));
}
if (!credentials.key ||
!credentials.algorithm) {
if (!credentials.key ||
!credentials.algorithm) {
throw Object.assign(Boom.internal('Invalid credentials'), result);
}
return callback(Boom.internal('Invalid credentials'), credentials);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
throw Object.assign(Boom.internal('Unknown algorithm'), result);
}
if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) {
return callback(Boom.internal('Unknown algorithm'), credentials);
}
// Construct artifacts container
// Construct artifacts container
const artifacts = {
ts: authorization.ts,
nonce: authorization.nonce,
host,
port,
hash: authorization.hash
};
const artifacts = {
ts: authorization.ts,
nonce: authorization.nonce,
host,
port,
hash: authorization.hash
};
// Calculate MAC
// Calculate MAC
const mac = Crypto.calculateMac('message', credentials, artifacts);
if (!Crypto.fixedTimeComparison(mac, authorization.mac)) {
throw Object.assign(Utils.unauthorized('Bad mac'), result);
}
const mac = Crypto.calculateMac('message', credentials, artifacts);
if (!Cryptiles.fixedTimeComparison(mac, authorization.mac)) {
return callback(Utils.unauthorized('Bad mac'), credentials);
}
// Check payload hash
// Check payload hash
const hash = Crypto.calculatePayloadHash(message, credentials.algorithm);
if (!Crypto.fixedTimeComparison(hash, authorization.hash)) {
throw Object.assign(Utils.unauthorized('Bad message hash'), result);
}
const hash = Crypto.calculatePayloadHash(message, credentials.algorithm);
if (!Cryptiles.fixedTimeComparison(hash, authorization.hash)) {
return callback(Utils.unauthorized('Bad message hash'), credentials);
// Check nonce
if (options.nonceFunc) {
try {
await options.nonceFunc(credentials.key, authorization.nonce, authorization.ts);
}
catch (err) {
throw Object.assign(Utils.unauthorized('Invalid nonce'), result);
}
}
// Check nonce
// Check timestamp staleness
options.nonceFunc(credentials.key, authorization.nonce, authorization.ts, (err) => {
if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
throw Object.assign(Utils.unauthorized('Stale timestamp'), result);
}
if (err) {
return callback(Utils.unauthorized('Invalid nonce'), credentials);
}
// Successful authentication
// Check timestamp staleness
if (Math.abs((authorization.ts * 1000) - now) > (options.timestampSkewSec * 1000)) {
return callback(Utils.unauthorized('Stale timestamp'), credentials);
}
// Successful authentication
return callback(null, credentials);
});
});
return result;
};
internals.nonceFunc = function (key, nonce, ts, nonceCallback) {
return nonceCallback(); // No validation
};

@@ -5,4 +5,4 @@ 'use strict';

const Boom = require('boom');
const Sntp = require('sntp');
const Boom = require('boom');

@@ -84,3 +84,3 @@

if (!host) {
return new Error('Invalid Host header');
throw Boom.badRequest('Invalid Host header');
}

@@ -125,7 +125,7 @@ }

if (!header) {
return Boom.unauthorized(null, 'Hawk');
throw Boom.unauthorized(null, 'Hawk');
}
if (header.length > exports.limits.maxMatchLength) {
return Boom.badRequest('Header length too long');
throw Boom.badRequest('Header length too long');
}

@@ -135,3 +135,3 @@

if (!headerParts) {
return Boom.badRequest('Invalid header syntax');
throw Boom.badRequest('Invalid header syntax');
}

@@ -141,3 +141,3 @@

if (scheme.toLowerCase() !== 'hawk') {
return Boom.unauthorized(null, 'Hawk');
throw Boom.unauthorized(null, 'Hawk');
}

@@ -147,3 +147,3 @@

if (!attributesString) {
return Boom.badRequest('Invalid header syntax');
throw Boom.badRequest('Invalid header syntax');
}

@@ -181,3 +181,3 @@

if (verify !== '') {
return Boom.badRequest(errorMessage || 'Bad header format');
throw Boom.badRequest(errorMessage || 'Bad header format');
}

@@ -184,0 +184,0 @@

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

@@ -16,15 +16,16 @@ "repository": "git://github.com/hueniverse/hawk",

"engines": {
"node": ">=4.5.0"
"node": ">=8.8.0"
},
"dependencies": {
"hoek": "4.x.x",
"boom": "4.x.x",
"cryptiles": "3.x.x",
"sntp": "2.x.x"
"hoek": "5.x.x",
"boom": "6.x.x",
"cryptiles": "4.x.x",
"sntp": "3.x.x"
},
"devDependencies": {
"babel-cli": "^6.1.2",
"babel-preset-es2015": "^6.1.2",
"code": "4.x.x",
"lab": "14.x.x"
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.6.1",
"babel-preset-minify": "^0.2.0",
"code": "5.x.x",
"lab": "15.x.x"
},

@@ -38,3 +39,3 @@ "babel": {

"build-client": "mkdir -p dist; babel lib/browser.js --out-file dist/browser.js",
"prepublish": "npm run-script build-client",
"prepare": "npm run-script build-client",
"test": "lab -a code -t 100 -L",

@@ -41,0 +42,0 @@ "test-cov-html": "lab -a code -r html -o coverage.html"

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

Current version: **6.x**
Current version: **7.x**
Note: 6.x, 5.x, 4.x, 3.x, and 2.x are the same exact protocol as 1.1. The version increments reflect changes in the node API.
Note: the protocol has not changed since version 1.1. The version increments reflect changes in the node API.

@@ -109,3 +109,3 @@ [![Build Status](https://travis-ci.org/hueniverse/hawk.svg?branch=master)](https://travis-ci.org/hueniverse/hawk)

const credentialsFunc = function (id, callback) {
const credentialsFunc = function (id) {

@@ -118,3 +118,3 @@ const credentials = {

return callback(null, credentials);
return credentials;
};

@@ -124,23 +124,22 @@

const handler = function (req, res) {
const handler = async function (req, res) {
// Authenticate incoming request
Hawk.server.authenticate(req, credentialsFunc, {}, (err, credentials, artifacts) => {
const ( credentials, artifacts } = await Hawk.server.authenticate(req, credentialsFunc);
// Prepare response
// Prepare response
const payload = (!err ? `Hello ${credentials.user} ${artifacts.ext}` : 'Shoosh!');
const headers = { 'Content-Type': 'text/plain' };
const payload = (!err ? `Hello ${credentials.user} ${artifacts.ext}` : 'Shoosh!');
const headers = { 'Content-Type': 'text/plain' };
// Generate Server-Authorization response header
// Generate Server-Authorization response header
const header = Hawk.server.header(credentials, artifacts, { payload, contentType: headers['Content-Type'] });
headers['Server-Authorization'] = header;
const header = Hawk.server.header(credentials, artifacts, { payload, contentType: headers['Content-Type'] });
headers['Server-Authorization'] = header;
// Send the response back
// Send the response back
res.writeHead(!err ? 200 : 401, headers);
res.end(payload);
});
res.writeHead(!err ? 200 : 401, headers);
res.end(payload);
};

@@ -178,4 +177,4 @@

const header = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });
requestOptions.headers.Authorization = header.field;
const { header } = Hawk.client.header('http://example.com:8000/resource/1?b=1&a=2', 'GET', { credentials: credentials, ext: 'some-app-data' });
requestOptions.headers.Authorization = header;

@@ -393,3 +392,3 @@ // Send authenticated request

const credentialsFunc = function (id, callback) {
const credentialsFunc = function (id) {

@@ -401,3 +400,3 @@ const credentials = {

return callback(null, credentials);
return credentials;
};

@@ -409,7 +408,11 @@

Hawk.uri.authenticate(req, credentialsFunc, {}, (err, credentials, attributes) => {
res.writeHead(!err ? 200 : 401, { 'Content-Type': 'text/plain' });
res.end(!err ? 'Access granted' : 'Shoosh!');
});
try {
const { credentials, attributes } = await Hawk.uri.authenticate(req, credentialsFunc);
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end('Access granted');
}
catch (err) {
res.writeHead(401, { 'Content-Type': 'text/plain' });
res.end('Shoosh!');
}
};

@@ -416,0 +419,0 @@

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc