Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Implement support for extended profile info.

  • Loading branch information...
commit f3be40cf56cb28d0836761a7d3f9f77c86981683 1 parent 0d31469
Jared Hanson authored March 05, 2012
37  lib/passport-twitter/strategy.js
@@ -48,6 +48,8 @@ function Strategy(options, verify) {
48 48
   
49 49
   OAuthStrategy.call(this, options, verify);
50 50
   this.name = 'twitter';
  51
+  
  52
+  this._skipExtendedUserProfile = (options.skipExtendedUserProfile === undefined) ? false : options.skipExtendedUserProfile;
51 53
 }
52 54
 
53 55
 /**
@@ -89,7 +91,8 @@ Strategy.prototype.authenticate = function(req) {
89 91
  *
90 92
  * Note that because Twitter supplies basic profile information in query
91 93
  * parameters when redirecting back to the application, loading of Twitter
92  
- * profiles *does not* result in an additional HTTP request.
  94
+ * profiles *does not* result in an additional HTTP request, when the
  95
+ * `skipExtendedUserProfile` is enabled.
93 96
  *
94 97
  * @param {String} token
95 98
  * @param {String} tokenSecret
@@ -98,11 +101,33 @@ Strategy.prototype.authenticate = function(req) {
98 101
  * @api protected
99 102
  */
100 103
 Strategy.prototype.userProfile = function(token, tokenSecret, params, done) {
101  
-  var profile = { provider: 'twitter' };
102  
-  profile.id = params.user_id;
103  
-  profile.username = params.screen_name;
104  
-  
105  
-  return done(null, profile);
  104
+  if (!this._skipExtendedUserProfile) {
  105
+    this._oauth.get('https://api.twitter.com/1/users/show.json?user_id=' + params.user_id, token, tokenSecret, function (err, body, res) {
  106
+      if (err) { return done(err); }
  107
+      
  108
+      try {
  109
+        var json = JSON.parse(body);
  110
+      
  111
+        var profile = { provider: 'twitter' };
  112
+        profile.id = json.id;
  113
+        profile.username = json.screen_name;
  114
+        profile.displayName = json.name;
  115
+      
  116
+        profile._raw = body;
  117
+        profile._json = json;
  118
+      
  119
+        done(null, profile);
  120
+      } catch(e) {
  121
+        done(e);
  122
+      }
  123
+    });
  124
+  } else {
  125
+    var profile = { provider: 'twitter' };
  126
+    profile.id = params.user_id;
  127
+    profile.username = params.screen_name;
  128
+
  129
+    done(null, profile);
  130
+  }
106 131
 }
107 132
 
108 133
 
