const nodemailer = require('nodemailer'); const logger = require('../utils/logger'); const emailTemplates = require('./emailTemplates'); const config = require('../config'); // Create reusable transporter let transporter; const initializeEmailService = () => { const emailConfig = { host: process.env.SMTP_HOST, port: parseInt(process.env.SMTP_PORT), secure: process.env.SMTP_SECURE === 'true', // true for 465, false for other ports auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS } }; // Additional settings for specific providers if (process.env.SMTP_SERVICE) { emailConfig.service = process.env.SMTP_SERVICE; // 'gmail' for example } // Handle TLS for port 587 if (emailConfig.port === 587) { emailConfig.secure = false; emailConfig.requireTLS = true; } transporter = nodemailer.createTransport(emailConfig); // Verify connection transporter.verify((error, success) => { if (error) { logger.error('SMTP connection failed:', error); } else { logger.info('SMTP server ready to send emails'); } }); }; const sendEmail = async ({ to, subject, text, html }) => { if (!transporter) { throw new Error('Email service not initialized'); } const mailOptions = { from: `${process.env.EMAIL_FROM_NAME} <${process.env.EMAIL_FROM_ADDRESS}>`, to, subject, text, html }; try { const info = await transporter.sendMail(mailOptions); logger.info(`Email sent: ${info.messageId}`); return info; } catch (error) { logger.error('Failed to send email:', error); throw error; } }; const sendPasswordRecovery = async (user) => { try { const baseUrl = config.isProduction ? `https://map.${config.domain}` : `http://localhost:${config.port}`; const variables = { APP_NAME: process.env.APP_NAME || 'CMlite Map', USER_NAME: user.Name || user.name || user.Email || user.email, USER_EMAIL: user.Email || user.email, PASSWORD: user.Password || user.password, LOGIN_URL: `${baseUrl}/login.html`, TIMESTAMP: new Date().toLocaleString() }; const { html, text } = await emailTemplates.render('password-recovery', variables); return await sendEmail({ to: user.Email || user.email, subject: `Password Recovery - ${variables.APP_NAME}`, text, html }); } catch (error) { logger.error('Failed to send password recovery email:', error); throw error; } }; const sendLoginDetails = async (user) => { try { const baseUrl = config.isProduction ? `https://map.${config.domain}` : `http://localhost:${config.port}`; const isAdmin = user.admin || user.Admin || false; const variables = { APP_NAME: process.env.APP_NAME || 'CMlite Map', USER_NAME: user.Name || user.name || user.Email || user.email, USER_EMAIL: user.Email || user.email, PASSWORD: user.Password || user.password, USER_ROLE: isAdmin ? 'Administrator' : 'User', LOGIN_URL: `${baseUrl}/login.html`, TIMESTAMP: new Date().toLocaleString() }; const { html, text } = await emailTemplates.render('login-details', variables); return await sendEmail({ to: user.Email || user.email, subject: `Your Login Details - ${variables.APP_NAME}`, text, html }); } catch (error) { logger.error('Failed to send login details email:', error); throw error; } }; module.exports = { initializeEmailService, sendEmail, sendPasswordRecovery, sendLoginDetails };