package io.gitlab.jfronny.gitea.helpdesk.mail; import io.gitlab.jfronny.gitea.helpdesk.UnexpectedMailException; import jakarta.mail.*; import jakarta.mail.internet.*; import java.io.IOException; import java.util.LinkedHashSet; import java.util.Set; public class WrappedMessage { public final MimeMessage message; private final String[] selfParts; private final MailInterface mail; public WrappedMessage(MimeMessage message, String selfAddress, MailInterface mail) { this.message = message; this.selfParts = selfAddress.split("@"); this.mail = mail; } public String getRecipientSubAddress() throws MessagingException, UnexpectedMailException { for (Address recipient : message.getAllRecipients()) { String[] parts = recipient.toString().split("@"); if (parts.length != 2) throw new UnexpectedMailException("Invalid recipient"); if (!parts[1].equals(selfParts[1])) continue; if (!parts[0].startsWith(selfParts[0] + "+")) continue; return parts[0].substring(selfParts[0].length() + 1); } throw new UnexpectedMailException("Lacking proper recipient"); } public String getText() throws MessagingException, IOException { return getText(message); } static String getText(Part p) throws MessagingException, IOException { if (p.isMimeType("text/*")) { String s = (String)p.getContent(); // p.isMimeType("text/html") ? Jsoup.parse(s).text() : s //TODO ensure this works return s; } if (p.isMimeType("multipart/alternative")) { // prefer html text over plain text Multipart mp = (Multipart)p.getContent(); String text = null; for (int i = 0; i < mp.getCount(); i++) { Part bp = mp.getBodyPart(i); if (bp.isMimeType("text/plain")) { if (text == null) text = getText(bp); } else if (bp.isMimeType("text/html")) { String s = getText(bp); if (s != null) return s; } else return getText(bp); } return text; } else if (p.isMimeType("multipart/*")) { Multipart mp = (Multipart)p.getContent(); for (int i = 0; i < mp.getCount(); i++) { String s = getText(mp.getBodyPart(i)); if (s != null) return s; } } return null; } public Set getAttachments() throws MessagingException, IOException { if (message.isMimeType("multipart/*")) { Multipart mp = (Multipart) message.getContent(); Set attachments = new LinkedHashSet<>(); for (int i = 0; i < mp.getCount(); i++) { MimeBodyPart part = (MimeBodyPart) mp.getBodyPart(i); if (Part.ATTACHMENT.equalsIgnoreCase(part.getDisposition())) { attachments.add(new Attachment(part.getFileName(), part::getInputStream)); } } return Set.copyOf(attachments); } else return Set.of(); } public String getSubject() throws MessagingException { return message.getSubject(); } public String getSender() throws MessagingException { return message.getFrom()[0].toString(); } public String getSenderName() throws MessagingException { if (message.getFrom()[0] instanceof InternetAddress addr) { return addr.getPersonal(); } return "Sender Suppressed"; } public void reply(String from, String content) throws MessagingException { mail.reply( from, getSender(), content, getSubject(), message.getHeader("Message-Id", null), message.getHeader("References", " "), message.getHeader("In-Reply-To", "") ); } }