From fb7643325036c94c0f94a9a0e96841e1f520e01c Mon Sep 17 00:00:00 2001 From: Hippo Date: Thu, 6 Jan 2022 14:39:35 +0530 Subject: [PATCH] Start sending verification emails Finally! --- package.json | 1 + server/index.js | 111 +++++++++++++++++++++++++++++++++++++++++++++--- yarn.lock | 5 +++ 3 files changed, 111 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 62721b4..126ed63 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "dotenv": "^10.0.0", "express": "^4.17.2", "knex": "^0.95.15", + "nodemailer": "^6.7.2", "sqlite3": "^5.0.2", "twing": "^5.1.0" } diff --git a/server/index.js b/server/index.js index fa8c795..060cbf3 100644 --- a/server/index.js +++ b/server/index.js @@ -1,4 +1,5 @@ const express = require('express') +const nodemailer = require('nodemailer') const bodyParser = require('body-parser') const path = require('path') const { URLSafeTimedSerializer } = require("@constemi/itsdangerjs") @@ -30,6 +31,53 @@ if (process.env.CROWDFUNDING_SITE_SECRET_KEY) { } } +// set up nodemailer (if configured) +let mailer +let emailFrom +if ( + !!process.env.CROWDFUNDING_SITE_EMAIL_HOST && + !!process.env.CROWDFUNDING_SITE_EMAIL_USER && + !!process.env.CROWDFUNDING_SITE_EMAIL_PASSWORD +) { + mailer = nodemailer.createTransport({ + host: process.env.CROWDFUNDING_SITE_EMAIL_HOST, + port: process.env.CROWDFUNDING_SITE_EMAIL_PORT || 587, + secure: process.env.CROWDFUNDING_SITE_EMAIL_SECURE == 'false' ? false : true, + auth: { + user: process.env.CROWDFUNDING_SITE_EMAIL_USER, + pass: process.env.CROWDFUNDING_SITE_EMAIL_PASSWORD, + } + }) + + if (!!process.env.CROWDFUNDING_SITE_EMAIL_FROM) { + emailFrom = process.env.CROWDFUNDING_SITE_EMAIL_FROM + } else { + emailFrom = process.env.CROWDFUNDING_SITE_EMAIL_USER + console.warn(`No "From" address set! Using ${emailFrom} as a default.`) + } +} else { + console.log("Email has not been configured! Some features won't work properly until this is set up :/") +} + +async function sendMail(message) { + if (DEBUG || !mailer) { + console.log(`\n\n-------------------------- BEGIN EMAIL --------------------------\n`) + console.log(`From: ${message.from}\nTo:${message.to}\nSubject:${message.subject||'(no subject)'}\n\n${message.text}`) + console.log(`\n--------------------------- END EMAIL ---------------------------`) + return + } else { + let receipt = await mailer.sendMail({ + from: message.from || emailFrom, + to: message.to, + subject: message.subject, + text: message.text, + html: message.html, + }) + + return receipt + } +} + // get goal details const goalPeople = Number(process.env.CROWDFUNDING_SITE_GOAL_PEOPLE) || 750 const goalRupees = Number(process.env.CROWDFUNDING_SITE_GOAL_RUPEES) || 500000 @@ -234,14 +282,14 @@ router.post('/pledge', async (req, res) => { existingPledge = await (Pledge .query({ where: { - 'email': req.query.email, - 'amount': amount, + 'email': pledge.get('email'), + 'amount': pledge.get('amount'), }, }) .orderBy('created_at', 'DESC') .fetch()) } catch(e) { - if (e.name == 'EmptyResponse' && DEBUG) { + if (e.message == 'EmptyResponse' && DEBUG) { console.debug('No existing pledge') } else { console.warn(`Weird error happened: ${e}`) @@ -252,9 +300,27 @@ router.post('/pledge', async (req, res) => { let serialiser = URLSafeTimedSerializer(secretKey, pledge.get('email')) let verificationLink = `${req.protocol}://${req.hostname}/verify?email=${encodeURIComponent(pledge.get('email'))}&key=${encodeURIComponent(serialiser.dumps(pledge.get('amount')))}` - // TODO: send out the email, along with existing pledge deets + // send out the email, along with existing pledge deets console.debug(`Verification link generated: ${verificationLink}`) + let text = `Hi ${pledge.get('name')}, +Thank you so much for your pledge of ₹${Number(pledge.get('amount')).toLocaleString('en-IN')} to Snipette! +To finish the pledge, please verify your email by clicking the link below: + +${verificationLink} + +If you have any questions, don't hesitate to reach out: you can drop a line +anytime to editors@snipettemag.com. + +Thanks, +The Snipette Team` + + let receipt = await sendMail({ + to: req.body.email, + subject: `Finish ${existingPledge ? 'updating' : 'saving'} your pledge to Snipette`, + text: text, + }) + res.send("Thank you! We're still working on setting up this website, so as you can see this page doesn't look great at the moment, but we will be sending you a confirmation email in a few days. Watch out for an email from editors@snipettemag.com, and if it doesn't reach, check your spam box :P") }) @@ -331,8 +397,41 @@ router.get('/verify', async (req, res) => { // save the new pledge await newPledge.save() - // dummy message - res.send('all done (not)') + // send the confirmation email + let text = `Hi ${pledge.get('name')}, +Your pledge of ₹${Number(pledge.get('amount')).toLocaleString('en-IN')} to Snipette Analog has been saved! + +Thank you so much for your support. Once we hit our goals, we will contact +you to make the final payment. Meanwhile, here are the details of your +pledge for reference: + + Name: ${pledge.get('name')} + Pledge amount: ${Number(pledge.get('amount')).toLocaleString('en-IN')}${pledge.overseas ? ' (plus $25 for shipping)' : ''} + Email: ${pledge.get('email')} + Phone: ${pledge.get('phone') || 'not provided'} + + Extra message: + ${pledge.get('other_message') || '[no message sent]'} + + We will attempt to contact you ${pledge.get('retry_times') <= 1 ? 'only once' : String(pledge.get('retry_times')) + ' times'} before giving up. + +You can update your pledge by going to the crowdfunding homepage and saving +a pledge with the same email address as you used before. + +If you have any questions, don't hesitate to reach out: you can drop a line +anytime to editors@snipettemag.com. + +Thanks, +The Snipette Team` + + let receipt = await sendMail({ + to: pledge.get('email'), + subject: `Your pledge has been saved!`, + text: text, + }) + + // Send confirmation message + res.send('Thank you! Your pledge has been saved. Watch out for the confirmation email in your inbox :)') }) router.use(express.static('dist')) diff --git a/yarn.lock b/yarn.lock index e974599..1ed7bb8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3958,6 +3958,11 @@ node-releases@^2.0.1: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== +nodemailer@^6.7.2: + version "6.7.2" + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.7.2.tgz#44b2ad5f7ed71b7067f7a21c4fedabaec62b85e0" + integrity sha512-Dz7zVwlef4k5R71fdmxwR8Q39fiboGbu3xgswkzGwczUfjp873rVxt1O46+Fh0j1ORnAC6L9+heI8uUpO6DT7Q== + nodemon@^2.0.15: version "2.0.15" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.15.tgz#504516ce3b43d9dc9a955ccd9ec57550a31a8d4e"