- IMAP 계정 등록/수정/삭제/연결테스트 - SSE 스트리밍으로 메일 목록 로드 (폴더별 지원) - 메일 상세 조회, 읽음 처리, 삭제(휴지통 이동), 폴더 이동 - 첨부파일 다운로드 (ReadableStream 진행바) - SMTP 발송, 답장, 전달 - imapConnectionPool, mailCache 서비스 - encryptionService Node 22+ 호환 수정 - authMiddleware query token 지원 추가 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
64 lines
2.1 KiB
TypeScript
64 lines
2.1 KiB
TypeScript
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();
|