Метеор: настройка поведения Accounts.sendVerificationEmail

Может ли кто-нибудь указать правильный способ отправки подтверждения по электронной почте при создании пользователя? Это важная часть...

a) Я хочу, чтобы пользователь сразу после регистрации получил доступ. Но если пользователь еще не нажал на ссылку для подтверждения в течение 48 часов, я хотел бы запретить ему вход в систему до тех пор, пока он не нажмет на ссылку.

Мой код до сих пор отправляет подтверждение по электронной почте, но пользователь имеет постоянный доступ к приложению с нажатием на ссылку подтверждения или без нее (поэтому мой код, конечно, неполный).

клиент.js

Template.join.events({
'submit #join-form': function(e,t){
 e.preventDefault();
  var firstName=  t.find('#join-firstName').value,
  lastName=  t.find('#join-lastName').value,
  email = t.find('#join-email').value,
  password = t.find('#join-password').value,
  username = firstName.substring(0) + '.' + lastName.substring(0),
  profile = {
    fullname: firstName + ' ' + lastName
  };
  Accounts.createUser({
    email: email,
    username: username,
    password: password,
    userType: // 'reader' or 'publisher'
    createdAt: new Date(),
    profile: profile
 }, function(error) {
if (error) {
  alert(error);
} else {
  Router.go('home');
       }
    });
   }
});

сервер.js

Meteor.startup(function () {
process.env.MAIL_URL = 'smtp://postmaster.....';
Accounts.emailTemplates.from = "[email protected]";
Accounts.emailTemplates.sitename = "My SIte Name";

Accounts.emailTemplates.verifyEmail.subject = function(user) {
  return 'Please confirm tour Email address' ;
},
Accounts.emailTemplates.verifyEmail.text = function(user, url) {
  return 'Click on the link below to verify your address: ' + url;
}
Accounts.config({
  sendVerificationEmail: true
});

Моя попытка была предпринята путем собственного чтения документации по метеорам и просмотра другого кода на SO. Я застрял, ребята. Спасибо за поддержку.


person meteorBuzz    schedule 02.12.2014    source источник


Ответы (1)


Я думаю, что основная идея состоит в том, чтобы иметь некоторый код проверки, например, в Accounts.validateLoginAttempt, который вы хотите проверять каждый раз, прежде чем пользователь входит в систему. Что вы можете сделать, так это сохранить дату и время, когда пользователь регистрируется в user.profile.joinDate. Если пользователь пытается войти

  • Проверьте, был ли адрес электронной почты подтвержден или
  • проверьте, входит ли пользователь в течение льготного периода в 48 часов
isWithinGracePeriod = function(user) { 
      ** TBD returning true or false. 
         This can be tricky when you 
         have multiple instances in 
         different time-zones. 
      ** }

и

Accounts.validateLoginAttempt(function(attempt){
  if (attempt.user && attempt.user.emails && !attempt.user.emails[0].verified ) {
    console.log('No verification action received yet.');
    return isWithinGracePeriod(attempt.user); 
  }
  return true;
});

Кроме того, вот материал HTML/пробелов:

<body>
    {{ > start }}
</body>

<template name="start">
  {{#if currentUser}}{{>showUserProfile}}{{else}}{{> login}}{{/if}}
</template>

<template name="login">
   ## Grab username/password here
</template>

Если шаблон login создан, мы можем попытаться получить код подтверждения после того, как пользователь щелкнул ссылку подтверждения. Обратите внимание, что если ни один пользователь не вошел в систему, то будет отображаться login, поэтому мы присоединяемся к login через

Template.login.created = function() {
  if (Accounts._verifyEmailToken) {
    Accounts.verifyEmail(Accounts._verifyEmailToken, function(err) {
      if (err != null) {
        if (err.message = 'Verify email link expired [403]') {
          var message ='Sorry this verification link has expired.';
          console.log(message);    
          alertBox = Blaze.renderWithData(Template.Alert, {message: message}, $("body").get(0));
        }
      } else {
        var message = "Thank you! Your email address has been confirmed.";
        console.log(message);
        alertBox = Blaze.renderWithData(Template.Alert, {message: message}, $("body").get(0));
      }
    });
  }
};

Ссылка для подтверждения отправляется в "крючке" на Accounts.createUser:

Accounts.onCreateUser(function(options, user) {
   user.profile = {};
   Meteor.setTimeout(function() {
   Accounts.sendVerificationEmail(user._id);
     }, 2 * 3000);
  return user;
});
person Steffo    schedule 02.12.2014
comment
Честно говоря, 48-часовой льготный период не должен быть таким строгим. Пока есть проверка с адресом электронной почты пользователя в какой-то момент. Я видел, что с Accounts.validateLoginAttempt есть «разрешенная» функция обратного вызова, которая возвращает либо true, либо false. Для начала, не могли бы вы показать мне, как установить LoginWithEmail. Я не понимаю, что он сейчас делает, когда пользователь нажимает на ссылку. +1 за методичный подход к вопросу, спасибо Стеффо - person meteorBuzz; 02.12.2014
comment
Повторно отредактировал ответ. Когда пользователь щелкает ссылку подтверждения (которая выглядит так: localhost:3000/# /verify-email/lots-of-funny-chars), создается шаблон login, а Accounts.verifyEmail берет забавные символы и проверяет их (об этом позаботится Meteor). - person Steffo; 02.12.2014
comment
Спасибо за отзыв. Я применю этот код и сообщу вам, как я скоро поступлю, и проголосую соответствующим образом. - person meteorBuzz; 03.12.2014
comment
Это было полезно. Я все еще пытаюсь деконструировать то, что происходит. То, что я хотел бы сделать, это вернуться и упростить. Можете ли вы показать мне чистый способ отправить пользователю ссылку для подтверждения по электронной почте. Это все, пожалуйста? - person meteorBuzz; 05.12.2014