Search code examples
meteor

How to check if email already exist for a user (emails[0].address) before try to use it to change the email of another user?


I have a method to change the user's address (every user has only one address, so it's emails[0].address).

In the method, Accounts.addEmail(this.userId, newemail); block finely the adding of an emails[0].address if another user has the same. I receive in client the error.reason === 'Email already exists.' Great.

But before calling Accounts.addEmail(this.userId, newemail);, I need to call Accounts.removeEmail(this.userId, emailold); who will remove the old address and leave emails[0].address free for Accounts.addEmail(this.userId, newemail); (which, when there is no email address in an account, use nicely by default emails[0].address).

So how can I handle and stop Accounts.removeEmail(this.userId, emailold); if newemail is used as emails[0].address by any other user?

Below my method.

Thanks

// Change Email Address of the User
Meteor.methods({
    addNewEmail: function(emailold, newemail) {
        
        // this function is executed in strict mode
        'use strict';
        
        // Consistency var check
        check([emailold, newemail], [String]);
        
        // Let other method calls from the same client start running,
        // without waiting this one to complete.
        this.unblock();

        //Remove the old email address for the user (only one by default)
        Accounts.removeEmail(this.userId, emailold);
        //Add the new email address for the user: by default, set to verified:false
        Accounts.addEmail(this.userId, newemail);
        // Send email verification to the new email address
        Accounts.sendVerificationEmail(this.userId, newemail);
        
        return true;
    }
});

Solution

  • You can update the users collection directly, and handle any errors yourself. This is what I do:

    Meteor.methods({
      "users.changeEmail"(address) {
        check(address, String);
    
        const existingAddressCheck = Meteor.users.findOne({"emails.0.address": address});
    
        if(existingAddressCheck) {
          if(existingAddressCheck._id === Meteor.userId()) {
            throw new Meteor.Error("users.changeEmail.sameEmail", "That's already your registered email address!");
          } else {
            throw new Meteor.Error("users.changeEmail.existing", "An account with that address already exists");
          }
        }
        return Meteor.users.update({_id: Meteor.userId()}, {$set: {"emails.0": {address, verified: false}}});
      }
    });