Skip to content
Snippets Groups Projects
Commit 020085f7 authored by Louis's avatar Louis :fire:
Browse files

Configure route to retrieve reset token and send reset email

parent da0ffbe9
No related branches found
No related tags found
No related merge requests found
...@@ -45,12 +45,27 @@ ...@@ -45,12 +45,27 @@
body: JSON.stringify(payload), body: JSON.stringify(payload),
}) })
if (!result.ok) { if (!result.ok && result.status !== 400) {
messageField.innerText = 'There was a problem resetting your password. Please request a new password reset link and try again later.' messageField.innerText = 'There was a problem resetting your password. Please request a new password reset link and try again later.'
return return
} }
const data = await result.clone().json() if (!result.ok && result.status === 400) {
const data = await result.clone().json()
const { error } = data
messageField.innerText = error.message
return
}
const parent = form.parentElement
parent.removeChild(form)
const success = document.createElement('div')
success.innerHTML = `<h3 class="centered">Password Reset Successful</h3>
<p class="centered">You successfully reset your password. You can log in to the Jetsam app with the password you just created. Now go and snap some pesky plastics!</p>
<div class="row centered">
\t<a href="https://jetsam.tech">Go to the Jetsam website</a>
</div>`
parent.appendChild(success)
}) })
}) })
}()) }())
\ No newline at end of file
...@@ -5,4 +5,7 @@ module.exports = { ...@@ -5,4 +5,7 @@ module.exports = {
port: Number(env('PORT')) || 8000, port: Number(env('PORT')) || 8000,
key: env('APP_KEY', () => require('core/utils/crypto').insecureHexString(32)), key: env('APP_KEY', () => require('core/utils/crypto').insecureHexString(32)),
dev: env('NODE_ENV', 'err') === 'development', dev: env('NODE_ENV', 'err') === 'development',
urls: {
web: env('WEB_URL', 'http://localhost'),
},
} }
...@@ -8,13 +8,19 @@ module.exports = { ...@@ -8,13 +8,19 @@ module.exports = {
}, },
}, },
sendgrid: { sendgrid: {
key: env('SENDGRID_API_KEY'), key: env('SENDGRID_KEY'),
opts: { opts: {
from: `${ env('MAIL_REPLY_NAME', env('MAIL_REPLY_EMAIL')) } <${ env('MAIL_REPLY_EMAIL') }>`, from: {
replyTo: env('MAIL_REPLY_EMAIL'), email: env('MAIL_FROM_ADDRESS'),
name: env('MAIL_FROM_NAME'),
},
replyTo: {
email: env('MAIL_FROM_ADDRESS'),
name: env('MAIL_FROM_NAME'),
},
}, },
templates: { templates: {
'reset-password': ' d-dd89d66ad75f40f5b3b0ed6849753cf7', 'reset-password': 'd-dd89d66ad75f40f5b3b0ed6849753cf7',
}, },
}, },
} }
...@@ -3,6 +3,8 @@ const moment = require('moment') ...@@ -3,6 +3,8 @@ const moment = require('moment')
const { User } = require('database/models') const { User } = require('database/models')
const HttpError = require('core/errors/HttpError') const HttpError = require('core/errors/HttpError')
const crypto = require('core/utils/crypto') const crypto = require('core/utils/crypto')
const reporter = require('services/Reporter')
const { config } = require('bootstrap')
exports.register = async ctx => { exports.register = async ctx => {
const { email, name, password, date_of_birth } = ctx.request.body const { email, name, password, date_of_birth } = ctx.request.body
...@@ -35,6 +37,32 @@ exports.login = async ctx => { ...@@ -35,6 +37,32 @@ exports.login = async ctx => {
exports.triggerPasswordReset = async ctx => { exports.triggerPasswordReset = async ctx => {
const { email } = ctx.request.body const { email } = ctx.request.body
const user = await User.findOne({ where: { email } })
if (!user) {
throw new HttpError({ status: 404, title: 'No Such Email', description: 'The provided email address is not associated with an account' })
}
const token = await user.generateResetToken()
const name = user.name || 'Jetsam User (You haven\'t told us your name!)'
const reset_link = new URL(`/reset-password?token=${ token }`, config('app.urls.web'))
const { mail } = require('services')
try {
await mail.sendTemplate(email, 'Reset Your Jetsam password', config('mail.templates.reset-password'), {
name,
reset_link,
})
} catch (e) {
reporter.report(e)
console.log(e.response.body.errors)
throw new HttpError({ status: 500, title: 'Failed to send reset email', description: 'Could not send the password reset email' })
}
ctx.body = {
reset_token: token,
}
} }
exports.handlePasswordReset = async ctx => { exports.handlePasswordReset = async ctx => {
...@@ -79,7 +107,7 @@ exports.handlePasswordReset = async ctx => { ...@@ -79,7 +107,7 @@ exports.handlePasswordReset = async ctx => {
confirm_password, confirm_password,
}, },
} }
ctx.status = 409 ctx.status = 400
return return
} }
......
...@@ -46,6 +46,9 @@ function mount(api) { ...@@ -46,6 +46,9 @@ function mount(api) {
api.post('/register', controller('api/auth', 'register')) api.post('/register', controller('api/auth', 'register'))
api.post('/login', controller('api/auth', 'login')) api.post('/login', controller('api/auth', 'login'))
api.post('/auth/reset-token', controller('api/auth', 'triggerPasswordReset'))
api.post('/auth/reset-password', controller('api/auth', 'handlePasswordReset'))
api.get('/self', controller('api/user', 'self')) api.get('/self', controller('api/user', 'self'))
api.put('/self/:property', controller('api/user', 'updateOne')) api.put('/self/:property', controller('api/user', 'updateOne'))
......
...@@ -2,6 +2,7 @@ const { loadEnvService } = require('./utils') ...@@ -2,6 +2,7 @@ const { loadEnvService } = require('./utils')
const SERVICES = [ const SERVICES = [
['cache', 'CACHE_DRIVER', 'memory'], ['cache', 'CACHE_DRIVER', 'memory'],
['mail', 'MAIL_DRIVER', 'log'],
] ]
const services = {} const services = {}
......
...@@ -75,6 +75,6 @@ ...@@ -75,6 +75,6 @@
})(); })();
</script> </script>
<!--<script type="application/javascript" src="/js/reset-password.js"></script>--> <script type="application/javascript" src="/js/reset-password.js"></script>
</body> </body>
</html> </html>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment