diff --git a/website/server/controllers/api-v3/auth.js b/website/server/controllers/api-v3/auth.js index cc1f85b33e..a0fc435731 100644 --- a/website/server/controllers/api-v3/auth.js +++ b/website/server/controllers/api-v3/auth.js @@ -1,5 +1,6 @@ import validator from 'validator'; import moment from 'moment'; +import sortBy from 'lodash/sortBy'; import nconf from 'nconf'; import { authWithHeaders, @@ -341,15 +342,23 @@ api.resetPassword = { if (validationErrors) throw validationErrors; const email = req.body.email.toLowerCase(); - const user = await User.findOne({ - $or: [ - { 'auth.local.username': email.replace(/^@/, '') }, - { 'auth.local.email': email }, - { 'auth.apple.emails.value': email }, - { 'auth.google.emails.value': email }, - { 'auth.facebook.emails.value': email }, - ], - }).exec(); + let user = await User.findOne( + { 'auth.local.email': email }, // Prefer to reset password for local auth + { auth: 1 }, + ).exec(); + if (!user) { // If no local auth with that email... + const potentialUsers = await User.find({ + $or: [ + { 'auth.local.username': email.replace(/^@/, '') }, + { 'auth.apple.emails.value': email }, + { 'auth.google.emails.value': email }, + { 'auth.facebook.emails.value': email }, + ], + }, + { auth: 1 }).exec(); + // ...prefer oldest social account or username with matching email + [user] = sortBy(potentialUsers, candidate => candidate.auth.timestamps.created); + } if (user) { // create an encrypted link to be used to reset the password