]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/actions/SendRetryMessageRequestAction.java
2300eae9d39c864cad97fb0e2b053aa7e638de3a
[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.api.push.ServiceId;
11 import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
12
13 import java.util.Optional;
14
15 public class SendRetryMessageRequestAction implements HandleAction {
16
17 private final RecipientId recipientId;
18 private final ServiceId serviceId;
19 private final ProtocolException protocolException;
20 private final SignalServiceEnvelope envelope;
21
22 public SendRetryMessageRequestAction(
23 final RecipientId recipientId,
24 final ServiceId serviceId,
25 final ProtocolException protocolException,
26 final SignalServiceEnvelope envelope
27 ) {
28 this.recipientId = recipientId;
29 this.serviceId = serviceId;
30 this.protocolException = protocolException;
31 this.envelope = envelope;
32 }
33
34 @Override
35 public void execute(Context context) throws Throwable {
36 context.getAccount().getAciSessionStore().archiveSessions(serviceId);
37
38 int senderDevice = protocolException.getSenderDevice();
39 Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(
40 protocolException.getGroupId().get())) : Optional.empty();
41
42 byte[] originalContent;
43 int envelopeType;
44 if (protocolException.getUnidentifiedSenderMessageContent().isPresent()) {
45 final var messageContent = protocolException.getUnidentifiedSenderMessageContent().get();
46 originalContent = messageContent.getContent();
47 envelopeType = messageContent.getType();
48 } else {
49 originalContent = envelope.getContent();
50 envelopeType = envelopeTypeToCiphertextMessageType(envelope.getType());
51 }
52
53 DecryptionErrorMessage decryptionErrorMessage = DecryptionErrorMessage.forOriginalMessage(originalContent,
54 envelopeType,
55 envelope.getTimestamp(),
56 senderDevice);
57
58 context.getSendHelper().sendRetryReceipt(decryptionErrorMessage, recipientId, groupId);
59 }
60
61 private static int envelopeTypeToCiphertextMessageType(int envelopeType) {
62 return switch (envelopeType) {
63 case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE -> CiphertextMessage.PREKEY_TYPE;
64 case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE -> CiphertextMessage.SENDERKEY_TYPE;
65 case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE -> 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 }