aboutsummaryrefslogtreecommitdiff
path: root/node_modules/passport-facebook/lib
diff options
context:
space:
mode:
authornanalelfe <nargiza.nosirova@mail.utoronto.ca>2016-07-27 01:45:42 +0000
committernanalelfe <nargiza.nosirova@mail.utoronto.ca>2016-07-27 01:45:42 +0000
commit3b002a6fb136b9e7e534ffbcfedabed72fcd373d (patch)
treed24c3cb1f9e0283de25c32259f692745c6b19bc1 /node_modules/passport-facebook/lib
parent25706820837bd05cdc3b186eb1d5ebabf9688a61 (diff)
Added passport-facbeook
Diffstat (limited to 'node_modules/passport-facebook/lib')
-rw-r--r--node_modules/passport-facebook/lib/errors/facebookauthorizationerror.js30
-rw-r--r--node_modules/passport-facebook/lib/errors/facebookgraphapierror.js32
-rw-r--r--node_modules/passport-facebook/lib/errors/facebooktokenerror.js36
-rw-r--r--node_modules/passport-facebook/lib/index.js9
-rw-r--r--node_modules/passport-facebook/lib/profile.js38
-rw-r--r--node_modules/passport-facebook/lib/strategy.js240
6 files changed, 385 insertions, 0 deletions
diff --git a/node_modules/passport-facebook/lib/errors/facebookauthorizationerror.js b/node_modules/passport-facebook/lib/errors/facebookauthorizationerror.js
new file mode 100644
index 0000000..3c14c96
--- /dev/null
+++ b/node_modules/passport-facebook/lib/errors/facebookauthorizationerror.js
@@ -0,0 +1,30 @@
+/**
+ * `FacebookAuthorizationError` error.
+ *
+ * FacebookAuthorizationError represents an error in response to an
+ * authorization request on Facebook. Note that these responses don't conform
+ * to the OAuth 2.0 specification.
+ *
+ * References:
+ * - https://developers.facebook.com/docs/reference/api/errors/
+ *
+ * @constructor
+ * @param {string} [message]
+ * @param {number} [code]
+ * @access public
+ */
+function FacebookAuthorizationError(message, code) {
+ Error.call(this);
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'FacebookAuthorizationError';
+ this.message = message;
+ this.code = code;
+ this.status = 500;
+}
+
+// Inherit from `Error`.
+FacebookAuthorizationError.prototype.__proto__ = Error.prototype;
+
+
+// Expose constructor.
+module.exports = FacebookAuthorizationError;
diff --git a/node_modules/passport-facebook/lib/errors/facebookgraphapierror.js b/node_modules/passport-facebook/lib/errors/facebookgraphapierror.js
new file mode 100644
index 0000000..a95f6ab
--- /dev/null
+++ b/node_modules/passport-facebook/lib/errors/facebookgraphapierror.js
@@ -0,0 +1,32 @@
+/**
+ * `FacebookGraphAPIError` error.
+ *
+ * References:
+ * - https://developers.facebook.com/docs/reference/api/errors/
+ *
+ * @constructor
+ * @param {string} [message]
+ * @param {string} [type]
+ * @param {number} [code]
+ * @param {number} [subcode]
+ * @param {string} [traceID]
+ * @access public
+ */
+function FacebookGraphAPIError(message, type, code, subcode, traceID) {
+ Error.call(this);
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'FacebookGraphAPIError';
+ this.message = message;
+ this.type = type;
+ this.code = code;
+ this.subcode = subcode;
+ this.traceID = traceID;
+ this.status = 500;
+}
+
+// Inherit from `Error`.
+FacebookGraphAPIError.prototype.__proto__ = Error.prototype;
+
+
+// Expose constructor.
+module.exports = FacebookGraphAPIError;
diff --git a/node_modules/passport-facebook/lib/errors/facebooktokenerror.js b/node_modules/passport-facebook/lib/errors/facebooktokenerror.js
new file mode 100644
index 0000000..ff4e9dc
--- /dev/null
+++ b/node_modules/passport-facebook/lib/errors/facebooktokenerror.js
@@ -0,0 +1,36 @@
+/**
+ * `FacebookTokenError` error.
+ *
+ * FacebookTokenError represents an error received from a Facebook's token
+ * endpoint. Note that these responses don't conform to the OAuth 2.0
+ * specification.
+ *
+ * References:
+ * - https://developers.facebook.com/docs/reference/api/errors/
+ *
+ * @constructor
+ * @param {string} [message]
+ * @param {string} [type]
+ * @param {number} [code]
+ * @param {number} [subcode]
+ * @param {string} [traceID]
+ * @access public
+ */
+function FacebookTokenError(message, type, code, subcode, traceID) {
+ Error.call(this);
+ Error.captureStackTrace(this, arguments.callee);
+ this.name = 'FacebookTokenError';
+ this.message = message;
+ this.type = type;
+ this.code = code;
+ this.subcode = subcode;
+ this.traceID = traceID;
+ this.status = 500;
+}
+
+// Inherit from `Error`.
+FacebookTokenError.prototype.__proto__ = Error.prototype;
+
+
+// Expose constructor.
+module.exports = FacebookTokenError;
diff --git a/node_modules/passport-facebook/lib/index.js b/node_modules/passport-facebook/lib/index.js
new file mode 100644
index 0000000..af2282d
--- /dev/null
+++ b/node_modules/passport-facebook/lib/index.js
@@ -0,0 +1,9 @@
+// Load modules.
+var Strategy = require('./strategy');
+
+
+// Expose Strategy.
+exports = module.exports = Strategy;
+
+// Exports.
+exports.Strategy = Strategy;
diff --git a/node_modules/passport-facebook/lib/profile.js b/node_modules/passport-facebook/lib/profile.js
new file mode 100644
index 0000000..ef00860
--- /dev/null
+++ b/node_modules/passport-facebook/lib/profile.js
@@ -0,0 +1,38 @@
+/**
+ * Parse profile.
+ *
+ * @param {object|string} json
+ * @return {object}
+ * @access public
+ */
+exports.parse = function(json) {
+ if ('string' == typeof json) {
+ json = JSON.parse(json);
+ }
+
+ var profile = {};
+ profile.id = json.id;
+ profile.username = json.username;
+ profile.displayName = json.name;
+ profile.name = { familyName: json.last_name,
+ givenName: json.first_name,
+ middleName: json.middle_name };
+
+ profile.gender = json.gender;
+ profile.profileUrl = json.link;
+
+ if (json.email) {
+ profile.emails = [{ value: json.email }];
+ }
+
+ if (json.picture) {
+ if (typeof json.picture == 'object' && json.picture.data) {
+ // October 2012 Breaking Changes
+ profile.photos = [{ value: json.picture.data.url }];
+ } else {
+ profile.photos = [{ value: json.picture }];
+ }
+ }
+
+ return profile;
+};
diff --git a/node_modules/passport-facebook/lib/strategy.js b/node_modules/passport-facebook/lib/strategy.js
new file mode 100644
index 0000000..f7881b1
--- /dev/null
+++ b/node_modules/passport-facebook/lib/strategy.js
@@ -0,0 +1,240 @@
+// Load modules.
+var OAuth2Strategy = require('passport-oauth2')
+ , util = require('util')
+ , uri = require('url')
+ , crypto = require('crypto')
+ , Profile = require('./profile')
+ , InternalOAuthError = require('passport-oauth2').InternalOAuthError
+ , FacebookAuthorizationError = require('./errors/facebookauthorizationerror')
+ , FacebookTokenError = require('./errors/facebooktokenerror')
+ , FacebookGraphAPIError = require('./errors/facebookgraphapierror');
+
+
+/**
+ * `Strategy` constructor.
+ *
+ * The Facebook authentication strategy authenticates requests by delegating to
+ * Facebook using the OAuth 2.0 protocol.
+ *
+ * Applications must supply a `verify` callback which accepts an `accessToken`,
+ * `refreshToken` and service-specific `profile`, and then calls the `cb`
+ * callback supplying a `user`, which should be set to `false` if the
+ * credentials are not valid. If an exception occured, `err` should be set.
+ *
+ * Options:
+ * - `clientID` your Facebook application's App ID
+ * - `clientSecret` your Facebook application's App Secret
+ * - `callbackURL` URL to which Facebook will redirect the user after granting authorization
+ *
+ * Examples:
+ *
+ * passport.use(new FacebookStrategy({
+ * clientID: '123-456-789',
+ * clientSecret: 'shhh-its-a-secret'
+ * callbackURL: 'https://www.example.net/auth/facebook/callback'
+ * },
+ * function(accessToken, refreshToken, profile, cb) {
+ * User.findOrCreate(..., function (err, user) {
+ * cb(err, user);
+ * });
+ * }
+ * ));
+ *
+ * @constructor
+ * @param {object} options
+ * @param {function} verify
+ * @access public
+ */
+function Strategy(options, verify) {
+ options = options || {};
+ options.authorizationURL = options.authorizationURL || 'https://www.facebook.com/dialog/oauth';
+ options.tokenURL = options.tokenURL || 'https://graph.facebook.com/oauth/access_token';
+ options.scopeSeparator = options.scopeSeparator || ',';
+
+ OAuth2Strategy.call(this, options, verify);
+ this.name = 'facebook';
+ this._profileURL = options.profileURL || 'https://graph.facebook.com/v2.5/me';
+ this._profileFields = options.profileFields || null;
+ this._enableProof = options.enableProof;
+ this._clientSecret = options.clientSecret;
+}
+
+// Inherit from `OAuth2Strategy`.
+util.inherits(Strategy, OAuth2Strategy);
+
+
+/**
+ * Authenticate request by delegating to Facebook using OAuth 2.0.
+ *
+ * @param {http.IncomingMessage} req
+ * @param {object} options
+ * @access protected
+ */
+Strategy.prototype.authenticate = function(req, options) {
+ // Facebook doesn't conform to the OAuth 2.0 specification, with respect to
+ // redirecting with error codes.
+ //
+ // FIX: https://github.com/jaredhanson/passport-oauth/issues/16
+ if (req.query && req.query.error_code && !req.query.error) {
+ return this.error(new FacebookAuthorizationError(req.query.error_message, parseInt(req.query.error_code, 10)));
+ }
+
+ OAuth2Strategy.prototype.authenticate.call(this, req, options);
+};
+
+/**
+ * Return extra Facebook-specific parameters to be included in the authorization
+ * request.
+ *
+ * Options:
+ * - `display` Display mode to render dialog, { `page`, `popup`, `touch` }.
+ *
+ * @param {object} options
+ * @return {object}
+ * @access protected
+ */
+Strategy.prototype.authorizationParams = function (options) {
+ var params = {};
+
+ // https://developers.facebook.com/docs/reference/dialogs/oauth/
+ if (options.display) {
+ params.display = options.display;
+ }
+
+ // https://developers.facebook.com/docs/facebook-login/reauthentication/
+ if (options.authType) {
+ params.auth_type = options.authType;
+ }
+ if (options.authNonce) {
+ params.auth_nonce = options.authNonce;
+ }
+
+ return params;
+};
+
+/**
+ * Retrieve user profile from Facebook.
+ *
+ * This function constructs a normalized profile, with the following properties:
+ *
+ * - `provider` always set to `facebook`
+ * - `id` the user's Facebook ID
+ * - `username` the user's Facebook username
+ * - `displayName` the user's full name
+ * - `name.familyName` the user's last name
+ * - `name.givenName` the user's first name
+ * - `name.middleName` the user's middle name
+ * - `gender` the user's gender: `male` or `female`
+ * - `profileUrl` the URL of the profile for the user on Facebook
+ * - `emails` the proxied or contact email address granted by the user
+ *
+ * @param {string} accessToken
+ * @param {function} done
+ * @access protected
+ */
+Strategy.prototype.userProfile = function(accessToken, done) {
+ var url = uri.parse(this._profileURL);
+ if (this._enableProof) {
+ // Secure API call by adding proof of the app secret. This is required when
+ // the "Require AppSecret Proof for Server API calls" setting has been
+ // enabled. The proof is a SHA256 hash of the access token, using the app
+ // secret as the key.
+ //
+ // For further details, refer to:
+ // https://developers.facebook.com/docs/reference/api/securing-graph-api/
+ var proof = crypto.createHmac('sha256', this._clientSecret).update(accessToken).digest('hex');
+ url.search = (url.search ? url.search + '&' : '') + 'appsecret_proof=' + proof;
+ }
+ if (this._profileFields) {
+ var fields = this._convertProfileFields(this._profileFields);
+ if (fields !== '') { url.search = (url.search ? url.search + '&' : '') + 'fields=' + fields; }
+ }
+ url = uri.format(url);
+
+ this._oauth2.get(url, accessToken, function (err, body, res) {
+ var json;
+
+ if (err) {
+ if (err.data) {
+ try {
+ json = JSON.parse(err.data);
+ } catch (_) {}
+ }
+
+ if (json && json.error && typeof json.error == 'object') {
+ return done(new FacebookGraphAPIError(json.error.message, json.error.type, json.error.code, json.error.error_subcode, json.error.fbtrace_id));
+ }
+ return done(new InternalOAuthError('Failed to fetch user profile', err));
+ }
+
+ try {
+ json = JSON.parse(body);
+ } catch (ex) {
+ return done(new Error('Failed to parse user profile'));
+ }
+
+ var profile = Profile.parse(json);
+ profile.provider = 'facebook';
+ profile._raw = body;
+ profile._json = json;
+
+ done(null, profile);
+ });
+};
+
+/**
+ * Parse error response from Facebook OAuth 2.0 token endpoint.
+ *
+ * @param {string} body
+ * @param {number} status
+ * @return {Error}
+ * @access protected
+ */
+Strategy.prototype.parseErrorResponse = function(body, status) {
+ var json = JSON.parse(body);
+ if (json.error && typeof json.error == 'object') {
+ return new FacebookTokenError(json.error.message, json.error.type, json.error.code, json.error.error_subcode, json.error.fbtrace_id);
+ }
+ return OAuth2Strategy.prototype.parseErrorResponse.call(this, body, status);
+};
+
+/**
+ * Convert Facebook profile to a normalized profile.
+ *
+ * @param {object} profileFields
+ * @return {string}
+ * @access protected
+ */
+Strategy.prototype._convertProfileFields = function(profileFields) {
+ var map = {
+ 'id': 'id',
+ 'username': 'username',
+ 'displayName': 'name',
+ 'name': ['last_name', 'first_name', 'middle_name'],
+ 'gender': 'gender',
+ 'birthday': 'birthday',
+ 'profileUrl': 'link',
+ 'emails': 'email',
+ 'photos': 'picture'
+ };
+
+ var fields = [];
+
+ profileFields.forEach(function(f) {
+ // return raw Facebook profile field to support the many fields that don't
+ // map cleanly to Portable Contacts
+ if (typeof map[f] === 'undefined') { return fields.push(f); };
+
+ if (Array.isArray(map[f])) {
+ Array.prototype.push.apply(fields, map[f]);
+ } else {
+ fields.push(map[f]);
+ }
+ });
+
+ return fields.join(',');
+};
+
+
+// Expose constructor.
+module.exports = Strategy;