We’ve found a bit of a bizarre bug in our authentication provider, which seems to affect (at least one) core authentication provider, and I expect more.
Here's the crux of the problem:
- Create a new account
- Change the email address on that account
- Don’t click on the link in the email
- Log out, log in with the old email
- Observe the email address on that account is now the new email, despite you having not verified it
This change of email address despite the user not confirming it will then result in additional bugs depending on the authentication provider in question:
With the one we use in Mozilla, after the steps shown in the video above, a user will no longer be able to log in with their old email, and will have to start logging in with their new one.
With Google, the user will still be able to log in with their old email (because a GoogleUserInfo
row still exists for it) and will never be able to log in with their new one because a duplicate user_id
error will be thrown for the new GoogleUserInfo
row that Discourse tries to create.
That problem can be seen in a spec I wrote, which passes when it really shouldn’t:
updater = EmailUpdater.new(user.guardian, user)
updater.change_to(new_email)
user.reload
expect(user.email).to eq(old_email)
response = login(old_identity)
expect(response['authenticated']).to eq(true)
user.reload
expect(user.email).to eq(new_email)
expect { login(new_identity) }.to raise_error(ActiveRecord::RecordNotUnique)
I’m starting to attempt to find a fix, but I thought I’d post now that I’ve finally nailed down the actual bug, in case anyone else had any ideas.