Comparing version 0.1.3 to 0.1.4
38
aws4.js
var aws4 = exports | ||
var url = require('url') | ||
var crypto = require('crypto') | ||
@@ -6,8 +7,18 @@ | ||
function hmac(key, string, encoding) { | ||
return crypto.createHmac('sha256', key).update(string, 'utf8').digest(encoding) | ||
} | ||
function hash(string, encoding) { | ||
return crypto.createHash('sha256').update(string, 'utf8').digest(encoding) | ||
} | ||
// request: { path | body, [host], [method], [headers], [service], [region] } | ||
// credentials: { accessKeyId, secretAccessKey, [sessionToken] } | ||
function RequestSigner(request, credentials) { | ||
if (typeof request === 'string') request = url.parse(request) | ||
var headers = request.headers || {} | ||
, hostParts = this.matchHost(request.hostname || request.host || headers['Host']) | ||
, date = new Date(headers['Date'] || new Date) | ||
@@ -19,4 +30,2 @@ this.request = request | ||
this.region = request.region || hostParts[1] || 'us-east-1' | ||
this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') | ||
this.date = this.datetime.substr(0, 8) | ||
} | ||
@@ -37,12 +46,16 @@ | ||
, headers = request.headers = (request.headers || {}) | ||
, date = new Date(headers['Date'] || new Date) | ||
this.datetime = date.toISOString().replace(/[:\-]|\.\d{3}/g, '') | ||
this.date = this.datetime.substr(0, 8) | ||
if (!request.method && request.body) | ||
request.method = 'POST' | ||
if (!headers['Host']) | ||
if (!headers['Host'] && !headers['host']) | ||
headers['Host'] = request.hostname || request.host || this.createHost() | ||
if (!request.hostname && !request.host) | ||
request.hostname = headers['Host'] | ||
request.hostname = headers['Host'] || headers['host'] | ||
if (request.body && !headers['Content-Type']) | ||
if (request.body && !headers['Content-Type'] && !headers['content-type']) | ||
headers['Content-Type'] = 'application/x-www-form-urlencoded' | ||
@@ -69,9 +82,6 @@ | ||
RequestSigner.prototype.signature = function() { | ||
function hmac(key, data, encoding) { | ||
return crypto.createHmac('sha256', key).update(data).digest(encoding) | ||
} | ||
var kDate = hmac('AWS4' + this.credentials.secretAccessKey, this.date) | ||
var kRegion = hmac(kDate, this.region) | ||
var kService = hmac(kRegion, this.service) | ||
var kCredentials = hmac(kService, 'aws4_request') | ||
, kRegion = hmac(kDate, this.region) | ||
, kService = hmac(kRegion, this.service) | ||
, kCredentials = hmac(kService, 'aws4_request') | ||
return hmac(kCredentials, this.stringToSign(), 'hex') | ||
@@ -85,3 +95,3 @@ } | ||
this.credentialString(), | ||
crypto.createHash('sha256').update(this.canonicalString()).digest('hex') | ||
hash(this.canonicalString(), 'hex') | ||
].join('\n') | ||
@@ -98,3 +108,3 @@ } | ||
this.signedHeaders(), | ||
crypto.createHash('sha256').update(this.request.body || '').digest('hex') | ||
hash(this.request.body || '', 'hex') | ||
].join('\n') | ||
@@ -101,0 +111,0 @@ } |
@@ -10,11 +10,23 @@ var http = require('http') | ||
// opts.headers now contains the signed AWS headers, and is ready for | ||
// use in standard node.js http(s) requests | ||
console.log(opts) | ||
/* | ||
{ | ||
host: 'sqs.us-east-1.amazonaws.com', | ||
path: '/?Action=ListQueues', | ||
headers: { | ||
Host: 'sqs.us-east-1.amazonaws.com', | ||
'X-Amz-Date': '20121226T061030Z', | ||
Authorization: 'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/sqs/aws4_request, SignedHeaders=host;x-amz-date, Signature=d847efb54cd60f0a256174848f26e43af4b5168dbec3118dc9fd84e942285791' | ||
} | ||
} | ||
*/ | ||
// eg, pipe the SOAP response from the above SQS request to stdout | ||
// we can now use this to query AWS using the standard node.js http API | ||
http.request(opts, function(res) { res.pipe(process.stdout) }).end() | ||
/* | ||
<?xml version="1.0"?> | ||
<ListQueuesResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/"> | ||
... | ||
*/ | ||
// create a utility function to pipe to stdout (with https this time) | ||
function request(o) { https.request(o, function(res) { res.pipe(process.stdout) }).end(o.body || '') } | ||
// you can pass AWS credentials in explicitly | ||
@@ -26,5 +38,12 @@ aws4.sign(opts, { accessKeyId: '', secretAccessKey: '' }) | ||
// create a utility function to pipe to stdout (with https this time) | ||
function request(o) { https.request(o, function(res) { res.pipe(process.stdout) }).end(o.body || '') } | ||
// aws4 can infer the HTTP method if a body is passed in | ||
// method will be POST and Content-Type: 'application/x-www-form-urlencoded' | ||
request(aws4.sign({ service: 'iam', body: 'Action=ListGroups&Version=2010-05-08' })) | ||
/* | ||
<ListGroupsResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/"> | ||
... | ||
*/ | ||
@@ -43,2 +62,6 @@ // can specify any custom option or header as per usual | ||
})) | ||
/* | ||
{"TableNames":[]} | ||
... | ||
*/ | ||
@@ -48,6 +71,19 @@ // works with all other services that support Signature Version 4 | ||
request(aws4.sign({ service: 'sts', path: '/?Action=GetSessionToken&Version=2011-06-15' })) | ||
/* | ||
<GetSessionTokenResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/"> | ||
... | ||
*/ | ||
request(aws4.sign({ service: 'glacier', path: '/-/vaults', headers: { 'X-Amz-Glacier-Version': '2012-06-01' } })) | ||
/* | ||
{"Marker":null,"VaultList":[]} | ||
... | ||
*/ | ||
request(aws4.sign({ service: 'cloudsearch', path: '/?Action=DescribeDomains' })) | ||
/* | ||
<DescribeDomainsResponse xmlns="http://cloudsearch.amazonaws.com/doc/2011-02-01"> | ||
... | ||
*/ | ||
{ | ||
"name": "aws4", | ||
"version": "0.1.3", | ||
"version": "0.1.4", | ||
"description": "Signs and prepares requests using AWS Signature Version 4", | ||
@@ -5,0 +5,0 @@ "author": "Michael Hart <michael.hart.au@gmail.com> (http://github.com/mhart)", |
@@ -26,11 +26,28 @@ aws4 | ||
// opts.headers now contains the signed AWS headers, and is ready for | ||
// use in standard node.js http(s) requests | ||
console.log(opts) | ||
/* | ||
{ | ||
host: 'sqs.us-east-1.amazonaws.com', | ||
path: '/?Action=ListQueues', | ||
headers: { | ||
Host: 'sqs.us-east-1.amazonaws.com', | ||
'X-Amz-Date': '20121226T061030Z', | ||
Authorization: 'AWS4-HMAC-SHA256 Credential=ABCDEF/20121226/us-east-1/sqs/aws4_request, SignedHeaders=host;x-amz-date, Signature=d847efb54cd60f0a256174848f26e43af4b5168dbec3118dc9fd84e942285791' | ||
} | ||
} | ||
*/ | ||
// eg, pipe the SOAP response from the above SQS request to stdout | ||
// we can now use this to query AWS using the standard node.js http API | ||
http.request(opts, function(res) { res.pipe(process.stdout) }).end() | ||
/* | ||
<?xml version="1.0"?> | ||
<ListQueuesResponse xmlns="http://queue.amazonaws.com/doc/2012-11-05/"> | ||
... | ||
*/ | ||
``` | ||
// create a utility function to pipe to stdout (with https this time) | ||
function request(o) { https.request(o, function(res) { res.pipe(process.stdout) }).end(o.body || '') } | ||
More options | ||
------------ | ||
```javascript | ||
// you can pass AWS credentials in explicitly | ||
@@ -42,5 +59,12 @@ aws4.sign(opts, { accessKeyId: '', secretAccessKey: '' }) | ||
// create a utility function to pipe to stdout (with https this time) | ||
function request(o) { https.request(o, function(res) { res.pipe(process.stdout) }).end(o.body || '') } | ||
// aws4 can infer the HTTP method if a body is passed in | ||
// method will be POST and Content-Type: 'application/x-www-form-urlencoded' | ||
request(aws4.sign({ service: 'iam', body: 'Action=ListGroups&Version=2010-05-08' })) | ||
/* | ||
<ListGroupsResponse xmlns="https://iam.amazonaws.com/doc/2010-05-08/"> | ||
... | ||
*/ | ||
@@ -59,2 +83,6 @@ // can specify any custom option or header as per usual | ||
})) | ||
/* | ||
{"TableNames":[]} | ||
... | ||
*/ | ||
@@ -64,6 +92,18 @@ // works with all other services that support Signature Version 4 | ||
request(aws4.sign({ service: 'sts', path: '/?Action=GetSessionToken&Version=2011-06-15' })) | ||
/* | ||
<GetSessionTokenResponse xmlns="https://sts.amazonaws.com/doc/2011-06-15/"> | ||
... | ||
*/ | ||
request(aws4.sign({ service: 'glacier', path: '/-/vaults', headers: { 'X-Amz-Glacier-Version': '2012-06-01' } })) | ||
/* | ||
{"Marker":null,"VaultList":[]} | ||
... | ||
*/ | ||
request(aws4.sign({ service: 'cloudsearch', path: '/?Action=DescribeDomains' })) | ||
/* | ||
<DescribeDomainsResponse xmlns="http://cloudsearch.amazonaws.com/doc/2011-02-01"> | ||
... | ||
*/ | ||
``` | ||
@@ -119,2 +159,11 @@ | ||
Installation | ||
------------ | ||
With [npm](http://npmjs.org/) do: | ||
``` | ||
npm install aws4 | ||
``` | ||
Thanks | ||
@@ -121,0 +170,0 @@ ------ |
@@ -27,2 +27,10 @@ var should = require('should') | ||
describe('#sign() when constructed with string url', function() { | ||
it('should parse into request correctly', function() { | ||
var signer = new aws4.RequestSigner('http://sqs.us-east-1.amazonaws.com/') | ||
signer.request.headers = { Date: date } | ||
signer.sign().headers['Authorization'].should.equal(auth) | ||
}) | ||
}) | ||
describe('#sign() with no credentials', function() { | ||
@@ -38,3 +46,3 @@ it('should use process.env values', function() { | ||
var cred = { accessKeyId: 'A', secretAccessKey: 'B' } | ||
var opts = aws4.sign({ service: 'sqs', headers: { Date: date } }, cred) | ||
, opts = aws4.sign({ service: 'sqs', headers: { Date: date } }, cred) | ||
opts.headers['Authorization'].should.equal( | ||
@@ -41,0 +49,0 @@ 'AWS4-HMAC-SHA256 Credential=A/20121226/us-east-1/sqs/aws4_request, ' + |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
18192
298
175