Live (In a Volcano) community card game.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

111 lines
3.2 KiB

// email.js
// Copyright (C) 2022 DTP Technologies, LLC
// License: Apache-2.0
'use strict';
const path = require('path');
const pug = require('pug');
const nodemailer = require('nodemailer');
const mongoose = require('mongoose');
const EmailBlacklist = mongoose.model('EmailBlacklist');
const disposableEmailDomains = require('disposable-email-provider-domains');
const emailValidator = require('email-validator');
const emailDomainCheck = require('email-domain-check');
const { SiteService } = require('../../lib/site-lib');
class EmailService extends SiteService {
constructor (dtp) {
super(dtp, module.exports);
}
async start ( ) {
await super.start();
if (process.env.DTP_EMAIL_ENABLED !== 'enabled') {
return;
}
const SMTP_PORT = parseInt(process.env.DTP_EMAIL_SMTP_PORT || '587', 10);
this.log.info('creating SMTP transport', {
host: process.env.DTP_EMAIL_SMTP_HOST,
port: SMTP_PORT,
});
this.transport = nodemailer.createTransport({
host: process.env.DTP_EMAIL_SMTP_HOST,
port: SMTP_PORT,
secure: process.env.DTP_EMAIL_SMTP_SECURE === 'enabled',
auth: {
user: process.env.DTP_EMAIL_SMTP_USER,
pass: process.env.DTP_EMAIL_SMTP_PASS,
},
pool: true,
maxConnections: parseInt(process.env.DTP_EMAIL_SMTP_POOL_MAX_CONN || '5', 10),
maxMessages: parseInt(process.env.DTP_EMAIL_SMTP_POOL_MAX_MSGS || '5', 10),
});
this.templates = {
html: {
welcome: pug.compileFile(path.join(this.dtp.config.root, 'app', 'templates', 'html', 'welcome.pug')),
},
text: {
welcome: pug.compileFile(path.join(this.dtp.config.root, 'app', 'templates', 'text', 'welcome.pug')),
},
};
}
async send (message) {
this.log.info('sending email', { to: message.to, subject: message.subject });
await this.transport.sendMail(message);
}
async checkEmailAddress (emailAddress) {
this.log.debug('validating email address', { emailAddress });
if (!emailValidator.validate(emailAddress)) {
throw new Error('Email address is invalid');
}
const domainCheck = await emailDomainCheck(emailAddress);
this.log.debug('email domain check', { domainCheck });
if (!domainCheck) {
throw new Error('Email address is invalid');
}
await this.isEmailBlacklisted(emailAddress);
}
async isEmailBlacklisted (emailAddress) {
emailAddress = emailAddress.toLowerCase().trim();
const domain = emailAddress.split('@')[1];
this.log.debug('checking email domain for blacklist', { domain });
if (disposableEmailDomains.domains.includes(domain)) {
this.log.alert('blacklisted email domain blocked', { emailAddress, domain });
throw new Error('Invalid email address');
}
const blacklistRecord = await EmailBlacklist.findOne({ email: emailAddress });
if (blacklistRecord) {
throw new Error('Email address has requested to not receive emails', { blacklistRecord });
}
return false;
}
async renderTemplate (templateId, templateType, message) {
return this.templates[templateType][templateId](message);
}
}
module.exports = {
slug: 'email',
name: 'email',
create: (dtp) => {
return new EmailService(dtp);
},
};