import log4js from "logger"; import nodemailer from "nodemailer"; type CommentEmailConfig = { enabled: boolean; fromEmail: string; smtpHost: string; smtpPort: number; smtpSecure: boolean; smtpUser: string; smtpPass: string; }; const logger = log4js.getLogger("COMMENT_EMAIL_TEST"); const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; export class CommentEmailTestValidationError extends Error { constructor(message: string) { super(message); this.name = "CommentEmailTestValidationError"; } } function hasValue(value: string): boolean { return value.trim().length > 0; } export function assertCommentEmailConfigReadyForTest(config: CommentEmailConfig): void { if (!config.enabled) { throw new CommentEmailTestValidationError("评论邮件通知总开关未开启"); } if (!hasValue(config.fromEmail) || !hasValue(config.smtpHost) || !hasValue(config.smtpUser) || !hasValue(config.smtpPass)) { throw new CommentEmailTestValidationError("邮件配置不完整,请先填写发件人、SMTP 主机、用户名和密码"); } if (!Number.isInteger(config.smtpPort) || config.smtpPort < 1 || config.smtpPort > 65535) { throw new CommentEmailTestValidationError("SMTP 端口不合法"); } } export function assertAdminEmailReady(adminEmail: string | null | undefined): asserts adminEmail is string { if (!adminEmail || adminEmail.trim().length === 0) { throw new CommentEmailTestValidationError("当前管理员账号未配置邮箱,无法接收测试邮件"); } if (!EMAIL_REGEX.test(adminEmail.trim())) { throw new CommentEmailTestValidationError("当前管理员账号邮箱格式不合法"); } } export async function sendCommentEmailTestMail(input: { toEmail: string; requestedBy: string; config: CommentEmailConfig; }) { assertCommentEmailConfigReadyForTest(input.config); assertAdminEmailReady(input.toEmail); const transporter = nodemailer.createTransport({ host: input.config.smtpHost, port: input.config.smtpPort, secure: input.config.smtpSecure, connectionTimeout: 10_000, greetingTimeout: 10_000, socketTimeout: 15_000, auth: { user: input.config.smtpUser, pass: input.config.smtpPass, }, }); await transporter.sendMail({ from: input.config.fromEmail, to: input.toEmail.trim(), subject: "[Person Panel] 评论邮件配置测试", text: `你好,${input.requestedBy}。\n\n这是一封评论邮件配置测试邮件,若你收到该邮件,说明 SMTP 配置可用。\n\n发送时间:${new Date().toISOString()}\n`, }); logger.info("comment email test message sent to admin account"); }