package io.gitlab.jfronny.gitea.helpdesk.mail; import com.sun.mail.pop3.POP3Store; import io.gitlab.jfronny.gitea.helpdesk.Config; import jakarta.mail.*; import jakarta.mail.internet.*; import org.jsoup.Jsoup; import java.util.*; import java.util.stream.Collectors; public class MailInterface implements AutoCloseable { private final Config.EMail config; private final Session pop3; private final Session smtp; private POP3Store lastPop3; public MailInterface(Config.EMail config) { this.config = config; { Properties properties = new Properties(); String[] splitHost = config.pop3.host.split(":"); if (splitHost.length == 1) { properties.put("mail.pop3.host", config.pop3.host); } else { properties.put("mail.pop3.host", splitHost[0]); properties.put("mail.pop3.port", Integer.parseInt(splitHost[1])); } if (config.pop3.ssl) properties.put("mail.pop3.ssl.enable", true); this.pop3 = Session.getInstance(properties); } { Properties properties = new Properties(); String[] splitHost = config.smtp.host.split(":"); if (splitHost.length == 1) { properties.put("mail.smtp.host", config.smtp.host); } else { properties.put("mail.smtp.host", splitHost[0]); properties.put("mail.smtp.port", Integer.parseInt(splitHost[1])); } if (config.smtp.ssl) properties.put("mail.smtp.ssl.enable", true); properties.put("mail.smtp.auth", true); this.smtp = Session.getInstance(properties); } } private POP3Store getStore() throws MessagingException { boolean reopen = lastPop3 == null; if (lastPop3 != null && !lastPop3.isConnected()) { lastPop3.close(); reopen = true; } if (reopen) { lastPop3 = (POP3Store) pop3.getStore("pop3"); lastPop3.connect(config.address, config.pop3.password); } return lastPop3; } public Set getInbox() throws MessagingException { try (Folder inbox = getStore().getFolder("INBOX")) { inbox.open(Folder.READ_ONLY); return Arrays.stream(inbox.getMessages()) .map(s -> new WrappedMessage((MimeMessage) s, config.address, this)) .collect(Collectors.toSet()); } } public void reply(String from, String to, String content, String subject, String previousMessageId, String previousReferences, String previousInReplyTo) throws MessagingException { MimeMessage reply = new MimeMessage(smtp); reply.setFrom(from); reply.addRecipients(Message.RecipientType.TO, to); reply.setSubject(subject.startsWith("Re: ") ? subject : "Re: " + subject); final MimeBodyPart textPart = new MimeBodyPart(); textPart.setContent(Jsoup.parse(content).text(), "text/plain"); final MimeBodyPart htmlPart = new MimeBodyPart(); htmlPart.setContent(content, "text/html"); final MimeMultipart mp = new MimeMultipart("alternative"); mp.addBodyPart(textPart); mp.addBodyPart(htmlPart); reply.setContent(mp); if (previousMessageId != null) reply.setHeader("In-Reply-To", previousMessageId); if (previousReferences == null) previousReferences = previousInReplyTo; if (previousMessageId != null) { if (previousReferences != null) previousReferences = MimeUtility.unfold(previousReferences) + " " + previousMessageId; else previousReferences = previousMessageId; } if (previousReferences != null) reply.setHeader("References", MimeUtility.fold(12, previousReferences)); send(reply); } public void send(Message message) throws MessagingException { Address[] recipients = message.getAllRecipients(); if (recipients.length != 1) throw new MessagingException("Unexpected number of recipients: " + recipients.length); try (Transport transport = smtp.getTransport(recipients[0])) { transport.connect(config.address, config.smtp.password); transport.sendMessage(message, recipients); } } public String getAddress() { return config.address; } @Override public void close() throws MessagingException { if (lastPop3 != null) lastPop3.close(); } }