Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch '0.4_compat_fixes'

Conflicts:
	lib/oauth.js
  • Loading branch information...
commit 13d9420c94087ac4f63a1437a54e1e4912af6214 2 parents 40b70bb + 531c088
@ciaranj ciaranj authored
View
7 Readme.md
@@ -7,8 +7,15 @@ Tested against both Twitter (http://twitter.com), term.ie (http://term.ie/oauth
Also provides rudimentary OAuth2 support, tested against facebook connect and github. For more complete usage examples please take a look
at connect-auth (http://github.com/ciaranj/connect-auth)
+If you're running a node.js version more recent than 0.4 then you will need to use a version of node.js greater than or equal to 0.9.0.
+If you're running a node.js version in the 0.2x stable branc, then you will need to use version 0.8.4.
+
+Please be aware that when moving from 0.8.x to 0.9.0 there are no major API changes your, I've bumped the semi-major version element
+so that I can release fixes to the 0.8.x stream if problems come out.
+
Change History
==============
+* 0.9.0 - Compatibility fixes to bring node-oauth up to speed with node.js 0.4x [thanks to Rasmus Andersson for starting the work ]
* 0.8.4 - Fixed issue #14 (Parameter ordering ignored encodings). Added support for repeated parameter names. Implements issue #15 (Use native SHA1 if available, 10x speed improvement!). Fixed issue #16 (Should use POST when requesting access tokens.). Fixed Issue #17 (OAuth2 spec compliance). Implemented enhancement #13 (Adds support for PUT & DELETE http verbs). Fixes issue #18 (Complex/Composite url arguments [thanks novemberborn])
* 0.8.3 - Fixed an issue where the auth header code depended on the Array's toString method (Yohei Sasaki) Updated the getOAuthRequestToken method so we can access google's OAuth secured methods. Also re-implemented and fleshed out the test suite.
* 0.8.2 - The request returning methods will now write the POST body if provided (Chris Anderson), the code responsible for manipulating the headers is a bit safe now when working with other code (Paul McKellar) and tweaked the package.json to use index.js instead of main.js
View
49 examples/term.ie.oauth-PLAINTEXT.js
@@ -2,30 +2,33 @@ var sys= require('sys')
var OAuth= require('../lib/oauth').OAuth;
-var oa= new OAuth("http://term.ie/oauth/example/request_token.php?foo=bar",
- "http://term.ie/oauth/example/access_token.php",
- "key",
- "secret",
- "1.0",
- null,
- "PLAINTEXT")
+var oa = new OAuth("http://term.ie/oauth/example/request_token.php?foo=bar",
+ "http://term.ie/oauth/example/access_token.php",
+ "key",
+ "secret",
+ "1.0",
+ null,
+ "PLAINTEXT")
oa.getOAuthRequestToken(function(error, oauth_token, oauth_token_secret, results){
- if(error) sys.puts('error :' + error)
- else {
- sys.puts('oauth_token :' + oauth_token)
- sys.puts('oauth_token_secret :' + oauth_token_secret)
- sys.puts('requestoken results :' + sys.inspect(results))
- sys.puts("Requesting access token")
- oa.getOAuthAccessToken(oauth_token, oauth_token_secret, function(error, oauth_access_token, oauth_access_token_secret, results2) {
- sys.puts('oauth_access_token :' + oauth_access_token)
- sys.puts('oauth_token_secret :' + oauth_access_token_secret)
- sys.puts('accesstoken results :' + sys.inspect(results2))
- sys.puts("Requesting access token")
- var data= "";
- oa.getProtectedResource("http://term.ie/oauth/example/echo_api.php?foo=bar&too=roo", "GET", oauth_access_token, oauth_access_token_secret, function (error, data, response) {
- sys.puts(data);
- });
+ if (error) return console.log('error :' + error)
+ console.log('oauth_token :' + oauth_token)
+ console.log('oauth_token_secret :' + oauth_token_secret)
+ console.log('requestoken results :', results)
+ console.log("Requesting access token")
+ oa.getOAuthAccessToken(oauth_token, oauth_token_secret,
+ function(error, oauth_access_token,
+ oauth_access_token_secret, results2) {
+ console.log('oauth_access_token :' + oauth_access_token)
+ console.log('oauth_token_secret :' + oauth_access_token_secret)
+ console.log('accesstoken results :', results2)
+ console.log("Requesting access token")
+ var data= "";
+ oa.getProtectedResource(
+ "http://term.ie/oauth/example/echo_api.php?foo=bar&too=roo", "GET",
+ oauth_access_token, oauth_access_token_secret,
+ function (error, data, response) {
+ console.log(data);
});
- }
+ });
})
View
43 lib/oauth.js
@@ -1,6 +1,7 @@
var crypto= require('crypto'),
sha1= require('./sha1'),
http= require('http'),
+ https= require('https'),
URL= require('url'),
querystring= require('querystring');
@@ -193,8 +194,21 @@ exports.OAuth.prototype._getNonce= function(nonceSize) {
return result.join('');
}
-exports.OAuth.prototype._createClient= function( port, hostname, sslEnabled, credentials ) {
- return http.createClient(port, hostname, sslEnabled, credentials);
+exports.OAuth.prototype._createClient= function( port, hostname, method, path, headers, sslEnabled ) {
+ var options = {
+ host: hostname,
+ port: port,
+ path: path,
+ method: method,
+ headers: headers
+ };
+ var httpModel;
+ if( sslEnabled ) {
+ httpModel= https;
+ } else {
+ httpModel= http;
+ }
+ return httpModel.request(options);
}
exports.OAuth.prototype._prepareParameters= function( oauth_token, oauth_token_secret, method, url, extra_params ) {
@@ -248,14 +262,6 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
if( parsedUrl.protocol == "http:" && !parsedUrl.port ) parsedUrl.port= 80;
if( parsedUrl.protocol == "https:" && !parsedUrl.port ) parsedUrl.port= 443;
- var oauthProvider;
- if( parsedUrl.protocol == "https:" ) {
- oauthProvider= this._createClient(parsedUrl.port, parsedUrl.hostname, true, crypto.createCredentials({}));
- }
- else {
- oauthProvider= this._createClient(parsedUrl.port, parsedUrl.hostname);
- }
-
var headers= {};
headers["Authorization"]= this._buildAuthorizationHeaders(orderedParameters);
headers["Host"] = parsedUrl.host
@@ -285,16 +291,23 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
if( parsedUrl.query ) path= parsedUrl.pathname + "?"+ parsedUrl.query ;
else path= parsedUrl.pathname;
- var request = oauthProvider.request(method, path , headers);
+ var request;
+ if( parsedUrl.protocol == "https:" ) {
+ request= this._createClient(parsedUrl.port, parsedUrl.hostname, method, path, headers, true);
+ }
+ else {
+ request= this._createClient(parsedUrl.port, parsedUrl.hostname, method, path, headers);
+ }
+
if( callback ) {
var data="";
var self= this;
- request.addListener('response', function (response) {
+ request.on('response', function (response) {
response.setEncoding('utf8');
- response.addListener('data', function (chunk) {
+ response.on('data', function (chunk) {
data+=chunk;
});
- response.addListener('end', function () {
+ response.on('end', function () {
if( response.statusCode != 200 ) {
callback({ statusCode: response.statusCode, data: data });
} else {
@@ -303,7 +316,7 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke
});
});
- request.socket.addListener("error",callback);
+ request.on("error", callback);
if( (method == "POST" || method =="PUT") && post_body != null && post_body != "" ) {
request.write(post_body);
View
27 lib/oauth2.js
@@ -1,10 +1,8 @@
var querystring= require('querystring'),
crypto= require('crypto'),
- http= require('http'),
+ https= require('https'),
URL= require('url');
-var sys= require('sys');
-
exports.OAuth2= function(clientId, clientSecret, baseSite, authorizePath, accessTokenPath) {
this._clientId= clientId;
this._clientSecret= clientSecret;
@@ -29,7 +27,6 @@ exports.OAuth2.prototype._request= function(method, url, headers, access_token,
var creds = crypto.createCredentials({ });
var parsedUrl= URL.parse( url, true );
if( parsedUrl.protocol == "https:" && !parsedUrl.port ) parsedUrl.port= 443;
- var httpClient = http.createClient(parsedUrl.port, parsedUrl.hostname, true, creds);
var realHeaders= {};
if( headers ) {
@@ -46,17 +43,17 @@ exports.OAuth2.prototype._request= function(method, url, headers, access_token,
parsedUrl.query["access_token"]= access_token;
}
- var request = httpClient.request(method, parsedUrl.pathname + "?" + querystring.stringify(parsedUrl.query), realHeaders );
-
- httpClient.addListener("secure", function () {
-/* // disable verification for now.
+ var result= "";
-var verified = httpClient.verifyPeer();
- if(!verified) this.end(); */
- });
+ var options = {
+ host:parsedUrl.hostname,
+ port: parsedUrl.port,
+ path: parsedUrl.pathname + "?" + querystring.stringify(parsedUrl.query),
+ method: method,
+ headers: realHeaders
+ };
- var result= "";
- request.addListener('response', function (response) {
+ request = https.request(options, function (response) {
response.addListener("data", function (chunk) {
result+= chunk
});
@@ -69,6 +66,10 @@ var verified = httpClient.verifyPeer();
});
});
+ request.on('error', function(e) {
+ callback(e);
+ });
+
request.end();
}
View
256 tests/oauth.js
@@ -126,23 +126,21 @@ vows.describe('OAuth').addBatch({
'When non standard ports are used': {
topic: function() {
var oa= new OAuth(null, null, null, null, null, null, "HMAC-SHA1"),
- mockProvider= {};
-
- mockProvider.request= function(method, path, headers) {
+ mockProvider= {};
+
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
assert.equal(headers.Host, "somehost.com:8080");
- return result= {addListener:function(){},
- end:function(){},
- socket: {addListener: function(){}}};
- }
- oa._createClient= function(port, host) {
- assert.equal(port, '8080');
- assert.equal(host, 'somehost.com');
- return mockProvider;
+ assert.equal(hostname, "somehost.com");
+ assert.equal(port, "8080");
+ return {
+ on: function() {},
+ end: function() {}
+ };
}
return oa;
},
- 'getProtectedResrouce should correctly define the host headers': function(oa) {
- oa.getProtectedResource("http://somehost.com:8080", "GET", "oauth_token", null, function(){require('sys').p('dddd')})
+ 'getProtectedResource should correctly define the host headers': function(oa) {
+ oa.getProtectedResource("http://somehost.com:8080", "GET", "oauth_token", null, function(){})
}
},
'When building the OAuth Authorization header': {
@@ -194,20 +192,13 @@ vows.describe('OAuth').addBatch({
var post_body_written= false;
var op= oa._createClient;
try {
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
return {
- request: function(method, path, headers) {
- return {
- write: function(post_body){
- post_body_written= true;
- assert.equal(post_body,"scope=foobar%2C1%2C2");
- },
- socket: {addListener: function(){}},
- addListener: function() {},
- end: function() {}
- }
+ write: function(post_body){
+ post_body_written= true;
+ assert.equal(post_body,"scope=foobar%2C1%2C2");
}
- }
+ };
}
oa._performSecureRequest("token", "token_secret", 'POST', 'http://foo.com/protected_resource', {"scope": "foobar,1,2"});
assert.equal(post_body_written, true);
@@ -237,19 +228,14 @@ vows.describe('OAuth').addBatch({
var callbackCalled= false;
var op= oa._createClient;
try {
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
return {
- request: function(method, path, headers) {
- return {
- write: function(){},
- socket: {addListener: function(){}},
- addListener: function() {},
- end: function() {
- callbackCalled= true;
- }
- }
+ write: function(){},
+ on: function() {},
+ end: function() {
+ callbackCalled= true;
}
- }
+ };
}
var request= oa.post("http://foo.com/blah", "token", "token_secret", "BLAH", "text/plain", function(e,d){})
assert.equal(callbackCalled, true);
@@ -265,21 +251,17 @@ vows.describe('OAuth').addBatch({
var op= oa._createClient;
try {
var callbackCalled= false;
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded")
return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded")
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
+ write: function(data){
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
+ },
+ on: function() {},
+ end: function() {
}
- }
+ };
}
var request= oa.post("http://foo.com/blah", "token", "token_secret", {"foo":"1,2,3", "bar":"1+2"})
assert.equal(callbackCalled, true);
@@ -295,22 +277,18 @@ vows.describe('OAuth').addBatch({
var op= oa._createClient;
try {
var callbackCalled= false;
- oa._createClient= function() {
- return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded");
- assert.equal(headers["Content-length"], 23);
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
- }
- }
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded");
+ assert.equal(headers["Content-length"], 23);
+ return {
+ write: function(data){
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
+ },
+ on: function() {},
+ end: function() {
+ }
+ };
}
var request= oa.post("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2")
assert.equal(callbackCalled, true);
@@ -325,23 +303,19 @@ vows.describe('OAuth').addBatch({
var op= oa._createClient;
try {
var callbackCalled= false;
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "unicorn/encoded");
+ assert.equal(headers["Content-length"], 23);
return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "unicorn/encoded");
- assert.equal(headers["Content-length"], 23);
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
+ write: function(data){
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
+ },
+ on: function() {},
+ end: function() {
}
- }
- }
+ };
+ }
var request= oa.post("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2", "unicorn/encoded")
assert.equal(callbackCalled, true);
}
@@ -366,18 +340,13 @@ vows.describe('OAuth').addBatch({
var callbackCalled= false;
var op= oa._createClient;
try {
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
return {
- request: function(method, path, headers) {
- return {
- socket: {addListener: function(){}},
- addListener: function() {},
- end: function() {
- callbackCalled= true;
- }
- }
+ on: function() {},
+ end: function() {
+ callbackCalled= true;
}
- }
+ };
}
var request= oa.get("http://foo.com/blah", "token", "token_secret", function(e,d) {})
assert.equal(callbackCalled, true);
@@ -400,25 +369,22 @@ vows.describe('OAuth').addBatch({
},
'if a callback is passed' : {
"it should call the internal request's end method and return nothing": function(oa) {
- var callbackCalled= false;
+ var callbackCalled= 0;
var op= oa._createClient;
try {
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
return {
- request: function(method, path, headers) {
- return {
- write: function(){},
- socket: {addListener: function(){}},
- addListener: function() {},
- end: function() {
- callbackCalled= true;
- }
- }
+ on: function() {},
+ write: function(data) {
+ callbackCalled++;
+ },
+ end: function() {
+ callbackCalled++;
}
- }
+ };
}
var request= oa.put("http://foo.com/blah", "token", "token_secret", "BLAH", "text/plain", function(e,d){})
- assert.equal(callbackCalled, true);
+ assert.equal(callbackCalled, 2);
assert.isUndefined(request);
}
finally {
@@ -431,21 +397,14 @@ vows.describe('OAuth').addBatch({
var op= oa._createClient;
try {
var callbackCalled= false;
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded")
return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded")
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
+ write: function(data) {
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
}
- }
+ };
}
var request= oa.put("http://foo.com/blah", "token", "token_secret", {"foo":"1,2,3", "bar":"1+2"})
assert.equal(callbackCalled, true);
@@ -458,25 +417,18 @@ vows.describe('OAuth').addBatch({
'if the post_body is a string' : {
"and no post_content_type is specified" : {
"It should be written as is, with a content length specified, and the encoding should be set to be x-www-form-urlencoded" : function(oa) {
- var op= oa._createClient;
- try {
- var callbackCalled= false;
- oa._createClient= function() {
+ var op= oa._createClient;
+ try {
+ var callbackCalled= false;
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded");
+ assert.equal(headers["Content-length"], 23);
return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded");
- assert.equal(headers["Content-length"], 23);
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
+ write: function(data) {
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
}
- }
+ };
}
var request= oa.put("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2")
assert.equal(callbackCalled, true);
@@ -491,22 +443,15 @@ vows.describe('OAuth').addBatch({
var op= oa._createClient;
try {
var callbackCalled= false;
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
+ assert.equal(headers["Content-Type"], "unicorn/encoded");
+ assert.equal(headers["Content-length"], 23);
return {
- request: function(method, path, headers) {
- assert.equal(headers["Content-Type"], "unicorn/encoded");
- assert.equal(headers["Content-length"], 23);
- return {
- socket: {addListener: function(){}},
- write: function(data) {
- callbackCalled= true;
- assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
- },
- addListener: function() {},
- end: function() {}
- }
- }
- }
+ write: function(data) {
+ callbackCalled= true;
+ assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2");
+ }
+ };
}
var request= oa.put("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2", "unicorn/encoded")
assert.equal(callbackCalled, true);
@@ -532,18 +477,13 @@ vows.describe('OAuth').addBatch({
var callbackCalled= false;
var op= oa._createClient;
try {
- oa._createClient= function() {
+ oa._createClient= function( port, hostname, method, path, headers, sshEnabled ) {
return {
- request: function(method, path, headers) {
- return {
- socket: {addListener: function(){}},
- addListener: function() {},
- end: function() {
- callbackCalled= true;
- }
- }
+ on: function() {},
+ end: function() {
+ callbackCalled= true;
}
- }
+ };
}
var request= oa.delete("http://foo.com/blah", "token", "token_secret", function(e,d) {})
assert.equal(callbackCalled, true);
Please sign in to comment.
Something went wrong with that request. Please try again.