-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Reject login when external oauth login matches a different account #34
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM aside from the wording of some of the error messages
src/auth/strategies/util.ts
Outdated
@@ -81,7 +88,7 @@ export async function ExternalServiceCallback( | |||
} | |||
|
|||
if (!user) { | |||
done(null, false, { "message": "Could not match login to existing account" }); | |||
done(null, false, { message: "Could not match login to an existing account. Please try again with a different login method." }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Kinda picky but this can also be triggered by someone choosing the wrong account in the account picker (i.e. for Google which allows multiple user accounts to be logged in) but if there isn't a Ground Truth account with that other account. So I'd say Please try again with a different account or login method
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, if the third-party IdP email doesn't correspond to the email they entered originally, we should:
- Just tell people that, or
- Change the UX so you can directly pick 3rd-party IdPs on the initial login screen (which may have other implications I'm not thinking of right now)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know if picking 3rd party IdPs directly is an option anymore, since there are so many accounts whose 3rd party IdP email doesn't match their main email address on their account, so it wouldn't work.
src/auth/strategies/util.ts
Outdated
@@ -25,6 +25,12 @@ export async function ExternalServiceCallback( | |||
// If `user` exists, the user has already logged in with this service and is good-to-go | |||
let user = await User.findOne({ [`services.${serviceName}.id`]: id }); | |||
|
|||
// Ensure that the oauth method used is linked to the user with the same email address that is entered | |||
if (session.email && user && session.email !== user.email) { | |||
done(null, false, { message: "Login method is linked to another email. Please try again with a different email address." }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This message is kind of confusing imo. Perhaps The 3rd party account you chose does not match the email address that you are trying to log in with. Please make sure your email address and the selected account match.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding to this, users will be confused by this if we aren't really clear. So it would be good to include the original email the user entered in the error message to. As in, if I enter [email protected] on the initial login screen, then choose a Google account with the email [email protected], the error message might show, "The Google account you signed in with ([email protected]) has a different email than what you originally entered ([email protected]). Please ensure your email address and the account you select have the same email address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If someone uses their gt email, [email protected], but chooses to sign in with google ([email protected]), and on the first screen they enter their google email, how should the error message read?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a great start, but I have a few concerns we need to address:
- I am almost certain there are a few users who will be locked out if we merge this change as-is (I can probably find you an example account). That means we need to check the database for accounts where the account email != the third-party IdP email, or if we can't do that, then we ought to develop a way for those users to rectify the problem.
- Do these changes also apply when someone is making a new account with a third-party IdP? Or just new sign-ins?
src/auth/strategies/util.ts
Outdated
@@ -25,6 +25,12 @@ export async function ExternalServiceCallback( | |||
// If `user` exists, the user has already logged in with this service and is good-to-go | |||
let user = await User.findOne({ [`services.${serviceName}.id`]: id }); | |||
|
|||
// Ensure that the oauth method used is linked to the user with the same email address that is entered | |||
if (session.email && user && session.email !== user.email) { | |||
done(null, false, { message: "Login method is linked to another email. Please try again with a different email address." }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding to this, users will be confused by this if we aren't really clear. So it would be good to include the original email the user entered in the error message to. As in, if I enter [email protected] on the initial login screen, then choose a Google account with the email [email protected], the error message might show, "The Google account you signed in with ([email protected]) has a different email than what you originally entered ([email protected]). Please ensure your email address and the account you select have the same email address.
src/auth/strategies/util.ts
Outdated
@@ -25,6 +25,12 @@ export async function ExternalServiceCallback( | |||
// If `user` exists, the user has already logged in with this service and is good-to-go | |||
let user = await User.findOne({ [`services.${serviceName}.id`]: id }); | |||
|
|||
// Ensure that the oauth method used is linked to the user with the same email address that is entered | |||
if (session.email && user && session.email !== user.email) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure we're using the trimmed and lowercased email for all comparisons.
src/auth/strategies/util.ts
Outdated
@@ -81,7 +88,7 @@ export async function ExternalServiceCallback( | |||
} | |||
|
|||
if (!user) { | |||
done(null, false, { "message": "Could not match login to existing account" }); | |||
done(null, false, { message: "Could not match login to an existing account. Please try again with a different login method." }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly, if the third-party IdP email doesn't correspond to the email they entered originally, we should:
- Just tell people that, or
- Change the UX so you can directly pick 3rd-party IdPs on the initial login screen (which may have other implications I'm not thinking of right now)
So it's a little weird how it works, for every user, there is an email field, and then each 3rd party IdP they use also has an associated email in the db. These two emails can be different. So when the user enters their email on the first screen, the system finds a user object with the corresponding email. Then, based on this, they are redirected to the corresponding service based on what they use. Once they login, they are essentially logged in based on their 3rd part IdP. This check that I implemented, it only makes sure that the initial email they enter matches the email address of the user which they select from the IdP. For example, if a user has an account with email address [email protected], but uses GitHub login on which service their email is [email protected], they must enter [email protected] on the first login screen. That's essentially what my check is doing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It sounds like the check you're doing is what makes the most sense here, just a small thing with the error message wording
|
||
// Ensure that the oauth method used is linked to the user with the same email address that is entered | ||
if (enteredEmail && user && enteredEmail !== user.email) { | ||
done(null, false, { message: "The 3rd party account you chose does not match the email address that you are trying to log in with. Please make sure your email address and the selected account match." }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you clarify the exact expectation in the error message by adding what aspect of the third-party account doesn't match (you mention the email address the user entered but the rest is vague)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Basically, I want them to login with a different 3rd party account. So Ill just tell them that. Let me know if this is good instead.
The {serviceName} account you selected is linked to a different email address than typed below. Please try again with a different 3rd party account.
Where service name is google, github, etc.
Closes #31