diff --git a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java index 2c05fbfdc9e278a7d6d1c481179fe4c4930aac4a..1f9903acf6b82b1ac579e1e6aa82ca9cbaed1c42 100644 --- a/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java +++ b/src/main/java/eu/siacs/conversations/crypto/axolotl/AxolotlService.java @@ -1176,28 +1176,45 @@ public class AxolotlService implements OnAdvancedStreamFeaturesLoaded { } @Nullable - public XmppAxolotlMessage encrypt(Message message) { + public XmppAxolotlMessage encrypt(final String content, Jid counterpart) { final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().asBareJid(), getOwnDeviceId()); - final String content; - if (message.hasFileOnRemoteHost()) { - content = message.getFileParams().url; - } else { - content = message.getRawBody(); + try { + axolotlMessage.encrypt(content); + } catch (CryptoFailedException e) { + Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage()); + return null; } + if (!buildHeader(axolotlMessage, counterpart)) return null; + return axolotlMessage; + } + + @Nullable + public XmppAxolotlMessage encrypt(final String content, Conversation conversation) { + final XmppAxolotlMessage axolotlMessage = new XmppAxolotlMessage(account.getJid().asBareJid(), getOwnDeviceId()); try { axolotlMessage.encrypt(content); } catch (CryptoFailedException e) { Log.w(Config.LOGTAG, getLogprefix(account) + "Failed to encrypt message: " + e.getMessage()); return null; } + if (!buildHeader(axolotlMessage, conversation)) return null; + return axolotlMessage; + } + + @Nullable + public XmppAxolotlMessage encrypt(Message message) { + final String content; + if (message.hasFileOnRemoteHost()) { + content = message.getFileParams().url; + } else { + content = message.getRawBody(); + } - final boolean success; if (message.isPrivateMessage()) { - success = buildHeader(axolotlMessage, message.getTrueCounterpart()); + return encrypt(content, message.getTrueCounterpart()); } else { - success = buildHeader(axolotlMessage, (Conversation) message.getConversation()); + return encrypt(content, (Conversation) message.getConversation()); } - return success ? axolotlMessage : null; } public void preparePayloadMessage(final Message message, final boolean delay) { diff --git a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java index 2a1b99ec519b749bb0ea4f7a2cd732af14682e74..e591fa4ed23bd7a9bb930d7c0ca32104f9ff9c37 100644 --- a/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java +++ b/src/main/java/eu/siacs/conversations/generator/MessageGenerator.java @@ -14,8 +14,6 @@ import eu.siacs.conversations.entities.Account; import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Conversational; import eu.siacs.conversations.entities.Message; -import eu.siacs.conversations.ui.util.QuoteHelper; -import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.xml.Element; import eu.siacs.conversations.xml.Namespace; @@ -202,7 +200,7 @@ public class MessageGenerator extends AbstractGenerator { return packet; } - public im.conversations.android.xmpp.model.stanza.Message reaction(final Conversational conversation, final Message inReplyTo, final String reactingTo, final Collection ourReactions, final Collection newReactions) { + public im.conversations.android.xmpp.model.stanza.Message reaction(final Conversational conversation, final Message inReplyTo, final String reactingTo, final Collection ourReactions) { final boolean groupChat = conversation.getMode() == Conversational.MODE_MULTI; final Jid to = conversation.getJid().asBareJid(); final im.conversations.android.xmpp.model.stanza.Message packet = new im.conversations.android.xmpp.model.stanza.Message(); @@ -214,23 +212,6 @@ public class MessageGenerator extends AbstractGenerator { reactions.addExtension(new Reaction(ourReaction)); } - if (newReactions.size() > 0) { - final var quote = QuoteHelper.quote(MessageUtils.prepareQuote(inReplyTo)) + "\n"; - packet.setBody(quote + String.join(" ", newReactions)); - - packet.addChild("reply", "urn:xmpp:reply:0") - .setAttribute("to", inReplyTo.getCounterpart()) - .setAttribute("id", reactingTo); - final var replyFallback = packet.addChild("fallback", "urn:xmpp:fallback:0").setAttribute("for", "urn:xmpp:reply:0"); - replyFallback.addChild("body", "urn:xmpp:fallback:0") - .setAttribute("start", "0") - .setAttribute("end", "" + quote.codePointCount(0, quote.length())); - - - final var fallback = packet.addChild("fallback", "urn:xmpp:fallback:0").setAttribute("for", "urn:xmpp:reactions:0"); - fallback.addChild("body", "urn:xmpp:fallback:0"); - } - final var thread = inReplyTo.getThread(); if (thread != null) packet.addChild(thread); diff --git a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java index 5aafa03e5269b7d005ea5308ec0e3b6c1adbe85d..ba8b4baf34c801418f8e439c3fa74a214578415a 100644 --- a/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java +++ b/src/main/java/eu/siacs/conversations/services/XmppConnectionService.java @@ -158,6 +158,7 @@ import eu.siacs.conversations.ui.UiCallback; import eu.siacs.conversations.ui.interfaces.OnAvatarPublication; import eu.siacs.conversations.ui.interfaces.OnMediaLoaded; import eu.siacs.conversations.ui.interfaces.OnSearchResultsAvailable; +import eu.siacs.conversations.ui.util.QuoteHelper; import eu.siacs.conversations.utils.AccountUtils; import eu.siacs.conversations.utils.Compatibility; import eu.siacs.conversations.utils.ConversationsFileObserver; @@ -166,6 +167,7 @@ import eu.siacs.conversations.utils.Emoticons; import eu.siacs.conversations.utils.EasyOnboardingInvite; import eu.siacs.conversations.utils.ExceptionHelper; import eu.siacs.conversations.utils.FileUtils; +import eu.siacs.conversations.utils.MessageUtils; import eu.siacs.conversations.utils.MimeUtils; import eu.siacs.conversations.utils.PhoneHelper; import eu.siacs.conversations.utils.QuickLoader; @@ -5307,11 +5309,43 @@ public class XmppConnectionService extends Service { if (Strings.isNullOrEmpty(reactToId)) { return false; } - final var reactionMessage = - mMessageGenerator.reaction(conversation, message, reactToId, reactions, newReactions); - sendMessagePacket(conversation.getAccount(), reactionMessage); - message.setReactions(combinedReactions); - updateMessage(message, false); + final var packet = + mMessageGenerator.reaction(conversation, message, reactToId, reactions); + + final var quote = QuoteHelper.quote(MessageUtils.prepareQuote(message)) + "\n"; + final var body = quote + String.join(" ", newReactions); + if (conversation.getNextEncryption() == Message.ENCRYPTION_AXOLOTL && newReactions.size() > 0) { + FILE_ATTACHMENT_EXECUTOR.execute(() -> { + XmppAxolotlMessage axolotlMessage = conversation.getAccount().getAxolotlService().encrypt(body, conversation); + packet.setAxolotlMessage(axolotlMessage.toElement()); + packet.addChild("encryption", "urn:xmpp:eme:0") + .setAttribute("name", "OMEMO") + .setAttribute("namespace", AxolotlService.PEP_PREFIX); + sendMessagePacket(conversation.getAccount(), packet); + message.setReactions(combinedReactions); + updateMessage(message, false); + }); + } else if (conversation.getNextEncryption() == Message.ENCRYPTION_NONE || newReactions.size() < 1) { + if (newReactions.size() > 0) { + packet.setBody(body); + + packet.addChild("reply", "urn:xmpp:reply:0") + .setAttribute("to", message.getCounterpart()) + .setAttribute("id", reactToId); + final var replyFallback = packet.addChild("fallback", "urn:xmpp:fallback:0").setAttribute("for", "urn:xmpp:reply:0"); + replyFallback.addChild("body", "urn:xmpp:fallback:0") + .setAttribute("start", "0") + .setAttribute("end", "" + quote.codePointCount(0, quote.length())); + + final var fallback = packet.addChild("fallback", "urn:xmpp:fallback:0").setAttribute("for", "urn:xmpp:reactions:0"); + fallback.addChild("body", "urn:xmpp:fallback:0"); + } + + sendMessagePacket(conversation.getAccount(), packet); + message.setReactions(combinedReactions); + updateMessage(message, false); + } + return true; } else { return false;