passport.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. var passport = require('passport');
  2. var LocalStrategy = require('passport-local').Strategy;
  3. var FacebookStrategy = require('passport-facebook').Strategy;
  4. var TwitterStrategy = require('passport-twitter').Strategy;
  5. var GithubStrategy = require('passport-github').Strategy;
  6. var User = require('../models/User');
  7. passport.serializeUser(function(user, done) {
  8. done(null, user.id);
  9. });
  10. passport.deserializeUser(function(id, done) {
  11. User.findById(id, function(err, user) {
  12. done(err, user);
  13. });
  14. });
  15. // Sign in with Email and Password
  16. passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, password, done) {
  17. User.findOne({ email: email }, function(err, user) {
  18. if (!user) {
  19. return done(null, false, { msg: 'O endereço de e-mail ' + email + ' não está associado com nenhuma conta. ' +
  20. 'Cheque seu e-mail e tente novamente.' });
  21. }
  22. user.comparePassword(password, function(err, isMatch) {
  23. if (!isMatch) {
  24. return done(null, false, { msg: 'Endereço de e-mail ou senha inválidos.' });
  25. }
  26. return done(null, user);
  27. });
  28. });
  29. }));
  30. // Sign in with Facebook
  31. passport.use(new FacebookStrategy({
  32. clientID: process.env.FACEBOOK_ID,
  33. clientSecret: process.env.FACEBOOK_SECRET,
  34. callbackURL: '/auth/facebook/callback',
  35. profileFields: ['name', 'email', 'gender', 'location'],
  36. passReqToCallback: true
  37. }, function(req, accessToken, refreshToken, profile, done) {
  38. if (req.user) {
  39. User.findOne({ facebook: profile.id }, function(err, user) {
  40. if (user) {
  41. req.flash('error', { msg: 'There is already an existing account linked with Facebook that belongs to you.' });
  42. done(err);
  43. } else {
  44. User.findById(req.user.id, function(err, user) {
  45. user.name = user.name || profile.name.givenName + ' ' + profile.name.familyName;
  46. user.gender = user.gender || profile._json.gender;
  47. user.username = profile.id;
  48. user.picture = user.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large';
  49. user.facebook = profile.id;
  50. user.save(function(err) {
  51. req.flash('success', { msg: 'Your Facebook account has been linked.' });
  52. done(err, user);
  53. });
  54. });
  55. }
  56. });
  57. } else {
  58. User.findOne({ facebook: profile.id }, function(err, user) {
  59. if (user) {
  60. return done(err, user);
  61. }
  62. User.findOne({ email: profile._json.email }, function(err, user) {
  63. if (user) {
  64. req.flash('error', { msg: user.email + ' is already associated with another account.' });
  65. done(err);
  66. } else {
  67. var newUser = new User({
  68. name: profile.name.givenName + ' ' + profile.name.familyName,
  69. email: profile._json.email,
  70. username: profile.id,
  71. gender: profile._json.gender,
  72. location: profile._json.location && profile._json.location.name,
  73. picture: 'https://graph.facebook.com/' + profile.id + '/picture?type=large',
  74. facebook: profile.id
  75. });
  76. newUser.save(function(err) {
  77. done(err, newUser);
  78. });
  79. }
  80. });
  81. });
  82. }
  83. }));
  84. // Sign in with Twitter
  85. passport.use(new TwitterStrategy({
  86. consumerKey: process.env.TWITTER_KEY,
  87. consumerSecret: process.env.TWITTER_SECRET,
  88. callbackURL: '/auth/twitter/callback',
  89. passReqToCallback: true
  90. }, function(req, accessToken, tokenSecret, profile, done) {
  91. if (req.user) {
  92. User.findOne({ twitter: profile.id }, function(err, user) {
  93. if (user) {
  94. req.flash('error', { msg: 'There is already an existing account linked with Twitter that belongs to you.' });
  95. done(err);
  96. } else {
  97. User.findById(req.user.id, function(err, user) {
  98. user.name = user.name || profile.displayName;
  99. user.location = user.location || profile._json.location;
  100. user.picture = user.picture || profile._json.profile_image_url_https;
  101. user.twitter = profile.id;
  102. user.username = profile.id;
  103. user.save(function(err) {
  104. req.flash('success', { msg: 'Your Twitter account has been linked.' });
  105. done(err, user);
  106. });
  107. });
  108. }
  109. });
  110. } else {
  111. User.findOne({ twitter: profile.id }, function(err, existingUser) {
  112. if (existingUser) {
  113. return done(null, existingUser);
  114. }
  115. // Twitter does not provide an email address, but email is a required field in our User schema.
  116. // We can "fake" a Twitter email address as follows: username@twitter.com.
  117. // Ideally, it should be changed by a user to their real email address afterwards.
  118. // For example, after login, check if email contains @twitter.com, then redirect to My Account page,
  119. // and restrict user's page navigation until they update their email address.
  120. var newUser = new User({
  121. name: profile.displayName,
  122. email: profile.username + '@twitter.com',
  123. location: profile._json.location,
  124. picture: profile._json.profile_image_url_https,
  125. twitter: profile.id,
  126. username: profile.username
  127. });
  128. newUser.save(function(err) {
  129. done(err, newUser);
  130. });
  131. });
  132. }
  133. }));
  134. // Sign in with Github
  135. passport.use(new GithubStrategy({
  136. clientID: process.env.GITHUB_ID,
  137. clientSecret: process.env.GITHUB_SECRET,
  138. callbackURL: '/auth/github/callback',
  139. passReqToCallback: true
  140. }, function(req, accessToken, refreshToken, profile, done) {
  141. if (req.user) {
  142. User.findOne({ github: profile.id }, function(err, user) {
  143. if (user) {
  144. req.flash('error', { msg: 'There is already an existing account linked with Github that belongs to you.' });
  145. } else {
  146. User.findById(req.user.id, function(err, user) {
  147. user.name = user.name || profile.displayName;
  148. user.picture = user.picture || profile._json.avatar_url;
  149. user.github = profile.id;
  150. user.save(function(err) {
  151. req.flash('success', { msg: 'Your Github account has been linked.' });
  152. done(err, user);
  153. });
  154. });
  155. }
  156. });
  157. } else {
  158. User.findOne({ github: profile.id }, function(err, user) {
  159. if (user) {
  160. return done(null, user);
  161. }
  162. User.findOne({ email: profile.email }, function(err, user) {
  163. if (user) {
  164. req.flash('error', { msg: user.email + ' is already associated with another account.' });
  165. done(err);
  166. } else {
  167. var newUser = new User({
  168. name: profile.displayName,
  169. email: profile._json.email,
  170. location: profile._json.location,
  171. picture: profile._json.avatar_url,
  172. github: profile.id
  173. });
  174. newUser.save(function(err) {
  175. done(err, newUser);
  176. });
  177. }
  178. });
  179. });
  180. }
  181. }));