From 2f1e39433462ee3d5f900dbd023e99535791c049 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 16:28:12 -0500 Subject: [PATCH 01/11] Add Merge strategy for Facebook so far --- config/passport.js | 50 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 9 deletions(-) diff --git a/config/passport.js b/config/passport.js index c04ad9153c..e869ed140b 100755 --- a/config/passport.js +++ b/config/passport.js @@ -33,20 +33,52 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, passw }); })); +/** + * Sign in with Facebook. + * + * Possible authentication states: + * + * 1. User is logged in. + * a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) + * b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) + * 2. User is not logged in. + * a. Already signed with Facebook before. (LOGIN) + * b. First time signing in with Facebook. (CREATE ACCOUNT) + */ + passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, refreshToken, profile, done) { if (req.user) { - User.findById(req.user.id, function(err, user) { - user.facebook = profile.id; - user.tokens.push({ kind: 'facebook', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.gender = user.profile.gender || profile._json.gender; - user.profile.picture = user.profile.picture || profile._json.profile_image_url; - user.save(function(err) { - done(err, user); - }); + User.findOne({ facebook: profile.id }, function(err, existingUser) { + if (existingUser) { + existingUser.github = existingUser.github || req.user.github; + existingUser.google = existingUser.google || req.user.google; + existingUser.twitter = existingUser.twitter || req.user.twitter; + existingUser.email = existingUser.email || req.user.email; + existingUser.password = existingUser.password || req.user.password; + existingUser.profile = existingUser.profile || req.user.profile; + existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); + existingUser.save(function(err) { + User.remove({ _id: req.user.id }, function(err) { + req.flash('info', { msg: 'Your accont has been merged with an existing one.' }); + return done(null, existingUser); + }); + }); + } else { + User.findById(req.user.id, function(err, user) { + user.facebook = profile.id; + user.tokens.push({ kind: 'facebook', accessToken: accessToken }); + user.profile.name = user.profile.name || profile.displayName; + user.profile.gender = user.profile.gender || profile._json.gender; + user.profile.picture = user.profile.picture || profile._json.profile_image_url; + user.save(function(err) { + done(err, user); + }); + }); + } }); } else { User.findOne({ facebook: profile.id }, function(err, existingUser) { + console.log(profile); if (existingUser) return done(null, existingUser); var user = new User(); user.email = profile._json.email; From e177ac10deeff4f1fa8cccd22d2d691adb6a24b3 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 22:18:57 -0500 Subject: [PATCH 02/11] Updated message if user with that email already exists --- controllers/user.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controllers/user.js b/controllers/user.js index 8ec8edbbce..0b9b4793a4 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -90,7 +90,7 @@ exports.postSignup = function(req, res, next) { user.save(function(err) { if (err) { if (err.code === 11000) { - req.flash('errors', { msg: 'User already exists.' }); + req.flash('errors', { msg: 'User with that email already exists.' }); } return res.redirect('/signup'); } From 90c5278bbc90cf026b89b1fe95961403fc36262c Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 22:23:19 -0500 Subject: [PATCH 03/11] Update profile picture in Facebook strategy --- config/passport.js | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/config/passport.js b/config/passport.js index e869ed140b..994b1ed960 100755 --- a/config/passport.js +++ b/config/passport.js @@ -34,21 +34,21 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, passw })); /** - * Sign in with Facebook. - * - * Possible authentication states: - * - * 1. User is logged in. - * a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) - * b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) - * 2. User is not logged in. - * a. Already signed with Facebook before. (LOGIN) - * b. First time signing in with Facebook. (CREATE ACCOUNT) - */ +* Sign in with Facebook. +* +* Possible authentication states: +* +* 1. User is logged in. +* a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) +* b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) +* 2. User is not logged in. +* a. Already signed with Facebook before. (LOGIN) +* b. First time signing in with Facebook. (CREATE ACCOUNT) +*/ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, refreshToken, profile, done) { if (req.user) { - User.findOne({ facebook: profile.id }, function(err, existingUser) { + User.findOne({ $or: [{ facebook: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { existingUser.github = existingUser.github || req.user.github; existingUser.google = existingUser.google || req.user.google; @@ -59,7 +59,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); existingUser.save(function(err) { User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your accont has been merged with an existing one.' }); + req.flash('info', { msg: 'Your account has been merged with an existing one that belongs to you' }); return done(null, existingUser); }); }); @@ -69,7 +69,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, user.tokens.push({ kind: 'facebook', accessToken: accessToken }); user.profile.name = user.profile.name || profile.displayName; user.profile.gender = user.profile.gender || profile._json.gender; - user.profile.picture = user.profile.picture || profile._json.profile_image_url; + user.profile.picture = user.profile.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large'; user.save(function(err) { done(err, user); }); @@ -78,7 +78,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, }); } else { User.findOne({ facebook: profile.id }, function(err, existingUser) { - console.log(profile); + console.log(profile) if (existingUser) return done(null, existingUser); var user = new User(); user.email = profile._json.email; @@ -86,7 +86,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, user.tokens.push({ kind: 'facebook', accessToken: accessToken }); user.profile.name = profile.displayName; user.profile.gender = profile._json.gender; - user.profile.picture = profile._json.profile_image_url; + user.profile.picture = 'https://graph.facebook.com/' + profile.id + '/picture?type=large'; user.save(function(err) { done(err, user); }); From dfeb12d6ce086bd2cffd8333caf6a8b4b20f9825 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 22:39:13 -0500 Subject: [PATCH 04/11] Add Google and Github merge strategies --- config/passport.js | 105 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 84 insertions(+), 21 deletions(-) diff --git a/config/passport.js b/config/passport.js index 994b1ed960..be92762e43 100755 --- a/config/passport.js +++ b/config/passport.js @@ -59,8 +59,8 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); existingUser.save(function(err) { User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your account has been merged with an existing one that belongs to you' }); - return done(null, existingUser); + req.flash('info', { msg: 'Your accounts have been merged' }); + return done(err, existingUser); }); }); } else { @@ -94,18 +94,49 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, } })); +/** + * Sign in with GitHub. + * + * Possible authentication states: + * + * 1. User is logged in. + * a. Already signed in with GitHub before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) + * b. First time signing in with GitHub. (ADD GITHUB ID TO EXISTING USER) + * 2. User is not logged in. + * a. Already signed with GitHub before. (LOGIN) + * b. First time signing in with GitHub. (CREATE ACCOUNT) + */ + passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refreshToken, profile, done) { if (req.user) { - User.findById(req.user.id, function(err, user) { - user.github = profile.id; - user.tokens.push({ kind: 'github', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.picture = user.profile.picture || profile._json.avatar_url; - user.profile.location = user.profile.location || profile._json.location; - user.profile.website = user.profile.website || profile._json.blog; - user.save(function(err) { - done(err, user); - }); + User.findOne({ $or: [{ github: profile.id }, { email: profile.email }] }, function(err, existingUser) { + if (existingUser) { + existingUser.facebook = existingUser.facebook || req.user.facebook; + existingUser.google = existingUser.google || req.user.google; + existingUser.twitter = existingUser.twitter || req.user.twitter; + existingUser.email = existingUser.email || req.user.email; + existingUser.password = existingUser.password || req.user.password; + existingUser.profile = existingUser.profile || req.user.profile; + existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); + existingUser.save(function(err) { + User.remove({ _id: req.user.id }, function(err) { + req.flash('info', { msg: 'Your accounts have been merged' }); + return done(err, existingUser); + }); + }); + } else { + User.findById(req.user.id, function(err, user) { + user.github = profile.id; + user.tokens.push({ kind: 'github', accessToken: accessToken }); + user.profile.name = user.profile.name || profile.displayName; + user.profile.picture = user.profile.picture || profile._json.avatar_url; + user.profile.location = user.profile.location || profile._json.location; + user.profile.website = user.profile.website || profile._json.blog; + user.save(function(err) { + done(err, user); + }); + }); + } }); } else { User.findOne({ github: profile.id }, function(err, existingUser) { @@ -154,17 +185,49 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok } })); +/** + * Sign in with Google. + * + * Possible authentication states: + * + * 1. User is logged in. + * a. Already signed in with Google before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) + * b. First time signing in with Google. (ADD GOOGLE ID TO EXISTING USER) + * 2. User is not logged in. + * a. Already signed with GitHub before. (LOGIN) + * b. First time signing in with Google. (CREATE ACCOUNT) + */ + passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refreshToken, profile, done) { if (req.user) { - User.findById(req.user.id, function(err, user) { - user.google = profile.id; - user.tokens.push({ kind: 'google', accessToken: accessToken }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.gender = user.profile.gender || profile._json.gender; - user.profile.picture = user.profile.picture || profile._json.picture; - user.save(function(err) { - done(err, user); - }); + + User.findOne({ $or: [{ google: profile.id }, { email: profile.email }] }, function(err, existingUser) { + if (existingUser) { + existingUser.facebook = existingUser.facebook || req.user.facebook; + existingUser.github = existingUser.github || req.user.github; + existingUser.twitter = existingUser.twitter || req.user.twitter; + existingUser.email = existingUser.email || req.user.email; + existingUser.password = existingUser.password || req.user.password; + existingUser.profile = existingUser.profile || req.user.profile; + existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); + existingUser.save(function(err) { + User.remove({ _id: req.user.id }, function(err) { + req.flash('info', { msg: 'Your accounts have been merged' }); + return done(err, existingUser); + }); + }); + } else { + User.findById(req.user.id, function(err, user) { + user.google = profile.id; + user.tokens.push({ kind: 'google', accessToken: accessToken }); + user.profile.name = user.profile.name || profile.displayName; + user.profile.gender = user.profile.gender || profile._json.gender; + user.profile.picture = user.profile.picture || profile._json.picture; + user.save(function(err) { + done(err, user); + }); + }); + } }); } else { User.findOne({ google: profile.id }, function(err, existingUser) { From 6d85931422510beaf7887e28b0dc3e65940a947d Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 23:17:58 -0500 Subject: [PATCH 05/11] Add Twitter merging strategy --- config/passport.js | 51 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/config/passport.js b/config/passport.js index be92762e43..a6af151812 100755 --- a/config/passport.js +++ b/config/passport.js @@ -156,18 +156,50 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre } })); +/** + * Sign in with Twitter. + * + * Possible authentication states: + * + * 1. User is logged in. + * a. Already signed in with Twitter before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) + * b. First time signing in with Twitter. (ADD TWITTER ID TO EXISTING USER) + * 2. User is not logged in. + * a. Already signed with Twitter before. (LOGIN) + * b. First time signing in with Twitter. (CREATE ACCOUNT) + */ + passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) { if (req.user) { - User.findById(req.user.id, function(err, user) { - user.twitter = profile.id; - user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret }); - user.profile.name = user.profile.name || profile.displayName; - user.profile.location = user.profile.location || profile._json.location; - user.profile.picture = user.profile.picture || profile._json.profile_image_url; - user.save(function(err) { - done(err, user); - }); + User.findOne({ $or: [{ twitter: profile.id }, { email: profile.email }] }, function(err, existingUser) { + if (existingUser) { + existingUser.facebook = existingUser.facebook || req.user.facebook; + existingUser.github = existingUser.github || req.user.github; + existingUser.google = existingUser.google || req.user.google; + existingUser.email = existingUser.email || req.user.email; + existingUser.password = existingUser.password || req.user.password; + existingUser.profile = existingUser.profile || req.user.profile; + existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); + existingUser.save(function(err) { + User.remove({ _id: req.user.id }, function(err) { + req.flash('info', { msg: 'Your accounts have been merged' }); + return done(err, existingUser); + }); + }); + } else { + User.findById(req.user.id, function(err, user) { + user.twitter = profile.id; + user.tokens.push({ kind: 'twitter', accessToken: accessToken, tokenSecret: tokenSecret }); + user.profile.name = user.profile.name || profile.displayName; + user.profile.location = user.profile.location || profile._json.location; + user.profile.picture = user.profile.picture || profile._json.profile_image_url; + user.save(function(err) { + done(err, user); + }); + }); + } }); + } else { User.findOne({ twitter: profile.id }, function(err, existingUser) { if (existingUser) return done(null, existingUser); @@ -200,7 +232,6 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refreshToken, profile, done) { if (req.user) { - User.findOne({ $or: [{ google: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { existingUser.facebook = existingUser.facebook || req.user.facebook; From 9d982b3f27e7664117b6b58427a58b700c0389f7 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 23:23:14 -0500 Subject: [PATCH 06/11] Update merging strategies --- config/passport.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/config/passport.js b/config/passport.js index a6af151812..4935692fb0 100755 --- a/config/passport.js +++ b/config/passport.js @@ -50,8 +50,9 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, if (req.user) { User.findOne({ $or: [{ facebook: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { - existingUser.github = existingUser.github || req.user.github; + existingUser.facebook = existingUser.facebook || req.user.facebook; existingUser.google = existingUser.google || req.user.google; + existingUser.github = existingUser.github || req.user.github; existingUser.twitter = existingUser.twitter || req.user.twitter; existingUser.email = existingUser.email || req.user.email; existingUser.password = existingUser.password || req.user.password; @@ -113,6 +114,7 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre if (existingUser) { existingUser.facebook = existingUser.facebook || req.user.facebook; existingUser.google = existingUser.google || req.user.google; + existingUser.github = existingUser.github || req.user.github; existingUser.twitter = existingUser.twitter || req.user.twitter; existingUser.email = existingUser.email || req.user.email; existingUser.password = existingUser.password || req.user.password; @@ -174,8 +176,9 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok User.findOne({ $or: [{ twitter: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { existingUser.facebook = existingUser.facebook || req.user.facebook; - existingUser.github = existingUser.github || req.user.github; existingUser.google = existingUser.google || req.user.google; + existingUser.twitter = existingUser.twitter || req.user.twitter; + existingUser.github = existingUser.github || req.user.github; existingUser.email = existingUser.email || req.user.email; existingUser.password = existingUser.password || req.user.password; existingUser.profile = existingUser.profile || req.user.profile; @@ -235,6 +238,7 @@ passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refre User.findOne({ $or: [{ google: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { existingUser.facebook = existingUser.facebook || req.user.facebook; + existingUser.google = existingUser.google || req.user.google; existingUser.github = existingUser.github || req.user.github; existingUser.twitter = existingUser.twitter || req.user.twitter; existingUser.email = existingUser.email || req.user.email; From 5f206082077a753cc1586202a5b1c25547e9151e Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 23:56:50 -0500 Subject: [PATCH 07/11] Instead of merging display flash messages notifying the user that account with another OAuth provider already exists. --- config/passport.js | 49 +++++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 27 deletions(-) diff --git a/config/passport.js b/config/passport.js index 4935692fb0..565478dc07 100755 --- a/config/passport.js +++ b/config/passport.js @@ -34,22 +34,26 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, passw })); /** -* Sign in with Facebook. -* -* Possible authentication states: -* -* 1. User is logged in. -* a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) -* b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) -* 2. User is not logged in. -* a. Already signed with Facebook before. (LOGIN) -* b. First time signing in with Facebook. (CREATE ACCOUNT) -*/ + * Sign in with Facebook. + * + * Possible authentication states: + * + * 1. User is logged in. + * a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) + * b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) + * 2. User is not logged in. + * a. Already signed with Facebook before. (LOGIN) + * b. First time signing in with Facebook. (CREATE ACCOUNT) + */ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, refreshToken, profile, done) { if (req.user) { User.findOne({ $or: [{ facebook: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { + console.log(existingUser.facebook) + console.log(req.user.facebook) + console.log(existingUser.google) + console.log(req.user.google) existingUser.facebook = existingUser.facebook || req.user.facebook; existingUser.google = existingUser.google || req.user.google; existingUser.github = existingUser.github || req.user.github; @@ -173,17 +177,19 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) { if (req.user) { - User.findOne({ $or: [{ twitter: profile.id }, { email: profile.email }] }, function(err, existingUser) { + User.findOne({ twitter: profile.id }, function(err, existingUser) { if (existingUser) { existingUser.facebook = existingUser.facebook || req.user.facebook; existingUser.google = existingUser.google || req.user.google; existingUser.twitter = existingUser.twitter || req.user.twitter; existingUser.github = existingUser.github || req.user.github; - existingUser.email = existingUser.email || req.user.email; + existingUser.email = req.user.email; existingUser.password = existingUser.password || req.user.password; existingUser.profile = existingUser.profile || req.user.profile; existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); existingUser.save(function(err) { + console.log(existingUser); + console.log(req.user.google) User.remove({ _id: req.user.id }, function(err) { req.flash('info', { msg: 'Your accounts have been merged' }); return done(err, existingUser); @@ -237,20 +243,8 @@ passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refre if (req.user) { User.findOne({ $or: [{ google: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { - existingUser.facebook = existingUser.facebook || req.user.facebook; - existingUser.google = existingUser.google || req.user.google; - existingUser.github = existingUser.github || req.user.github; - existingUser.twitter = existingUser.twitter || req.user.twitter; - existingUser.email = existingUser.email || req.user.email; - existingUser.password = existingUser.password || req.user.password; - existingUser.profile = existingUser.profile || req.user.profile; - existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); - existingUser.save(function(err) { - User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your accounts have been merged' }); - return done(err, existingUser); - }); - }); + req.flash('errors', { msg: 'There is already a Google account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); + done(err); } else { User.findById(req.user.id, function(err, user) { user.google = profile.id; @@ -259,6 +253,7 @@ passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refre user.profile.gender = user.profile.gender || profile._json.gender; user.profile.picture = user.profile.picture || profile._json.picture; user.save(function(err) { + req.flash('info', { msg: 'Google account has been linked.' }); done(err, user); }); }); From 8fdf42928f0b1f5cf2c1ded7215b163adb72dcbf Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 23:58:59 -0500 Subject: [PATCH 08/11] Flash notifications for Facebook, Github, Twitter auth link --- config/passport.js | 75 ++++++---------------------------------------- 1 file changed, 9 insertions(+), 66 deletions(-) diff --git a/config/passport.js b/config/passport.js index 565478dc07..552d9bb5f9 100755 --- a/config/passport.js +++ b/config/passport.js @@ -50,24 +50,8 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, if (req.user) { User.findOne({ $or: [{ facebook: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { - console.log(existingUser.facebook) - console.log(req.user.facebook) - console.log(existingUser.google) - console.log(req.user.google) - existingUser.facebook = existingUser.facebook || req.user.facebook; - existingUser.google = existingUser.google || req.user.google; - existingUser.github = existingUser.github || req.user.github; - existingUser.twitter = existingUser.twitter || req.user.twitter; - existingUser.email = existingUser.email || req.user.email; - existingUser.password = existingUser.password || req.user.password; - existingUser.profile = existingUser.profile || req.user.profile; - existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); - existingUser.save(function(err) { - User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your accounts have been merged' }); - return done(err, existingUser); - }); - }); + req.flash('errors', { msg: 'There is already a Facebook account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); + done(err); } else { User.findById(req.user.id, function(err, user) { user.facebook = profile.id; @@ -76,6 +60,7 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, user.profile.gender = user.profile.gender || profile._json.gender; user.profile.picture = user.profile.picture || 'https://graph.facebook.com/' + profile.id + '/picture?type=large'; user.save(function(err) { + req.flash('info', { msg: 'Facebook account has been linked.' }); done(err, user); }); }); @@ -116,20 +101,8 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre if (req.user) { User.findOne({ $or: [{ github: profile.id }, { email: profile.email }] }, function(err, existingUser) { if (existingUser) { - existingUser.facebook = existingUser.facebook || req.user.facebook; - existingUser.google = existingUser.google || req.user.google; - existingUser.github = existingUser.github || req.user.github; - existingUser.twitter = existingUser.twitter || req.user.twitter; - existingUser.email = existingUser.email || req.user.email; - existingUser.password = existingUser.password || req.user.password; - existingUser.profile = existingUser.profile || req.user.profile; - existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); - existingUser.save(function(err) { - User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your accounts have been merged' }); - return done(err, existingUser); - }); - }); + req.flash('errors', { msg: 'There is already a GitHub account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); + done(err); } else { User.findById(req.user.id, function(err, user) { user.github = profile.id; @@ -139,6 +112,7 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre user.profile.location = user.profile.location || profile._json.location; user.profile.website = user.profile.website || profile._json.blog; user.save(function(err) { + req.flash('info', { msg: 'GitHub account has been linked.' }); done(err, user); }); }); @@ -164,37 +138,14 @@ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refre /** * Sign in with Twitter. - * - * Possible authentication states: - * - * 1. User is logged in. - * a. Already signed in with Twitter before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) - * b. First time signing in with Twitter. (ADD TWITTER ID TO EXISTING USER) - * 2. User is not logged in. - * a. Already signed with Twitter before. (LOGIN) - * b. First time signing in with Twitter. (CREATE ACCOUNT) */ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tokenSecret, profile, done) { if (req.user) { User.findOne({ twitter: profile.id }, function(err, existingUser) { if (existingUser) { - existingUser.facebook = existingUser.facebook || req.user.facebook; - existingUser.google = existingUser.google || req.user.google; - existingUser.twitter = existingUser.twitter || req.user.twitter; - existingUser.github = existingUser.github || req.user.github; - existingUser.email = req.user.email; - existingUser.password = existingUser.password || req.user.password; - existingUser.profile = existingUser.profile || req.user.profile; - existingUser.tokens = _.union(existingUser.tokens, req.user.tokens); - existingUser.save(function(err) { - console.log(existingUser); - console.log(req.user.google) - User.remove({ _id: req.user.id }, function(err) { - req.flash('info', { msg: 'Your accounts have been merged' }); - return done(err, existingUser); - }); - }); + req.flash('errors', { msg: 'There is already a Twitter account that belongs to you. Sign in with that account or delete it, then link it with your current account.' }); + done(err); } else { User.findById(req.user.id, function(err, user) { user.twitter = profile.id; @@ -203,6 +154,7 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok user.profile.location = user.profile.location || profile._json.location; user.profile.picture = user.profile.picture || profile._json.profile_image_url; user.save(function(err) { + req.flash('info', { msg: 'Twitter account has been linked.' }); done(err, user); }); }); @@ -228,15 +180,6 @@ passport.use(new TwitterStrategy(secrets.twitter, function(req, accessToken, tok /** * Sign in with Google. - * - * Possible authentication states: - * - * 1. User is logged in. - * a. Already signed in with Google before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) - * b. First time signing in with Google. (ADD GOOGLE ID TO EXISTING USER) - * 2. User is not logged in. - * a. Already signed with GitHub before. (LOGIN) - * b. First time signing in with Google. (CREATE ACCOUNT) */ passport.use(new GoogleStrategy(secrets.google, function(req, accessToken, refreshToken, profile, done) { From b6c6d433f2da793c0c291225ea34a7b581681e4a Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Fri, 31 Jan 2014 23:59:57 -0500 Subject: [PATCH 09/11] Update TODO --- README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/README.md b/README.md index 26ba9c477b..d597125da2 100644 --- a/README.md +++ b/README.md @@ -638,12 +638,6 @@ If you want to see a really cool real-time dashboard check out this [live exampl TODO ---- - Pages that require login, should automatically redirect to last attempted URL on successful sign-in. -- Authentication strategies should handles all edge cases below: - - A user has never used your site before. They have no User model and no Identities either. - - A user is logged out but they have logged into your site with a provider previously. They are now signing in with the same one again. - - Just as above but they are now signing in with a different provider. - - A user is logged in with a provider but they try to login with the same provider again. - - A user is logged in but they try to login with a different provider. Contributing ------------ From ea573672fb3844090ae669e263d70168ba1ab240 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sat, 1 Feb 2014 00:03:05 -0500 Subject: [PATCH 10/11] Update comments --- config/passport.js | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/config/passport.js b/config/passport.js index 552d9bb5f9..518e89a3fa 100755 --- a/config/passport.js +++ b/config/passport.js @@ -35,15 +35,6 @@ passport.use(new LocalStrategy({ usernameField: 'email' }, function(email, passw /** * Sign in with Facebook. - * - * Possible authentication states: - * - * 1. User is logged in. - * a. Already signed in with Facebook before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) - * b. First time signing in with Facebook. (ADD FACEBOOK ID TO EXISTING USER) - * 2. User is not logged in. - * a. Already signed with Facebook before. (LOGIN) - * b. First time signing in with Facebook. (CREATE ACCOUNT) */ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, refreshToken, profile, done) { @@ -86,15 +77,6 @@ passport.use(new FacebookStrategy(secrets.facebook, function (req, accessToken, /** * Sign in with GitHub. - * - * Possible authentication states: - * - * 1. User is logged in. - * a. Already signed in with GitHub before. (MERGE ACCOUNTS, EXISTING ACCOUNT HAS PRECEDENCE) - * b. First time signing in with GitHub. (ADD GITHUB ID TO EXISTING USER) - * 2. User is not logged in. - * a. Already signed with GitHub before. (LOGIN) - * b. First time signing in with GitHub. (CREATE ACCOUNT) */ passport.use(new GitHubStrategy(secrets.github, function(req, accessToken, refreshToken, profile, done) { From fdecdc5b53965240c5720d2cf6938adcf341c1c2 Mon Sep 17 00:00:00 2001 From: Sahat Yalkabov Date: Sat, 1 Feb 2014 00:04:54 -0500 Subject: [PATCH 11/11] Flash notification on OAuth Provider Unlink --- controllers/user.js | 1 + 1 file changed, 1 insertion(+) diff --git a/controllers/user.js b/controllers/user.js index 0b9b4793a4..e813dddd17 100644 --- a/controllers/user.js +++ b/controllers/user.js @@ -195,6 +195,7 @@ exports.getOauthUnlink = function(req, res, next) { user.save(function(err) { if (err) return next(err); + req.flash('info', { msg: provider + ' account has been unlinked.' }); res.redirect('/account'); }); });