From b5b2e9375391154e79753cc3328a0b9704ee4376 Mon Sep 17 00:00:00 2001 From: Cassie Tarakajian Date: Tue, 5 Oct 2021 15:39:34 -0400 Subject: [PATCH] [#1910] Fix GitHub login to work with new passport-github2 package --- server/config/passport.js | 17 ++++++++++++++--- server/models/user.js | 17 +++++++++++++++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/server/config/passport.js b/server/config/passport.js index 63b90e6fc6..12a8a8e204 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -106,7 +106,8 @@ passport.use( clientSecret: process.env.GITHUB_SECRET, callbackURL: '/auth/github/callback', passReqToCallback: true, - scope: ['user:email'] + scope: ['user:email'], + allRawEmails: true }, (req, accessToken, refreshToken, profile, done) => { User.findOne({ github: profile.id }, (findByGithubErr, existingUser) => { @@ -132,8 +133,18 @@ passport.use( } req.user.save((saveErr) => done(null, req.user)); } else { - User.findByEmail(emails, (findByEmailErr, existingEmailUser) => { - if (existingEmailUser) { + User.findAllByEmails(emails, (findByEmailErr, existingEmailUsers) => { + if (existingEmailUsers.length) { + let existingEmailUser; + // Handle case where user has made multiple p5.js Editor accounts, + // with emails that are connected to the same GitHub account + if (existingEmailUsers.length > 1) { + existingEmailUser = existingEmailUsers.find( + (u) => (u.email = primaryEmail) + ); + } else { + [existingEmailUser] = existingEmailUsers; + } existingEmailUser.email = existingEmailUser.email || primaryEmail; existingEmailUser.github = profile.id; existingEmailUser.username = diff --git a/server/models/user.js b/server/models/user.js index 0ffe79c6c5..cbea6ceb2d 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -207,6 +207,23 @@ userSchema.statics.findByEmail = function findByEmail(email, cb) { return this.findOne(query).collation({ locale: 'en', strength: 2 }).exec(cb); }; +/** + * + * Queries User collection by emails and returns all Users that match. + * + * @param {string[]} emails - Array of email strings + * @callback [cb] - Optional error-first callback that passes User document + * @return {Promise} - Returns Promise fulfilled by User document + */ +userSchema.statics.findAllByEmails = function findAllByEmails(emails, cb) { + const query = { + email: { $in: emails } + }; + // Email addresses should be case-insensitive unique + // In MongoDB, you must use collation in order to do a case-insensitive query + return this.find(query).collation({ locale: 'en', strength: 2 }).exec(cb); +}; + /** * * Queries User collection by username and returns one User document.