passport-linkedin-api-v2
Version:
A simple Passport strategy for LinkedIn OAuth2 API Version 2.
188 lines (187 loc) • 7.75 kB
JavaScript
;
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
var passport_oauth2_1 = __importDefault(require("passport-oauth2"));
var request = __importStar(require("request"));
var LI_OAUTH = 'https://www.linkedin.com/oauth/v2';
var AUTH = LI_OAUTH + '/authorization';
var TOKEN = LI_OAUTH + '/accessToken';
var LI_V2 = 'https://api.linkedin.com/v2';
var ME = LI_V2 + '/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))';
var EMAIL = LI_V2 + '/emailAddress?q=members&projection=(elements*(handle~))';
var LinkedinAuth = /** @class */ (function (_super) {
__extends(LinkedinAuth, _super);
function LinkedinAuth(options, verify) {
var _this = this;
var opts = Object.assign(options, {
authorizationURL: AUTH,
tokenURL: TOKEN,
customHeaders: { 'x-li-format': 'json' },
});
_this = _super.call(this, opts, verify) || this;
return _this;
}
/**
* Fetch user profile once authenticated with LI.
* @param accessToken The access token for LI.
* @param done Callback function.
*/
LinkedinAuth.prototype.userProfile = function (accessToken, done) {
if (accessToken == null) {
return done(new passport_oauth2_1.default.InternalOAuthError('failed to fetch access token', null));
}
this._oauth2.setAccessTokenName('oauth2_access_token');
LinkedinAuth.getLiteProfile(accessToken, done);
};
/**
* Handles LI Responses
* @param body The LI Response body.
*/
LinkedinAuth.handleLiResponse = function (body) {
if (body.status >= 400) {
throw body.message;
}
};
/**
* Get Lite profile of user.
* @param accessToken The access token to request the lite profile.
* @param done Callback function.
*/
LinkedinAuth.getLiteProfile = function (accessToken, done) {
request.get(ME, { headers: LinkedinAuth.getHeader(accessToken) }, function (error, response, body) {
if (error) {
return done(new passport_oauth2_1.default.InternalOAuthError('failed to fetch user profile', error));
}
try {
var json_1 = JSON.parse(body);
LinkedinAuth.handleLiResponse(json_1);
LinkedinAuth.getUserEmail(accessToken, function (err, email) {
if (err) {
return done(new passport_oauth2_1.default.InternalOAuthError('failed to fetch user email', error));
}
json_1.email = email;
json_1.accessToken = accessToken;
done(null, LinkedinAuth.parseLinkedInProfile(json_1, body));
});
}
catch (e) {
done(e);
}
});
};
/**
* Returns the email of the user.
* @param accessToken The access token to request the email.
* @param done Callback function.
*/
LinkedinAuth.getUserEmail = function (accessToken, done) {
request.get(EMAIL, { headers: LinkedinAuth.getHeader(accessToken) }, function (error, response, body) {
if (error) {
return done(new passport_oauth2_1.default.InternalOAuthError('failed to fetch user email', error));
}
try {
var json = JSON.parse(body);
LinkedinAuth.handleLiResponse(json);
done(null, json);
}
catch (e) {
done(e);
}
});
};
/**
* Parses and extracts all available information from the LI profile.
* @param linkedInProfile The LI profile.
* @param raw The raw LI profile.
*/
LinkedinAuth.parseLinkedInProfile = function (linkedInProfile, raw) {
var email = '';
if (linkedInProfile.email.elements && linkedInProfile.email.elements.length > 0 &&
linkedInProfile.email.elements[0]['handle~'] &&
linkedInProfile.email.elements[0]['handle~'].emailAddress) {
email = linkedInProfile.email.elements[0]['handle~'].emailAddress.toLocaleLowerCase();
}
var lastName = '';
if (linkedInProfile.lastName) {
lastName = LinkedinAuth.getMultiLocaleString(linkedInProfile.lastName);
}
var firstName = '';
if (linkedInProfile.firstName) {
firstName = LinkedinAuth.getMultiLocaleString(linkedInProfile.firstName);
}
var profilePicture = '';
var profilePictures = [];
if (linkedInProfile.profilePicture && linkedInProfile.profilePicture['displayImage~'] &&
linkedInProfile.profilePicture['displayImage~'].elements &&
linkedInProfile.profilePicture['displayImage~'].elements.length > 0) {
var image = linkedInProfile.profilePicture['displayImage~'].elements[0];
if (image.identifiers && image.identifiers.length > 0) {
profilePicture = image.identifiers[0].identifier;
for (var i = 0; i < image.identifiers.length; i++) {
profilePictures.push(image.identifiers[i]);
}
}
}
// Returning user with details from linkedIn profile
return {
email: email,
lastName: lastName,
firstName: firstName,
profilePicture: profilePicture,
profilePictures: profilePictures,
_profileJson: linkedInProfile,
_profileRaw: raw,
linkedIn: {
accessToken: linkedInProfile.accessToken,
id: linkedInProfile.id,
},
};
};
LinkedinAuth.getMultiLocaleString = function (multiLocaleSring) {
if (multiLocaleSring.localized == null || multiLocaleSring.preferredLocale == null) {
return '';
}
var locale = multiLocaleSring.preferredLocale.language;
if (multiLocaleSring.preferredLocale.country) {
locale += '_' + multiLocaleSring.preferredLocale.country;
}
return multiLocaleSring.localized[locale];
};
LinkedinAuth.getHeader = function (accessToken) {
var headers = [];
headers['Authorization'] = 'Bearer ' + accessToken;
return headers;
};
LinkedinAuth.prototype.authorizationParams = function (options) {
var params = {};
// LinkedIn requires state parameter. It will return an error if not set.
if (options.state) {
params['state'] = options.state;
}
return params;
};
return LinkedinAuth;
}(passport_oauth2_1.default));
exports.LinkedinAuth = LinkedinAuth;