113 lines
4.4 KiB
Java
113 lines
4.4 KiB
Java
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<WrappedMessage> 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();
|
|
}
|
|
}
|