Skip to content

Commit

Permalink
Don't initialize mailer on startup (directus#6169)
Browse files Browse the repository at this point in the history
* Fix m2m relationship not showing current col/pk

* Don't initialize mailer on first boot

Another step to serverless!
  • Loading branch information
rijkvanzanten authored Jun 9, 2021
1 parent 61f66ea commit 76a31ca
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 53 deletions.
85 changes: 39 additions & 46 deletions api/src/mailer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,47 @@ import nodemailer, { Transporter } from 'nodemailer';
import env from './env';
import logger from './logger';

let transporter: Transporter | null = null;
let transporter: Transporter;

if (env.EMAIL_TRANSPORT === 'sendmail') {
transporter = nodemailer.createTransport({
sendmail: true,
newline: env.EMAIL_SENDMAIL_NEW_LINE || 'unix',
path: env.EMAIL_SENDMAIL_PATH || '/usr/sbin/sendmail',
});
} else if (env.EMAIL_TRANSPORT.toLowerCase() === 'smtp') {
let auth: boolean | { user?: string; pass?: string } = false;
export default function getMailer(): Transporter {
if (transporter) return transporter;

if (env.EMAIL_SMTP_USER || env.EMAIL_SMTP_PASSWORD) {
auth = {
user: env.EMAIL_SMTP_USER,
pass: env.EMAIL_SMTP_PASSWORD,
};
}

transporter = nodemailer.createTransport({
pool: env.EMAIL_SMTP_POOL,
host: env.EMAIL_SMTP_HOST,
port: env.EMAIL_SMTP_PORT,
secure: env.EMAIL_SMTP_SECURE,
auth: auth,
} as Record<string, unknown>);
} else if (env.EMAIL_TRANSPORT.toLowerCase() === 'mailgun') {
const mg = require('nodemailer-mailgun-transport');
transporter = nodemailer.createTransport(
mg({
auth: {
api_key: env.EMAIL_MAILGUN_API_KEY,
domain: env.EMAIL_MAILGUN_DOMAIN,
},
}) as any
);
} else {
logger.warn('Illegal transport given for email. Check the EMAIL_TRANSPORT env var.');
}
if (env.EMAIL_TRANSPORT === 'sendmail') {
transporter = nodemailer.createTransport({
sendmail: true,
newline: env.EMAIL_SENDMAIL_NEW_LINE || 'unix',
path: env.EMAIL_SENDMAIL_PATH || '/usr/sbin/sendmail',
});
} else if (env.EMAIL_TRANSPORT.toLowerCase() === 'smtp') {
let auth: boolean | { user?: string; pass?: string } = false;

if (transporter) {
transporter.verify((error) => {
if (error) {
logger.warn(`Couldn't connect to email server.`);
logger.warn(`Email verification error: ${error}`);
} else {
logger.info(`Email connection established`);
if (env.EMAIL_SMTP_USER || env.EMAIL_SMTP_PASSWORD) {
auth = {
user: env.EMAIL_SMTP_USER,
pass: env.EMAIL_SMTP_PASSWORD,
};
}
});
}

export default transporter;
transporter = nodemailer.createTransport({
pool: env.EMAIL_SMTP_POOL,
host: env.EMAIL_SMTP_HOST,
port: env.EMAIL_SMTP_PORT,
secure: env.EMAIL_SMTP_SECURE,
auth: auth,
} as Record<string, unknown>);
} else if (env.EMAIL_TRANSPORT.toLowerCase() === 'mailgun') {
const mg = require('nodemailer-mailgun-transport');
transporter = nodemailer.createTransport(
mg({
auth: {
api_key: env.EMAIL_MAILGUN_API_KEY,
domain: env.EMAIL_MAILGUN_DOMAIN,
},
}) as any
);
} else {
logger.warn('Illegal transport given for email. Check the EMAIL_TRANSPORT env var.');
}

return transporter;
}
17 changes: 12 additions & 5 deletions api/src/services/mail/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import env from '../../env';
import { InvalidPayloadException } from '../../exceptions';
import logger from '../../logger';
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../../types';
import mailer from '../../mailer';
import { SendMailOptions } from 'nodemailer';
import getMailer from '../../mailer';
import { Transporter, SendMailOptions } from 'nodemailer';

const liquidEngine = new Liquid({
root: [path.resolve(env.EXTENSIONS_PATH, 'templates'), path.resolve(__dirname, 'templates')],
Expand All @@ -26,16 +26,23 @@ export class MailService {
schema: SchemaOverview;
accountability: Accountability | null;
knex: Knex;
mailer: Transporter;

constructor(opts: AbstractServiceOptions) {
this.schema = opts.schema;
this.accountability = opts.accountability || null;
this.knex = opts?.knex || getDatabase();
this.mailer = getMailer();

this.mailer.verify((error) => {
if (error) {
logger.warn(`Email connection failed:`);
logger.warn(error);
}
});
}

async send(options: EmailOptions): Promise<void> {
if (!mailer) return;

const { template, ...emailOptions } = options;
let { html } = options;

Expand All @@ -55,7 +62,7 @@ export class MailService {
}

try {
await mailer.sendMail({ ...emailOptions, from, html });
await this.mailer.sendMail({ ...emailOptions, from, html });
} catch (error) {
logger.warn('[Email] Unexpected error while sending an email:');
logger.warn(error);
Expand Down
6 changes: 4 additions & 2 deletions api/src/services/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { rateLimiter } from '../middleware/rate-limiter';
import storage from '../storage';
import { AbstractServiceOptions, Accountability, SchemaOverview } from '../types';
import { toArray } from '../utils/to-array';
import mailer from '../mailer';
import getMailer from '../mailer';
import { SettingsService } from './settings';

export class ServerService {
Expand Down Expand Up @@ -316,8 +316,10 @@ export class ServerService {
],
};

const mailer = getMailer();

try {
await mailer?.verify();
await mailer.verify();
} catch (err) {
checks['email:connection'][0].status = 'error';
checks['email:connection'][0].output = err;
Expand Down

0 comments on commit 76a31ca

Please sign in to comment.