Last active
October 18, 2020 13:50
-
-
Save nosvalds/7a0eb6f742fbfcfb0914be3854e839aa to your computer and use it in GitHub Desktop.
forgot password controller function
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const table = process.env.USERS_TABLE; | |
const fs = require('fs'); | |
const fsPromises = fs.promises; | |
const Handlebars = require("handlebars"); | |
// AWS | |
const AWS = require('aws-sdk') | |
const dynamodb = new AWS.DynamoDB.DocumentClient(); | |
const ses = new AWS.SES({region: 'us-east-1'}); // Simple email service | |
/** | |
* Generate a reset password token and send email to the user | |
* @param {*} req body.email - required | |
* @param {*} res | |
*/ | |
const forgotPassword = async (req, res) => { | |
try { | |
// Retrieve user by email provided in the request | |
let user = await User.getByEmail(req.body.email); | |
// User not found, don't send failure as that could let hackers know which emails do exist | |
if (!user) { | |
return res.status(200).send() | |
} | |
// expire any existing tokens for the user | |
await User.expirePasswordTokens(user) | |
// password token expires after one hour | |
let expireDate = new Date(); | |
expireDate.setHours(expireDate.getHours() + 1) | |
let token = createResetToken(); | |
// create a new entry in the user's password_reset_token map | |
let updatedTokens = { | |
...user.password_reset_tokens, // use spread operator to copy exisiting token entries | |
[token]: { | |
"used": false, | |
"expiration": expireDate.toISOString(), | |
"updated": new Date().toISOString(), | |
"created": new Date().toISOString() | |
} | |
} | |
// prepare params to update User with new password_reset_tokens item | |
const params = { | |
TableName: table, | |
Key: { | |
email: user.email | |
}, | |
UpdateExpression: "set password_reset_tokens=:v", | |
ExpressionAttributeValues: { ":v": updatedTokens }, | |
ReturnValues: "ALL_NEW" | |
}; | |
// use DynamoDB.DocumentClient to update | |
await dynamodb.update(params).promise(); | |
// prep data for the email | |
let url = domain + '/password/reset?token=' + encodeURIComponent(token) + '&email=' + req.body.email | |
// if we're offline just log and send the reset URL | |
if (process.env.IS_OFFLINE) { | |
console.log("password_reset_url: "+ url); | |
return res.status(200).json({"password_reset_url": url}) | |
} | |
let emailData = { | |
"url": url, | |
"toEmail": req.body.email, | |
"expire": expireDate.toLocaleDateString() + " " + expireDate.toLocaleTimeString(), | |
"year": expireDate.getFullYear(), | |
}; | |
let filePath = process.cwd() + "/emailTemplates/forgotPasswordEmail.html"; | |
// get HTML email template | |
let emailHtmlTemplate = await fsPromises.readFile(filePath); | |
// Inject data into the template | |
let templateHtml = Handlebars.compile(emailHtmlTemplate.toString()); | |
let bodyHtml = templateHtml(emailData); | |
// Prepare SES Parameters | |
let params = { | |
Destination: { | |
ToAddresses: [emailData.toEmail] | |
}, | |
Message: { | |
Body: { | |
Text: { Data: 'To reset your password, please click the link below.\n\n https://' + emailData.url | |
}, | |
Html: { | |
Data: bodyHtml | |
} | |
}, | |
Subject: { | |
Data: 'DigitalHumani - Password Reset Request' | |
} | |
}, | |
Source: "info@DigitalHumani.com" | |
}; | |
await ses.sendEmail(params).promise() | |
return res.status(200).json(`Password Reset Email sent successfully to ${emailData.toEmail}`) | |
} | |
catch (error) { return res.status(400).json({ error: error.message }); } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment