diff --git a/Mail/.env.tpl b/Mail/.env.tpl index c763c329e0..708d62583b 100644 --- a/Mail/.env.tpl +++ b/Mail/.env.tpl @@ -6,3 +6,4 @@ SMTP_EMAIL={{ .Env.SMTP_EMAIL }} SMTP_FROM_NAME={{ .Env.SMTP_FROM_NAME }} SMTP_IS_SECURE={{ .Env.SMTP_IS_SECURE }} SMTP_HOST={{ .Env.SMTP_HOST }} +SENDGRID_API_KEY={{ .Env.SENDGRID_API_KEY }} diff --git a/Mail/Config.ts b/Mail/Config.ts index f65d916e96..fd48d26ab7 100644 --- a/Mail/Config.ts +++ b/Mail/Config.ts @@ -25,3 +25,6 @@ export const InternalSmtpFromEmail: Email = new Email( export const InternalSmtpFromName: string = process.env['INTERNAL_SMTP_NAME'] || ''; + +export const SendGridApiKey: string = + process.env['SENDGRID_API_KEY'] || ''; diff --git a/Mail/Services/MailService.ts b/Mail/Services/MailService.ts index 61c9fc6805..8dd65c79c5 100755 --- a/Mail/Services/MailService.ts +++ b/Mail/Services/MailService.ts @@ -15,6 +15,8 @@ import Port from 'Common/Types/Port'; import { JSONObject } from 'Common/Types/JSON'; import logger from 'CommonServer/Utils/Logger'; import { IsDevelopment } from 'CommonServer/Config'; +import { SendGridApiKey } from '../Config'; +import SendgridMail from '@sendgrid/mail'; Handlebars.registerHelper('ifCond', function (v1, v2, options) { if (v1 === v2) { @@ -115,6 +117,11 @@ export default class MailService { }; } + public static getGlobalFromEmail(){ + const emailServer = this.getGlobalSmtpSettings(); + return emailServer.fromEmail; + } + private static getGlobalSmtpSettings(): EmailServer { return this.getEmailServer(process.env); } @@ -195,9 +202,7 @@ export default class MailService { mail: EmailMessage, emailServer?: EmailServer ): Promise { - if (!emailServer) { - emailServer = this.getGlobalSmtpSettings(); - } + // default vars. if (!mail.vars) { @@ -213,6 +218,24 @@ export default class MailService { : this.compileText(mail.body || '', mail.vars); mail.subject = this.compileText(mail.subject, mail.vars); + if(!emailServer && SendGridApiKey){ + SendgridMail.setApiKey(SendGridApiKey); + + const msg = { + to: mail.toEmail.toString(), // Change to your recipient + from: this.getGlobalFromEmail().toString(), // Change to your verified sender + subject: mail.subject, + html: mail.body, + } + + await SendgridMail.send(msg) + return; + } + + if (!emailServer) { + emailServer = this.getGlobalSmtpSettings(); + } + await this.transportMail(mail, emailServer); } } diff --git a/Mail/package-lock.json b/Mail/package-lock.json index 5791c6a409..b3c6cfc3b5 100644 --- a/Mail/package-lock.json +++ b/Mail/package-lock.json @@ -9,6 +9,7 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@sendgrid/mail": "^7.7.0", "@types/node": "^17.0.27", "@types/nodemailer": "^6.4.4", "@types/nodemailer-express-handlebars": "^4.0.2", @@ -66,7 +67,11 @@ "@types/ejs": "^3.1.1", "@types/gridfs-stream": "^0.5.35", "@types/json2csv": "^5.0.3", + "@types/markdown-it": "^12.2.3", + "@types/nodemailer": "^6.4.7", "airtable": "^0.11.3", + "axios": "^1.3.3", + "bullmq": "^3.6.6", "Common": "file:../Common", "cors": "^2.8.5", "dotenv": "^16.0.0", @@ -76,6 +81,7 @@ "handlebars": "^4.7.7", "json2csv": "^5.0.7", "jsonwebtoken": "^9.0.0", + "markdown-it": "^13.0.1", "Model": "file:../Model", "node-device-detector": "^2.0.0", "nodemailer": "^6.7.3", @@ -86,6 +92,7 @@ "stripe": "^10.17.0", "typeorm": "^0.3.10", "typeorm-extension": "^2.2.13", + "vm2": "^3.9.14", "winston": "^3.6.0" }, "devDependencies": { @@ -93,7 +100,7 @@ "@types/cors": "^2.8.12", "@types/express": "^4.17.13", "@types/jest": "^27.4.1", - "@types/jsonwebtoken": "^8.5.8", + "@types/jsonwebtoken": "^8.5.9", "@types/node": "^17.0.22", "jest": "^27.5.1", "ts-jest": "^27.1.4" @@ -147,6 +154,41 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "dependencies": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, + "node_modules/@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "dependencies": { + "deepmerge": "^4.2.2" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "dependencies": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + }, + "engines": { + "node": "6.* || 8.* || >=10.*" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -256,6 +298,14 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "node_modules/axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "dependencies": { + "follow-redirects": "^1.14.8" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -376,6 +426,14 @@ "ms": "^2.1.1" } }, + "node_modules/deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -450,6 +508,25 @@ "node": ">=8" } }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -994,6 +1071,32 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@sendgrid/client": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/client/-/client-7.7.0.tgz", + "integrity": "sha512-SxH+y8jeAQSnDavrTD0uGDXYIIkFylCo+eDofVmZLQ0f862nnqbC3Vd1ej6b7Le7lboyzQF6F7Fodv02rYspuA==", + "requires": { + "@sendgrid/helpers": "^7.7.0", + "axios": "^0.26.0" + } + }, + "@sendgrid/helpers": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/helpers/-/helpers-7.7.0.tgz", + "integrity": "sha512-3AsAxfN3GDBcXoZ/y1mzAAbKzTtUZ5+ZrHOmWQ279AuaFXUNCh9bPnRpN504bgveTqoW+11IzPg3I0WVgDINpw==", + "requires": { + "deepmerge": "^4.2.2" + } + }, + "@sendgrid/mail": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@sendgrid/mail/-/mail-7.7.0.tgz", + "integrity": "sha512-5+nApPE9wINBvHSUxwOxkkQqM/IAAaBYoP9hw7WwgDNQPxraruVqHizeTitVtKGiqWCKm2mnjh4XGN3fvFLqaw==", + "requires": { + "@sendgrid/client": "^7.7.0", + "@sendgrid/helpers": "^7.7.0" + } + }, "@tsconfig/node10": { "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", @@ -1085,6 +1188,14 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==" }, + "axios": { + "version": "0.26.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", + "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "requires": { + "follow-redirects": "^1.14.8" + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1191,9 +1302,13 @@ "@types/gridfs-stream": "^0.5.35", "@types/jest": "^27.4.1", "@types/json2csv": "^5.0.3", - "@types/jsonwebtoken": "^8.5.8", + "@types/jsonwebtoken": "^8.5.9", + "@types/markdown-it": "^12.2.3", "@types/node": "^17.0.22", + "@types/nodemailer": "^6.4.7", "airtable": "^0.11.3", + "axios": "^1.3.3", + "bullmq": "^3.6.6", "Common": "file:../Common", "cors": "^2.8.5", "dotenv": "^16.0.0", @@ -1204,6 +1319,7 @@ "jest": "^27.5.1", "json2csv": "^5.0.7", "jsonwebtoken": "^9.0.0", + "markdown-it": "^13.0.1", "Model": "file:../Model", "node-device-detector": "^2.0.0", "nodemailer": "^6.7.3", @@ -1215,6 +1331,7 @@ "ts-jest": "^27.1.4", "typeorm": "^0.3.10", "typeorm-extension": "^2.2.13", + "vm2": "^3.9.14", "winston": "^3.6.0" } }, @@ -1237,6 +1354,11 @@ "ms": "^2.1.1" } }, + "deepmerge": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1295,6 +1417,11 @@ "to-regex-range": "^5.0.1" } }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", diff --git a/Mail/package.json b/Mail/package.json index 28b4c76b93..b6c2bb1392 100644 --- a/Mail/package.json +++ b/Mail/package.json @@ -12,6 +12,7 @@ "author": "", "license": "MIT", "dependencies": { + "@sendgrid/mail": "^7.7.0", "@types/node": "^17.0.27", "@types/nodemailer": "^6.4.4", "@types/nodemailer-express-handlebars": "^4.0.2", diff --git a/config.tpl.env b/config.tpl.env index a13a34d441..24f3e6ee05 100644 --- a/config.tpl.env +++ b/config.tpl.env @@ -135,4 +135,7 @@ ANALYTICS_KEY= ANALYTICS_HOST= DATABASE_MIGRATIONS_HOST=localhost -DATABASE_MIGRATIONS_PORT=5400 \ No newline at end of file +DATABASE_MIGRATIONS_PORT=5400 + + +SENDGRID_API_KEY= \ No newline at end of file