]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/actions/SendRetryMessageRequestAction.java
Rotate profile key after blocking a contact/group
[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.groups.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.SignalServiceProtos;
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 context.getAccount().getSessionStore().archiveSessions(recipientId);
33
34 int senderDevice = protocolException.getSenderDevice();
35 Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(
36 protocolException.getGroupId().get())) : Optional.empty();
37
38 byte[] originalContent;
39 int envelopeType;
40 if (protocolException.getUnidentifiedSenderMessageContent().isPresent()) {
41 final var messageContent = protocolException.getUnidentifiedSenderMessageContent().get();
42 originalContent = messageContent.getContent();
43 envelopeType = messageContent.getType();
44 } else {
45 originalContent = envelope.getContent();
46 envelopeType = 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 return switch (envelopeType) {
59 case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE -> CiphertextMessage.PREKEY_TYPE;
60 case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE -> CiphertextMessage.SENDERKEY_TYPE;
61 case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
62 default -> CiphertextMessage.WHISPER_TYPE;
63 };
64 }
65
66 @Override
67 public boolean equals(final Object o) {
68 if (this == o) return true;
69 if (o == null || getClass() != o.getClass()) return false;
70
71 final SendRetryMessageRequestAction that = (SendRetryMessageRequestAction) o;
72
73 if (!recipientId.equals(that.recipientId)) return false;
74 if (!protocolException.equals(that.protocolException)) return false;
75 return envelope.equals(that.envelope);
76 }
77
78 @Override
79 public int hashCode() {
80 int result = recipientId.hashCode();
81 result = 31 * result + protocolException.hashCode();
82 result = 31 * result + envelope.hashCode();
83 return result;
84 }
85 }