From 4a66567aa01a1ffaeff1b7d0e9e857ff07b240cf Mon Sep 17 00:00:00 2001 From: Ash Monty Date: Sat, 22 Oct 2022 20:25:30 +0200 Subject: [PATCH 1/3] feat: add assets subdomain, add email assets --- .../emails/emailConfirmationTemplate.html | 203 ++++++++++++++++++ src/assets/emails/genericTemplate.html | 169 +++++++++++++++ ...tendo-wordmark-multicolor-purple+white.png | Bin 0 -> 5299 bytes .../pretendo-wordmark-singlecolor-purple.png | Bin 0 -> 5842 bytes src/server.js | 2 + src/services/assets/index.js | 22 ++ 6 files changed, 396 insertions(+) create mode 100644 src/assets/emails/emailConfirmationTemplate.html create mode 100644 src/assets/emails/genericTemplate.html create mode 100644 src/assets/images/pretendo-wordmark-multicolor-purple+white.png create mode 100644 src/assets/images/pretendo-wordmark-singlecolor-purple.png create mode 100644 src/services/assets/index.js diff --git a/src/assets/emails/emailConfirmationTemplate.html b/src/assets/emails/emailConfirmationTemplate.html new file mode 100644 index 0000000..4c459b9 --- /dev/null +++ b/src/assets/emails/emailConfirmationTemplate.html @@ -0,0 +1,203 @@ + + + + + + + + +
Hello {{username}}! Your Pretendo Network ID activation is almost complete. Please click the link in this email to confirm your e-mail address and complete the activation process.
+ + + + +
+ + + + +
+ + + + + + +
  + + + + + + + +
 
+ + + + + + + + + + + + + + + + + + + +
+ + + +
 
+ + + + + + +
  + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
+ Hello {{username}}! +
 
+ Your Pretendo Network ID activation is almost complete. Please click the link below to confirm your e-mail address and complete the activation process. +
 
 
+ You may also enter the following 6-digit code on your console: +
 
+ {{confirmation-code}} +
 
+ We hope you have fun using our services! +
 
+ The Pretendo Network team +
 
+
 
+
 
+ Note: this email message was auto-generated, please do not respond. For further assistance, please join our Discord server. +
 
+
+
 
+
+
+ + \ No newline at end of file diff --git a/src/assets/emails/genericTemplate.html b/src/assets/emails/genericTemplate.html new file mode 100644 index 0000000..1dd0110 --- /dev/null +++ b/src/assets/emails/genericTemplate.html @@ -0,0 +1,169 @@ + + + + + + + + +
{{preview}}
+ + + + +
+ + + + +
+ + + + + + +
  + + + + + + + +
 
+ + + + + + + + + + + + + + + + + + + +
+ + + +
 
+ + + + + + +
  + + + + + + + + + + + + + + + + + + + + + + +
 
+ Dear {{username}}, +
 
+ {{paragraph}} +
 
+ The Pretendo Network team +
 
+
 
+
 
+ Note: this email message was auto-generated, please do not respond. For further assistance, please join our Discord server. +
 
+
+
 
