Метеор: сделайте что-нибудь при подтверждении подтверждения по электронной почте

На моем сервере я сделал учетные записи, требующие подтверждения по электронной почте и для отправки подтверждающего электронного письма:

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

Где-то в Интернете я читал, что ссылка для подтверждения перенаправит пользователя на домашнюю страницу веб-приложения после нажатия.

На этой домашней странице я пытаюсь поймать, когда в первый раз это подтверждается, поскольку я хотел бы добавить некоторые записи в базу данных MONGO в первый раз, когда электронная почта будет проверена, и пользователь будет аутентифицирован.

Поэтому я пытаюсь получить это подтверждение на стороне клиента, выполнив это:

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.')

          }
        });
      }
    }

К сожалению, я никогда не получил console.log('Thank you! Your email address has been confirmed.') войти в консоль..... я всегда получаю console.log('Sorry this verification link has expired.') даже после первого раза я нажимаю на него.

Что мне здесь не хватает???

Как получить функцию для вызова при первой проверке электронной почты???

Спасибо.

4 ответа

Проверка вашего сообщения об ошибке неверна: вы выполняете назначение вместо условной проверки.

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

Я предлагаю вам вывести содержимое err.message для продвижения вперед, поскольку оно может вообще не быть связано с истечением срока действия ссылки!

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.')
      }
    });
  }
}

Два возможных решения:

Решение № 1

Используйте патч обезьяны для перехвата вызова обратного вызова, переданного verifyEmail() так что вы можете делать то, что вы хотите в дополнение к вызову исходного обратного вызова. Примерно так (не проверено):

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));
    }
  }));
});

Обратите внимание, что если вы используете вышеупомянутый подход, вам, вероятно, все еще понадобится сервер, чтобы убедиться, что адрес электронной почты пользователя действительно проверен (т.е. emails массив содержит объект с verified: true) прежде чем фактически добавлять вещи в БД. По этой причине вы можете предпочесть...

Решение № 2

На сервере смотрите Meteor.users Коллекция для изменения статуса проверки адресов электронной почты. Примерно так (не проверено):

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
    }
  }
});

Хорошо.... после игры с вариантами..... я нашел, что это работает. Единственным недостатком является то, что в консоли отображается предупреждение. Это предупреждение:

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

Я считаю, что это потому, что я использую пакет account-ui..... и, возможно, использует account-ui Accounts.onEmailVerificationLink а теперь мы переопределяем это.....

Это решение:

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;
      });

    }

Если электронная почта уже подтверждена, verifyEmail функция вернет Error: Verify email link expired [403] ошибка.

Убедитесь, что вы отправляете токен подтверждения только на неподтвержденный адрес электронной почты, если вы звоните resetPassword Функция электронной почты будет автоматически проверена.

Возможно, вы однажды проверили токен подтверждения в учетной записи, и он подтвердил адрес электронной почты, а затем при повторной попытке выдает ошибку истекшей ссылки.

Хороший способ проверить, подтверждено ли письмо, - добавить следующий фрагмент кода на свою панель инструментов (или куда бы ни шла страница, когда {{#if currentUser}} условие верно):

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

Надеюсь это поможет!

Другие вопросы по тегам