Skip to content

Commit

Permalink
Fixed forwarding messages.| #74
Browse files Browse the repository at this point in the history
  • Loading branch information
DenBond7 committed Nov 13, 2024
1 parent 1771d28 commit 5acf449
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 22 deletions.
106 changes: 95 additions & 11 deletions FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ import jakarta.mail.internet.InternetAddress
import jakarta.mail.internet.MimeBodyPart
import jakarta.mail.internet.MimeMessage
import jakarta.mail.internet.MimeMultipart
import jakarta.mail.internet.MimeUtility
import jakarta.mail.search.AndTerm
import jakarta.mail.search.BodyTerm
import jakarta.mail.search.FromStringTerm
Expand Down Expand Up @@ -693,7 +694,7 @@ class EmailUtil {
}

return@withContext when (outgoingMsgInfo.messageType) {
MessageType.NEW, MessageType.FORWARD, MessageType.DRAFT -> {
MessageType.NEW, MessageType.DRAFT -> {
prepareNewMsg(
session = session,
info = outgoingMsgInfo,
Expand All @@ -719,6 +720,20 @@ class EmailUtil {
)
}

MessageType.FORWARD -> {
prepareForwardedMsg(
context = context,
accountEntity = accountEntity,
session = session,
info = outgoingMsgInfo,
pubKeys = pubKeys,
protectedPubKeys = protectedPubKeys,
prvKeys = prvKeys,
protector = ringProtector,
hideArmorMeta = hideArmorMeta
)
}

else -> throw IllegalStateException("Unsupported message type")
}
}
Expand Down Expand Up @@ -1018,6 +1033,65 @@ class EmailUtil {
return@withContext msg
}

private suspend fun prepareForwardedMsg(
context: Context,
accountEntity: AccountEntity,
session: Session,
info: OutgoingMessageInfo,
pubKeys: List<String>? = null,
protectedPubKeys: List<String>? = null,
prvKeys: List<String>? = null,
protector: SecretKeyRingProtector? = null,
hideArmorMeta: Boolean = false,
): MimeMessage = withContext(Dispatchers.IO) {
val replyToMimeMessage = getReplyToMimeMessage(context, accountEntity, session, info)
return@withContext prepareNewMsg(
session = session,
info = info,
pubKeys = pubKeys,
protectedPubKeys = protectedPubKeys,
prvKeys = prvKeys,
protector = protector,
hideArmorMeta = hideArmorMeta
).apply {
//based on [MimeMessage.reply()]
val msgId = replyToMimeMessage.messageID
if (msgId != null) {
setHeader(JavaEmailConstants.HEADER_IN_REPLY_TO, msgId)
}

/*
* Set the References header as described in RFC 2822:
*
* The "References:" field will contain the contents of the parent's
* "References:" field (if any) followed by the contents of the parent's
* "Message-ID:" field (if any). If the parent message does not contain
* a "References:" field but does have an "In-Reply-To:" field
* containing a single message identifier, then the "References:" field
* will contain the contents of the parent's "In-Reply-To:" field
* followed by the contents of the parent's "Message-ID:" field (if
* any). If the parent has none of the "References:", "In-Reply-To:",
* or "Message-ID:" fields, then the new message will have no
* "References:" field.
*/
var refs = getHeader(JavaEmailConstants.HEADER_REFERENCES, " ")
if (refs == null) {
// XXX - should only use if it contains a single message identifier
refs = getHeader(JavaEmailConstants.HEADER_IN_REPLY_TO, " ")
}
if (msgId != null) {
refs = if (refs != null) {
MimeUtility.unfold(refs) + " " + msgId
} else {
msgId
}
}
if (refs != null) {
setHeader(JavaEmailConstants.HEADER_REFERENCES, MimeUtility.fold(12, refs))
}
}
}

fun genReplyMessage(
replyToMsg: MimeMessage,
info: OutgoingMessageInfo,
Expand Down Expand Up @@ -1166,6 +1240,25 @@ class EmailUtil {
protector: SecretKeyRingProtector? = null,
hideArmorMeta: Boolean = false,
): Message = withContext(Dispatchers.IO) {
val replyToMimeMessage = getReplyToMimeMessage(context, accountEntity, session, info)

return@withContext genReplyMessage(
replyToMsg = replyToMimeMessage,
info = info,
pubKeys = pubKeys,
protectedPubKeys = protectedPubKeys,
prvKeys = prvKeys,
protector = protector,
hideArmorMeta = hideArmorMeta
)
}

private suspend fun getReplyToMimeMessage(
context: Context,
accountEntity: AccountEntity,
session: Session,
info: OutgoingMessageInfo,
): MimeMessage {
val replyToMessageEntityId = info.replyToMessageEntityId
?: throw IllegalArgumentException("replyToMessageEntityId is null")

Expand All @@ -1190,16 +1283,7 @@ class EmailUtil {
Passphrase.fromPassword(accountEntity.servicePgpPassphrase)
)
)

return@withContext genReplyMessage(
replyToMsg = FlowCryptMimeMessage(session, decryptionStream),
info = info,
pubKeys = pubKeys,
protectedPubKeys = protectedPubKeys,
prvKeys = prvKeys,
protector = protector,
hideArmorMeta = hideArmorMeta
)
return FlowCryptMimeMessage(session, decryptionStream)
}

private fun prepareBodyPart(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import com.flowcrypt.email.util.exception.ForceHandlingException
import com.google.android.gms.auth.UserRecoverableAuthException
import com.google.android.gms.common.util.CollectionUtils
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException
import com.google.api.client.googleapis.json.GoogleJsonResponseException
import com.google.api.client.http.FileContent
import com.google.api.services.gmail.model.Draft
import jakarta.mail.AuthenticationFailedException
Expand Down Expand Up @@ -481,17 +482,34 @@ class MessagesSenderWorker(context: Context, params: WorkerParameters) :
.send(GmailApiHelper.DEFAULT_USER_ID, gmailMsg, mediaContent)
.execute()
} else {
gmail
.users()
.drafts()
.send(
GmailApiHelper.DEFAULT_USER_ID,
Draft().apply {
message = gmailMsg
id = msgEntity.draftId
},
mediaContent
).execute()
try {
gmail
.users()
.drafts()
.send(
GmailApiHelper.DEFAULT_USER_ID,
Draft().apply {
message = gmailMsg
id = msgEntity.draftId
},
mediaContent
).execute()
} catch (e: GoogleJsonResponseException) {
val isDraftNotFound = e.details.errors.any {
it.message == "Requested entity was not found."
}

if (isDraftNotFound) {
//try to send via messages().send()
gmail
.users()
.messages()
.send(GmailApiHelper.DEFAULT_USER_ID, gmailMsg, mediaContent)
.execute()
} else {
throw e
}
}
}

if (gmailMsg.id == null) {
Expand Down

0 comments on commit 5acf449

Please sign in to comment.