+
+
+ + \ No newline at end of file diff --git a/src/assets/images/pretendo-wordmark-multicolor-purple+white.png b/src/assets/images/pretendo-wordmark-multicolor-purple+white.png new file mode 100644 index 0000000000000000000000000000000000000000..66c89d53644bb1e7276065b57d3de48f26084364 GIT binary patch literal 5299 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 K0jrQT3;rKUTjt3C literal 0 HcmV?d00001 diff --git a/src/assets/images/pretendo-wordmark-singlecolor-purple.png b/src/assets/images/pretendo-wordmark-singlecolor-purple.png new file mode 100644 index 0000000000000000000000000000000000000000..99039475c6c9f0a90b726c286ff9d75c9797c5fb GIT binary patch literal 5842 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 literal 0 HcmV?d00001 diff --git a/src/server.js b/src/server.js index c4dcf6b..9372a3a 100644 --- a/src/server.js +++ b/src/server.js @@ -23,6 +23,7 @@ const nasc = require('./services/nasc'); const datastore = require('./services/datastore'); const api = require('./services/api'); const localcdn = require('./services/local-cdn'); +const assets = require('./services/assets'); // START APPLICATION @@ -42,6 +43,7 @@ app.use(nasc); app.use(datastore); app.use(api); app.use(localcdn); +app.use(assets); // 404 handler logger.info('Creating 404 status handler'); diff --git a/src/services/assets/index.js b/src/services/assets/index.js new file mode 100644 index 0000000..2059739 --- /dev/null +++ b/src/services/assets/index.js @@ -0,0 +1,22 @@ +// handles serving assets + +const express = require('express'); +const subdomain = require('express-subdomain'); +const logger = require('../../../logger'); +const path = require('path'); + +// Router to handle the subdomain restriction +const assets = express.Router(); + +// Setup public folder +logger.info('[assets] Setting up public folder'); +assets.use(express.static(path.join(__dirname, '../../assets'))); + +// Main router for endpoints +const router = express.Router(); + +// Create subdomains +logger.info('[conntest] Creating \'assets\' subdomain'); +router.use(subdomain('assets', assets)); + +module.exports = router; \ No newline at end of file From 734486d94aea5a513f36795e39314d7560c633d8 Mon Sep 17 00:00:00 2001 From: Ash Monty Date: Sat, 22 Oct 2022 20:56:35 +0200 Subject: [PATCH 2/3] feat: add html mailer --- src/mailer.js | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/mailer.js b/src/mailer.js index d8228e2..6bca5ec 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -1,5 +1,8 @@ const nodemailer = require('nodemailer'); const { config, disabledFeatures } = require('./config-manager'); +const path = require('path'); +const fs = require("fs"); +const genericEmailTemplate = fs.readFileSync(path.join(__dirname, './assets/emails/genericTemplate.html'), 'utf8'); let transporter; @@ -15,6 +18,35 @@ async function sendMail(options) { } } +/** + @param {Object} options + @param {String} options.to The address to send the email to + @param {String} options.subject The subject of the email + @param {String} options.username The username of the user (shown in the greeting) + @param {String} options.paragraph The main content of the email + @param {String} options.preview The preview text of the email (shown in the inbox by the email client) +*/ +async function sendHtmlMail(options) { + if (!disabledFeatures.email) { + const { to, subject, username, paragraph, preview } = options; + + let html = genericEmailTemplate; + + html = html.replace(/{{username}}/g, username); + html = html.replace(/{{paragraph}}/g, paragraph); + html = html.replace(/{{preview}}/g, preview); + + const transporterOptions = { + to, + subject, + html + } + await transporter.sendMail(transporterOptions); + } +} + + module.exports = { - sendMail + sendMail, + sendHtmlMail }; From 29d25f414f030c4be0b9015de7721fd00dbc7946 Mon Sep 17 00:00:00 2001 From: Ash Monty Date: Sat, 22 Oct 2022 21:49:15 +0200 Subject: [PATCH 3/3] feat: add buttons, confirmation email to sendMail, add new props --- ...emplate.html => confirmationTemplate.html} | 2 +- src/assets/emails/genericTemplate.html | 1 + src/mailer.js | 50 ++++++++++++------- src/util.js | 20 ++++++-- 4 files changed, 50 insertions(+), 23 deletions(-) rename src/assets/emails/{emailConfirmationTemplate.html => confirmationTemplate.html} (99%) diff --git a/src/assets/emails/emailConfirmationTemplate.html b/src/assets/emails/confirmationTemplate.html similarity index 99% rename from src/assets/emails/emailConfirmationTemplate.html rename to src/assets/emails/confirmationTemplate.html index 4c459b9..e8eebe2 100644 --- a/src/assets/emails/emailConfirmationTemplate.html +++ b/src/assets/emails/confirmationTemplate.html @@ -127,7 +127,7 @@ - + Confirm email address diff --git a/src/assets/emails/genericTemplate.html b/src/assets/emails/genericTemplate.html index 1dd0110..5f189c9 100644 --- a/src/assets/emails/genericTemplate.html +++ b/src/assets/emails/genericTemplate.html @@ -122,6 +122,7 @@ {{paragraph}} +   diff --git a/src/mailer.js b/src/mailer.js index 6bca5ec..b4e5ce8 100644 --- a/src/mailer.js +++ b/src/mailer.js @@ -3,6 +3,7 @@ const { config, disabledFeatures } = require('./config-manager'); const path = require('path'); const fs = require("fs"); const genericEmailTemplate = fs.readFileSync(path.join(__dirname, './assets/emails/genericTemplate.html'), 'utf8'); +const confirmationEmailTemplate = fs.readFileSync(path.join(__dirname, './assets/emails/confirmationTemplate.html'), 'utf8'); let transporter; @@ -10,43 +11,54 @@ if (!disabledFeatures.email) { transporter = nodemailer.createTransport(config.email); } -async function sendMail(options) { - if (!disabledFeatures.email) { - options.from = config.email.from; - - await transporter.sendMail(options); - } -} - /** @param {Object} options @param {String} options.to The address to send the email to @param {String} options.subject The subject of the email + @param {String} options.username The username of the user (shown in the greeting) - @param {String} options.paragraph The main content of the email @param {String} options.preview The preview text of the email (shown in the inbox by the email client) + @param {String} options.text The text version of the email + + @param {String} options.paragraph The main content of the email + + @param {Object} options.confirmation Whether or not the email is a confirmation email + @param {String} options.confirmation.href The link to the confirmation page + @param {String} options.confirmation.code The confirmation code + + @param {Object} options.link An object containing the link to be shown in the email + @param {String} options.link.href The URL of the link + @param {String} options.link.text The text of the link + */ -async function sendHtmlMail(options) { +async function sendMail(options) { if (!disabledFeatures.email) { - const { to, subject, username, paragraph, preview } = options; + const { to, subject, username, paragraph, preview, text, link, confirmation } = options; - let html = genericEmailTemplate; + let html = confirmation ? confirmationEmailTemplate : genericEmailTemplate; html = html.replace(/{{username}}/g, username); html = html.replace(/{{paragraph}}/g, paragraph); - html = html.replace(/{{preview}}/g, preview); + html = html.replace(/{{preview}}/g, (preview || "")); + html = html.replace(/{{confirmation-href}}/g, (confirmation?.href || "")); + html = html.replace(/{{confirmation-code}}/g, (confirmation?.code || "")); - const transporterOptions = { + if (link) { + const { href, text } = link; + + const button = ` ${text}` + html = html.replace(//g, button); + } + + await transporter.sendMail({ to, subject, + text, html - } - await transporter.sendMail(transporterOptions); + }); } } - module.exports = { - sendMail, - sendHtmlMail + sendMail }; diff --git a/src/util.js b/src/util.js index 5550a70..0050b38 100644 --- a/src/util.js +++ b/src/util.js @@ -250,15 +250,23 @@ async function sendConfirmationEmail(pnid) { await mailer.sendMail({ to: pnid.get('email.address'), subject: '[Pretendo Network] Please confirm your email address', - html: `Hello,

