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

Add token validation to password reset screen

parent 51073600
No related branches found
No related tags found
No related merge requests found
const crypto = require('core/utils/crypto')
const moment = require('moment')
exports.login = async ctx => {
const { email, password } = ctx.request.body
......@@ -21,10 +22,55 @@ exports.handleLoginRedirect = async ctx => {
}
}
const resetErrorMessages = {
missing: 'No token was found in the URL. If you clicked a link to get here, please make sure that it contains a password reset token. You may need to request a new password reset in the Jetsam app.',
invalid: 'The link you clicked was invalid or has expired. Password reset links are valid for 1 hour from the time we send them to you; you may need to request a new password reset in the Jetsam app.',
}
exports.resetPassword = async ctx => {
const errorData = {
back_link: 'https://jetsam.tech',
}
const token = ctx.query.token
if (!token) {
errorData.message = resetErrorMessages.missing
await ctx.render('auth/reset-password-error', errorData)
ctx.status = 400
return
}
const { sequelize } = require('database/models')
const [{ exists }] = await sequelize.query('SELECT exists(select reset_token from users where reset_token = :token limit 1)', { replacements: { token } })
if (!exists) {
errorData.message = resetErrorMessages.invalid
await ctx.render('auth/reset-password-error', errorData)
ctx.status = 404
return
}
let data = null
try {
data = JSON.parse(await crypto.decrypt(token))
} catch (e) {
errorData.message = resetErrorMessages.invalid
await ctx.render('auth/reset-password-error', errorData)
ctx.status = 400
return
}
const time = moment.utc(data.expires)
if (data.id == null || data.expires == null || time.isSameOrBefore(moment.utc())) {
errorData.message = resetErrorMessages.invalid
await ctx.render('auth/reset-password-error', errorData)
ctx.status = 400
return
}
await ctx.render('auth/reset-password', {
token: ctx.query.token,
token,
})
}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Password Reset | Jetsam</title>
<meta name="description" content="Jetsam is a social plastics logging app that puts the power of change in your hands!">
<meta property="og:description" content="Jetsam is a social plastics logging app that puts the power of change in your hands!">
<meta property="og:image" content="https://jetsam.tech/images/card-image.png">
<meta property="og:image:type" content="image/png">
<meta name="twitter:site" content="@jetsam_tech">
<meta name="twitter:creator" content="@louisdoesdev">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/png" href="https://jetsam.tech/images/logo.png">
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/normalize/8.0.1/normalize.min.css"
integrity="sha256-l85OmPOjvil/SOvVt3HnSSjzF1TUMyT9eV0c2BzEGzU="
crossorigin="anonymous" />
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css"
integrity="sha256-2YQRJMXD7pIAPHiXr0s+vlRWA7GYJEK0ARns7k2sbHY="
crossorigin="anonymous" />
<link rel="stylesheet" href="/css/main.css?v=2">
</head>
<body>
<main class="container" style="max-width: 600px">
<header class="header">
<img class="logo" src="https://jetsam.tech/images/logo.png" width="128px" height="128px">
<div>
<h1>Jetsam</h1>
<h3>Your World; Cleaner</h3>
</div>
</header>
<h3 class="centered">Password Reset Error</h3>
<p class="centered">{{ message }}</p>
<div class="row centered">
<a href="{{ back_link }}">Go Back</a>
</div>
</main>
</body>
</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