From 4d2d62d777b78eb4d7041e2df0fd1abe99830550 Mon Sep 17 00:00:00 2001 From: Jonasz Bigda Date: Thu, 10 Sep 2020 18:11:58 +0200 Subject: [PATCH] password reset --- config/index.js | 1 + config/mailTemplateReset.js | 14 ++++++----- routes/routeUser.js | 12 ++++++--- services/databaseServices.js | 2 -- services/mailServices.js | 47 +++++++++++++++++++++++++++++++++++- services/services.js | 18 +++++++++++++- services/services.test.js | 7 +++++- 7 files changed, 87 insertions(+), 14 deletions(-) diff --git a/config/index.js b/config/index.js index c8a0056..84cc01f 100644 --- a/config/index.js +++ b/config/index.js @@ -8,3 +8,4 @@ export const jwtSecret = process.env.JWT_SECRET; export const CRM_KEY = process.env.CRM_KEY; export const CRM_USER = process.env.CRM_USER; export const CRM_EMAIL = process.env.CRM_EMAIL; +export const MAIL_PASS = process.env.MAIL_PASS; diff --git a/config/mailTemplateReset.js b/config/mailTemplateReset.js index a4c634b..1fa8b00 100644 --- a/config/mailTemplateReset.js +++ b/config/mailTemplateReset.js @@ -1,6 +1,6 @@ export default function makeResetPassMessage(newPass) { - return; - ` + return { + html: ` @@ -77,9 +77,9 @@ export default function makeResetPassMessage(newPass) { @@ -126,7 +126,7 @@ export default function makeResetPassMessage(newPass) {
- +
@@ -134,5 +134,7 @@ export default function makeResetPassMessage(newPass) { - `; + `, + text: `Drogi użytkowniku, dostałeś tę wiadomość, ponieważ użyłeś opcji "Nie pamiętam hasła" w aplikacji Menui. Twoje tymczasowe hasło to: ${newPass}. Zaloguj się za jego pomocą i ustaw nowe bezpieczne hasło. Jeżeli nie wysyłałeś prośby o zmianę hasła, prosimy zignoruj tę wiadomość. Pozdrawiamy - Zespół Menui`, + }; } diff --git a/routes/routeUser.js b/routes/routeUser.js index ab1d716..b9cf303 100644 --- a/routes/routeUser.js +++ b/routes/routeUser.js @@ -16,6 +16,7 @@ import { } from "../services/services.js"; import * as config from "../config/index.js"; import AgileCRMManager from "agile_crm"; +import { resetPassword } from "../services/mailServices.js"; const { CRM_USER, CRM_EMAIL, CRM_KEY } = config; var router = express.Router(); @@ -69,13 +70,18 @@ router.post("/changepass", async (req, res) => { } }); -// RESET PASSWORD -router.post("/resetpassword", (req, res) => { +// REQUEST PASSWORD RESET +router.post("/forgotpassword", async (req, res) => { try { - // + await resetPassword(req.body.email); + res.send( + "Link do utworzenia nowego hasła został wysłany na adres email powiązany z kontem. Sprawdź również folder SPAM." + ); } catch (error) { handleError(error, res); } }); +// RESET PASS + export default router; diff --git a/services/databaseServices.js b/services/databaseServices.js index a61a222..5ce5c9d 100644 --- a/services/databaseServices.js +++ b/services/databaseServices.js @@ -1,8 +1,6 @@ import Restaurant from "../models/restaurant.js"; import Dish from "../models/dish.js"; import User from "../models/users.js"; -import mongoose from "mongoose"; -import sanitizer from "string-sanitizer"; import { newError } from "./services.js"; export async function changeUserPass(userId, newPass) { diff --git a/services/mailServices.js b/services/mailServices.js index 26db702..b289d27 100644 --- a/services/mailServices.js +++ b/services/mailServices.js @@ -1,2 +1,47 @@ import nodemailer from "nodemailer"; -import makeResetPassMessage from "../config/mailTemplateReset"; +import path from "path"; +import { MAIL_PASS } from "../config/index.js"; +import makeResetPassMessage from "../config/mailTemplateReset.js"; +import { newError, generatePasswordResetLink } from "../services/services.js"; + +const images = path.resolve("images"); + +async function sendMail(reciever, subject, textMessage, htmlMessage) { + let transporter = nodemailer.createTransport({ + host: "smtp.dpoczta.pl", + port: 587, + secure: false, + auth: { + user: "noreply@menui.pl", + pass: MAIL_PASS, + }, + }); + + let info = await transporter.sendMail({ + from: '"Menui" ', + to: reciever, + subject: subject, + text: textMessage, + html: htmlMessage, + attachments: [ + { + filename: "logo.svg", + path: images + "/logo.svg", + cid: "logo", + }, + ], + }); +} + +export async function resetPassword(email) { + const resetLink = generatePasswordResetLink(email); + const message = makeResetPassMessage(resetLink); + await sendMail( + email, + "Menui - Resetowanie hasła", + message.text, + message.html + ).catch((err) => { + throw newError("Nieznany błąd podczas resetu hasła", 500); + }); +} diff --git a/services/services.js b/services/services.js index 9c746dc..2999505 100644 --- a/services/services.js +++ b/services/services.js @@ -1,5 +1,5 @@ import Restaurant from "../models/restaurant.js"; -import {} from "./dataPrepServices.js"; +import crypto from "crypto"; import Dish from "../models/dish.js"; import User from "../models/users.js"; import mongoose from "mongoose"; @@ -59,6 +59,22 @@ export function generateAuthToken(user) { return token; } +function generatePasswordResetToken(email) { + const token = jwt.sign( + { + email: email, + }, + jwtSecret, + { expiresIn: "15m" } + ); + return token; +} + +export function generatePasswordResetLink(email) { + const token = generatePasswordResetToken(email); + const link = `htt`; +} + export async function checkEmailTaken(email) { if (!email) throw newError("No input email", 204); await User.exists({ email: email }).then((res) => { diff --git a/services/services.test.js b/services/services.test.js index 2e409d8..b1d3df8 100644 --- a/services/services.test.js +++ b/services/services.test.js @@ -1,4 +1,4 @@ -import { validateRestaurant, toShortDate } from "./services"; +import { toShortDate, generateNewPassword } from "./services"; jest.mock("@azure/storage-blob", () => { return { @@ -17,3 +17,8 @@ jest.mock("bcrypt", () => { test("should return false for no date on input", () => { expect(toShortDate()).toBe(false); }); + +test("should generate random 10 characters long password", () => { + let generatedPass = generateNewPassword(); + expect(generatedPass.length).toBe(10); +});