Skip to content

Commit

Permalink
Merge pull request #42 from jeremyruppel/oauth
Browse files Browse the repository at this point in the history
Make OAuth nonce time-independent
  • Loading branch information
jeremyruppel authored Oct 27, 2016
2 parents 4bd0acd + dc72447 commit ab7c78d
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 24 deletions.
30 changes: 13 additions & 17 deletions services/oauth.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
var request = require('superagent');
var crypto = require('crypto');

/**
* Returns a nonce for the timestamp `time`. OAuth 1.0 defines a
* nonce as a value unique to a given timestamp.
* @param {Number} time
* @returns {String}
* @see https://oauth.net/core/1.0a/#nonce
* @private
*/

function nonce(time) {
return crypto.createHash('sha1').update(String(time)).digest('hex');
}

/**
* Returns the HMAC-SHA1 digest of `text` and `key` in baset64 encoding.
* @param {String} text
Expand Down Expand Up @@ -142,18 +129,27 @@ OAuth.prototype.timestamp = function () {
return Math.floor(Date.now() / 1000);
};

/**
* Generates a pseudo-random string. OAuth 1.0 defines a
* nonce as a value unique within a given timestamp in seconds.
* @returns {String}
* @see https://oauth.net/core/1.0a/#nonce
*/

OAuth.prototype.nonce = function () {
return crypto.pseudoRandomBytes(32).toString('base64');
};

/**
* Creates an object with the standard OAuth 1.0 query params
* for this instance.
* @returns {Object}
*/

OAuth.prototype.params = function () {
var timestamp = this.timestamp();

return {
oauth_nonce: nonce(timestamp),
oauth_timestamp: timestamp,
oauth_nonce: this.nonce(),
oauth_timestamp: this.timestamp(),
oauth_consumer_key: this.consumerKey,
oauth_signature_method: 'HMAC-SHA1',
oauth_version: '1.0'
Expand Down
5 changes: 3 additions & 2 deletions test/plugins.oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ describe('plugins/oauth', function () {
beforeEach(function () {
sandbox = sinon.sandbox.create();
sandbox.stub(OAuth.prototype, 'timestamp').returns(499166400);
sandbox.stub(OAuth.prototype, 'nonce').returns('p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=');
});

afterEach(function () {
Expand All @@ -21,13 +22,13 @@ describe('plugins/oauth', function () {
var api = nock('https://api.flickr.com')
.get('/services/rest')
.query({
oauth_nonce: '2114a105bc84fafbd4a05333b0b7f836c5dba8db',
oauth_nonce: 'p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=',
oauth_consumer_key: 'consumer key',
oauth_token: 'oauth token',
oauth_version: '1.0',
oauth_timestamp: 499166400,
oauth_signature_method: 'HMAC-SHA1',
oauth_signature: 'a8DFIqDyb0o1tnB2XeqM85RFz6o=',
oauth_signature: '5WSz6hwZ6F8jbeYv3eyErif1ySo=',
method: 'flickr.test.echo',
foo: 'bar',
format: 'json',
Expand Down
31 changes: 26 additions & 5 deletions test/services.oauth.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ describe('services/oauth', function () {
beforeEach(function () {
subject = new OAuth('consumer key', 'consumer secret');
sinon.stub(subject, 'timestamp').returns(499166400);
sinon.stub(subject, 'nonce').returns('p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=');
});

describe('#request', function () {
Expand All @@ -18,13 +19,13 @@ describe('services/oauth', function () {
var api = nock('https://www.flickr.com')
.get('/services/oauth/request_token')
.query({
oauth_nonce: '2114a105bc84fafbd4a05333b0b7f836c5dba8db',
oauth_nonce: 'p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=',
oauth_timestamp: 499166400,
oauth_consumer_key: subject.consumerKey,
oauth_signature_method: 'HMAC-SHA1',
oauth_version: '1.0',
oauth_callback: 'https://www.example.com/callback',
oauth_signature: 'n9Lnt7f7j9LrDJ0U6X30SSHSmW4='
oauth_signature: 'JC6IWgvysQg30vh3Xk6TjARQWps='
})
.reply(200, 'oauth_callback_confirmed=true&oauth_token=foo&oauth_token_secret=bar');

Expand All @@ -48,12 +49,12 @@ describe('services/oauth', function () {
.query({
oauth_token: 'token',
oauth_verifier: 'verfier',
oauth_nonce: '2114a105bc84fafbd4a05333b0b7f836c5dba8db',
oauth_nonce: 'p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=',
oauth_timestamp: 499166400,
oauth_consumer_key: subject.consumerKey,
oauth_signature_method: 'HMAC-SHA1',
oauth_version: '1.0',
oauth_signature: 'kdVh2jMIk5AGoN/63AGQ4kexpSg='
oauth_signature: '7+3k1AWzUyxOoNO4rymh0Txz5FA='
})
.reply(200, 'fullname=Jamal%20Fanaian&oauth_token=foo&oauth_token_secret=bar&user_nsid=21207597%40N07&username=jamalfanaian');

Expand Down Expand Up @@ -82,12 +83,32 @@ describe('services/oauth', function () {

});

describe('#nonce', function () {

beforeEach(function () {
sinon.restore(subject.nonce);
});

it('returns a string', function () {
assert.equal(typeof subject.nonce(), 'string');
});

it('returns 32 bytes of data', function () {
assert.equal(Buffer.byteLength(subject.nonce(), 'base64'), 32);
});

it('does not return the same nonce twice', function () {
assert.notEqual(subject.nonce(), subject.nonce());
});

});

describe('#params', function () {

it('returns OAuth 1.0 params', function () {
var params = subject.params();

assert.equal(params.oauth_nonce, '2114a105bc84fafbd4a05333b0b7f836c5dba8db');
assert.equal(params.oauth_nonce, 'p2m2bnHdXVIsQH0FUv0oN9XrJU57ak7dSSpHU36mn4k=');
assert.equal(params.oauth_timestamp, 499166400);
assert.equal(params.oauth_consumer_key, subject.consumerKey);
assert.equal(params.oauth_signature_method, 'HMAC-SHA1');
Expand Down

0 comments on commit ab7c78d

Please sign in to comment.