]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/actions/SendRetryMessageRequestAction.java
Always renew session when failing to decrypt message
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / actions / SendRetryMessageRequestAction.java
1 package org.asamk.signal.manager.actions;
2
3 import org.asamk.signal.manager.api.GroupId;
4 import org.asamk.signal.manager.helper.Context;
5 import org.asamk.signal.manager.storage.recipients.RecipientId;
6 import org.signal.libsignal.metadata.ProtocolException;
7 import org.signal.libsignal.protocol.message.CiphertextMessage;
8 import org.signal.libsignal.protocol.message.DecryptionErrorMessage;
9 import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
10 import org.whispersystems.signalservice.internal.push.Envelope;
11
12 import java.util.Optional;
13
14 public class SendRetryMessageRequestAction implements HandleAction {
15
16 private final RecipientId recipientId;
17 private final ProtocolException protocolException;
18 private final SignalServiceEnvelope envelope;
19
20 public SendRetryMessageRequestAction(
21 final RecipientId recipientId,
22 final ProtocolException protocolException,
23 final SignalServiceEnvelope envelope
24 ) {
25 this.recipientId = recipientId;
26 this.protocolException = protocolException;
27 this.envelope = envelope;
28 }
29
30 @Override
31 public void execute(Context context) throws Throwable {
32 int senderDevice = protocolException.getSenderDevice();
33 Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(
34 protocolException.getGroupId().get())) : Optional.empty();
35
36 byte[] originalContent;
37 int envelopeType;
38 if (protocolException.getUnidentifiedSenderMessageContent().isPresent()) {
39 final var messageContent = protocolException.getUnidentifiedSenderMessageContent().get();
40 originalContent = messageContent.getContent();
41 envelopeType = messageContent.getType();
42 } else {
43 originalContent = envelope.getContent();
44 envelopeType = envelope.getType() == null
45 ? CiphertextMessage.WHISPER_TYPE
46 : envelopeTypeToCiphertextMessageType(envelope.getType());
47 }
48
49 DecryptionErrorMessage decryptionErrorMessage = DecryptionErrorMessage.forOriginalMessage(originalContent,
50 envelopeType,
51 envelope.getTimestamp(),
52 senderDevice);
53
54 context.getSendHelper().sendRetryReceipt(decryptionErrorMessage, recipientId, groupId);
55 }
56
57 private static int envelopeTypeToCiphertextMessageType(int envelopeType) {
58 final var type = Envelope.Type.fromValue(envelopeType);
59 if (type == null) {
60 return CiphertextMessage.WHISPER_TYPE;
61 }
62 return switch (type) {
63 case PREKEY_BUNDLE -> CiphertextMessage.PREKEY_TYPE;
64 case UNIDENTIFIED_SENDER -> CiphertextMessage.SENDERKEY_TYPE;
65 case PLAINTEXT_CONTENT -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
66 default -> CiphertextMessage.WHISPER_TYPE;
67 };
68 }
69
70 @Override
71 public boolean equals(final Object o) {
72 if (this == o) return true;
73 if (o == null || getClass() != o.getClass()) return false;
74
75 final SendRetryMessageRequestAction that = (SendRetryMessageRequestAction) o;
76
77 if (!recipientId.equals(that.recipientId)) return false;
78 if (!protocolException.equals(that.protocolException)) return false;
79 return envelope.equals(that.envelope);
80 }
81
82 @Override
83 public int hashCode() {
84 int result = recipientId.hashCode();
85 result = 31 * result + protocolException.hashCode();
86 result = 31 * result + envelope.hashCode();
87 return result;
88 }
89 }