LT-102: Send a email which includes password reset link if Forgot Password option is selected
- Add custom Reset Password template and reset password - Show the first error instead showing all errors of invalidated input values in Sign Up and changePassword templates
This commit is contained in:
parent
28ba53b328
commit
a5d4c6d0eb
@ -6,10 +6,11 @@ Meteor.startup(function () {
|
|||||||
var server = Meteor.settings && Meteor.settings.mailServerSettings && Meteor.settings.mailServerSettings.server || null;
|
var server = Meteor.settings && Meteor.settings.mailServerSettings && Meteor.settings.mailServerSettings.server || null;
|
||||||
var port = Meteor.settings && Meteor.settings.mailServerSettings && Meteor.settings.mailServerSettings.port || null;
|
var port = Meteor.settings && Meteor.settings.mailServerSettings && Meteor.settings.mailServerSettings.port || null;
|
||||||
var verifyEmail = Meteor.settings && Meteor.settings.public && Meteor.settings.public.verifyEmail || false;
|
var verifyEmail = Meteor.settings && Meteor.settings.public && Meteor.settings.public.verifyEmail || false;
|
||||||
|
var siteName = Meteor.settings && Meteor.settings.public && Meteor.settings.public.siteName || "Lesion Tracker";
|
||||||
|
|
||||||
if (verifyEmail && username && password && server && port) {
|
if (username && password && server && port) {
|
||||||
Accounts.emailTemplates.siteName = 'Lesion Tracker';
|
Accounts.emailTemplates.siteName = siteName;
|
||||||
Accounts.emailTemplates.from = 'Lesion Tracker Admin <'+username+'>';
|
Accounts.emailTemplates.from = siteName+' Admin <'+username+'>';
|
||||||
|
|
||||||
process.env.MAIL_URL = 'smtp://' +
|
process.env.MAIL_URL = 'smtp://' +
|
||||||
encodeURIComponent(username) + ':' +
|
encodeURIComponent(username) + ':' +
|
||||||
@ -18,7 +19,7 @@ Meteor.startup(function () {
|
|||||||
|
|
||||||
// Subject line of the email.
|
// Subject line of the email.
|
||||||
Accounts.emailTemplates.verifyEmail.subject = function(user) {
|
Accounts.emailTemplates.verifyEmail.subject = function(user) {
|
||||||
return 'Confirm Your Email Address for Lesion Tracker';
|
return 'Confirm Your Email Address for '+siteName;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Email text
|
// Email text
|
||||||
@ -26,9 +27,24 @@ Meteor.startup(function () {
|
|||||||
return 'Thank you for registering. Please click on the following link to verify your email address: \r\n' + url;
|
return 'Thank you for registering. Please click on the following link to verify your email address: \r\n' + url;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Reset password mail
|
||||||
|
Accounts.emailTemplates.resetPassword.subject = function() {
|
||||||
|
return 'Reset your '+siteName+' password'
|
||||||
|
};
|
||||||
|
|
||||||
|
Accounts.urls.resetPassword = function(token) {
|
||||||
|
return Meteor.absoluteUrl('resetPassword/' + token);
|
||||||
|
};
|
||||||
|
|
||||||
|
Accounts.emailTemplates.resetPassword.text = function(user, url) {
|
||||||
|
return "Hello " + user.profile.fullName + ",\n\n" +
|
||||||
|
"Click the following link to set your new password:\n" +
|
||||||
|
url + "\n\n";
|
||||||
|
};
|
||||||
|
|
||||||
// Send email when account is created
|
// Send email when account is created
|
||||||
Accounts.config({
|
Accounts.config({
|
||||||
sendVerificationEmail: true
|
sendVerificationEmail: verifyEmail
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -8,9 +8,9 @@
|
|||||||
<div id="changePasswordPageMessage" class="subtitle-auth" style="{{getChangePasswordMessageColor}}">{{getChangePasswordMessage}}</div>
|
<div id="changePasswordPageMessage" class="subtitle-auth" style="{{getChangePasswordMessageColor}}">{{getChangePasswordMessage}}</div>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
{{#if entryErrorMessages}}
|
{{#if changePasswordErrorMessages}}
|
||||||
<div id="errorMessages" class="list-errors">
|
<div id="errorMessages" class="list-errors">
|
||||||
{{#each entryErrorMessages}}
|
{{#each changePasswordErrorMessages}}
|
||||||
<div class="alert alert-danger list-item">{{this}}</div>
|
<div class="alert alert-danger list-item">{{this}}</div>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -46,14 +46,19 @@ Template.changePassword.helpers({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
entryErrorMessages: function() {
|
changePasswordErrorMessages: function() {
|
||||||
var errorMessages = [];
|
var allErrorMessages = Object.keys(ActiveEntry.errorMessages.all()).filter(function(key) {
|
||||||
Object.keys(ActiveEntry.errorMessages.all()).forEach(function(key) {
|
return (key === "password" || key === "confirm") && ActiveEntry.errorMessages.get(key);
|
||||||
if ((key === "password" || key === "confirm") && ActiveEntry.errorMessages.get(key)) {
|
|
||||||
errorMessages.push(ActiveEntry.errorMessages.get(key));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return errorMessages;
|
|
||||||
|
if (allErrorMessages.length > 0) {
|
||||||
|
var errorMessage = ActiveEntry.errorMessages.get(allErrorMessages[0]);
|
||||||
|
if (errorMessage) {
|
||||||
|
return [errorMessage];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -30,13 +30,18 @@ Template.entrySignUp.helpers({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
entryErrorMessages: function () {
|
entryErrorMessages: function () {
|
||||||
var errorMessages = [];
|
var allErrorMessages = Object.keys(ActiveEntry.errorMessages.all()).filter(function(key) {
|
||||||
Object.keys(ActiveEntry.errorMessages.all()).forEach(function(key) {
|
return key !== "signInError" && ActiveEntry.errorMessages.get(key);
|
||||||
if (key !== "signInError" && ActiveEntry.errorMessages.get(key)) {
|
|
||||||
errorMessages.push(ActiveEntry.errorMessages.get(key));
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return errorMessages;
|
|
||||||
|
if (allErrorMessages.length > 0) {
|
||||||
|
var errorMessage = ActiveEntry.errorMessages.get(allErrorMessages[0]);
|
||||||
|
if (errorMessage) {
|
||||||
|
return [errorMessage];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
},
|
},
|
||||||
getButtonText: function () {
|
getButtonText: function () {
|
||||||
if (ActiveEntry.errorMessages.get('signInError')) {
|
if (ActiveEntry.errorMessages.get('signInError')) {
|
||||||
|
|||||||
@ -5,7 +5,8 @@
|
|||||||
<div class="entryLogo" style="background-image: url('{{getLogoUrl}}')"></div>
|
<div class="entryLogo" style="background-image: url('{{getLogoUrl}}')"></div>
|
||||||
|
|
||||||
<h1 id="signInPageTitle" class="title-auth">Forgot Password</h1>
|
<h1 id="signInPageTitle" class="title-auth">Forgot Password</h1>
|
||||||
<div id="signInPageMessage" class="subtitle-auth" >Imdivrove your clincal practice with checklists.</div>
|
<div id="signInPageMessage" class="subtitle-auth" >Improve your clinical practice with checklists.</div>
|
||||||
|
<p id="signInPageMessage" class="subtitle-auth" style="{{getForgotPasswordMessageColor}}">{{{getForgotPasswordMessage}}}</p>
|
||||||
|
|
||||||
<form>
|
<form>
|
||||||
<div class="input-symbol">
|
<div class="input-symbol">
|
||||||
@ -15,6 +16,11 @@
|
|||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<button id="sendReminderButton" type="submit" class="btn-gray btn-main btn-large" style="{{getButtonColor}}">Send Reminder</button><br><br>
|
<button id="sendReminderButton" type="submit" class="btn-gray btn-main btn-large" style="{{getButtonColor}}">Send Reminder</button><br><br>
|
||||||
|
{{#if forgotPasswordNotification}}
|
||||||
|
<div class="alert alert-success">
|
||||||
|
{{{forgotPasswordNotification}}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
@ -22,3 +28,45 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template name="resetPassword">
|
||||||
|
{{#if resetPassword}}
|
||||||
|
<div id="resetPassword" class="page entryPage" style="{{getOpacityWithCorner}}">
|
||||||
|
<div class="content-scrollable">
|
||||||
|
<div class="wrapper-auth">
|
||||||
|
<div class="entryLogo" style="background-image: url('{{getLogoUrl}}')"></div>
|
||||||
|
|
||||||
|
<h1 id="signInPageTitle" class="title-auth">Reset Password</h1>
|
||||||
|
<div id="signInPageMessage" class="subtitle-auth" >Improve your clinical practice with checklists.</div>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
{{#if resetPasswordErrorMessages}}
|
||||||
|
<div id="errorMessages" class="list-errors">
|
||||||
|
{{#each resetPasswordErrorMessages}}
|
||||||
|
<div class="alert alert-danger list-item">{{this}}</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
<div class="input-symbol ">
|
||||||
|
<input id="resetPasswordInput" type="password" name="password" placeholder="Password" style="{{getPasswordStyling}}" />
|
||||||
|
<span class="fa fa-lock" title="Password"></span>
|
||||||
|
<!-- <span class="icon-lock" title="Password"></span> -->
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="input-symbol">
|
||||||
|
<input id="resetPasswordConfirmInput" type="password" name="confirm" placeholder="Confirm Password" style="{{getConfirmPasswordStyling}}" />
|
||||||
|
<span class="fa fa-lock" title="Confirm Password"></span>
|
||||||
|
<!-- <span class="icon-lock" title="Confirm Password"></span> -->
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
</form>
|
||||||
|
<button id="resetPasswordButton" type="submit" class="btn-gray btn-main btn-large" style="{{getButtonColor}}">Reset Password</button><br><br>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
|
</template>
|
||||||
|
|||||||
@ -5,11 +5,33 @@ Router.route('/forgotPassword', {
|
|||||||
template: "forgotPassword"
|
template: "forgotPassword"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Router.route('/resetPassword/:token', {
|
||||||
|
template: 'resetPassword',
|
||||||
|
name: 'resetPassword',
|
||||||
|
onBeforeAction: function() {
|
||||||
|
var token = this.params.token;
|
||||||
|
Session.set('_resetPasswordToken', token);
|
||||||
|
this.next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Template.forgotPassword.helpers({
|
Template.forgotPassword.helpers({
|
||||||
getForgotPasswordStyle: function (){
|
getForgotPasswordMessageColor: function (){
|
||||||
return "border: 1px solid gray";
|
if (ActiveEntry.errorMessages.get('forgotPassword')) {
|
||||||
}
|
return "color: #a94442; background-color: #f2dede; border-color: #ebccd1;"
|
||||||
|
} else {
|
||||||
|
return "color: black;"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
getForgotPasswordMessage: function (){
|
||||||
|
return ActiveEntry.errorMessages.get('forgotPassword');
|
||||||
|
},
|
||||||
|
getForgotPasswordStyle: function (){
|
||||||
|
return "border: 1px solid gray";
|
||||||
|
},
|
||||||
|
forgotPasswordNotification: function() {
|
||||||
|
return ActiveEntry.successMessages.get("forgotPassword");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.forgotPassword.events({
|
Template.forgotPassword.events({
|
||||||
@ -17,6 +39,46 @@ Template.forgotPassword.events({
|
|||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
console.log('send reminder!');
|
console.log('send reminder!');
|
||||||
Accounts.forgotPassword({email: $('#signInPageEmailInput').val()});
|
var emailAddress = $('#signInPageEmailInput').val();
|
||||||
|
ActiveEntry.forgotPassword(emailAddress);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Reset password template
|
||||||
|
Template.resetPassword.helpers({
|
||||||
|
resetPassword: function(){
|
||||||
|
return Session.get('_resetPasswordToken');
|
||||||
|
},
|
||||||
|
resetPasswordErrorMessages: function() {
|
||||||
|
if (ActiveEntry.errorMessages.get("password")) {
|
||||||
|
return [ActiveEntry.errorMessages.get("password")];
|
||||||
|
}
|
||||||
|
if (ActiveEntry.errorMessages.get("confirm")) {
|
||||||
|
return [ActiveEntry.errorMessages.get("confirm")];
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Template.resetPassword.events({
|
||||||
|
'keyup #resetPasswordInput': function (event, template) {
|
||||||
|
var password = $('#resetPasswordInput').val();
|
||||||
|
ActiveEntry.verifyPassword(password);
|
||||||
|
ActiveEntry.errorMessages.set('forgotPassword', null);
|
||||||
|
},
|
||||||
|
'keyup #resetPasswordConfirmInput': function (event, template) {
|
||||||
|
|
||||||
|
var password = $('#resetPasswordInput').val();
|
||||||
|
var confirmPassword = $('#resetPasswordConfirmInput').val();
|
||||||
|
|
||||||
|
ActiveEntry.verifyConfirmPassword(password, confirmPassword);
|
||||||
|
ActiveEntry.errorMessages.set('forgotPassword', null);
|
||||||
|
},
|
||||||
|
'click #resetPasswordButton': function(e, template) {
|
||||||
|
e.preventDefault();
|
||||||
|
var password = $('#resetPasswordInput').val();
|
||||||
|
var passwordConfirm = $('#resetPasswordConfirmInput').val();
|
||||||
|
ActiveEntry.resetPassword(password, passwordConfirm);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|||||||
@ -263,6 +263,47 @@ ActiveEntry.signUp = function (emailValue, passwordValue, confirmPassword, fullN
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ActiveEntry.forgotPassword = function(emailAddress) {
|
||||||
|
ActiveEntry.verifyEmail(emailAddress);
|
||||||
|
ActiveEntry.errorMessages.set("forgotPassword", null);
|
||||||
|
ActiveEntry.successMessages.set("forgotPassword", null);
|
||||||
|
|
||||||
|
if (ActiveEntry.errorMessages.get("email")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accounts.forgotPassword({email:emailAddress }, function(error){
|
||||||
|
if (error) {
|
||||||
|
console.warn(error.message);
|
||||||
|
ActiveEntry.errorMessages.set("forgotPassword", error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Show email sent notification
|
||||||
|
ActiveEntry.successMessages.set("forgotPassword", "Your password reset email is sent to <strong>"+emailAddress+"</strong>");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
ActiveEntry.resetPassword = function(passwordValue, confirmPassword) {
|
||||||
|
ActiveEntry.verifyPassword(passwordValue);
|
||||||
|
ActiveEntry.verifyConfirmPassword(passwordValue, confirmPassword);
|
||||||
|
ActiveEntry.errorMessages.set("resetPassword", null);
|
||||||
|
|
||||||
|
// Check error messages
|
||||||
|
if (ActiveEntry.errorMessages.get("password") || ActiveEntry.errorMessages.get("confirm")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Accounts.resetPassword(Session.get('_resetPasswordToken'), passwordValue, function(error) {
|
||||||
|
if (error) {
|
||||||
|
ActiveEntry.errorMessages.set("resetPassword", error.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Session.set('_resetPasswordToken', null);
|
||||||
|
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||||
|
Router.go(ActiveEntryConfig.signIn.destination);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
// Insert hashed password in previousPasswords fields
|
// Insert hashed password in previousPasswords fields
|
||||||
ActiveEntry.insertHashedPassword = function(passwordValue) {
|
ActiveEntry.insertHashedPassword = function(passwordValue) {
|
||||||
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
var ActiveEntryConfig = Session.get('Photonic.ActiveEntry');
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
#entrySignIn.entryPage,
|
#entrySignIn.entryPage,
|
||||||
#entrySignUp.entryPage,
|
#entrySignUp.entryPage,
|
||||||
#changePassword
|
#changePassword,
|
||||||
|
#forgotPassword,
|
||||||
|
#resetPassword
|
||||||
.wrapper-auth
|
.wrapper-auth
|
||||||
.title-auth
|
.title-auth
|
||||||
color: white
|
color: white
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user