Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixes to Foursquare code. Now supporting LinkedIn.
  • Loading branch information
bnoguchi committed Apr 15, 2011
1 parent a942116 commit 2181c51
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 11 deletions.
2 changes: 1 addition & 1 deletion index.js
Expand Up @@ -72,7 +72,7 @@ everyauth

everyauth.modules = {};
everyauth.enabled = {};
var includeModules = [['everymodule', false], ['password', true], ['oauth', false], ['twitter', true]
var includeModules = [['everymodule', false], ['password', true], ['oauth', false], ['twitter', true], ['linkedin', true]
, ['oauth2', false], ['facebook', true], ['github', true], ['instagram', true], ['foursquare', true]];

for (var i = 0, l = includeModules.length; i < l; i++) {
Expand Down
21 changes: 16 additions & 5 deletions lib/foursquare.js
@@ -1,5 +1,6 @@
var oauthModule = require('./oauth2')
, Promise = require('./promise');
, Promise = require('./promise')
, rest = require('restler');

var foursquare = module.exports =
oauthModule.submodule('foursquare')
Expand All @@ -14,14 +15,24 @@ oauthModule.submodule('foursquare')

.authQueryParam('response_type', 'code')

.accessTokenHttpMethod('get')
.accessTokenParam('grant_type', 'authorization_code')

.fetchOAuthUser( function (accessToken, accessTokenSecret, params) {
.fetchOAuthUser( function (accessToken) {
console.log(arguments);
var promise = new Promise();
this.oauth.get(this.apiHost() + '/users/self', accessToken, accessTokenSecret, function (err, data) {
if (err) return promise.fail(err);
var oauthUser = JSON.parse(data).response.user;
rest.get(this.apiHost() + '/users/self', {
query: { oauth_token: accessToken }
}).on('success', function (data, res) {
var oauthUser = data.response.user;
promise.fulfill(oauthUser);
}).on('error', function (data, res) {
promise.fail(err);
});
return promise;
})

.convertErr( function (data) {
var errMsg = JSON.parse(data.data).meta.errorDetail;
return new Error(errMsg);
});
51 changes: 51 additions & 0 deletions lib/linkedin.js
@@ -0,0 +1,51 @@
var oauthModule = require('./oauth')
, Promise = require('./promise')
, OAuth = require('oauth').OAuth;

var linkedin = module.exports =
oauthModule.submodule('linkedin')
.definit( function () {
this.oauth = new OAuth(
this.oauthHost() + this.requestTokenPath()
, this.oauthHost() + this.accessTokenPath()
, this.consumerKey()
, this.consumerSecret()
, '1.0', null, 'HMAC-SHA1', null
, {
Accept: '/'
, Connection: 'close'
, 'User-Agent': 'Node authentication'
, 'x-li-format': 'json' // So we get JSON responses
});
})

.apiHost('https://api.linkedin.com/v1')
.oauthHost('https://api.linkedin.com')

.requestTokenPath('/uas/oauth/requestToken')
.authorizePath('/uas/oauth/authorize')
.accessTokenPath('/uas/oauth/accessToken')

.entryPath('/auth/linkedin')
.callbackPath('/auth/linkedin/callback')

.redirectToProviderAuth( function (res, token) {
res.writeHead(303, { 'Location': 'https://www.linkedin.com' + this.authorizePath() + '?oauth_token=' + token });
res.end();
})

.fetchOAuthUser( function (accessToken, accessTokenSecret, params) {
var promise = new Promise();
this.oauth.get(this.apiHost() + '/people/~:(id,first-name,last-name,headline,location:(name,country:(code)),industry,num-connections,num-connections-capped,summary,specialties,proposal-comments,associations,honors,interests,positions,publications,patents,languages,skills,certifications,educations,three-current-positions,three-past-positions,num-recommenders,recommendations-received,phone-numbers,im-accounts,twitter-accounts,date-of-birth,main-address,member-url-resources,picture-url,site-standard-profile-request:(url),api-standard-profile-request:(url,headers),public-profile-url)', accessToken, accessTokenSecret, function (err, data) {
if (err) return promise.fail(err);
var oauthUser = JSON.parse(data);
console.log(oauthUser);
promise.fulfill(oauthUser);
});
return promise;
})
.convertErr( function (data) {
var errJson = JSON.parse(data.data)
, errMsg = errJson.message;
return new Error(errMsg);
});
11 changes: 8 additions & 3 deletions lib/oauth.js
Expand Up @@ -10,15 +10,17 @@ everyModule.submodule('oauth')
, oauthHost: 'the host for the OAuth provider'
, requestTokenPath: "the path on the OAuth provider's domain where we request the request token, e.g., /oauth/request_token"
, accessTokenPath: "the path on the OAuth provider's domain where we request the access token, e.g., /oauth/access_token"
, authorizePath: 'the path on the OAuth provider where you direct a visitor to login, e.g., /oauth/authorize'
, consumerKey: 'the api key provided by the OAuth provider'
, consumerSecret: 'the api secret provided by the OAuth provider'
, myHostname: 'e.g., http://localhost:3000 . Notice no trailing slash'
, redirectPath: 'Where to redirect to after a failed or successful OAuth authorization'
, convertErr: 'a function (data) that extracts an error message from data arg, where `data` is what is returned from a failed OAuth request'
})
.definit( function () {
this.oauth = new OAuth(
this.apiHost() + this.requestTokenPath()
, this.apiHost() + this.accessTokenPath()
this.oauthHost() + this.requestTokenPath()
, this.oauthHost() + this.accessTokenPath()
, this.consumerKey()
, this.consumerSecret()
, '1.0', null, 'HMAC-SHA1');
Expand Down Expand Up @@ -57,6 +59,7 @@ everyModule.submodule('oauth')
.step('fetchOAuthUser')
.accepts('accessToken accessTokenSecret params')
.promises('oauthUser')
.stepTimeout(8000)
.step('findOrCreateUser')
.accepts('session accessToken accessTokenSecret oauthUser')
.promises('user')
Expand Down Expand Up @@ -85,7 +88,7 @@ everyModule.submodule('oauth')
_provider.tokenSecret = tokenSecret;
})
.redirectToProviderAuth( function (res, token) {
res.writeHead(303, { 'Location': 'http://twitter.com/oauth/authenticate?oauth_token=' + token });
res.writeHead(303, { 'Location': this.oauthHost() + this.authorizePath() + '?oauth_token=' + token });
res.end();
})

Expand Down Expand Up @@ -142,6 +145,8 @@ everyModule.submodule('oauth')
res.end();
});

// Defaults inherited by submodules
oauth
.requestTokenPath('/oauth/request_token')
.authorizePath('/oauth/authorize')
.accessTokenPath('/oauth/access_token');
4 changes: 3 additions & 1 deletion lib/oauth2.js
Expand Up @@ -23,6 +23,7 @@ everyModule.submodule('oauth2')
"we direct the user for authentication, e.g., /oauth/authorize"
, accessTokenPath: "the path on the OAuth provider's domain " +
"where we request the access token, e.g., /oauth/access_token"
, accessTokenHttpMethod: 'the http method ("get" or "post") with which to make our access token request'
, postAccessTokenParamsVia: '"query" to POST the params to the access ' +
'token endpoint as a querysting; "data" to POST the params to ' +
'the access token endpoint in the request body'
Expand Down Expand Up @@ -112,7 +113,7 @@ everyModule.submodule('oauth2')

var opts = {};
opts[this.postAccessTokenParamsVia()] = params;
rest.post(url, opts)
rest[this.accessTokenHttpMethod()].call(rest, url, opts)
.on('success', function (data, res) {
if ('string' === typeof data) {
data = querystring.parse(data);
Expand Down Expand Up @@ -172,6 +173,7 @@ oauth2.cloneOnSubmodule.push('moreAuthQueryParams', 'moreAccessTokenParams');
oauth2
.authPath('/oauth/authorize')
.accessTokenPath('/oauth/access_token')
.accessTokenHttpMethod('post')
.postAccessTokenParamsVia('query');

// Add or over-write existing query params that
Expand Down
2 changes: 1 addition & 1 deletion lib/twitter.js
Expand Up @@ -15,4 +15,4 @@ oauthModule.submodule('twitter')
promise.fulfill(oauthUser);
});
return promise;
})
});

0 comments on commit 2181c51

Please sign in to comment.