From 505cdc3829f4e30c0fe2698df55a4eef149bd28e Mon Sep 17 00:00:00 2001 From: Nixxx19 Date: Tue, 3 Mar 2026 19:32:56 +0530 Subject: [PATCH 1/3] fix: add email validation for google oauth --- server/config/passport.js | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/server/config/passport.js b/server/config/passport.js index ea8163e975..cee7ea3d1c 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -124,6 +124,21 @@ const getVerifiedEmails = (githubEmails) => const getPrimaryEmail = (githubEmails) => (lodash.find(githubEmails, { primary: true }) || {}).value; +/** + * Get primary email from Google OAuth profile. + * Returns the first email if available, or null if emails array is missing/empty. + */ +const getGooglePrimaryEmail = (googleEmails) => { + if ( + !googleEmails || + !Array.isArray(googleEmails) || + googleEmails.length === 0 + ) { + return null; + } + return googleEmails[0]?.value || null; +}; + /** * Sign in with GitHub. */ @@ -240,8 +255,18 @@ passport.use( }, async (req, accessToken, refreshToken, profile, done) => { try { + // Validate that emails array exists and has at least one element + const primaryEmail = getGooglePrimaryEmail(profile._json?.emails); + if (!primaryEmail) { + return done(null, false, { + msg: + 'Unable to retrieve email from Google account. ' + + 'Please ensure your Google account has an email address and try again.' + }); + } + const existingUser = await User.findOne({ - google: profile._json.emails[0].value + google: primaryEmail }).exec(); if (existingUser) { @@ -258,18 +283,16 @@ passport.use( return done(null, existingUser); } - const primaryEmail = profile._json.emails[0].value; - if (req.user) { if (!req.user.google) { - req.user.google = profile._json.emails[0].value; + req.user.google = primaryEmail; req.user.tokens.push({ kind: 'google', accessToken }); req.user.verified = User.EmailConfirmation().Verified; } await req.user.save(); return done(null, req.user); } - let username = profile._json.emails[0].value.split('@')[0]; + let username = primaryEmail.split('@')[0]; const existingEmailUser = await User.findByEmail(primaryEmail); const existingUsernameUser = await User.findByUsername(username, { caseInsensitive: true @@ -285,7 +308,7 @@ passport.use( return done(null, false, { msg: accountSuspensionMessage }); } existingEmailUser.email = existingEmailUser.email || primaryEmail; - existingEmailUser.google = profile._json.emails[0].value; + existingEmailUser.google = primaryEmail; existingEmailUser.username = existingEmailUser.username || username; existingEmailUser.tokens.push({ kind: 'google', @@ -301,7 +324,7 @@ passport.use( const user = new User(); user.email = primaryEmail; - user.google = profile._json.emails[0].value; + user.google = primaryEmail; user.username = username; user.tokens.push({ kind: 'google', accessToken }); user.name = profile._json.displayName; From d45dbaf78c32ec3a9351752350afe056a6ed181f Mon Sep 17 00:00:00 2001 From: Nixxx19 Date: Tue, 3 Mar 2026 19:34:22 +0530 Subject: [PATCH 2/3] refactor: add email trimming in google oauth helper --- server/config/passport.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/config/passport.js b/server/config/passport.js index cee7ea3d1c..4bf1329631 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -136,7 +136,8 @@ const getGooglePrimaryEmail = (googleEmails) => { ) { return null; } - return googleEmails[0]?.value || null; + const primaryEmail = googleEmails[0]?.value?.trim(); + return primaryEmail || null; }; /** From a14c4a5438003366ca672fcbe9c28f143cfe0e33 Mon Sep 17 00:00:00 2001 From: Nixxx19 Date: Sat, 7 Mar 2026 21:11:18 +0530 Subject: [PATCH 3/3] Remove redundant null check --- server/config/passport.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/server/config/passport.js b/server/config/passport.js index 4bf1329631..87dd8e49a1 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -129,11 +129,7 @@ const getPrimaryEmail = (githubEmails) => * Returns the first email if available, or null if emails array is missing/empty. */ const getGooglePrimaryEmail = (googleEmails) => { - if ( - !googleEmails || - !Array.isArray(googleEmails) || - googleEmails.length === 0 - ) { + if (!Array.isArray(googleEmails) || googleEmails.length === 0) { return null; } const primaryEmail = googleEmails[0]?.value?.trim();