diff --git a/client/styles/global.scss b/client/styles/global.scss index 07fa29e7..0f6656c1 100644 --- a/client/styles/global.scss +++ b/client/styles/global.scss @@ -93,27 +93,7 @@ a { } } -#loginsubmitbutton { - width: 40%; - display: block; - height: 30px; - margin: 0px auto; - background-color: #2ecc71; - margin-top: 20px; - margin-bottom: 35px; - border-radius: 5px; - cursor: pointer; - text-align: center; - font-weight: 600; - color: white; - padding-top: 5px; - - &:hover { - background-color: #4cd785; - } -} - -#registersubmitbutton { +#loginsubmitbutton, #registersubmitbutton, #forgotsubmitbutton { width: 40%; display: block; height: 30px; diff --git a/client/views/login/login.html b/client/views/login/login.html index 055dcd3e..0c7824be 100644 --- a/client/views/login/login.html +++ b/client/views/login/login.html @@ -12,6 +12,10 @@

Login

Don't have an account?

Register

+
+

+ Forgot Password +

Login diff --git a/client/views/login/login.js b/client/views/login/login.js index f6451621..9fe4c8f5 100644 --- a/client/views/login/login.js +++ b/client/views/login/login.js @@ -1,3 +1,5 @@ +import $ from 'jquery' + function showError(reason, parentElement, nextElement) { if (typeof currentError !== 'undefined') { Blaze.remove(currentError); @@ -42,6 +44,16 @@ Template.login.events({ }, 10); }); }, + 'click #forgotemphasis': function (event, template) { + $('.formcontainer').fadeOut(400); + $('#darker').fadeOut(400, () => { + Blaze.remove(popoverTemplate); + window.setTimeout(() => { + const parentNode = document.getElementById('nav'); + popoverTemplate = Blaze.render(Template.resetpwd, parentNode); + }, 10); + }); + }, 'keypress #passwordbox': function (event, template) { // eslint-disable-next-line no-param-reassign event.which = event.which || event.keyCode; diff --git a/client/views/resetpwd/resetpwd.html b/client/views/resetpwd/resetpwd.html new file mode 100644 index 00000000..c6e7bdcb --- /dev/null +++ b/client/views/resetpwd/resetpwd.html @@ -0,0 +1,37 @@ + \ No newline at end of file diff --git a/client/views/resetpwd/resetpwd.js b/client/views/resetpwd/resetpwd.js new file mode 100644 index 00000000..c16e645d --- /dev/null +++ b/client/views/resetpwd/resetpwd.js @@ -0,0 +1,103 @@ +import $ from 'jquery'; + +Accounts.onResetPasswordLink((token, done) => { + Router.go('resetpwd'); +}); + +if (Accounts._resetPasswordToken) { + Session.set('resetPasswordVar', Accounts._resetPasswordToken); +} + +function showChangePwdError(reason, parentElement, nextElement) { + if (typeof currentError !== 'undefined') { + Blaze.remove(currentError); + } + const parentNode = $('.' + parentElement)[0]; + const nextNode = $('.' + nextElement)[0]; + currentError = Blaze.renderWithData(Template.form_error, reason, parentNode, nextNode); +} + +Template.resetpwd.onRendered(() => { + $('.formcontainer').hide().fadeIn(400); + $('#darker').hide().fadeIn(400); +}); + +Template.resetpwd.helpers({ + resetPassword() { + return Session.get('resetPasswordVar'); + }, +}); + +Template.resetpwd.events({ + 'keypress #newpasswordconfirm': function (event, template) { + event.which = event.which || event.keyCode; + if (event.which === 13) { + event.preventDefault(); + $('#newpwdsubmitbutton').click(); + } + }, + 'keypress #loginemail': function (event, template) { + event.which = event.which || event.keyCode; + if (event.which === 13) { + event.preventDefault(); + $('#forgotsubmitbutton').click(); + } + }, + 'click #forgotsubmitbutton': function (event, template) { + $('#mailSentMessage').css('display', 'none'); + const email = $('#loginemail').val(); + $('#newPwdLoadingSpinner').css('display', 'block'); + Accounts.forgotPassword({ email: email }, function (e) { + $('#newPwdLoadingSpinner').css('display', 'none'); + if (e) { + const errorMessage = [ + { reason: 'User not found', message: "The email address that you've entered doesn't match any account." }, + { reason: 'Internal server error', message: 'Please check your internet connection.' }, + ]; + const in1 = errorMessage.findIndex(x => x.reason === e.reason); + if (in1 === -1) { + showChangePwdError(e.reason, 'formcontainer', 'inputcontainer'); + } else { + showChangePwdError(errorMessage[in1].message, 'formcontainer', 'inputcontainer'); + } + } else { + $('#mailSentMessage').css('display', 'block'); + } + }); + }, + 'click #newpwdsubmitbutton': function (event, template) { + const newPass = $('#newpasswordbox').val(); + const newPassConfirm = $('#newpasswordconfirm').val(); + if (!$('#newpasswordbox')[0].checkValidity()) { + showChangePwdError('Password must be between 6 and 30 characters', 'newpwdbox', 'newpwdform'); + return false; + } else if (newPass !== newPassConfirm) { + showChangePwdError('Passwords do not match', 'newpwdbox', 'newpwdform'); + return false; + } + Accounts.resetPassword(Session.get('resetPasswordVar'), newPass, function (e) { + if (e) { + const errorMessage = [ + { reason: 'Token expired', message: 'This link is expired.' }, + { reason: 'Internal server error', message: 'Please check your internet connection.' }, + ]; + const in1 = errorMessage.findIndex(x => x.reason === e.reason); + if (in1 === -1) { + showChangePwdError(e.reason, 'newpwdbox', 'newpwdform'); + } else { + showChangePwdError(errorMessage[in1].message, 'newpwdbox', 'newpwdform'); + } + } else { + $('.newpwdbox').css('display', 'none'); + $('#pwdchangemessage').css('display', 'block'); + setTimeout(() => { + Session.set('resetPasswordVar', null); + Router.go('/'); + }, 3000); + } + }); + }, + 'click #navHome': function (event, template) { + Router.go('/'); + }, +}); diff --git a/client/views/resetpwd/resetpwd.scss b/client/views/resetpwd/resetpwd.scss new file mode 100644 index 00000000..1532ae4f --- /dev/null +++ b/client/views/resetpwd/resetpwd.scss @@ -0,0 +1,75 @@ +.newpwdbox { + text-align: center; +} + +.newpwdnav { + height: 50px; + background-color: #293340; + margin-bottom: 50px; +} + +.newpwdnav > #navHome > .fa-home { + font-size: 2em; + padding: 10px; +} + +.input { + width: 300px!important; +} + +#newpwdsubmitbutton { + width: 200px; + display: block; + height: 30px; + margin: 0px auto; + background-color: #2ecc71; + margin-top: 20px; + margin-bottom: 10px; + border-radius: 5px; + cursor: pointer; + text-align: center; + font-weight: 600; + color: white; + padding-top: 5px; + + &:hover { + background-color: #4cd785; + } +} + +#forgotsubmitbutton { + margin-bottom: 10px !important; +} + +.newpwdbox > h1 { + margin-bottom: 20px; +} + +.newpwdbox > .error { + max-width: 420px; + display: inline-block; +} + +#newPwdLoadingSpinner { + width: 12%; + display: inline-block; + margin-left: 44%; + display: none; +} + +#mailSentMessage { + color: #42a1f4; + background-color: #fff; + width: 50%; + margin-left: 25%; + text-align: center; + display: none; +} + +#pwdchangemessage { + display: none; + width: 300px; + text-align: center; + width: 100%; + font-size: 1.5em; +} \ No newline at end of file diff --git a/lib/routes.js b/lib/routes.js index 2a5f6b0a..906922c3 100644 --- a/lib/routes.js +++ b/lib/routes.js @@ -201,3 +201,7 @@ Router.route('/rss/:tablename', { this.response.end(xmlData); }, }); + +Router.route('resetpwd', { + template: 'resetpwd', +}); \ No newline at end of file diff --git a/server/methods.js b/server/methods.js index 6d4b5233..7021f7a3 100644 --- a/server/methods.js +++ b/server/methods.js @@ -196,7 +196,7 @@ Meteor.methods({ $set: newValues, }, (error, count, status) => { if (error) { - errorKey = error.invalidKeys[0].name; + const errorKey = error.invalidKeys[0].name; throw new Meteor.Error(errorKey); } });