Your Pretendo Network ID activation is almost complete.

Please click the link below to confirm your e-mail address and complete the activation process.

https://api.pretendo.cc/v1/email/verify?token=${pnid.get('identification.email_token')}

If you are unable to connect to the above URL, please enter the following confirmation code on the device to which your Prentendo Network ID is linked.

<<Confirmation code: ${pnid.get('identification.email_code')}>>` + username: pnid.get('username'), + confirmation: { + href: `https://api.pretendo.cc/v1/email/verify?token=${pnid.get('identification.email_token')}`, + code: pnid.get('identification.email_code') + }, + text: `Hello ${pnid.get('username')}! \r\n\r\nYour Pretendo Network ID activation is almost complete. Please click the link to confirm your e-mail address and complete the activation process: \r\nhttps://api.pretendo.cc/v1/email/verify?token=${pnid.get('identification.email_token')} \r\n\r\nYou may also enter the following 6-digit code on your console: ${pnid.get('identification.email_code')}` }); + } async function sendEmailConfirmedEmail(pnid) { await mailer.sendMail({ to: pnid.get('email.address'), subject: '[Pretendo Network] Email address confirmed', - html: 'Your email address has been confirmed!' + username: pnid.get('username'), + paragraph: 'your email address has been confirmed. We hope you have fun on Pretendo Network!', + text: `Dear ${pnid.get('username')}, \r\n\r\nYour email address has been confirmed. We hope you have fun on Pretendo Network!` }); } @@ -285,7 +293,13 @@ async function sendForgotPasswordEmail(pnid) { await mailer.sendMail({ to: pnid.get('email.address'), subject: '[Pretendo Network] Forgot Password', - html: `Visit this link to reset your password ${config.website_base}/account/reset-password?token=${encodeURIComponent(passwordResetToken)}` + username: pnid.get('username'), + paragraph: 'a password reset has been requested from this account. If you did not request the password reset, please ignore this email. If you did request this password reset, please click the link below to reset your password.', + link: { + text: 'Reset password', + href: `${config.website_base}/account/reset-password?token=${encodeURIComponent(passwordResetToken)}` + }, + text: `Dear ${pnid.get('username')}, a password reset has been requested from this account. \r\n\r\nIf you did not request the password reset, please ignore this email. \r\nIf you did request this password reset, please click the link to reset your password: ${config.website_base}/account/reset-password?token=${encodeURIComponent(passwordResetToken)}` }); }