Skip to content
This repository was archived by the owner on Feb 13, 2018. It is now read-only.

Commit 94c31e8

Browse files
author
Tim Whitlock
committed
major oauth character encoding fix
1 parent a23170b commit 94c31e8

File tree

1 file changed

+29
-4
lines changed

1 file changed

+29
-4
lines changed

lib/twitter.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
// pseudo constants
88
//
99
var TWITTER_API_TIMEOUT = 10000,
10-
TWITTER_API_USERAGENT = 'Node/'+process.version.substr(1),
10+
TWITTER_API_USERAGENT = 'Node/'+process.version.substr(1)+'; https://github.com/timwhitlock/node-twitter-api',
1111
TWITTER_API_BASE = 'https://api.twitter.com/1.1',
1212
TWITTER_STREAM_BASE = 'https://stream.twitter.com/1.1',
1313
TWITTER_OAUTH_REQUEST_TOKEN_URL = 'https://twitter.com/oauth/request_token',
@@ -18,7 +18,31 @@ var TWITTER_API_TIMEOUT = 10000,
1818
TWITTER_OAUTH2_INVALIDATE_URL = 'https://api.twitter.com/oauth2/invalidate_token';
1919

2020

21+
/**
22+
* OAuth safe encodeURIComponent of string
23+
* handles ignored characters that OAuth expects encoded "! * ' ( )"
24+
*/
25+
function uriEncodeString( text ){
26+
return encodeURIComponent(text).replace( /[\!\*\'\(\)]/g, function( chr ){
27+
chr = chr.charCodeAt(0).toString(16);
28+
while( chr.length < 2 ){
29+
chr = '0'+hex;
30+
}
31+
return '%'+chr;
32+
} )
33+
}
34+
2135

36+
/**
37+
* OAuth safe encodeURIComponent of params object
38+
*/
39+
function uriEncodeParams( obj ){
40+
var pairs = [], key;
41+
for( key in obj ){
42+
pairs.push( uriEncodeString(key) +'='+ uriEncodeString(obj[key]) );
43+
}
44+
return pairs.join('&');
45+
}
2246

2347

2448
/**
@@ -87,7 +111,7 @@ OAuthParams.prototype.normalize = function(){
87111
}
88112

89113
OAuthParams.prototype.serialize = function(){
90-
return require('querystring').stringify( this.args );
114+
return uriEncodeParams( this.args );
91115
}
92116

93117
OAuthParams.prototype.sign = function( requestMethod, requestUri ){
@@ -99,8 +123,8 @@ OAuthParams.prototype.sign = function( requestMethod, requestUri ){
99123
delete this.args.oauth_signature;
100124
// normalize, build and sign
101125
this.normalize();
102-
var str = requestMethod.toUpperCase() +'&'+ encodeURIComponent(requestUri) +'&'+ encodeURIComponent(this.serialize()),
103-
key = encodeURIComponent(this.consumer_secret) +'&'+ encodeURIComponent(this.token_secret),
126+
var str = requestMethod.toUpperCase() +'&'+ uriEncodeString(requestUri) +'&'+ uriEncodeString(this.serialize()),
127+
key = uriEncodeString(this.consumer_secret) +'&'+ uriEncodeString(this.token_secret),
104128
hash = require('crypto').createHmac('sha1',key).update(str);
105129
this.args.oauth_signature = hash.digest('base64');
106130
return this;
@@ -309,6 +333,7 @@ TwitterClient.prototype._call = function( requestMethod, requestUri, requestArgs
309333
authHeader = params.getHeader();
310334
}
311335
var query = params.serialize();
336+
312337
// build http request starting with parsed endpoint
313338
var http = require('url').parse( requestUri );
314339
http.headers = {

0 commit comments

Comments
 (0)