import nodemailer, { Transporter } from 'nodemailer'; import { Logger } from 'pino'; import { EmailOptions, EmailTransport, hasTransport, hasTransportOptions } from '../config/types'; import { InvalidConfiguration } from '../errors'; import mockHandler from './mockHandler'; import { BuildEmailResult, MockEmailHandler } from './types'; async function handleTransport(transport: Transporter, email: EmailTransport, logger: Logger): BuildEmailResult { try { await transport.verify(); } catch (err) { logger.error( 'There is an error with the email configuration you have provided.', err, ); } return { ...email, transport }; } const ensureConfigHasFrom = (emailConfig) => { if (!emailConfig.fromName || !emailConfig.fromAddress) { throw new InvalidConfiguration('Email fromName and fromAddress must be configured when transport is configured'); } }; const handleMockAccount = async (emailConfig: EmailOptions, logger: Logger) => { let mockAccount: MockEmailHandler; try { mockAccount = await mockHandler(emailConfig); const { account: { web, user, pass } } = mockAccount; if (emailConfig.logMockCredentials) { logger.info('E-mail configured with mock configuration'); logger.info(`Log into mock email provider at ${web}`); logger.info(`Mock email account username: ${user}`); logger.info(`Mock email account password: ${pass}`); } } catch (err) { logger.error('There was a problem setting up the mock email handler', err); } return mockAccount; }; export default async function buildEmail(emailConfig: EmailOptions, logger: Logger): BuildEmailResult { if (hasTransport(emailConfig) && emailConfig.transport) { ensureConfigHasFrom(emailConfig); const email = { ...emailConfig }; const { transport } : {transport: Transporter} = emailConfig; return handleTransport(transport, email, logger); } if (hasTransportOptions(emailConfig) && emailConfig.transportOptions) { ensureConfigHasFrom(emailConfig); const email = { ...emailConfig } as EmailTransport; const transport = nodemailer.createTransport(emailConfig.transportOptions); return handleTransport(transport, email, logger); } return handleMockAccount(emailConfig, logger); }