From 8300520bb92b390669319e28274c9be15fd8832b Mon Sep 17 00:00:00 2001 From: stryder2000 Date: Thu, 8 Apr 2021 11:47:04 +0530 Subject: [PATCH] Fixed email bug and Added forgotpassword route to landing page login portal --- controllers/bookingController.js | 3 +- controllers/dist/bookingController.dev.js | 12 +- public/css/style2.css | 6 + utils/dist/email.dev.js | 142 ++++++ utils/email.js | 43 +- views/_header.pug | 1 - views/dist/landing.html | 1 + views/email/_style.pug | 9 +- views/email/baseEmail.pug | 6 +- views/email/bookingSuccess.pug | 18 + views/email/dist/_style.html | 515 +++++++++++---------- views/email/dist/baseEmail.html | 313 +++++++++++++ views/email/dist/bookingSuccess.html | 331 ++++++++++++++ views/email/dist/passwordReset.html | 519 +++++++++++----------- views/email/dist/welcome.html | 329 ++++++++++++++ views/landing.pug | 2 + views/tour.pug | 2 +- 17 files changed, 1703 insertions(+), 549 deletions(-) create mode 100644 utils/dist/email.dev.js create mode 100644 views/email/bookingSuccess.pug create mode 100644 views/email/dist/baseEmail.html create mode 100644 views/email/dist/bookingSuccess.html create mode 100644 views/email/dist/welcome.html diff --git a/controllers/bookingController.js b/controllers/bookingController.js index a73e6a1..64f9d4a 100644 --- a/controllers/bookingController.js +++ b/controllers/bookingController.js @@ -4,7 +4,7 @@ const stripe = require('stripe')( const Tour = require('../dev-data/models/tourModel'); const User = require('../dev-data/models/userModel'); const Booking = require('../dev-data/models/bookingModel'); - +const Email = require('./../utils/email'); const factory = require('./handlerFactory'); const catchAsync = require('../utils/catchAsync'); @@ -63,6 +63,7 @@ exports.webhookCheckout = async (req, res, next) => { const tour = session.client_reference_id; const user = (await User.findOne({ email: session.customer_email })).id; const price = session.display_items[0].amount / 100; + await new Email(user, 'natours.trips@gmail.com').sendBookingSuccessful(); await Booking.create({ tour, user, price }); } diff --git a/controllers/dist/bookingController.dev.js b/controllers/dist/bookingController.dev.js index bae3321..a4a087e 100644 --- a/controllers/dist/bookingController.dev.js +++ b/controllers/dist/bookingController.dev.js @@ -8,6 +8,8 @@ var User = require('../dev-data/models/userModel'); var Booking = require('../dev-data/models/bookingModel'); +var Email = require('./../utils/email'); + var factory = require('./handlerFactory'); var catchAsync = require('../utils/catchAsync'); @@ -78,7 +80,7 @@ exports.webhookCheckout = function _callee2(req, res, next) { case 8: if (!(event.type === 'checkout.session.completed')) { - _context2.next = 17; + _context2.next = 19; break; } @@ -93,18 +95,22 @@ exports.webhookCheckout = function _callee2(req, res, next) { user = _context2.sent.id; price = session.display_items[0].amount / 100; _context2.next = 17; + return regeneratorRuntime.awrap(new Email(user, 'natours.trips@gmail.com').sendBookingSuccessful()); + + case 17: + _context2.next = 19; return regeneratorRuntime.awrap(Booking.create({ tour: tour, user: user, price: price })); - case 17: + case 19: res.status(200).json({ received: true }); - case 18: + case 20: case "end": return _context2.stop(); } diff --git a/public/css/style2.css b/public/css/style2.css index e5bd438..07721fb 100644 --- a/public/css/style2.css +++ b/public/css/style2.css @@ -1113,6 +1113,12 @@ body { visibility: hidden; transform: translateY(-4rem); } + +.forgot-password { + font-size: 1.6rem; + margin-left: 1rem; +} + .popup { z-index: 9999; height: 100vh; diff --git a/utils/dist/email.dev.js b/utils/dist/email.dev.js new file mode 100644 index 0000000..2e1f139 --- /dev/null +++ b/utils/dist/email.dev.js @@ -0,0 +1,142 @@ +"use strict"; + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +var nodemailer = require('nodemailer'); + +var pug = require('pug'); + +var htmlToText = require('html-to-text'); + +module.exports = +/*#__PURE__*/ +function () { + function Email(user, url) { + _classCallCheck(this, Email); + + this.from = "Siddharth Singh ".concat(process.env.EMAIL_FROM); + this.url = url; + this.name = user.name; + this.to = user.email; + } + + _createClass(Email, [{ + key: "newTransport", + value: function newTransport() { + return regeneratorRuntime.async(function newTransport$(_context) { + while (1) { + switch (_context.prev = _context.next) { + case 0: + return _context.abrupt("return", nodemailer.createTransport({ + service: 'Gmail', + auth: { + user: process.env.GMAIL_USERNAME, + pass: process.env.GMAIL_PASSWORD + } + })); + + case 1: + case "end": + return _context.stop(); + } + } + }); + } //Send the actual email + + }, { + key: "send", + value: function send(template, subject) { + var html, mailOptions, transporter; + return regeneratorRuntime.async(function send$(_context2) { + while (1) { + switch (_context2.prev = _context2.next) { + case 0: + // 1) Render HTML based on a pug template + html = pug.renderFile("".concat(__dirname, "/../views/email/").concat(template, ".pug"), { + firstName: this.name, + url: this.url, + subject: subject + }); // 2) Define email options + + mailOptions = { + from: this.from, + to: this.to, + subject: subject, + html: html, + text: htmlToText.fromString(html) + }; // 3) Create a transport and send email + + _context2.next = 4; + return regeneratorRuntime.awrap(this.newTransport()); + + case 4: + transporter = _context2.sent; + _context2.next = 7; + return regeneratorRuntime.awrap(transporter.sendMail(mailOptions)); + + case 7: + case "end": + return _context2.stop(); + } + } + }, null, this); + } + }, { + key: "sendWelcome", + value: function sendWelcome() { + return regeneratorRuntime.async(function sendWelcome$(_context3) { + while (1) { + switch (_context3.prev = _context3.next) { + case 0: + _context3.next = 2; + return regeneratorRuntime.awrap(this.send('welcome', 'Welcome to the Natours Family!')); + + case 2: + case "end": + return _context3.stop(); + } + } + }, null, this); + } + }, { + key: "sendPasswordReset", + value: function sendPasswordReset() { + return regeneratorRuntime.async(function sendPasswordReset$(_context4) { + while (1) { + switch (_context4.prev = _context4.next) { + case 0: + _context4.next = 2; + return regeneratorRuntime.awrap(this.send('passwordReset', 'Your password reset token (valid for only 10 minutes.)')); + + case 2: + case "end": + return _context4.stop(); + } + } + }, null, this); + } + }, { + key: "sendBookingSuccessful", + value: function sendBookingSuccessful() { + return regeneratorRuntime.async(function sendBookingSuccessful$(_context5) { + while (1) { + switch (_context5.prev = _context5.next) { + case 0: + _context5.next = 2; + return regeneratorRuntime.awrap(this.send('bookingSuccess', 'Booking Confirmation')); + + case 2: + case "end": + return _context5.stop(); + } + } + }, null, this); + } + }]); + + return Email; +}(); \ No newline at end of file diff --git a/utils/email.js b/utils/email.js index 55c5cd6..7ab0e25 100644 --- a/utils/email.js +++ b/utils/email.js @@ -6,36 +6,43 @@ module.exports = class Email { constructor(user, url) { this.from = `Siddharth Singh ${process.env.EMAIL_FROM}`; this.url = url; - this.firstname = user.name.split(' ')[0]; + this.name = user.name; this.to = user.email; } async newTransport() { - if (process.env.NODE_ENV === 'production') { - //Gmail - return nodemailer.createTransport({ - service: 'Gmail', - auth: { - user: process.env.GMAIL_USERNAME, - pass: process.env.GMAIL_PASSWORD, - }, - }); - } return nodemailer.createTransport({ - host: process.env.EMAIL_HOST, - port: process.env.EMAIL_PORT, + service: 'Gmail', auth: { - user: process.env.EMAIL_USERNAME, - pass: process.env.EMAIL_PASSWORD, + user: process.env.GMAIL_USERNAME, + pass: process.env.GMAIL_PASSWORD, }, }); + // if (process.env.NODE_ENV === 'production') { + // //Gmail + // return nodemailer.createTransport({ + // service: 'Gmail', + // auth: { + // user: process.env.GMAIL_USERNAME, + // pass: process.env.GMAIL_PASSWORD, + // }, + // }); + // } + // return nodemailer.createTransport({ + // host: process.env.EMAIL_HOST, + // port: process.env.EMAIL_PORT, + // auth: { + // user: process.env.EMAIL_USERNAME, + // pass: process.env.EMAIL_PASSWORD, + // }, + // }); } //Send the actual email async send(template, subject) { // 1) Render HTML based on a pug template const html = pug.renderFile(`${__dirname}/../views/email/${template}.pug`, { - firstName: this.firstName, + firstName: this.name, url: this.url, subject, }); @@ -64,4 +71,8 @@ module.exports = class Email { 'Your password reset token (valid for only 10 minutes.)' ); } + + async sendBookingSuccessful() { + await this.send('bookingSuccess', 'Booking Confirmation'); + } }; diff --git a/views/_header.pug b/views/_header.pug index c134eb5..57b3cda 100644 --- a/views/_header.pug +++ b/views/_header.pug @@ -8,7 +8,6 @@ header.header a.nav__el.nav__el--logout Log out a.nav__el(href='/me') img.nav__user-img(src=`/img/users/${user.photo}`, alt=`Photo of ${user.name}`) - span     span= user.name.split(' ')[0] else a.nav__el(href='/login') Log in diff --git a/views/dist/landing.html b/views/dist/landing.html index 0f4f1f7..7f013a3 100644 --- a/views/dist/landing.html +++ b/views/dist/landing.html @@ -242,6 +242,7 @@

Start Booking Now!

+

Forgot your password?

Do not have an account?

Sign up now! → diff --git a/views/email/_style.pug b/views/email/_style.pug index e8e3706..c037f40 100644 --- a/views/email/_style.pug +++ b/views/email/_style.pug @@ -20,8 +20,8 @@ style. mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; - } - table td { + } + table td { font-family: sans-serif; font-size: 14px; vertical-align: top; @@ -129,10 +129,9 @@ style. color: #55c57a; cursor: pointer; display: inline-block; - font-size: 14px; - font-weight: bold; + font-size: 16px; margin: 0; - padding: 12px 25px; + padding: 8px 12px; text-decoration: none; text-transform: capitalize; } diff --git a/views/email/baseEmail.pug b/views/email/baseEmail.pug index b7e00a0..2bc6b2a 100644 --- a/views/email/baseEmail.pug +++ b/views/email/baseEmail.pug @@ -10,12 +10,10 @@ html table.body(role='presentation', border='0', cellpadding='0', cellspacing='0') tbody tr - td td.container .content // START CENTERED WHITE CONTAINER table.main(role='presentation') - // START MAIN AREA tbody tr @@ -33,8 +31,8 @@ html tbody tr td.content-block - span.apple-link Natours Inc, 123 Nowhere Road, San Francisco CA 99999 + span.apple-link Natours Inc, 123 Nowhere Road, Gurgaon, New Delhi, India - 122001 br - | Don't like these emails? + | Don't like these emails? a(href='#') Unsubscribe //- td   diff --git a/views/email/bookingSuccess.pug b/views/email/bookingSuccess.pug new file mode 100644 index 0000000..fea48ab --- /dev/null +++ b/views/email/bookingSuccess.pug @@ -0,0 +1,18 @@ +extends baseEmail + +block content + p Hi #{firstName}! + p Good news🤗, Your booking has been confirmed. + p We will be happy to host you. + p This is an automated email, you are not required to reply to this. + p If you have any questions or need any help, please reach out to + table.btn.btn-primary(role='presentation', border='0', cellpadding='0', cellspacing='0') + tbody + tr + td(align='left') + table(role='presentation', border='0', cellpadding='0', cellspacing='0') + tbody + tr + td + a(href=`${url}`, target='_blank') Natours support + p and let us know. \ No newline at end of file diff --git a/views/email/dist/_style.html b/views/email/dist/_style.html index 1eedcf2..5688e49 100644 --- a/views/email/dist/_style.html +++ b/views/email/dist/_style.html @@ -1,261 +1,260 @@ \ No newline at end of file diff --git a/views/email/dist/baseEmail.html b/views/email/dist/baseEmail.html new file mode 100644 index 0000000..0410026 --- /dev/null +++ b/views/email/dist/baseEmail.html @@ -0,0 +1,313 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/views/email/dist/bookingSuccess.html b/views/email/dist/bookingSuccess.html new file mode 100644 index 0000000..1da9b1f --- /dev/null +++ b/views/email/dist/bookingSuccess.html @@ -0,0 +1,331 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/views/email/dist/passwordReset.html b/views/email/dist/passwordReset.html index cbea7d8..2e7841b 100644 --- a/views/email/dist/passwordReset.html +++ b/views/email/dist/passwordReset.html @@ -5,271 +5,270 @@ -