diff --git a/lib/oauth2.js b/lib/oauth2.js index 82773c49..0f3d2632 100644 --- a/lib/oauth2.js +++ b/lib/oauth2.js @@ -7,7 +7,7 @@ function Strategy(options, verify) { options = options || {}; options.authorizationURL = options.authorizationURL || 'https://www.linkedin.com/oauth/v2/authorization'; options.tokenURL = options.tokenURL || 'https://www.linkedin.com/oauth/v2/accessToken'; - options.scope = options.scope || ['r_basicprofile']; + options.scope = options.scope || ['r_liteprofile']; options.profileFields = options.profileFields || null; //By default we want data in JSON @@ -15,7 +15,7 @@ function Strategy(options, verify) { OAuth2Strategy.call(this, options, verify); this.name = 'linkedin'; - this.profileUrl = 'https://api.linkedin.com/v1/people/~:(' + this._convertScopeToUserProfileFields(options.scope, options.profileFields) + ')'; + this.profileUrl = 'https://api.linkedin.com/v2/me?projection=(' + this._convertScopeToUserProfileFields(options.scope, options.profileFields) + ')'; } util.inherits(Strategy, OAuth2Strategy); @@ -24,8 +24,27 @@ Strategy.prototype.userProfile = function(accessToken, done) { //LinkedIn uses a custom name for the access_token parameter this._oauth2.setAccessTokenName("oauth2_access_token"); + if (!!this.emailUrl) { + var self = this + this._oauth2.get(this.emailUrl, accessToken, function (err, body, res) { + if (err) { return done(new InternalOAuthError('failed to fetch user email', err)); } + + try { + var json = JSON.parse(body); + var emails = json.elements; + self._fetchAsyncProfile(accessToken, done, emails); + + } catch(e) { + done(e); + } + }); + } else { + this._fetchAsyncProfile(accessToken, done); + } +}; - this._oauth2.get(this.profileUrl, accessToken, function (err, body, res) { +Strategy.prototype._fetchAsyncProfile = function(accessToken, done, emails) { + this._oauth2.get(this.profileUrl, accessToken, function (err, body, res) { if (err) { return done(new InternalOAuthError('failed to fetch user profile', err)); } try { @@ -39,7 +58,7 @@ Strategy.prototype.userProfile = function(accessToken, done) { familyName: json.lastName, givenName: json.firstName }; - profile.emails = [{ value: json.emailAddress }]; + profile.emails = emails || [{ value: json.emailAddress }]; profile.photos = []; if (json.pictureUrl) { profile.photos.push({ value: json.pictureUrl }); @@ -52,76 +71,32 @@ Strategy.prototype.userProfile = function(accessToken, done) { done(e); } }); -} - - +}; Strategy.prototype._convertScopeToUserProfileFields = function(scope, profileFields) { var self = this; var map = { - 'r_basicprofile': [ + 'r_liteprofile': [ 'id', - 'first-name', - 'last-name', - 'picture-url', - 'picture-urls::(original)', - 'formatted-name', - 'maiden-name', - 'phonetic-first-name', - 'phonetic-last-name', - 'formatted-phonetic-name', - 'headline', - 'location:(name,country:(code))', - 'industry', - 'distance', - 'relation-to-viewer:(distance,connections)', - 'current-share', - 'num-connections', - 'num-connections-capped', - 'summary', - 'specialties', - 'positions', - 'site-standard-profile-request', - 'api-standard-profile-request:(headers,url)', - 'public-profile-url' + 'firstName', + 'lastName', + 'profilePicture(displayImage~:playableStreams)' ], - 'r_emailaddress': ['email-address'], - 'r_fullprofile': [ - 'last-modified-timestamp', - 'proposal-comments', - 'associations', - 'interests', - 'publications', - 'patents', - 'languages', - 'skills', - 'certifications', - 'educations', - 'courses', - 'volunteer', - 'three-current-positions', - 'three-past-positions', - 'num-recommenders', - 'recommendations-received', - 'mfeed-rss-url', - 'following', - 'job-bookmarks', - 'suggestions', - 'date-of-birth', - 'member-url-resources:(name,url)', - 'related-profile-views', - 'honors-awards' - ] }; + var r_emailaddress = 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))'; var fields = []; // To obtain pre-defined field mappings if(Array.isArray(scope) && profileFields === null) { - if(scope.indexOf('r_basicprofile') === -1){ - scope.unshift('r_basicprofile'); + if(scope.indexOf('r_liteprofile') === -1){ + scope.unshift('r_liteprofile'); + } + + if(scope.indexOf('r_emailaddress') !== -1){ + self.emailUrl = r_emailaddress } scope.forEach(function(f) {