Submit
Path:
~
/
/
proc
/
thread-self
/
root
/
usr
/
local
/
lib
/
node_modules
/
npm
/
node_modules
/
request
/
node_modules
/
hawk
/
lib
/
File Content:
client.js
'use strict'; // Load modules const Url = require('url'); const Hoek = require('hoek'); const Cryptiles = require('cryptiles'); const Crypto = require('./crypto'); const Utils = require('./utils'); // Declare internals const internals = {}; // Generate an Authorization header for a given request /* uri: 'http://example.com/resource?a=b' or object from Url.parse() 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 } */ exports.header = function (uri, method, options) { const result = { field: '', artifacts: {} }; // Validate inputs if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || !method || typeof method !== 'string' || !options || typeof options !== 'object') { result.err = 'Invalid argument type'; return result; } // Application time const timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec); // Validate credentials const credentials = options.credentials; if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) { result.err = 'Invalid credential object'; return result; } if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { result.err = 'Unknown algorithm'; return result; } // Parse URI if (typeof uri === 'string') { uri = Url.parse(uri); } // Calculate signature const artifacts = { ts: timestamp, nonce: options.nonce || Cryptiles.randomString(6), method, resource: uri.pathname + (uri.search || ''), // Maintain trailing '?' host: uri.hostname, port: uri.port || (uri.protocol === 'http:' ? 80 : 443), 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 = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, options.contentType); } const mac = Crypto.calculateMac('header', credentials, artifacts); // Construct header const hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''; // Other falsey values allowed 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 + '"'; if (artifacts.app) { header = header + ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'; } result.field = header; return result; }; // Validate server response /* res: node's response object artifacts: object received from header().artifacts options: { payload: optional payload received required: specifies if a Server-Authorization header is required. Defaults to 'false' } */ exports.authenticate = function (res, credentials, artifacts, options, callback) { artifacts = Hoek.clone(artifacts); options = options || {}; let wwwAttributes = null; let serverAuthAttributes = null; const finalize = function (err) { if (callback) { const headers = { 'www-authenticate': wwwAttributes, 'server-authorization': serverAuthAttributes }; return callback(err, headers); } return !err; }; if (res.headers['www-authenticate']) { // Parse HTTP WWW-Authenticate header wwwAttributes = Utils.parseAuthorizationHeader(res.headers['www-authenticate'], ['ts', 'tsm', 'error']); if (wwwAttributes instanceof Error) { wwwAttributes = null; return finalize(new Error('Invalid WWW-Authenticate header')); } // Validate server timestamp (not used to update clock since it is done via the SNPT client) if (wwwAttributes.ts) { const tsm = Crypto.calculateTsMac(wwwAttributes.ts, credentials); if (tsm !== wwwAttributes.tsm) { return finalize(new Error('Invalid server timestamp hash')); } } } // Parse HTTP Server-Authorization header if (!res.headers['server-authorization'] && !options.required) { return finalize(); } serverAuthAttributes = Utils.parseAuthorizationHeader(res.headers['server-authorization'], ['mac', 'ext', 'hash']); if (serverAuthAttributes instanceof Error) { serverAuthAttributes = null; return finalize(new Error('Invalid Server-Authorization header')); } artifacts.ext = serverAuthAttributes.ext; artifacts.hash = serverAuthAttributes.hash; const mac = Crypto.calculateMac('response', credentials, artifacts); if (mac !== serverAuthAttributes.mac) { return finalize(new Error('Bad response mac')); } if (!options.payload && options.payload !== '') { return finalize(); } if (!serverAuthAttributes.hash) { return finalize(new Error('Missing response hash attribute')); } const calculatedHash = Crypto.calculatePayloadHash(options.payload, credentials.algorithm, res.headers['content-type']); if (calculatedHash !== serverAuthAttributes.hash) { return finalize(new Error('Bad response payload mac')); } return finalize(); }; // Generate a bewit value for a given URI /* uri: 'http://example.com/resource?a=b' or object from Url.parse() 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 }; */ exports.getBewit = function (uri, options) { // Validate inputs if (!uri || (typeof uri !== 'string' && typeof uri !== 'object') || !options || typeof options !== 'object' || !options.ttlSec) { return ''; } options.ext = (options.ext === null || options.ext === undefined ? '' : options.ext); // Zero is valid value // Application time const now = Utils.now(options.localtimeOffsetMsec); // Validate credentials const credentials = options.credentials; if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) { return ''; } if (Crypto.algorithms.indexOf(credentials.algorithm) === -1) { return ''; } // Parse URI if (typeof uri === 'string') { uri = Url.parse(uri); } // Calculate signature const exp = Math.floor(now / 1000) + options.ttlSec; const mac = Crypto.calculateMac('bewit', credentials, { ts: exp, nonce: '', method: 'GET', resource: uri.pathname + (uri.search || ''), // Maintain trailing '?' host: uri.hostname, port: uri.port || (uri.protocol === 'http:' ? 80 : 443), ext: options.ext }); // Construct bewit: id\exp\mac\ext const bewit = credentials.id + '\\' + exp + '\\' + mac + '\\' + options.ext; return Hoek.base64urlEncode(bewit); }; // 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() / 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) } */ 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 const timestamp = options.timestamp || Utils.nowSecs(options.localtimeOffsetMsec); // Validate credentials const 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 const artifacts = { ts: timestamp, nonce: options.nonce || Cryptiles.randomString(6), host, port, hash: Crypto.calculatePayloadHash(message, credentials.algorithm) }; // Construct authorization const result = { id: credentials.id, ts: artifacts.ts, nonce: artifacts.nonce, hash: artifacts.hash, mac: Crypto.calculateMac('message', credentials, artifacts) }; return result; };
Submit
FILE
FOLDER
Name
Size
Permission
Action
browser.js
27106 bytes
0755
client.js
11142 bytes
0755
crypto.js
3544 bytes
0755
index.js
380 bytes
0755
server.js
17927 bytes
0755
utils.js
4406 bytes
0755
N4ST4R_ID | Naxtarrr