diff --git a/.gitignore b/.gitignore index e705ba7..a48f5af 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ reports/ # Node.js node_modules npm-debug.log + +package-lock.json diff --git a/.npmignore b/.npmignore index a50451d..c0fd2d7 100644 --- a/.npmignore +++ b/.npmignore @@ -6,3 +6,4 @@ test/ .jshintrc .travis.yml +package-lock.json diff --git a/lib/errors/parsererror.js b/lib/errors/parsererror.js new file mode 100644 index 0000000..4b16af7 --- /dev/null +++ b/lib/errors/parsererror.js @@ -0,0 +1,23 @@ +/** + * `ParserError` error. + * + * @constructor + * @param {string} [message] + * @param {string} [code] + * @access public + */ +function ParserError(message, code) { + Error.call(this); + Error.captureStackTrace(this, arguments.callee); + this.name = 'ParserError'; + this.message = message; + this.code = code; + } + + // Inherit from `Error`. + ParserError.prototype.__proto__ = Error.prototype; + + + // Expose constructor. + module.exports = ParserError; + \ No newline at end of file diff --git a/lib/strategy.js b/lib/strategy.js index 274cd92..a9cc534 100644 --- a/lib/strategy.js +++ b/lib/strategy.js @@ -6,6 +6,7 @@ var OAuth2Strategy = require('passport-oauth2') , OpenIDProfile = require('./profile/openid') , InternalOAuthError = require('passport-oauth2').InternalOAuthError , GooglePlusAPIError = require('./errors/googleplusapierror') + , ParserError = require('./errors/parsererror') , UserInfoError = require('./errors/userinfoerror'); @@ -24,6 +25,7 @@ var OAuth2Strategy = require('passport-oauth2') * - `clientID` your Google application's client id * - `clientSecret` your Google application's client secret * - `callbackURL` URL to which Google will redirect the user after granting authorization + * - `profileParser` an object containing a name and a parse(json) function if you want to consume another google API (ie. People API) * * Examples: * @@ -52,12 +54,22 @@ function Strategy(options, verify) { OAuth2Strategy.call(this, options, verify); this.name = 'google'; this._userProfileURL = options.userProfileURL || 'https://www.googleapis.com/plus/v1/people/me'; - - var url = uri.parse(this._userProfileURL); - if (url.pathname.indexOf('/userinfo') == (url.pathname.length - '/userinfo'.length)) { - this._userProfileFormat = 'openid'; + + this.profileParsers = { + 'openid': OpenIDProfile, + 'google+': GooglePlusProfile + }; + + if (options.profileParser) { + this._userProfileFormat = options.profileParser.name || 'custom'; + this.profileParsers[this._userProfileFormat] = options.profileParser; } else { - this._userProfileFormat = 'google+'; // Google Sign-In + var url = uri.parse(this._userProfileURL); + if (url.pathname.indexOf('/userinfo') == (url.pathname.length - '/userinfo'.length)) { + this._userProfileFormat = 'openid'; + } else { + this._userProfileFormat = 'google+'; // Google Sign-In + } } } @@ -105,16 +117,11 @@ Strategy.prototype.userProfile = function(accessToken, done) { return done(new Error('Failed to parse user profile')); } - var profile; - switch (self._userProfileFormat) { - case 'openid': - profile = OpenIDProfile.parse(json); - break; - default: // Google Sign-In - profile = GooglePlusProfile.parse(json); - break; + var parser = self.profileParsers[self._userProfileFormat]; + if (!parser) { + return done(new ParserError('Parser not found for profile format '+ self._userProfileFormat)); } - + var profile = parser.parse(json); profile.provider = 'google'; profile._raw = body; profile._json = json;