Files
mantra.press/server/router/account/password-reset/index.js

182 lines
7.4 KiB
JavaScript

const express = require('express')
const emailAPI = require('../../../email/email-api')
module.exports = function (options) {
const db = options.db;
var router = express.Router();
router.route('/')
.get(function(request, response, next) {
response.display("password-reset-initiation", {
user: request.user,
pageTitle: "Password Reset - Mantra"
})
}).post(function(request, response, next) {
// TODO: Create UserPasswordReset object.
// TODO: Send email with link to /account/password-reset/:id
db.User.findOne({
include: [
{
association: db.User.UserEmails,
required: true,
where: {
emailAddress: request.body.email
}
},
{
association: db.User.UserPasswordReset
}
// TODO: Include user.UserPasswordReset
]
}).then(user => {
if (user) {
// TODO: Check if user already created a password reset artifact to save on a db transaction
return Promise.all([
user.userEmails[0],
user.userPasswordReset ? user.userPasswordReset : db.UserPasswordReset.create({
userId: user.id
})
])
} else {
return [null, null]
}
}).then(async (results) => {
userEmail = results[0]
userPasswordReset = results[1]
if (userPasswordReset) {
await userPasswordReset.increment('sent')
// Send password reset email...
return emailAPI.sendPasswordResetEmail(userPasswordReset.token, userEmail.emailAddress)
} else {
return null
}
}).then(emailResult => {
if (emailResult) {
response.display("password-reset-initiated", {
user: request.user,
pageTitle: "Password Reset Initiated - Mantra"
})
} else {
// TODO: Check if email is an immigrant
db.Immigrant.findOne({
where: {
emailAddress: request.body.email
},
include: [
{
association: db.Immigrant.User,
},
{
association: db.Immigrant.Email,
required: true,
}
]
}).then(async (immigrant) => {
if (immigrant && immigrant.user == null) {
// Resend invitation
await emailAPI.sendImmigrationInvitationEmail(
immigrant.id, immigrant.emailAddress, immigrant.displayName
)
response.display("password-reset-initiated", {
user: request.user,
pageTitle: "Password Reset Initiated - Mantra"
})
} else {
next(`Failed to create a user password reset artifact (user ${request.body.email} doesn't exist)`)
}
}).catch (error => {
next(error)
})
// TODO: Create password reset error page with possible reasons...
}
}).catch(reason => {
console.error("Something went wrong with reset: ", reason)
// TODO: Tell user
next(reason)
})
})
router.route('/:token')
.get(function(request, response, next) {
if (request.user) {
// TODO:
response.display("logout-to-continue", {
user: request.user,
pageTitle: "Logout Before Continue - Mantra"
})
} else {
db.UserPasswordReset.findByPk(request.params.token, {
include: [
{
association: db.UserPasswordReset.User
}
]
})
.then(userPasswordReset => {
if (userPasswordReset) {
response.display("password-reset", {
user: request.user,
pageTitle: "Password Reset - Mantra",
userPasswordReset: userPasswordReset
})
} else {
next()
}
}).catch(error => {
next(error)
})
}
}).post(function(request, response, next) {
if (Boolean(request.body.password) && request.body.password == request.body.confirmPassword) {
db.UserPasswordReset.findByPk(request.params.token, {
include: [
{
association: db.UserPasswordReset.User,
required: true,
include: [
{
association: db.User.Passwords,
required: true
}
]
}
]
}).then(userPasswordReset => {
if (userPasswordReset) {
var password = userPasswordReset.user.passwords[0]
password.password = request.body.password // Password will be hashed...
return Promise.all([userPasswordReset, password.save()])
} else {
return [null, null]
}
}).then(results => {
userPasswordReset = results[0]
password = results[1]
if (password) {
// Password reset success invite user to reset...
response.redirect("/account")
// Cleanup...
userPasswordReset.destroy({
force: true
}).then(() => {})
.catch(reason => console.error("Failed to destroy userPasswordReset", reason))
} else {
// TODO: Give user failed password page...
next("Failed to reset password")
}
}).catch(error => {
next(error)
})
} else {
// TODO: Tell user password reset failed..
next("Passwords do not match")
}
})
return router;
};