Skip to content Skip to sidebar Skip to footer

Meteor: Check Email Does Not Exist In Meteor.users Collection Before Creating An Account

I have a form where users enter their email address and password into a join form. This creates the account but I now want to develop it further. client.js: Template.joinForm.event

Solution 1:

The extra empty array nameOfArrayis now created on the server if the account is allowed to be created, ie, passing the validateNewUser function. Of course, you can add more validation checks for example, password length.

client.js:

Template.joinForm.events({
    'submit .form-join': function(e, t) {
        e.preventDefault();
        var email = t.find('#email').value,
            password = t.find('#password').value,
            username = Random.id();
        Accounts.createUser({
            email: email,
            username: username,
            password: password,
            profile: profile
        }, function(error) {
            if (error) {
                alert(error.reason);
            } else {
                Router.go('/');
            }
        });
    }
});

server.js:

Accounts.onCreateUser(function(options, user) {
    var newEmail = user.emails[0].address;
    console.log(newEmail);
    var emailAlreadyExist = Meteor.users
        .find({"emails.address": newEmail}, {limit: 1})
        .count() > 0;
    console.log(emailAlreadyExist + ' already exists');
    if (emailAlreadyExist === true) {
        thrownewMeteor.Error(403, "email already registered");
    } else {
        profile = options.profile;
        profile.nameOfArray = [];
        user.profile = profile;
        return user;
    }
});

Solution 2:

I've found that Accounts.createUser has it's own validation built in and checks for already existing email/login.

Meteor docs: Accounts.createUser:

If there are existing users with a username or email only differing in case, createUser will fail.

Thus Accounts.onCreateUser doesn't even fire if Accounts.createUser email/login validation throws error.

Solution 3:

The Accounts.validateNewUser function requires users to validate their email after submitting. It's basically that step where, after you sign up for something, before you can sign in you have to enter a code that's sent to you on your email or mobile device -- basically, it ensures that the user is who they say they are. It's what might prevent you from signing up with the email totallyfake@totally_not_a_real_place.com.

If I'm reading your question right, you're more interested in seeing if an email is unique than in seeing if the user actually owns that email account. You can do this with Accounts.onCreateUser, which runs on the server:

Called whenever a new user is created. Return the new user object, or throw an Error to abort the creation.

The full process will look something like this. On the client, exactly what you have:

Template.joinForm.events({
'submit .form-join': function(e, t) {
    e.preventDefault();
    var email = t.find('#email').value,
        password = t.find('#password').value,
        username = Random.id(),
        array = [],
        profile = {
            nameOfArray: array
        };

    Accounts.createUser({
        email: email,
        username: username,
        password: password,
        profile: profile
    }, function(error) {
        if (error) {
            alert(error);
        } else {
            Router.go('/');
        }
    });
    }
});

Then, on the server, before the user is actually created, it will run the user through your onCreateUser function, and whatever you return will be inserted into the users collection:

Accounts.onCreateUser(function(options, user) { 
  var email = user.emails[0];
  if (!email) { thrownewMeteor.Error("You must provide a non-empty email"); // this may actually not be necessary -- createUser might do it for youif (Meteor.users.find({emails: email}) { 
    thrownewMeteor.Error("A user with email " + email + " already exists!"); 
  }

  ... // whatever other transformation you might wantreturn user; 
});

You might also check out the accounts-ui package, since depending on how much you want to do vary from a vanilla implementation of user accounts, a lot may already be done for you.

Solution 4:

The Accounts.validateNewUser is used to check if the fields of the user object comply with the desired format, returning true or false accordingly.

To check if the email is already registered, I think you should include this verification in the Accounts.onCreateUser function (http://docs.meteor.com/#/full/accounts_oncreateuser).

Without having tested the code, you can try something like this:

Accounts.validateNewUser(function (user) {
     // Check compliance of the user object fields, using check http://docs.meteor.com/#/full/check
});

Accounts.onCreateUser(function(options, user) {
       if (options.profile){
          user.profile = options.profile;
       }

       if (Meteor.users.find({email: user.email}).fetch == 0) {
           if(Accounts.validateNewUser(user)){
                Accounts.sendVerificationEmail(userId, [email]);
                return user;
           } else {
               thrownewMeteor.Error(403, "Error checking user fields");
       } else {
         thrownewMeteor.Error(403, "email address is already registered");
       }       
 }     

Post a Comment for "Meteor: Check Email Does Not Exist In Meteor.users Collection Before Creating An Account"