mirror of
https://github.com/wassname/talk.git
synced 2026-06-27 17:50:42 +08:00
Replace nodemailer with emailjs (#2983)
* chore: replace nodemailer with emailjs * fix: bumped version
This commit is contained in:
Generated
+5
-14
@@ -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
@@ -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",
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user