Moderated users bypass email confirmation

mattrogowski

Well-known member
Affected version
2.3.2
This isn't a bug in terms of malfunctioning code as it's been specifically programmed to do this, but I'm not sure I agree with the behaviour.

Had a client ask about requiring email confirmation before being added to the approval queue. I tested and found that for most registrations, this happens already.

If a user gets queued for approval for spam though, they bypass this step completely. I'm not sure this is necessarily how people will actually realise this works.

The "Enable email confirmation" option says "If selected, users will need to click on a link in an email before their registration is completed." and the "Enable manual approval" option says "If selected, an administrator will need to manually approve users before their registration is completed.". They can both be enabled, but there's nothing to say the former won't happen if the latter is applied specifically due to failing spam checks - it suggests both would need to happen before the registration is complete.

I assume it's been built this way as the email confirmation is a more passive form of confirming they're a real person, and if you have admin approval enabled too then you still want to have that manual step. I'm not sure however why you would want to bypass the passive step if the user was flagged for spam, considering you would have to manually approve them either way. You're bypassing a major step in combatting spam. Wouldn't it actually make more sense to make them verify the email first, before queueing them for approval? If they're bots, you'd probably find a large number never confirm their email address so never get queued for manual approval, which would save a lot of clutter and accidental approval of spam accounts. And if they do confirm it, well there's still the manual step - but it'd be more likely to reduce the number that make it to manual approval.

It's this from RegistrationService that does it:

PHP:
protected function setInitialUserState()
{
    $user = $this->user;
    $options = $this->app->options();

    if ($user->user_state != 'valid')
    {
        return; // We have likely already set the user state elsewhere, e.g. spam trigger
    }

    if ($options->registrationSetup['emailConfirmation'] && !$this->skipEmailConfirm)
    {
        $user->user_state = 'email_confirm';
    }
    else if ($options->registrationSetup['moderation'])
    {
        $user->user_state = 'moderated';
    }
    else
    {
        $user->user_state = 'valid';
    }
}

If they were set to moderated before, they never hit the code that sets them to email_confirm. Non-spam-flagged users still then get set to moderated anyway after confirming their email.

I suppose it may be like this as manual approval isn’t always enabled, but in that case it can simply check if there’s spam details logged when they confirm the email and then it can queue them for approval based on that. That’s essentially what it does already it’s just a delayed application of the moderated state.

It's awkward with both states being controlled by user_state, but I made a small addon that lets it run the spam checks, store that data as normal, but always sets the user_state back to valid if it was set to moderated. Doing this means they then have to confirm their email like everyone else, and then when they do they get queued for moderation like everyone else, and all the spam trigger data is still there from when they registered. So from an approval point of view, it works the same as it ever did, except the user has confirmed their email address first and in the process will weed out a lot of fake accounts.
 
Last edited:
This footgun has come up several times, and the documentation is deeply misleading about what happens with the user state when spam checks and account confirmation being required
 
Back
Top Bottom