Replace nodemailer with emailjs (#2983)

* chore: replace nodemailer with emailjs

* fix: bumped version
This commit is contained in:
Wyatt Johnson
2020-06-24 22:24:37 +00:00
committed by GitHub
parent db8c9de0e7
commit f3ef9ef778
3 changed files with 45 additions and 39 deletions
+5 -14
View File
@@ -7906,15 +7906,6 @@
}
}
},
"@types/nodemailer": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.0.tgz",
"integrity": "sha512-KY7bFWB0MahRZvVW4CuW83qcCDny59pJJ0MQ5ifvfcjNwPlIT0vW4uARO4u1gtkYnWdhSvURegecY/tzcukJcA==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/normalize-package-data": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
@@ -18037,6 +18028,11 @@
"minimalistic-crypto-utils": "^1.0.0"
}
},
"emailjs": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/emailjs/-/emailjs-3.2.0.tgz",
"integrity": "sha512-eZMcUgkhNkHlr9J8ifhNyvuMEoSlpZzZj10kgCaa3b2DQo9GKkYYoQ4dB0iOQ6WERrT7VKW7XOTEbt7ZbTtyyQ=="
},
"emoji-regex": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.1.1.tgz",
@@ -36242,11 +36238,6 @@
"semver": "^5.3.0"
}
},
"nodemailer": {
"version": "6.4.6",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.4.6.tgz",
"integrity": "sha512-/kJ+FYVEm2HuUlw87hjSqTss+GU35D4giOpdSfGp7DO+5h6RlJj7R94YaYHOkoxu1CSaM0d3WRBtCzwXrY6MKA=="
},
"noms": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/noms/-/noms-0.0.0.tgz",
+1 -2
View File
@@ -88,6 +88,7 @@
"dataloader": "1.4.0",
"dompurify": "^2.0.8",
"dotenv": "^8.2.0",
"emailjs": "^3.2.0",
"env-rewrite": "^1.0.2",
"express": "^4.17.1",
"express-enforces-ssl": "^1.1.0",
@@ -123,7 +124,6 @@
"mongodb-core": "^3.2.7",
"ms": "^2.1.2",
"node-fetch": "^2.6.0",
"nodemailer": "^6.4.6",
"nunjucks": "^3.2.1",
"on-finished": "^2.3.0",
"passport": "^0.4.1",
@@ -204,7 +204,6 @@
"@types/ms": "^0.7.31",
"@types/node": "^12.12.34",
"@types/node-fetch": "^2.5.5",
"@types/nodemailer": "^6.4.0",
"@types/nunjucks": "^3.1.3",
"@types/on-finished": "^2.3.1",
"@types/passport": "^1.0.3",
+39 -23
View File
@@ -3,14 +3,18 @@ import { DOMLocalization } from "@fluent/dom/compat";
import Joi from "@hapi/joi";
import { Job } from "bull";
import createDOMPurify from "dompurify";
import {
Message,
MessageAttachment,
SMTPClient,
SMTPConnectionOptions,
} from "emailjs";
import { minify } from "html-minifier";
import htmlToText from "html-to-text";
import { JSDOM } from "jsdom";
import { juiceResources } from "juice";
import { camelCase, isNil } from "lodash";
import { Db } from "mongodb";
import { createTransport } from "nodemailer";
import { Options } from "nodemailer/lib/smtp-connection";
import { LanguageCode } from "coral-common/helpers";
import { Config } from "coral-server/config";
@@ -51,12 +55,16 @@ const MailerDataSchema = Joi.object().keys({
tenantID: Joi.string(),
});
interface Message {
from: string;
to: string;
html: string;
text: string;
subject: string;
function send(client: SMTPClient, message: Message): Promise<Message> {
return new Promise((resolve, reject) => {
client.send(message, (err, msg) => {
if (err) {
return reject(err);
}
return resolve(msg);
});
});
}
/**
@@ -150,6 +158,18 @@ function createMessageTranslator(i18n: I18n) {
// Juice the HTML to inline resources.
const html = await juiceHTML(dom.serialize());
// Wrap the html in an email attachment as an alternative representation of
// the email message. This is casted "as MessageAttachment" following the
// test example here:
//
// https://github.com/eleith/emailjs/blob/0781d02cbf7de0d55b417d00ae7f5ab1283bf527/test/message.ts#L166-L169
//
// TODO: (wyattjoh) tracking issue here https://github.com/eleith/emailjs/issues/254
const attachment = {
data: html,
alternative: true,
} as MessageAttachment;
// Get the translated subject.
const subject = translate(
bundle,
@@ -162,13 +182,13 @@ function createMessageTranslator(i18n: I18n) {
const text = htmlToText.fromString(html);
// Prepare the message payload.
return {
return new Message({
from: fromAddress,
to: data.message.to,
html,
text,
subject,
};
attachment,
});
};
}
@@ -177,9 +197,7 @@ export const createJobProcessor = (options: MailProcessorOptions) => {
// Create the cache adapter that will handle invalidating the email transport
// when the tenant experiences a change.
const cache = new TenantCacheAdapter<ReturnType<typeof createTransport>>(
tenantCache
);
const cache = new TenantCacheAdapter<SMTPClient>(tenantCache);
// Create the message translator function.
const translateMessage = createMessageTranslator(i18n);
@@ -268,23 +286,21 @@ export const createJobProcessor = (options: MailProcessorOptions) => {
if (!transport) {
try {
// Create the new transport options.
const opts: Options = {
const opts: Partial<SMTPConnectionOptions> = {
host: smtp.host,
port: smtp.port,
secure: smtp.secure,
tls: smtp.secure,
};
if (smtp.authentication && smtp.username && smtp.password) {
// If authentication details are provided, add them to the transport
// configuration.
opts.auth = {
type: "login",
user: smtp.username,
pass: smtp.password,
};
opts.user = smtp.username;
opts.password = smtp.password;
opts.authentication = ["LOGIN"];
}
// Create the transport based on the smtp uri.
transport = createTransport(opts);
transport = new SMTPClient(opts);
} catch (e) {
throw new WrappedInternalError(e, "could not create email transport");
}
@@ -303,7 +319,7 @@ export const createJobProcessor = (options: MailProcessorOptions) => {
try {
// Send the mail message.
await transport.sendMail(message);
await send(transport, message);
} catch (e) {
throw new WrappedInternalError(e, "could not send email");
}