diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/Readme.md b/Readme.md index d126d99..1b30f98 100644 --- a/Readme.md +++ b/Readme.md @@ -10,8 +10,9 @@ Also provides rudimentary OAuth2 support, tested against facebook connect and gi Change History ============== -* 0.9.3 - Adds support for following 301 redirects (Thanks bdickason) -* 0.9.2 - Correct content length calculated for non-ascii post bodies (Thanks selead) +* 0.9.4 - Support for OAuth providers that drop connections (don't send response lengths? [Google]) And change OAuth2 getOAuthAccessToken to POST rather than GET ( Possible Breaking change!!! ... re-tested against Google, Github, Facebook, FourSquare and Janrain and seems ok .. is closer to the spec (v20) ) +* 0.9.3 - Adds support for following 301 redirects (Thanks bdickason) +* 0.9.2 - Correct content length calculated for non-ascii post bodies (Thanks selead) Allowed for configuration of the 'access token' name used when requesting protected resources (OAuth2) * 0.9.1 - Added support for automatically following 302 redirects (Thanks neyric) Added support for OAuth Echo (Thanks Ryan LeFevre). Improved handling of 2xx responses (Thanks Neil Mansilla). * 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 ] @@ -20,7 +21,7 @@ Allowed for configuration of the 'access token' name used when requesting protec * 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 * 0.8.1 - Added mechanism to get hold of a signed Node Request object, ready for attaching response listeners etc. (Perfect for streaming APIs) * 0.8.0 - Standardised method capitalisation, the old getOauthAccessToken is now getOAuthAccessToken (Breaking change to existing code) -* 0.7.7 - Looks like non oauth_ parameters where appearing within the Authorization headers, which I believe to be inccorrect. +* 0.7.7 - Looks like non oauth_ parameters where appearing within the Authorization headers, which I believe to be incorrect. * 0.7.6 - Added in oauth_verifier property to getAccessToken required for 1.0A * 0.7.5 - Added in a main.js to simplify the require'ing of OAuth * 0.7.4 - Minor change to add an error listener to the OAuth client (thanks troyk) diff --git a/lib/oauth2.js b/lib/oauth2.js index 7b841fa..1906235 100644 --- a/lib/oauth2.js +++ b/lib/oauth2.js @@ -22,16 +22,11 @@ exports.OAuth2.prototype.setAccessTokenName= function ( name ) { this._accessTokenName= name; } -exports.OAuth2.prototype._getAccessTokenUrl= function( params ) { - var params= params || {}; - params['client_id'] = this._clientId; - params['client_secret'] = this._clientSecret; - params['type']= 'web_server'; - - return this._baseSite + this._accessTokenUrl + "?" + querystring.stringify(params); +exports.OAuth2.prototype._getAccessTokenUrl= function() { + return this._baseSite + this._accessTokenUrl; /* + "?" + querystring.stringify(params); */ } -exports.OAuth2.prototype._request= function(method, url, headers, access_token, callback) { +exports.OAuth2.prototype._request= function(method, url, headers, post_body, access_token, callback) { var creds = crypto.createCredentials({ }); var parsedUrl= URL.parse( url, true ); @@ -45,19 +40,19 @@ exports.OAuth2.prototype._request= function(method, url, headers, access_token, } realHeaders['Host']= parsedUrl.host; - //TODO: Content length should be dynamic when dealing with POST methods.... - realHeaders['Content-Length']= 0; + realHeaders['Content-Length']= post_body ? Buffer.byteLength(post_body) : 0; if( access_token ) { if( ! parsedUrl.query ) parsedUrl.query= {}; parsedUrl.query[this._accessTokenName]= access_token; } var result= ""; - + var queryStr= querystring.stringify(parsedUrl.query); + if( queryStr ) queryStr= "?" + queryStr; var options = { host:parsedUrl.hostname, port: parsedUrl.port, - path: parsedUrl.pathname + "?" + querystring.stringify(parsedUrl.query), + path: parsedUrl.pathname + queryStr, method: method, headers: realHeaders }; @@ -90,12 +85,14 @@ exports.OAuth2.prototype._request= function(method, url, headers, access_token, passBackControl( response, result ); }); }); - request.on('error', function(e) { callbackCalled= true; callback(e); }); + if( method == 'POST' && post_body ) { + request.write(post_body); + } request.end(); } @@ -109,9 +106,19 @@ exports.OAuth2.prototype.getAuthorizeUrl= function( params ) { exports.OAuth2.prototype.getOAuthAccessToken= function(code, params, callback) { var params= params || {}; + params['client_id'] = this._clientId; + params['client_secret'] = this._clientSecret; + params['type']= 'web_server'; params['code']= code; - this._request("POST", this._getAccessTokenUrl(params), {}, null, function(error, data, response) { + var post_data= querystring.stringify( params ); + var post_headers= { + 'Content-Type': 'application/x-www-form-urlencoded' + }; + + + this._request("POST", this._getAccessTokenUrl(), post_headers, post_data, null, function(error, data, response) { + console.log( 'e> ' + error) if( error ) callback(error); else { var results; @@ -137,9 +144,9 @@ exports.OAuth2.prototype.getOAuthAccessToken= function(code, params, callback) { // Deprecated exports.OAuth2.prototype.getProtectedResource= function(url, access_token, callback) { - this._request("GET", url, {}, access_token, callback ); + this._request("GET", url, {}, "", access_token, callback ); } exports.OAuth2.prototype.get= function(url, access_token, callback) { - this._request("GET", url, {}, access_token, callback ); + this._request("GET", url, {}, "", access_token, callback ); } diff --git a/package.json b/package.json index 31b4e94..cf9a513 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,11 @@ { "name" : "oauth" , "description" : "Library for interacting with OAuth 1.0, 1.0A, 2 and Echo. Provides simplified client access and allows for construction of more complex apis and OAuth providers." -, "version" : "0.9.3" +, "version" : "0.9.4" , "directories" : { "lib" : "./lib" } , "main" : "index.js" , "author" : "Ciaran Jessup " , "repository" : { "type":"git", "url":"http://github.com/ciaranj/node-oauth.git" } +, "devDependencies": { + "vows": "0.5.x" + } } diff --git a/tests/oauth2.js b/tests/oauth2.js index 4b49a44..efe8224 100644 --- a/tests/oauth2.js +++ b/tests/oauth2.js @@ -6,7 +6,7 @@ vows.describe('OAuth2').addBatch({ 'When handling the access token response': { topic: new OAuth2(), 'we should correctly extract the token if received as form-data': function (oa) { - oa._request= function( method, url, fo, bar, callback) { + oa._request= function( method, url, fo, bar, bleh, callback) { callback(null, "access_token=access&refresh_token=refresh"); }; oa.getOAuthAccessToken("", {}, function(error, access_token, refresh_token) { @@ -15,7 +15,7 @@ vows.describe('OAuth2').addBatch({ }); }, 'we should correctly extract the token if received as a JSON literal': function (oa) { - oa._request= function( method, url, fo, bar, callback) { + oa._request= function(method, url, headers, post_body, access_token, callback) { callback(null, '{"access_token":"access","refresh_token":"refresh"}'); }; oa.getOAuthAccessToken("", {}, function(error, access_token, refresh_token) {