]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/actions/SendRetryMessageRequestAction.java
add09e72efd44515cd78f2080c59de868c754a11
[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 private final ServiceId accountId;
22
23 public SendRetryMessageRequestAction(
24 final RecipientId recipientId,
25 final ServiceId serviceId,
26 final ProtocolException protocolException,
27 final SignalServiceEnvelope envelope,
28 final ServiceId accountId
29 ) {
30 this.recipientId = recipientId;
31 this.serviceId = serviceId;
32 this.protocolException = protocolException;
33 this.envelope = envelope;
34 this.accountId = accountId;
35 }
36
37 @Override
38 public void execute(Context context) throws Throwable {
39 context.getAccount().getAccountData(accountId).getSessionStore().archiveSessions(serviceId);
40
41 int senderDevice = protocolException.getSenderDevice();
42 Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(
43 protocolException.getGroupId().get())) : Optional.empty();
44
45 byte[] originalContent;
46 int envelopeType;
47 if (protocolException.getUnidentifiedSenderMessageContent().isPresent()) {
48 final var messageContent = protocolException.getUnidentifiedSenderMessageContent().get();
49 originalContent = messageContent.getContent();
50 envelopeType = messageContent.getType();
51 } else {
52 originalContent = envelope.getContent();
53 envelopeType = envelopeTypeToCiphertextMessageType(envelope.getType());
54 }
55
56 DecryptionErrorMessage decryptionErrorMessage = DecryptionErrorMessage.forOriginalMessage(originalContent,
57 envelopeType,
58 envelope.getTimestamp(),
59 senderDevice);
60
61 context.getSendHelper().sendRetryReceipt(decryptionErrorMessage, recipientId, groupId);
62 }
63
64 private static int envelopeTypeToCiphertextMessageType(int envelopeType) {
65 return switch (envelopeType) {
66 case SignalServiceProtos.Envelope.Type.PREKEY_BUNDLE_VALUE -> CiphertextMessage.PREKEY_TYPE;
67 case SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER_VALUE -> CiphertextMessage.SENDERKEY_TYPE;
68 case SignalServiceProtos.Envelope.Type.PLAINTEXT_CONTENT_VALUE -> CiphertextMessage.PLAINTEXT_CONTENT_TYPE;
69 default -> CiphertextMessage.WHISPER_TYPE;
70 };
71 }
72
73 @Override
74 public boolean equals(final Object o) {
75 if (this == o) return true;
76 if (o == null || getClass() != o.getClass()) return false;
77
78 final SendRetryMessageRequestAction that = (SendRetryMessageRequestAction) o;
79
80 if (!recipientId.equals(that.recipientId)) return false;
81 if (!protocolException.equals(that.protocolException)) return false;
82 return envelope.equals(that.envelope);
83 }
84
85 @Override
86 public int hashCode() {
87 int result = recipientId.hashCode();
88 result = 31 * result + protocolException.hashCode();
89 result = 31 * result + envelope.hashCode();
90 return result;
91 }
92 }