Reputation: 3200
Can someone please provide the correct method to send an email verification upon user creation? This is the important part...
a) I would like the user to have immediate access upon signing up. But if the user has not yet clicked clicked on the verification link within 48 hours, I would like to deny them logging in until they have clicked on the link.
My code so far sends an email verification but the user has continuos access to the application with or without clicking on the verification link (so my code is of course incomplete).
client.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');
}
});
}
});
server.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
});
My attempt have been made through own readings on meteor docs and looking at other code on SO. I am stuck guys. Thanks for the support.
Upvotes: 2
Views: 2458
Reputation: 622
I think the basic idea is to have some validation code eg in Accounts.validateLoginAttempt
which you want to check every time before user logs in. What you can do is to store the date&time when user signs up in user.profile.joinDate
. If a user tries to login
isWithinGracePeriod = function(user) { ** TBD returning true or false. This can be tricky when you have multiple instances in different time-zones. ** }
and
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; });
Further, here is the HTML/spacebars stuff:
<body>
{{ > start }}
</body>
<template name="start">
{{#if currentUser}}{{>showUserProfile}}{{else}}{{> login}}{{/if}}
</template>
<template name="login">
## Grab username/password here
</template>
If the login
template is created, we can try to capture the verification code after the user clicked the verification link. Note that, if no user is logged in, then login
will be rendered, so we attach to login
via
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));
}
});
}
};
The verification link is send in "hook" to Accounts.createUser
:
Accounts.onCreateUser(function(options, user) {
user.profile = {};
Meteor.setTimeout(function() {
Accounts.sendVerificationEmail(user._id);
}, 2 * 3000);
return user;
});
Upvotes: 3