From e8f827e6a77f9d57213ef0fd7f658863a0bd69f3 Mon Sep 17 00:00:00 2001 From: Thomas Forgione Date: Fri, 29 Sep 2017 14:35:13 +0200 Subject: [PATCH] We can now change password Fixes #2 --- controllers/auth/templates/login.pug | 2 + .../auth/templates/passwordForgotten.pug | 12 +++ controllers/auth/templates/resetPassword.pug | 32 +++++++ .../auth/templates/resetPasswordMail.pug | 50 +++++++++++ .../templates/resetPasswordMailWasSent.pug | 8 ++ ...validation-mail.pug => validationMail.pug} | 0 ...validation-mail.txt => validationMail.txt} | 0 controllers/auth/urls.js | 5 ++ controllers/auth/views.js | 87 ++++++++++++++++++- 9 files changed, 194 insertions(+), 2 deletions(-) create mode 100644 controllers/auth/templates/passwordForgotten.pug create mode 100644 controllers/auth/templates/resetPassword.pug create mode 100644 controllers/auth/templates/resetPasswordMail.pug create mode 100644 controllers/auth/templates/resetPasswordMailWasSent.pug rename controllers/auth/templates/{validation-mail.pug => validationMail.pug} (100%) rename controllers/auth/templates/{validation-mail.txt => validationMail.txt} (100%) diff --git a/controllers/auth/templates/login.pug b/controllers/auth/templates/login.pug index f5af6e3..7dcb628 100644 --- a/controllers/auth/templates/login.pug +++ b/controllers/auth/templates/login.pug @@ -12,6 +12,8 @@ block content input.form-control(type="text", name="username", placeholder="Username", autofocus) .form-group input.form-control(type="password", name="password", placeholder="Password") + .form-group + a(href=getUrl('passwordForgotten')) Forgot your password ? .form-group input.btn.btn-primary.form-control(type="submit", value="Log in") .col diff --git a/controllers/auth/templates/passwordForgotten.pug b/controllers/auth/templates/passwordForgotten.pug new file mode 100644 index 0000000..a415346 --- /dev/null +++ b/controllers/auth/templates/passwordForgotten.pug @@ -0,0 +1,12 @@ +extends ../../../templates/base.pug + +block content + .row + .col + .col + form(method="POST", action=getUrl("passwordForgottenTarget")) + .form-group + input.form-control(type="text", name="email", placeholder="Enter your email address", autofocus) + .form-group + input.btn.btn-primary.form-control(type="submit", value="Request a new password") + .col diff --git a/controllers/auth/templates/resetPassword.pug b/controllers/auth/templates/resetPassword.pug new file mode 100644 index 0000000..ade9f0d --- /dev/null +++ b/controllers/auth/templates/resetPassword.pug @@ -0,0 +1,32 @@ +extends ../../../templates/base.pug +block content + .row + .col + .col + form(method="POST", action=getUrl("resetPasswordTarget")) + input(style="display:none;", type="text", name="activationKey", value=user.activationKey) + .form-group + input#pass1.form-control(type='password', name='password', placeholder='Password') + .form-group + input#pass2.form-control(type='password', placeholder='Retype your password') + .form-group + input.btn.btn-primary.form-control(type='submit', value='Change your password') + .col + +block extrajs + script. + var mail = document.getElementById('email'), + pass = document.getElementById('pass1'), + pass2 = document.getElementById('pass2'); + + function validatePasswords() { + if (pass1.value === pass2.value) { + pass2.setCustomValidity(''); + } else { + pass2.setCustomValidity("Passwords don't match"); + } + } + + pass1.addEventListener('change', validatePasswords); + pass2.addEventListener('keyup', validatePasswords); + diff --git a/controllers/auth/templates/resetPasswordMail.pug b/controllers/auth/templates/resetPasswordMail.pug new file mode 100644 index 0000000..0d36039 --- /dev/null +++ b/controllers/auth/templates/resetPasswordMail.pug @@ -0,0 +1,50 @@ +style. + .body { + width: 570px; + padding: 0px; + margin-right: auto; + margin-left: auto; + border: solid; + border-width: thin; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + } + + .header { + padding: 10px; + border-bottom: solid; + border-bottom-width: thin; + } + + .footer { + font-size: 75%; + padding: 10px; + border-top: solid; + border-top-width: thin; + } + + h1 { + text-align: center; + } + + p { + padding: 10px; + margin: 0px; + } + + .username { + font-style: italic; + } + +.body + .header + h1 Welcome on ADEjs! + p. + Hello #{user.username}! + p. + You recently told us that you lost your password. + p. + To set a new password, please visit visit this link. + + .footer. + If you did not subscribe on PyADE with this email address, please ignore this e-mail. diff --git a/controllers/auth/templates/resetPasswordMailWasSent.pug b/controllers/auth/templates/resetPasswordMailWasSent.pug new file mode 100644 index 0000000..9fd1357 --- /dev/null +++ b/controllers/auth/templates/resetPasswordMailWasSent.pug @@ -0,0 +1,8 @@ +extends ../../../templates/base.pug + +block content + h1 A mail was sent to you + p. + In this mail, you'll find a link to reset your account. + p. + Please, don't forget that my server is cheap, so depending on your mail provider, my email might get thrown in the spam :'( diff --git a/controllers/auth/templates/validation-mail.pug b/controllers/auth/templates/validationMail.pug similarity index 100% rename from controllers/auth/templates/validation-mail.pug rename to controllers/auth/templates/validationMail.pug diff --git a/controllers/auth/templates/validation-mail.txt b/controllers/auth/templates/validationMail.txt similarity index 100% rename from controllers/auth/templates/validation-mail.txt rename to controllers/auth/templates/validationMail.txt diff --git a/controllers/auth/urls.js b/controllers/auth/urls.js index 3519978..65322a2 100644 --- a/controllers/auth/urls.js +++ b/controllers/auth/urls.js @@ -7,5 +7,10 @@ module.exports = [ url('/signup/', 'signup', 'signup'), url('/signup-target/', 'signupTarget', 'signupTarget', 'POST'), url('/mail-was-sent/', 'mailWasSent', 'mailWasSent'), + url('/reset-password-mail-was-sent/', 'resetPasswordMailWasSent', 'resetPasswordMailWasSent'), url('/activate/:activationKey', 'activate', 'activate'), + url('/password-forgotten', 'passwordForgotten', 'passwordForgotten'), + url('/password-forgotten-target', 'passwordForgottenTarget', 'passwordForgottenTarget', 'POST'), + url('/reset-password/:activationKey', 'resetPassword', 'resetPassword'), + url('/reset-password-target', 'resetPasswordTarget', 'resetPasswordTarget', 'POST'), ] diff --git a/controllers/auth/views.js b/controllers/auth/views.js index 8048ec0..1979728 100644 --- a/controllers/auth/views.js +++ b/controllers/auth/views.js @@ -108,7 +108,7 @@ module.exports.signupTarget = function(req, res, render) { baseUrl + 'activate/' + user.activationKey; let html = pug.renderFile( - __dirname + '/templates/validation-mail.pug', + __dirname + '/templates/validationMail.pug', res.locals, ); @@ -134,7 +134,7 @@ module.exports.mailWasSent = function(req, res, render) { module.exports.activate = function(req, res, render, next) { User.getByActivationKey(req.params.activationKey, (err, user) => { - if (user === undefined) { + if (user === undefined || user.active) { return next(); } @@ -148,3 +148,86 @@ module.exports.activate = function(req, res, render, next) { }); } +module.exports.passwordForgotten = function(req, res, render, next) { + render('passwordForgotten.pug'); +} + +module.exports.passwordForgottenTarget = function(req, res, render, next) { + User.getByEmail(req.body.email, (err, user) => { + if (err !== undefined) { + return res.send("Nope"); + } + + require('crypto').randomBytes(48, function(err, buffer) { + user.activationKey = buffer.toString('hex'); + user.save(); + + if (!user.active) { + return res.send("Nope"); + } + + res.locals.user = user; + + let baseUrl = + req.headers.referer.split('/').slice(0, 3).join('/') + '/' + + res.locals.resetUrl = + baseUrl + 'reset-password/' + user.activationKey; + + let html = pug.renderFile( + __dirname + '/templates/resetPasswordMail.pug', + res.locals, + ); + + mail({ + from: config.MAIL.FROM, + to: user.username + ' <' + user.email + '>', + subject: 'Welcome on ADEjs!', + text:'', + attachment: [ + {data: html, alternative: true} + ] + }, (err, result) => { + res.redirect(getUrl('resetPasswordMailWasSent')); + }); + + }); + + }); +} + +module.exports.resetPasswordMailWasSent = function(req, res, render, next) { + render('resetPasswordMailWasSent.pug'); +} + +module.exports.resetPassword = function(req, res, render, next) { + + User.getByActivationKey(req.params.activationKey, (err, user) => { + if (user === undefined || !user.active) { + return next(); + } + + res.locals.user = user; + render('resetPassword.pug'); + }); + +} + +module.exports.resetPasswordTarget = function(req, res, render, next) { + + User.getByActivationKey(req.body.activationKey, (err, user) => { + + if (user === undefined || !user.active) { + return next(); + } + + user.password = req.body.password; + user.activationKey = undefined; + user.save(() => { + req.session.user = user; + req.session.save(); + res.redirect(getUrl('index')); + }); + }); +} +