diff --git a/FAQ.md b/FAQ.md index b2a4212e10..8314b42c36 100644 --- a/FAQ.md +++ b/FAQ.md @@ -3419,6 +3419,7 @@ The resend menu item will be shown grayed (dimmed) if the message headers are no Remarks: +* Messages to, CC or BCC *undisclosed-recipients:* cannot be resend * The original subject is sent as-is, unless it is being changed * The original message text will be sent as-is, unless text is being entered * The original attachments are sent as they are, unless attachments are being added or removed diff --git a/app/src/main/java/eu/faircode/email/FragmentMessages.java b/app/src/main/java/eu/faircode/email/FragmentMessages.java index c8b7ff9393..f77313b723 100644 --- a/app/src/main/java/eu/faircode/email/FragmentMessages.java +++ b/app/src/main/java/eu/faircode/email/FragmentMessages.java @@ -238,6 +238,7 @@ import javax.mail.MessageRemovedException; import javax.mail.MessagingException; import javax.mail.Part; import javax.mail.Session; +import javax.mail.internet.AddressException; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; @@ -2790,6 +2791,15 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. } } + boolean canResend = true; + for (Address r : recipients) { + String email = ((InternetAddress) r).getAddress(); + if ("undisclosed-recipients:".equals(email)) { + canResend = false; + break; + } + } + PopupMenuLifecycle popupMenu = new PopupMenuLifecycle(context, getViewLifecycleOwner(), anchor); popupMenu.inflate(R.menu.popup_reply); popupMenu.getMenu().findItem(R.id.menu_reply_to_all).setVisible(recipients.length > 0); @@ -2799,6 +2809,7 @@ public class FragmentMessages extends FragmentBase implements SharedPreferences. popupMenu.getMenu().findItem(R.id.menu_reply_hard_bounce).setEnabled(canBounce); popupMenu.getMenu().findItem(R.id.menu_new_message).setVisible(to != null && to.length > 0); popupMenu.getMenu().findItem(R.id.menu_resend).setVisible(experiments); + popupMenu.getMenu().findItem(R.id.menu_resend).setEnabled(canResend); popupMenu.getMenu().findItem(R.id.menu_reply_answer).setVisible(answers != 0 || !ActivityBilling.isPro(context)); popupMenu.getMenu().findItem(R.id.menu_reply_to_sender).setEnabled(message.content); diff --git a/app/src/main/java/eu/faircode/email/MessageHelper.java b/app/src/main/java/eu/faircode/email/MessageHelper.java index 49e19b235b..70634b1ff7 100644 --- a/app/src/main/java/eu/faircode/email/MessageHelper.java +++ b/app/src/main/java/eu/faircode/email/MessageHelper.java @@ -318,46 +318,49 @@ public class MessageHelper { ByteArrayInputStream bis = new ByteArrayInputStream(message.headers.getBytes()); List
headers = Collections.list(new InternetHeaders(bis).getAllHeaders()); - for (Header header : headers) { - String name = header.getName(); - String value = header.getValue(); - if (name == null || TextUtils.isEmpty(value)) - continue; + for (Header header : headers) + try { + String name = header.getName(); + String value = header.getValue(); + if (name == null || TextUtils.isEmpty(value)) + continue; - switch (name.toLowerCase(Locale.ROOT)) { - case "date": - imessage.setHeader("Date", value); - break; - case "from": - imessage.setFrom(value); - break; - case "to": - imessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(value)); - break; - case "cc": - imessage.setRecipients(Message.RecipientType.CC, InternetAddress.parse(value)); - break; - case "bcc": - imessage.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(value)); - break; - case "reply-to": - imessage.setReplyTo(InternetAddress.parse(value)); - break; - case "message-id": - if (send) { - imessage.setHeader("Resent-Message-ID", message.msgid); - imessage.updateMessageID(value); - } - break; - case "references": - imessage.setHeader("References", value); - break; - case "in-reply-to": - imessage.setHeader("In-Reply-To", value); - break; - // Resent-Sender (=on behalf of) + switch (name.toLowerCase(Locale.ROOT)) { + case "date": + imessage.setHeader("Date", value); + break; + case "from": + imessage.setFrom(value); + break; + case "to": + imessage.setRecipients(Message.RecipientType.TO, InternetAddress.parse(value)); + break; + case "cc": + imessage.setRecipients(Message.RecipientType.CC, InternetAddress.parse(value)); + break; + case "bcc": + imessage.setRecipients(Message.RecipientType.BCC, InternetAddress.parse(value)); + break; + case "reply-to": + imessage.setReplyTo(InternetAddress.parse(value)); + break; + case "message-id": + if (send) { + imessage.setHeader("Resent-Message-ID", message.msgid); + imessage.updateMessageID(value); + } + break; + case "references": + imessage.setHeader("References", value); + break; + case "in-reply-to": + imessage.setHeader("In-Reply-To", value); + break; + // Resent-Sender (=on behalf of) + } + } catch (Throwable ex) { + Log.e(ex); } - } // The "Resent-Date:" indicates the date and time at which the resent // message is dispatched by the resender of the message.