index.js 1.06 KB
var crypto = require('crypto')
  , qs = require('querystring')
  ;

function sha1 (key, body) {
  return crypto.createHmac('sha1', key).update(body).digest('base64')
}

function rfc3986 (str) {
  return encodeURIComponent(str)
    .replace(/!/g,'%21')
    .replace(/\*/g,'%2A')
    .replace(/\(/g,'%28')
    .replace(/\)/g,'%29')
    .replace(/'/g,'%27')
    ;
}

function hmacsign (httpMethod, base_uri, params, consumer_secret, token_secret) {
  // adapted from https://dev.twitter.com/docs/auth/oauth and 
  // https://dev.twitter.com/docs/auth/creating-signature

  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')

  var base = [
    httpMethod ? httpMethod.toUpperCase() : 'GET',
    rfc3986(base_uri),
    querystring
  ].join('&')

  var key = [
    consumer_secret,
    token_secret || ''
  ].map(rfc3986).join('&')

  return sha1(key, base)
}

exports.hmacsign = hmacsign
exports.rfc3986 = rfc3986