You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					90 lines
				
				2.7 KiB
			
		
		
			
		
	
	
					90 lines
				
				2.7 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								'use strict'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								var crypto = require('crypto')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function randomString (size) {
							 | 
						||
| 
								 | 
							
								  var bits = (size + 1) * 6
							 | 
						||
| 
								 | 
							
								  var buffer = crypto.randomBytes(Math.ceil(bits / 8))
							 | 
						||
| 
								 | 
							
								  var string = buffer.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '')
							 | 
						||
| 
								 | 
							
								  return string.slice(0, size)
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								function calculatePayloadHash (payload, algorithm, contentType) {
							 | 
						||
| 
								 | 
							
								  var hash = crypto.createHash(algorithm)
							 | 
						||
| 
								 | 
							
								  hash.update('hawk.1.payload\n')
							 | 
						||
| 
								 | 
							
								  hash.update((contentType ? contentType.split(';')[0].trim().toLowerCase() : '') + '\n')
							 | 
						||
| 
								 | 
							
								  hash.update(payload || '')
							 | 
						||
| 
								 | 
							
								  hash.update('\n')
							 | 
						||
| 
								 | 
							
								  return hash.digest('base64')
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.calculateMac = function (credentials, opts) {
							 | 
						||
| 
								 | 
							
								  var normalized = 'hawk.1.header\n' +
							 | 
						||
| 
								 | 
							
								    opts.ts + '\n' +
							 | 
						||
| 
								 | 
							
								    opts.nonce + '\n' +
							 | 
						||
| 
								 | 
							
								    (opts.method || '').toUpperCase() + '\n' +
							 | 
						||
| 
								 | 
							
								    opts.resource + '\n' +
							 | 
						||
| 
								 | 
							
								    opts.host.toLowerCase() + '\n' +
							 | 
						||
| 
								 | 
							
								    opts.port + '\n' +
							 | 
						||
| 
								 | 
							
								    (opts.hash || '') + '\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.ext) {
							 | 
						||
| 
								 | 
							
								    normalized = normalized + opts.ext.replace('\\', '\\\\').replace('\n', '\\n')
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  normalized = normalized + '\n'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (opts.app) {
							 | 
						||
| 
								 | 
							
								    normalized = normalized + opts.app + '\n' + (opts.dlg || '') + '\n'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var hmac = crypto.createHmac(credentials.algorithm, credentials.key).update(normalized)
							 | 
						||
| 
								 | 
							
								  var digest = hmac.digest('base64')
							 | 
						||
| 
								 | 
							
								  return digest
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								exports.header = function (uri, method, opts) {
							 | 
						||
| 
								 | 
							
								  var timestamp = opts.timestamp || Math.floor((Date.now() + (opts.localtimeOffsetMsec || 0)) / 1000)
							 | 
						||
| 
								 | 
							
								  var credentials = opts.credentials
							 | 
						||
| 
								 | 
							
								  if (!credentials || !credentials.id || !credentials.key || !credentials.algorithm) {
							 | 
						||
| 
								 | 
							
								    return ''
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (['sha1', 'sha256'].indexOf(credentials.algorithm) === -1) {
							 | 
						||
| 
								 | 
							
								    return ''
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var artifacts = {
							 | 
						||
| 
								 | 
							
								    ts: timestamp,
							 | 
						||
| 
								 | 
							
								    nonce: opts.nonce || randomString(6),
							 | 
						||
| 
								 | 
							
								    method: method,
							 | 
						||
| 
								 | 
							
								    resource: uri.pathname + (uri.search || ''),
							 | 
						||
| 
								 | 
							
								    host: uri.hostname,
							 | 
						||
| 
								 | 
							
								    port: uri.port || (uri.protocol === 'http:' ? 80 : 443),
							 | 
						||
| 
								 | 
							
								    hash: opts.hash,
							 | 
						||
| 
								 | 
							
								    ext: opts.ext,
							 | 
						||
| 
								 | 
							
								    app: opts.app,
							 | 
						||
| 
								 | 
							
								    dlg: opts.dlg
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (!artifacts.hash && (opts.payload || opts.payload === '')) {
							 | 
						||
| 
								 | 
							
								    artifacts.hash = calculatePayloadHash(opts.payload, credentials.algorithm, opts.contentType)
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var mac = exports.calculateMac(credentials, artifacts)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  var hasExt = artifacts.ext !== null && artifacts.ext !== undefined && artifacts.ext !== ''
							 | 
						||
| 
								 | 
							
								  var header = 'Hawk id="' + credentials.id +
							 | 
						||
| 
								 | 
							
								    '", ts="' + artifacts.ts +
							 | 
						||
| 
								 | 
							
								    '", nonce="' + artifacts.nonce +
							 | 
						||
| 
								 | 
							
								    (artifacts.hash ? '", hash="' + artifacts.hash : '') +
							 | 
						||
| 
								 | 
							
								    (hasExt ? '", ext="' + artifacts.ext.replace(/\\/g, '\\\\').replace(/"/g, '\\"') : '') +
							 | 
						||
| 
								 | 
							
								    '", mac="' + mac + '"'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  if (artifacts.app) {
							 | 
						||
| 
								 | 
							
								    header = header + ', app="' + artifacts.app + (artifacts.dlg ? '", dlg="' + artifacts.dlg : '') + '"'
							 | 
						||
| 
								 | 
							
								  }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  return header
							 | 
						||
| 
								 | 
							
								}
							 |