108  test/strategy-test.js
@@ -18,6 +18,71 @@ vows.describe('TwitterStrategy').addBatch({
18 18
     'should be named twitter': function (strategy) {
19 19
       assert.equal(strategy.name, 'twitter');
20 20
     },
  21
+  },
  22
+  
  23
+  'strategy when loading user profile': {
  24
+    topic: function() {
  25
+      var strategy = new TwitterStrategy({
  26
+        consumerKey: 'ABC123',
  27
+        consumerSecret: 'secret'
  28
+      },
  29
+      function() {});
  30
+      
  31
+      // mock
  32
+      strategy._oauth.get = function(url, token, tokenSecret, callback) {
  33
+        var body = '{"id_str":"6253282","id":6253282,"profile_text_color":"437792","created_at":"Wed May 23 06:01:13 +0000 2007","contributors_enabled":true,"follow_request_sent":null,"lang":"en","listed_count":10154,"profile_sidebar_border_color":"0094C2","show_all_inline_media":false,"friends_count":34,"utc_offset":-28800,"location":"San Francisco, CA","name":"Twitter API","profile_background_tile":false,"profile_sidebar_fill_color":"a9d9f1","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1438634086\/avatar_normal.png","protected":false,"geo_enabled":true,"following":null,"default_profile_image":false,"statuses_count":3252,"is_translator":false,"favourites_count":22,"profile_background_color":"e8f2f7","description":"The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Do not get an answer? It is on my website.","time_zone":"Pacific Time (US & Canada)","screen_name":"twitterapi","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/229557229\/twitterapi-bg.png","profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1438634086\/avatar_normal.png","profile_link_color":"0094C2","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/229557229\/twitterapi-bg.png","followers_count":931299,"status":{"in_reply_to_status_id_str":null,"in_reply_to_user_id_str":null,"retweeted":false,"coordinates":null,"in_reply_to_screen_name":null,"created_at":"Tue Feb 14 23:39:43 +0000 2012","possibly_sensitive":false,"contributors":null,"in_reply_to_status_id":null,"entities":{"urls":[{"display_url":"tmblr.co\/ZgBqayGQi3ls","indices":[106,126],"expanded_url":"http:\/\/tmblr.co\/ZgBqayGQi3ls","url":"http:\/\/t.co\/cOzUfFNW"}],"user_mentions":[],"hashtags":[]},"geo":null,"in_reply_to_user_id":null,"place":null,"favorited":false,"truncated":false,"id_str":"169566520693882882","id":169566520693882882,"retweet_count":82,"text":"Photo Upload Issue - Some users may be experiencing an issue when uploading a photo. Our engineers are... http:\/\/t.co\/cOzUfFNW"},"default_profile":false,"notifications":null,"url":"http:\/\/dev.twitter.com","profile_use_background_image":true,"verified":true}';
  34
+        
  35
+        callback(null, body, undefined);
  36
+      }
  37
+      
  38
+      return strategy;
  39
+    },
  40
+    
  41
+    'when told to load user profile': {
  42
+      topic: function(strategy) {
  43
+        var self = this;
  44
+        function done(err, profile) {
  45
+          self.callback(err, profile);
  46
+        }
  47
+        
  48
+        process.nextTick(function () {
  49
+          strategy.userProfile('token', 'token-secret', {}, done);
  50
+        });
  51
+      },
  52
+      
  53
+      'should not error' : function(err, req) {
  54
+        assert.isNull(err);
  55
+      },
  56
+      'should load profile' : function(err, profile) {
  57
+        assert.equal(profile.provider, 'twitter');
  58
+        assert.equal(profile.id, '6253282');
  59
+        assert.equal(profile.username, 'twitterapi');
  60
+        assert.equal(profile.displayName, 'Twitter API');
  61
+      },
  62
+      'should set raw property' : function(err, profile) {
  63
+        assert.isString(profile._raw);
  64
+      },
  65
+      'should set json property' : function(err, profile) {
  66
+        assert.isObject(profile._json);
  67
+      },
  68
+    },
  69
+  },
  70
+  
  71
+  'strategy when loading user profile and encountering an error': {
  72
+    topic: function() {
  73
+      var strategy = new TwitterStrategy({
  74
+        consumerKey: 'ABC123',
  75
+        consumerSecret: 'secret'
  76
+      },
  77
+      function() {});
  78
+      
  79
+      // mock
  80
+      strategy._oauth.get = function(url, token, tokenSecret, callback) {
  81
+        callback(new Error('something went wrong'));
  82
+      }
  83
+      
  84
+      return strategy;
  85
+    },
21 86
     
22 87
     'when told to load user profile': {
23 88
       topic: function(strategy) {
@@ -25,8 +90,49 @@ vows.describe('TwitterStrategy').addBatch({
25 90
         function done(err, profile) {
26 91
           self.callback(err, profile);
27 92
         }
  93
+        
  94
+        process.nextTick(function () {
  95
+          strategy.userProfile('token', 'token-secret', {}, done);
  96
+        });
  97
+      },
  98
+      
  99
+      'should error' : function(err, req) {
  100
+        assert.isNotNull(err);
  101
+      },
  102
+      'should not load profile' : function(err, profile) {
  103
+        assert.isUndefined(profile);
  104
+      },
  105
+    },
  106
+  },
  107
+  
  108
+  'strategy when loading user profile without extended info': {
  109
+    topic: function() {
  110
+      var strategy = new TwitterStrategy({
  111
+        consumerKey: 'ABC123',
  112
+        consumerSecret: 'secret',
  113
+        skipExtendedUserProfile: true
  114
+      },
  115
+      function() {});
  116
+      
  117
+      // mock
  118
+      strategy._oauth.get = function(url, token, tokenSecret, callback) {
  119
+        var body = '{"id_str":"6253282","id":6253282,"profile_text_color":"437792","created_at":"Wed May 23 06:01:13 +0000 2007","contributors_enabled":true,"follow_request_sent":null,"lang":"en","listed_count":10154,"profile_sidebar_border_color":"0094C2","show_all_inline_media":false,"friends_count":34,"utc_offset":-28800,"location":"San Francisco, CA","name":"Twitter API","profile_background_tile":false,"profile_sidebar_fill_color":"a9d9f1","profile_image_url_https":"https:\/\/si0.twimg.com\/profile_images\/1438634086\/avatar_normal.png","protected":false,"geo_enabled":true,"following":null,"default_profile_image":false,"statuses_count":3252,"is_translator":false,"favourites_count":22,"profile_background_color":"e8f2f7","description":"The Real Twitter API. I tweet about API changes, service issues and happily answer questions about Twitter and our API. Do not get an answer? It is on my website.","time_zone":"Pacific Time (US & Canada)","screen_name":"twitterapi","profile_background_image_url":"http:\/\/a0.twimg.com\/profile_background_images\/229557229\/twitterapi-bg.png","profile_image_url":"http:\/\/a0.twimg.com\/profile_images\/1438634086\/avatar_normal.png","profile_link_color":"0094C2","profile_background_image_url_https":"https:\/\/si0.twimg.com\/profile_background_images\/229557229\/twitterapi-bg.png","followers_count":931299,"status":{"in_reply_to_status_id_str":null,"in_reply_to_user_id_str":null,"retweeted":false,"coordinates":null,"in_reply_to_screen_name":null,"created_at":"Tue Feb 14 23:39:43 +0000 2012","possibly_sensitive":false,"contributors":null,"in_reply_to_status_id":null,"entities":{"urls":[{"display_url":"tmblr.co\/ZgBqayGQi3ls","indices":[106,126],"expanded_url":"http:\/\/tmblr.co\/ZgBqayGQi3ls","url":"http:\/\/t.co\/cOzUfFNW"}],"user_mentions":[],"hashtags":[]},"geo":null,"in_reply_to_user_id":null,"place":null,"favorited":false,"truncated":false,"id_str":"169566520693882882","id":169566520693882882,"retweet_count":82,"text":"Photo Upload Issue - Some users may be experiencing an issue when uploading a photo. Our engineers are... http:\/\/t.co\/cOzUfFNW"},"default_profile":false,"notifications":null,"url":"http:\/\/dev.twitter.com","profile_use_background_image":true,"verified":true}';
  120
+        
  121
+        throw new Error('OAuth request should not be issued when extended user profile is disabled');
  122
+      }
  123
+      
  124
+      return strategy;
  125
+    },
  126
+    
  127
+    'when told to load user profile': {
  128
+      topic: function(strategy) {
  129
+        var self = this;
  130
+        function done(err, profile) {
  131
+          self.callback(err, profile);
  132
+        }
  133
+        
28 134
         process.nextTick(function () {
29  
-          strategy.userProfile('', '', {"user_id":"1705","screen_name":"jaredhanson"}, done);
  135
+          strategy.userProfile('token', 'token-secret', {"user_id":"1705","screen_name":"jaredhanson"}, done);
30 136
         });
31 137
       },
32 138
       

0 notes on commit f3be40c

Please sign in to comment.
Something went wrong with that request. Please try again.