/**
 * Module dependencies.
 */
var util = require('util')
  , OAuthStrategy = require('passport-oauth').OAuthStrategy;


function Strategy(options, verify) {
  options = options || {};
  options.requestTokenURL = options.requestTokenURL || 'https://api.linkedin.com/uas/oauth/requestToken';
  options.accessTokenURL = options.accessTokenURL || 'https://api.linkedin.com/uas/oauth/accessToken';
  options.userAuthorizationURL = options.userAuthorizationURL || 'https://www.linkedin.com/uas/oauth/authenticate';
  options.sessionKey = options.sessionKey || 'oauth:linkedin';

  OAuthStrategy.call(this, options, verify);
  this.name = 'linkedin';
}

/**
 * Inherit from `OAuthStrategy`.
 */
util.inherits(Strategy, OAuthStrategy);

Strategy.prototype.authenticate = function(req) {
  // When a user denies authorization on LinkedIn, they are presented with a
  // link to return to the application in the following format:
  //
  //     http://www.example.com/auth/linkedin/callback?oauth_problem=user_refused
  //
  // Following the link back to the application is interpreted as an
  // authentication failure.
  if (req.query && req.query.oauth_problem) {
    return this.fail();
  }
  
  // Call the base class for standard OAuth authentication.
  OAuthStrategy.prototype.authenticate.call(this, req);
}

Strategy.prototype.userProfile = function(token, tokenSecret, params, done) {
  this._oauth.get('https://api.linkedin.com/v1/people/~:(id,first-name,last-name)?format=json', token, tokenSecret, function (err, body, res) {
    if (err) { return done(err); }
    
    try {
      o = JSON.parse(body);
      
      var profile = { provider: 'linkedin' };
      profile.id = o.id;
      profile.displayName = o.firstName + ' ' + o.lastName;
      profile.name = { familyName: o.lastName,
                       givenName: o.firstName };
      
      done(null, profile);
    } catch(e) {
      done(e);
    }
  });
}


/**
 * Expose `Strategy`.
 */
module.exports = Strategy;

@@ -115,16 +115,1205 @@
 tegy;%0A%0A%0A
+/**%0A * %60Strategy%60 constructor.%0A *%0A * The LinkedIn authentication strategy authenticates requests by delegating to%0A * LinkedIn using the OAuth protocol.%0A *%0A * Applications must supply a %60verify%60 callback which accepts a %60token%60,%0A * %60tokenSecret%60 and service-specific %60profile%60, and then calls the %60done%60%0A * callback supplying a %60user%60, which should be set to %60false%60 if the%0A * credentials are not valid.  If an exception occured, %60err%60 should be set.%0A *%0A * Options:%0A *   - %60consumerKey%60     identifies client to LinkedIn%0A *   - %60consumerSecret%60  secret used to establish ownership of the consumer key%0A *   - %60callbackURL%60     URL to which LinkedIn will redirect the user after obtaining authorization%0A *%0A * Examples:%0A *%0A *     passport.use(new LinkedInStrategy(%7B%0A *         consumerKey: '123-456-789',%0A *         consumerSecret: 'shhh-its-a-secret'%0A *         callbackURL: 'https://www.example.net/auth/linkedin/callback'%0A *       %7D,%0A *       function(token, tokenSecret, profile, done) %7B%0A *         User.findOrCreate(..., function (err, user) %7B%0A *           done(err, user);%0A *         %7D);%0A *       %7D%0A *     ));%0A *%0A * @param %7BObject%7D options%0A * @param %7BFunction%7D verify%0A * @api public%0A */%0A
 function
@@ -1913,16 +1913,131 @@
 tegy);%0A%0A
+/**%0A * Authenticate request by delegating to LinkedIn using OAuth.%0A *%0A * @param %7BObject%7D req%0A * @api protected%0A */%0A
 Strategy
@@ -2605,16 +2605,362 @@
 eq);%0A%7D%0A%0A
+/**%0A * Retrieve user profile from LinkedIn.%0A *%0A * This function constructs a normalized profile, with the following properties:%0A *%0A *   - %60id%60%0A *   - %60displayName%60%0A *   - %60name.familyName%60%0A *   - %60name.givenName%60%0A *%0A * @param %7BString%7D token%0A * @param %7BString%7D tokenSecret%0A * @param %7BObject%7D params%0A * @param %7BFunction%7D done%0A * @api protected%0A */%0A
 Strategy

Document Strategy.