(to: string, subject: string, htmlBody: string, textBody: string)
| 9 | |
| 10 | export class EmailModel { |
| 11 | private static async send(to: string, subject: string, htmlBody: string, textBody: string) { |
| 12 | const emailConfig = await AppConfig.getEmailConfig(); |
| 13 | |
| 14 | if (!emailConfig.from || !emailConfig.host || !emailConfig.port) { |
| 15 | throw new Error('config.email.from, config.email.host, or config.email.port is not set'); |
| 16 | } |
| 17 | |
| 18 | let tlsMode = emailConfig.tlsMode; |
| 19 | if (tlsMode === 'auto') { |
| 20 | tlsMode = Number(emailConfig.port) === 465 ? 'immediate' : 'starttls'; |
| 21 | } |
| 22 | |
| 23 | const transporterConfig = { |
| 24 | host: emailConfig.host, |
| 25 | port: emailConfig.port, |
| 26 | |
| 27 | secure: tlsMode === 'immediate', |
| 28 | requireTLS: tlsMode === 'starttls', |
| 29 | ignoreTLS: tlsMode === 'none', |
| 30 | tls: emailConfig.tlsVerify === false |
| 31 | ? { rejectUnauthorized: false } |
| 32 | : emailConfig.tlsVerify !== true |
| 33 | ? { servername: emailConfig.tlsVerify } |
| 34 | : {}, |
| 35 | |
| 36 | auth: (SMTP_USERNAME || SMTP_PASSWORD) |
| 37 | ? { |
| 38 | user: SMTP_USERNAME, |
| 39 | pass: SMTP_PASSWORD, |
| 40 | } |
| 41 | : null, |
| 42 | }; |
| 43 | |
| 44 | const transporter = nodemailer.createTransport(transporterConfig); |
| 45 | |
| 46 | const mailOptions = { |
| 47 | from: emailConfig.from, |
| 48 | to, |
| 49 | subject, |
| 50 | html: htmlBody, |
| 51 | text: textBody, |
| 52 | }; |
| 53 | |
| 54 | try { |
| 55 | await transporter.sendMail(mailOptions); |
| 56 | console.log(`Email sent to "${to}", "${subject}"`); |
| 57 | } catch (error) { |
| 58 | console.log(error); |
| 59 | throw new Error(`Failed to send email to "${to}", "${subject}"`); |
| 60 | } |
| 61 | } |
| 62 | |
| 63 | /** Based off of https://github.com/ActiveCampaign/postmark-templates/tree/main/templates-inlined/basic/password-reset */ |
| 64 | private static getHtmlBody(title: string, htmlBody: string) { |
no test coverage detected