New signup with old email including + doesnt work in rest API

AI-generated summary

User hosna reports that new signups using email subaddresses (e.g., email+1@gmail.com) are blocked via REST API, even though the normalize_emails setting is disabled. JammyDodger initially suggests checking that setting, but hosna confirms it’s off. supermathie tests on try.discourse.org and can’t reproduce the issue, asking for console output and version info. hosna provides console results showing the base email is blocked, and the error message translates to “Primary email is not allowed.” supermathie clarifies the block is likely due to the base email being on a blocklist, not normalization. hosna notes the behavior seems inconsistent with disabled normalization. supermathie explains that Discourse intentionally blocks subaddresses of blocked emails as an anti-griefing measure, regardless of settings. The underlying code checks the canonical email (stripping + and . for Gmail) and uses Levenshtein distance (default 2) to catch similar addresses — which explains why email+1@gmail.com is blocked if email@gmail.com is. supermathie links to the relevant code in screened_email.rb for transparency.

It seems in a recent update, new signup with same email including a + to represent a new email isnt allowed. my system is highly dependent on it. how to enable it again?

for example if I have already signup with email@gmail.com, I cant signup with email+1@gmail.com

btw I am testing this with rest api

also, I dont have this option checked:

I believe that’s the normalize emails admin setting: :+1:

Edit: I did not see that edit before I posted. :slight_smile:

yes it is already disabled for me

I can’t duplicate this on try.discourse.org.

Can you sign up from the normal UI with this email?

Also, can you double check the +1 email wasn’t already used for a signup?

yes normal UI is ok. rest api is not ok.

I did exactly the same and could not duplicate the problem on the latest code running live - it behaved as expected with the normalize emails setting disabled:

Can you show the output of these from the rails console:

[1] pry(main)> SiteSetting.normalize_emails

[2] pry(main)> User.find_by_email('YOURUSERNAME@gmail.com').username

[3] pry(main)> User.find_by_email('YOURUSERNAME+1@gmail.com').username

Also, what version of Discourse are you on?

I might also double check you’re hitting your production site and not your test one (or vice versa).

I updated right now

here it is

What do these translate to?

(and can you copy/paste them here)

I should have asked this first :man_facepalming:

“Primary email is not allowed.”
it is a translation for user.email.blocked

hmmm

it seems the normalized email is blocked. :thinking:

I mean if email@gmail.com is blocked, then email+1@gmail.com is blocked too. it is wierd to me when I have not normalized email option selected.

That’s why I should have asked first instead of assuming it was “already taken” :rofl:

What are your overridden settings in the email and user categories?

Have you blocked that email address, or, say, the Gmail domain?

I didnt underestand this. where should I check?

yes I can see the normalized email is blocked.

In this case we almost definitely block subaddresses of blocked addresses regardless of the setting as an anti-griefing measure since the normalisation option is not the default.

“Only show overridden” in settings. But now I suspect we don’t need to worry about that.

Back at my desk I took a look at the actual code that does this rejection:

Right at the top we’re checking the canonical email against the blocklist:

  def self.canonical(email)
    name, domain = email.split("@", 2)
    name = name.gsub(/\+.*/, "")
    name = name.gsub(".", "") if %w[gmail.com googlemail.com].include?(domain.downcase)
    "#{name}@#{domain}".downcase
  end

And even if that didn’t catch it, it would be caught by the Levenshtein distance check here:

[1] pry(main)> ScreenedEmail.levenshtein('fakezabanshenas@gmail.com', 'fakezabanshenas+1@gmail.com')
=> 2

as the default for SiteSetting.levenshtein_distance_spammer_emails is 2.