oauth-sign
Advanced tools
Comparing version 0.3.0 to 0.4.0
52
index.js
@@ -19,2 +19,23 @@ var crypto = require('crypto') | ||
// Maps object to bi-dimensional array | ||
// Converts { foo: 'A', bar: [ 'b', 'B' ]} to | ||
// [ ['foo', 'A'], ['bar', 'b'], ['bar', 'B'] ] | ||
function map (obj) { | ||
var key, val, arr = [] | ||
for (key in obj) { | ||
val = obj[key] | ||
if (Array.isArray(val)) | ||
for (var i = 0; i < val.length; i++) | ||
arr.push([key, val[i]]) | ||
else | ||
arr.push([key, val]) | ||
} | ||
return arr | ||
} | ||
// Compare function for sort | ||
function compare (a, b) { | ||
return a > b ? 1 : a < b ? -1 : 0 | ||
} | ||
function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) { | ||
@@ -24,15 +45,32 @@ // adapted from https://dev.twitter.com/docs/auth/oauth and | ||
var querystring = Object.keys(params).sort().map(function(key){ | ||
// big WTF here with the escape + encoding but it's what twitter wants | ||
return escape(rfc3986(key)) + "%3D" + escape(rfc3986(params[key])) | ||
}).join('%26') | ||
// Parameter normalization | ||
// http://tools.ietf.org/html/rfc5849#section-3.4.1.3.2 | ||
var normalized = map(params) | ||
// 1. First, the name and value of each parameter are encoded | ||
.map(function (p) { | ||
return [ rfc3986(p[0]), rfc3986(p[1] || '') ] | ||
}) | ||
// 2. The parameters are sorted by name, using ascending byte value | ||
// ordering. If two or more parameters share the same name, they | ||
// are sorted by their value. | ||
.sort(function (a, b) { | ||
return compare(a[0], b[0]) || compare(a[1], b[1]) | ||
}) | ||
// 3. The name of each parameter is concatenated to its corresponding | ||
// value using an "=" character (ASCII code 61) as a separator, even | ||
// if the value is empty. | ||
.map(function (p) { return p.join('=') }) | ||
// 4. The sorted name/value pairs are concatenated together into a | ||
// single string by using an "&" character (ASCII code 38) as | ||
// separator. | ||
.join('&') | ||
var base = [ | ||
httpMethod ? httpMethod.toUpperCase() : 'GET', | ||
rfc3986(httpMethod ? httpMethod.toUpperCase() : 'GET'), | ||
rfc3986(base_uri), | ||
querystring | ||
rfc3986(normalized) | ||
].join('&') | ||
var key = [ | ||
consumer_secret, | ||
consumer_secret || '', | ||
token_secret || '' | ||
@@ -39,0 +77,0 @@ ].map(rfc3986).join('&') |
@@ -5,3 +5,3 @@ { | ||
"description": "OAuth 1 signing. Formerly a vendor lib in mikeal/request, now a standalone module.", | ||
"version": "0.3.0", | ||
"version": "0.4.0", | ||
"repository": { | ||
@@ -8,0 +8,0 @@ "url": "https://github.com/mikeal/oauth-sign" |
14
test.js
@@ -49,2 +49,16 @@ var hmacsign = require('./index').hmacsign | ||
// example in rfc5849 | ||
var params = qs.parse('b5=%3D%253D&a3=a&c%40=&a2=r%20b' + '&' + 'c2&a3=2+q') | ||
params.oauth_consumer_key = '9djdj82h48djs9d2' | ||
params.oauth_token = 'kkk9d7dh3k39sjv7' | ||
params.oauth_nonce = '7d8f3e4a' | ||
params.oauth_signature_method = 'HMAC-SHA1' | ||
params.oauth_timestamp = '137131201' | ||
var rfc5849sign = hmacsign('POST', 'http://example.com/request', | ||
params, "j49sk3j29djd", "dh893hdasih9") | ||
console.log(rfc5849sign) | ||
console.log('r6/TJjbCOr97/+UU0NsvSne7s5g=') | ||
assert.equal(rfc5849sign, 'r6/TJjbCOr97/+UU0NsvSne7s5g=') | ||
14563
123