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; };