diff --git a/backend/src/main/java/io/metersphere/notice/sender/impl/MailNoticeSender.java b/backend/src/main/java/io/metersphere/notice/sender/impl/MailNoticeSender.java index 51249df4e9..9049820c2e 100644 --- a/backend/src/main/java/io/metersphere/notice/sender/impl/MailNoticeSender.java +++ b/backend/src/main/java/io/metersphere/notice/sender/impl/MailNoticeSender.java @@ -1,45 +1,39 @@ package io.metersphere.notice.sender.impl; +import io.metersphere.base.domain.SystemParameter; +import io.metersphere.base.domain.SystemParameterExample; +import io.metersphere.base.mapper.SystemParameterMapper; +import io.metersphere.commons.constants.ParamConstants; +import io.metersphere.commons.utils.EncryptUtils; import io.metersphere.commons.utils.LogUtil; import io.metersphere.notice.domain.MessageDetail; import io.metersphere.notice.domain.Receiver; import io.metersphere.notice.domain.UserDetail; import io.metersphere.notice.sender.AbstractNoticeSender; import io.metersphere.notice.sender.NoticeModel; -import io.metersphere.notice.service.MailService; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import javax.annotation.Resource; -import javax.mail.MessagingException; +import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; import java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.Properties; import java.util.stream.Collectors; @Component public class MailNoticeSender extends AbstractNoticeSender { @Resource - private MailService mailService; + private SystemParameterMapper systemParameterMapper; + + public void sendMail(String context, NoticeModel noticeModel) throws Exception { - public void sendMail(String context, NoticeModel noticeModel) throws MessagingException { - LogUtil.debug("发送邮件开始 "); - JavaMailSenderImpl javaMailSender = mailService.getMailSender(); - MimeMessage mimeMessage = javaMailSender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); - //helper.setFrom(javaMailSender.getUsername()); - if (javaMailSender.getUsername().contains("@")) { - helper.setFrom(javaMailSender.getUsername()); - } else { - String mailHost = javaMailSender.getHost(); - String domainName = mailHost.substring(mailHost.indexOf(".") + 1, mailHost.length()); - helper.setFrom(javaMailSender.getUsername() + "@" + domainName); - } - LogUtil.debug("发件人地址" + javaMailSender.getUsername()); - LogUtil.debug("helper" + helper); - helper.setSubject("MeterSphere " + noticeModel.getSubject()); List userIds = noticeModel.getReceivers().stream() .map(Receiver::getUserId) .distinct() @@ -53,27 +47,67 @@ public class MailNoticeSender extends AbstractNoticeSender { .distinct() .toArray(String[]::new); - LogUtil.info("收件人地址: {}", userIds); + send(noticeModel.getSubject(), context, users, new String[0]); + } + + private void send(String subject, String context, String[] users, String[] cc) throws Exception { + LogUtil.debug("发送邮件开始 "); + SystemParameterExample example = new SystemParameterExample(); + example.createCriteria().andParamKeyLike(ParamConstants.Classify.MAIL.getValue() + "%"); + List paramList = systemParameterMapper.selectByExample(example); + Map paramMap = paramList.stream().collect(Collectors.toMap(SystemParameter::getParamKey, p -> { + if (StringUtils.equals(p.getParamKey(), ParamConstants.MAIL.PASSWORD.getValue())) { + return EncryptUtils.aesDecrypt(p.getParamValue()).toString(); + } + if (StringUtils.isEmpty(p.getParamValue())) { + return ""; + } else { + return p.getParamValue(); + } + })); + JavaMailSenderImpl javaMailSender = getMailSender(paramMap); + MimeMessage mimeMessage = javaMailSender.createMimeMessage(); + MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); + String username = javaMailSender.getUsername(); + String email; + if (username.contains("@")) { + email = username; + } else { + String mailHost = javaMailSender.getHost(); + String domainName = mailHost.substring(mailHost.indexOf(".") + 1); + email = username + "@" + domainName; + } + InternetAddress from = new InternetAddress(); + String smtpFrom = paramMap.get(ParamConstants.MAIL.FROM.getValue()); + if (StringUtils.isBlank(smtpFrom)) { + from.setAddress(email); + from.setPersonal(username); + } else { + // 指定发件人后,address 应该是邮件服务器验证过的发件人 + if (smtpFrom.contains("@")) { + from.setAddress(smtpFrom); + } else { + from.setAddress(email); + } + from.setPersonal(smtpFrom); + } + helper.setFrom(from); + + LogUtil.debug("发件人地址" + javaMailSender.getUsername()); + LogUtil.debug("helper" + helper); + helper.setSubject("MeterSphere " + subject); + + LogUtil.info("收件人地址: {}", users); helper.setText(context, true); helper.setTo(users); + if (cc != null && cc.length > 0) { + helper.setCc(cc); + } javaMailSender.send(mimeMessage); } - public void sendExternalMail(String context, NoticeModel noticeModel) throws MessagingException { - LogUtil.debug("发送邮件开始 "); - JavaMailSenderImpl javaMailSender = mailService.getMailSender(); - MimeMessage mimeMessage = javaMailSender.createMimeMessage(); - MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true); - if (javaMailSender.getUsername().contains("@")) { - helper.setFrom(javaMailSender.getUsername()); - } else { - String mailHost = javaMailSender.getHost(); - String domainName = mailHost.substring(mailHost.indexOf(".") + 1, mailHost.length()); - helper.setFrom(javaMailSender.getUsername() + "@" + domainName); - } - LogUtil.debug("发件人地址" + javaMailSender.getUsername()); - LogUtil.debug("helper" + helper); - helper.setSubject(noticeModel.getSubject()); + public void sendExternalMail(String context, NoticeModel noticeModel) throws Exception { + List userIds = noticeModel.getReceivers().stream() .map(Receiver::getUserId) .distinct() @@ -83,7 +117,7 @@ public class MailNoticeSender extends AbstractNoticeSender { } List recipients = new ArrayList<>(); - if(CollectionUtils.isNotEmpty(noticeModel.getRecipients())){ + if (CollectionUtils.isNotEmpty(noticeModel.getRecipients())) { recipients = noticeModel.getRecipients().stream() .map(Receiver::getUserId) .distinct() @@ -93,19 +127,14 @@ public class MailNoticeSender extends AbstractNoticeSender { String[] users = userIds.stream() .distinct() .toArray(String[]::new); - - LogUtil.info("收件人地址: {}", userIds); - helper.setText(context, true); - helper.setTo(users); - - if(CollectionUtils.isNotEmpty(recipients)){ - String[] ccArr = recipients.stream() + String[] ccArr = new String[0]; + if (CollectionUtils.isNotEmpty(recipients)) { + ccArr = recipients.stream() .distinct() .toArray(String[]::new); - helper.setCc(ccArr); } - javaMailSender.send(mimeMessage); + send(noticeModel.getSubject(), context, users, ccArr); } @Override @@ -118,4 +147,33 @@ public class MailNoticeSender extends AbstractNoticeSender { LogUtil.error(e); } } + + + public JavaMailSenderImpl getMailSender(Map paramMap) { + Properties props = new Properties(); + JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); + javaMailSender.setDefaultEncoding("UTF-8"); + javaMailSender.setProtocol("smtp"); + javaMailSender.setHost(paramMap.get(ParamConstants.MAIL.SERVER.getValue())); + javaMailSender.setPort(Integer.parseInt(paramMap.get(ParamConstants.MAIL.PORT.getValue()))); + javaMailSender.setUsername(paramMap.get(ParamConstants.MAIL.ACCOUNT.getValue())); + javaMailSender.setPassword(paramMap.get(ParamConstants.MAIL.PASSWORD.getValue())); + + if (BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.SSL.getValue()))) { + javaMailSender.setProtocol("smtps"); + props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); + } + if (BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.TLS.getValue()))) { + String result = BooleanUtils.toString(BooleanUtils.toBoolean(paramMap.get(ParamConstants.MAIL.TLS.getValue())), "true", "false"); + props.put("mail.smtp.starttls.enable", result); + props.put("mail.smtp.starttls.required", result); + } + + props.put("mail.smtp.ssl.trust", javaMailSender.getHost()); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.timeout", "30000"); + props.put("mail.smtp.connectiontimeout", "5000"); + javaMailSender.setJavaMailProperties(props); + return javaMailSender; + } } diff --git a/backend/src/main/java/io/metersphere/notice/service/MailService.java b/backend/src/main/java/io/metersphere/notice/service/MailService.java deleted file mode 100644 index de4a2d3f68..0000000000 --- a/backend/src/main/java/io/metersphere/notice/service/MailService.java +++ /dev/null @@ -1,81 +0,0 @@ -package io.metersphere.notice.service; - -import io.metersphere.base.domain.SystemParameter; -import io.metersphere.commons.constants.ParamConstants; -import io.metersphere.commons.utils.EncryptUtils; -import io.metersphere.service.SystemParameterService; -import org.apache.commons.lang3.BooleanUtils; -import org.springframework.mail.javamail.JavaMailSenderImpl; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Propagation; -import org.springframework.transaction.annotation.Transactional; - -import javax.annotation.Resource; -import java.util.List; -import java.util.Properties; - -@Service -@Transactional(propagation = Propagation.NOT_SUPPORTED) -public class MailService { - @Resource - private SystemParameterService systemParameterService; - - public JavaMailSenderImpl getMailSender() { - Properties props = new Properties(); - JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); - List paramList = systemParameterService.getParamList(ParamConstants.Classify.MAIL.getValue()); - javaMailSender.setDefaultEncoding("UTF-8"); - javaMailSender.setProtocol("smtp"); - props.put("mail.smtp.auth", "true"); - String smtpHost = ""; - for (SystemParameter p : paramList) { - switch (p.getParamKey()) { - case "smtp.host": - javaMailSender.setHost(p.getParamValue()); - smtpHost = p.getParamValue(); - break; - case "smtp.port": - javaMailSender.setPort(Integer.parseInt(p.getParamValue())); - break; - case "smtp.account": - javaMailSender.setUsername(p.getParamValue()); - break; - case "smtp.password": - javaMailSender.setPassword(EncryptUtils.aesDecrypt(p.getParamValue()).toString()); - break; - case "smtp.ssl": - if (BooleanUtils.toBoolean(p.getParamValue())) { - javaMailSender.setProtocol("smtps"); - props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); - } - break; - case "smtp.tls": - String result = BooleanUtils.toString(BooleanUtils.toBoolean(p.getParamValue()), "true", "false"); - props.put("mail.smtp.starttls.enable", result); - props.put("mail.smtp.starttls.required", result); - props.put("mail.smtp.ssl.trust", smtpHost); - break; - /* case "smtp.anon": - boolean isAnon = BooleanUtils.toBoolean(p.getParamValue()); - if (isAnon) { - props.put("mail.smtp.auth", "false"); - javaMailSender.setUsername(null); - javaMailSender.setPassword(null); - } - break;*/ - default: - break; - } - } - - props.put("mail.smtp.timeout", "30000"); - props.put("mail.smtp.connectiontimeout", "5000"); - javaMailSender.setJavaMailProperties(props); - return javaMailSender; - } -} - - - - - diff --git a/backend/src/main/java/io/metersphere/service/SystemParameterService.java b/backend/src/main/java/io/metersphere/service/SystemParameterService.java index e707285a07..40a074d51a 100644 --- a/backend/src/main/java/io/metersphere/service/SystemParameterService.java +++ b/backend/src/main/java/io/metersphere/service/SystemParameterService.java @@ -22,21 +22,20 @@ import io.metersphere.log.vo.DetailColumn; import io.metersphere.log.vo.OperatingLogDetails; import io.metersphere.log.vo.system.SystemReference; import io.metersphere.notice.domain.MailInfo; +import io.metersphere.notice.domain.Receiver; +import io.metersphere.notice.sender.NoticeModel; +import io.metersphere.notice.sender.impl.MailNoticeSender; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.springframework.mail.javamail.JavaMailSenderImpl; -import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import javax.annotation.Resource; import javax.mail.MessagingException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; +import java.util.Arrays; import java.util.HashMap; import java.util.List; -import java.util.Properties; import java.util.UUID; @@ -53,6 +52,8 @@ public class SystemParameterService { private SystemHeaderMapper systemHeaderMapper; @Resource private ApiTestEnvironmentService apiTestEnvironmentService; + @Resource + private MailNoticeSender mailNoticeSender; public String searchEmail() { return extSystemParameterMapper.email(); @@ -102,62 +103,27 @@ public class SystemParameterService { } public void testConnection(HashMap hashMap) { - JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl(); - javaMailSender.setDefaultEncoding("UTF-8"); - javaMailSender.setHost(hashMap.get(ParamConstants.MAIL.SERVER.getValue())); - javaMailSender.setPort(Integer.parseInt(hashMap.get(ParamConstants.MAIL.PORT.getValue()))); - javaMailSender.setUsername(hashMap.get(ParamConstants.MAIL.ACCOUNT.getValue())); - javaMailSender.setPassword(hashMap.get(ParamConstants.MAIL.PASSWORD.getValue())); - Properties props = new Properties(); - String recipients = hashMap.get(ParamConstants.MAIL.RECIPIENTS.getValue()); - if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.SSL.getValue()))) { - props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); - } - if (BooleanUtils.toBoolean(hashMap.get(ParamConstants.MAIL.TLS.getValue()))) { - props.put("mail.smtp.starttls.enable", "true"); - props.put("mail.smtp.ssl.trust", hashMap.get(ParamConstants.MAIL.SERVER.getValue())); - - } - props.put("mail.smtp.timeout", "30000"); - props.put("mail.smtp.connectiontimeout", "5000"); - javaMailSender.setJavaMailProperties(props); + JavaMailSenderImpl javaMailSender = mailNoticeSender.getMailSender(hashMap); try { javaMailSender.testConnection(); } catch (MessagingException e) { LogUtil.error(e.getMessage(), e); MSException.throwException(Translator.get("connection_failed")); } + + String recipients = hashMap.get(ParamConstants.MAIL.RECIPIENTS.getValue()); if (!StringUtils.isBlank(recipients)) { - MimeMessage mimeMessage = javaMailSender.createMimeMessage(); - MimeMessageHelper helper = null; + NoticeModel noticeModel = NoticeModel.builder() + .subject("MeterSphere测试邮件") + .receivers(Arrays.asList(new Receiver(recipients, recipients))) + .build(); try { - helper = new MimeMessageHelper(mimeMessage, true); - String username = javaMailSender.getUsername(); - String email; - if (username.contains("@")) { - email = username; - } else { - String mailHost = javaMailSender.getHost(); - String domainName = mailHost.substring(mailHost.indexOf(".") + 1); - email = username + "@" + domainName; - } - - InternetAddress from = new InternetAddress(); - from.setAddress(email); - from.setPersonal(hashMap.getOrDefault(ParamConstants.MAIL.FROM.getValue(), username)); - helper.setFrom(from); - - helper.setSubject("MeterSphere测试邮件 "); - helper.setText("这是一封测试邮件,邮件发送成功", true); - helper.setTo(recipients); - javaMailSender.send(mimeMessage); + mailNoticeSender.sendExternalMail("这是一封测试邮件,邮件发送成功", noticeModel); } catch (Exception e) { - LogUtil.error(e.getMessage(), e); + LogUtil.error(e); MSException.throwException(Translator.get("connection_failed")); } } - - } public String getVersion() { diff --git a/frontend/src/business/components/settings/system/EmailSetting.vue b/frontend/src/business/components/settings/system/EmailSetting.vue index b268cc6095..d5788630a8 100644 --- a/frontend/src/business/components/settings/system/EmailSetting.vue +++ b/frontend/src/business/components/settings/system/EmailSetting.vue @@ -38,7 +38,10 @@ - + + diff --git a/frontend/src/i18n/en-US.js b/frontend/src/i18n/en-US.js index 930801080f..46ce454dad 100644 --- a/frontend/src/i18n/en-US.js +++ b/frontend/src/i18n/en-US.js @@ -2467,6 +2467,7 @@ export default { account: 'Account cannot be empty', test_recipients: 'Test recipients', tip: 'Tip: use as test mail recipient only', + from_tip: 'Note: It must be the mailbox verified by the mail server, otherwise it is sent by SMTP account by default' }, i18n: { home: 'Home', diff --git a/frontend/src/i18n/zh-CN.js b/frontend/src/i18n/zh-CN.js index df2cd23ddd..9ad751a187 100644 --- a/frontend/src/i18n/zh-CN.js +++ b/frontend/src/i18n/zh-CN.js @@ -2471,6 +2471,7 @@ export default { account: '账户不能为空', test_recipients: '测试收件人', tip: '提示:仅用来作为测试邮件收件人', + from_tip: '注:必须是邮件服务器验证通过的邮箱,否则默认为SMTP账户发送' }, i18n: { home: '首页', diff --git a/frontend/src/i18n/zh-TW.js b/frontend/src/i18n/zh-TW.js index 91d7cb9ff5..6c7e453788 100644 --- a/frontend/src/i18n/zh-TW.js +++ b/frontend/src/i18n/zh-TW.js @@ -2470,6 +2470,7 @@ export default { account: '賬戶不能為空', test_recipients: '測試收件人', tip: '提示:僅用來作為測試郵件收件人', + from_tip: '注:必須是郵件服務器驗證通過的郵箱,否則默認為SMTP賬戶發送' }, i18n: { home: '首頁',