import nodemailer from 'nodemailer'; import { encryptionService } from './encryptionService'; import { UserMailAccount } from './userMailAccountService'; export interface SendMailDto { to: string; cc?: string; subject: string; html: string; text?: string; inReplyTo?: string; references?: string; } class UserMailSmtpService { private getSmtpConfig(account: UserMailAccount) { const decryptedPassword = encryptionService.decrypt(account.password); // IMAP host에서 SMTP host 추론 const smtpHost = account.host .replace(/^imap\./, 'smtp.') .replace(/^mail\./, 'smtp.'); // 포트 추론: TLS → 465, plain → 587 const port = account.useTls ? 465 : 587; return { host: smtpHost, port, secure: account.useTls, // 465: true, 587: false (STARTTLS) auth: { user: account.username, pass: decryptedPassword }, tls: { rejectUnauthorized: false }, }; } async sendMail(account: UserMailAccount, dto: SendMailDto): Promise<{ success: boolean; message: string }> { try { const transporter = nodemailer.createTransport(this.getSmtpConfig(account)); await transporter.sendMail({ from: `${account.displayName} <${account.email}>`, to: dto.to, cc: dto.cc, subject: dto.subject, html: dto.html, text: dto.text, inReplyTo: dto.inReplyTo, references: dto.references, }); return { success: true, message: '발송 완료' }; } catch (err) { return { success: false, message: err instanceof Error ? err.message : '발송 실패' }; } } async testSmtpConnection(account: UserMailAccount): Promise<{ success: boolean; message: string }> { try { const transporter = nodemailer.createTransport(this.getSmtpConfig(account)); await transporter.verify(); return { success: true, message: 'SMTP 연결 성공' }; } catch (err) { return { success: false, message: err instanceof Error ? err.message : 'SMTP 연결 실패' }; } } } export const userMailSmtpService = new UserMailSmtpService();