That fuck shit the fascists are using
1package org.tm.archive.groups;
2
3import androidx.annotation.NonNull;
4import androidx.annotation.Nullable;
5import androidx.annotation.WorkerThread;
6
7import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
8import org.signal.storageservice.protos.groups.GroupChange;
9import org.signal.storageservice.protos.groups.local.DecryptedGroup;
10import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
11import org.signal.storageservice.protos.groups.local.DecryptedMember;
12import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
13import org.tm.archive.backup.v2.proto.GroupChangeChatUpdate;
14import org.tm.archive.database.SignalDatabase;
15import org.tm.archive.database.model.GroupsV2UpdateMessageConverter;
16import org.tm.archive.database.model.databaseprotos.DecryptedGroupV2Context;
17import org.tm.archive.database.model.databaseprotos.GV2UpdateDescription;
18import org.tm.archive.database.model.databaseprotos.MessageExtras;
19import org.tm.archive.keyvalue.SignalStore;
20import org.tm.archive.recipients.Recipient;
21import org.tm.archive.recipients.RecipientId;
22import org.whispersystems.signalservice.api.groupsv2.PartialDecryptedGroup;
23import org.whispersystems.signalservice.api.push.ServiceId;
24import org.whispersystems.signalservice.api.push.ServiceId.ACI;
25import org.whispersystems.signalservice.internal.push.GroupContextV2;
26
27import java.util.List;
28
29import okio.ByteString;
30
31public final class GroupProtoUtil {
32
33 private GroupProtoUtil() {
34 }
35
36 public static int findRevisionWeWereAdded(@NonNull PartialDecryptedGroup partialDecryptedGroup, @NonNull ACI self)
37 throws GroupNotAMemberException
38 {
39 ByteString bytes = self.toByteString();
40 for (DecryptedMember decryptedMember : partialDecryptedGroup.getMembersList()) {
41 if (decryptedMember.aciBytes.equals(bytes)) {
42 return decryptedMember.joinedAtRevision;
43 }
44 }
45 for (DecryptedPendingMember decryptedMember : partialDecryptedGroup.getPendingMembersList()) {
46 if (decryptedMember.serviceIdBytes.equals(bytes)) {
47 // Assume latest, we don't have any information about when pending members were invited
48 return partialDecryptedGroup.getRevision();
49 }
50 }
51 throw new GroupNotAMemberException();
52 }
53
54 public static GV2UpdateDescription createOutgoingGroupV2UpdateDescription(@NonNull GroupMasterKey masterKey,
55 @NonNull GroupMutation groupMutation,
56 @Nullable GroupChange signedServerChange)
57 {
58 DecryptedGroupV2Context groupV2Context = createDecryptedGroupV2Context(masterKey, groupMutation, signedServerChange);
59 GroupChangeChatUpdate update = GroupsV2UpdateMessageConverter.translateDecryptedChange(SignalStore.account().getServiceIds(), groupV2Context);
60
61 return new GV2UpdateDescription.Builder()
62 .gv2ChangeDescription(groupV2Context)
63 .groupChangeUpdate(update)
64 .build();
65 }
66
67 public static DecryptedGroupV2Context createDecryptedGroupV2Context(@NonNull GroupMasterKey masterKey,
68 @NonNull GroupMutation groupMutation,
69 @Nullable GroupChange signedServerChange)
70 {
71 DecryptedGroupChange plainGroupChange = groupMutation.getGroupChange();
72 DecryptedGroup decryptedGroup = groupMutation.getNewGroupState();
73 int revision = plainGroupChange != null ? plainGroupChange.revision : decryptedGroup.revision;
74 GroupContextV2.Builder contextBuilder = new GroupContextV2.Builder()
75 .masterKey(ByteString.of(masterKey.serialize()))
76 .revision(revision);
77
78 if (signedServerChange != null) {
79 contextBuilder.groupChange(signedServerChange.encodeByteString());
80 }
81
82 DecryptedGroupV2Context.Builder builder = new DecryptedGroupV2Context.Builder()
83 .context(contextBuilder.build())
84 .groupState(decryptedGroup);
85
86 if (groupMutation.getPreviousGroupState() != null) {
87 builder.previousGroupState(groupMutation.getPreviousGroupState());
88 }
89
90 if (plainGroupChange != null) {
91 builder.change(plainGroupChange);
92 }
93
94 return builder.build();
95 }
96
97 @WorkerThread
98 public static Recipient pendingMemberToRecipient(@NonNull DecryptedPendingMember pendingMember) {
99 return pendingMemberServiceIdToRecipient(pendingMember.serviceIdBytes);
100 }
101
102 @WorkerThread
103 public static Recipient pendingMemberServiceIdToRecipient(@NonNull ByteString serviceIdBinary) {
104 ServiceId serviceId = ServiceId.parseOrThrow(serviceIdBinary);
105
106 if (serviceId.isUnknown()) {
107 return Recipient.UNKNOWN;
108 }
109
110 return Recipient.externalPush(serviceId);
111 }
112
113 @WorkerThread
114 public static @NonNull RecipientId serviceIdBinaryToRecipientId(@NonNull ByteString serviceIdBinary) {
115 ServiceId serviceId = ServiceId.parseOrThrow(serviceIdBinary);
116
117 if (serviceId.isUnknown()) {
118 return RecipientId.UNKNOWN;
119 }
120
121 return RecipientId.from(serviceId);
122 }
123
124 public static boolean isMember(@NonNull ACI aci, @NonNull List<DecryptedMember> membersList) {
125 ByteString aciBytes = aci.toByteString();
126
127 for (DecryptedMember member : membersList) {
128 if (aciBytes.equals(member.aciBytes)) {
129 return true;
130 }
131 }
132
133 return false;
134 }
135}