Meteor: Do Something On Email Verification Confirmation

末鹿安然 提交于 2019-12-12 18:04:42

问题


On my server I made accounts require email verification and to send the verification email:

Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});

I read somewhere online that the verification link will redirect the user to the home page of the web app once clicked.

On that home page I try to catch the first time it gets confirmed as I would like to add some entries to the MONGO DB the FIRST TIME the email gets verified and the user gets authenticated.

So I try to get this confirmation on the client side by doing this:

Template.home.created = function(){
      if (Accounts._verifyEmailToken) {
        Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
          if (err != null) {
            if (err.message = 'Verify email link expired [403]') {
              console.log('Sorry this verification link has expired.')
            }
          } else {
            console.log('Thank you! Your email address has been confirmed.')

          }
        });
      }
    }

Unfortunately I NEVER got console.log('Thank you! Your email address has been confirmed.') to log in the console..... I always get console.log('Sorry this verification link has expired.') even after the first time I click on it.

What am I missing here???

How do I get a function to be called the first time the email gets verified???

Thank you.


回答1:


Your error message verification is wrong: you are doing an assignment instead of a conditional check.

if (err.message = 'Verify email link expired [403]') // WRONG!
if (err.message == 'Verify email link expired [403]') // this is a condition

I suggest you output the contents of err.message to move forward, because it may not be related to link expiration at all!

Template.home.created = function(){
  if (Accounts._verifyEmailToken) {
    Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
      if (err != null) {
        console.log(err.message);
      } else {
        console.log('Thank you! Your email address has been confirmed.')
      }
    });
  }
}



回答2:


Ok....after playing around with the options.....I found this to work. The only downside is that a warning shows up in the console. This is the warning:

Accounts.onEmailVerificationLink was called more than once. Only one callback added will be executed.

I believe this is because I am using accounts-ui package.....and perhaps accounts-ui uses Accounts.onEmailVerificationLink as well and now we are overriding it.....

This is the solution:

Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false});

    if(Meteor.isClient){

      Accounts.onEmailVerificationLink(function(token, done){
        console.log('inside onEmailVerificationLink');
        console.log('token');
        console.log(token);

        Accounts.verifyEmail(token, function(err) {
          if (err != null) {
            console.log(err.message);
          } else {
            console.log('Thank you! Your email address has been confirmed.')
          }
        });

      });
    }


    if(Meteor.isServer){
      Accounts.onCreateUser(function(options, user){

         console.log('inside onCreateUser');
         return user;
      });

    }



回答3:


Two potential solutions:

Solution #1

Use monkey patching to intercept the call to the callback passed to verifyEmail() so that you can do what you want in addition to calling the original callback. Something like this (untested):

Accounts.verifyEmail = _.wrap(Accounts.verifyEmail, function (origVerifyEmail, token, callback) {
  return origVerifyEmail.call(Accounts, token, _.wrap(callback, function (origCallback, err) {
    try {
      if (! err) {
        // Add entries to the DB here
      }
    } finally {
      return origCallback.apply(null, _.rest(arguments));
    }
  }));
});

Note that if you use the above approach, you will presumably still need the server to ensure that the user's email address is in fact verified (i.e. the user's emails array contains an object with verified: true) before actually adding stuff to the DB. For that reason, you might prefer...

Solution #2

On the server, watch the Meteor.users collection for changes to the verification status of email addresses. Something like this (untested):

Meteor.users.find().observe({
  changed: function (oldUser, newUser) {
    if (! _.findWhere(oldUser.emails, { verified: true }) &&
      _.findWhere(newUser.emails, { verified: true })) {
      // Add entries to the DB here
    }
  }
});



回答4:


If an email is already verified, verifyEmail function will return the Error: Verify email link expired [403] error.

Make sure that you are only sending the verification token to an unverified email address, if you call the resetPassword function the email will automatically be verified.

It could be that you tested the verification token once on an account and it verified the email and then when you tried again it gave you the link expired error.

A good way to test if the email is verified is to add the following snippet of code to your dashboard (or wherever the page goes when {{#if currentUser}} condition is true):

<p>
    {{#if currentUser.emails.[0].verified}}
        <p>Email is verified</p>
    {{else}}
        <p>Email is not verified</p>
    {{/if}}
</p>

Hope this helps!



来源:https://stackoverflow.com/questions/32732683/meteor-do-something-on-email-verification-confirmation

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!