]> nmode's Git Repositories - signal-cli/commitdiff
Update libsignal-service
authorAsamK <asamk@gmx.de>
Thu, 25 Jul 2024 14:24:41 +0000 (16:24 +0200)
committerAsamK <asamk@gmx.de>
Thu, 25 Jul 2024 14:27:24 +0000 (16:27 +0200)
graalvm-config-dir/jni-config.json
lib/src/main/java/org/asamk/signal/manager/api/ProofRequiredException.java
lib/src/main/java/org/asamk/signal/manager/config/ServiceConfig.java
lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java
lib/src/main/java/org/asamk/signal/manager/helper/ProfileHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java
lib/src/main/java/org/asamk/signal/manager/helper/UnidentifiedAccessHelper.java
settings.gradle.kts
src/main/java/org/asamk/signal/BaseConfig.java

index 4050838c44c9d686ecf99af96722c506bd3974a7..381dca9ee90a88d7586289147a294d5ffbce6759 100644 (file)
@@ -1,7 +1,13 @@
 [
+{
+  "name":"[B"
+},
 {
   "name":"[Z"
 },
+{
+  "name":"[[B"
+},
 {
   "name":"com.sun.security.auth.module.UnixSystem",
   "fields":[{"name":"gid"}, {"name":"groups"}, {"name":"uid"}, {"name":"username"}]
index 277406cbc616defa30beef1b0693ebcbfcda0482..21b4034d1f08dbcab4f28f57e06fb0ce1c4d6005 100644 (file)
@@ -36,7 +36,6 @@ public class ProofRequiredException extends Exception {
 
         static Option from(org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException.Option option) {
             return switch (option) {
-                case RECAPTCHA -> CAPTCHA;
                 case CAPTCHA -> CAPTCHA;
                 case PUSH_CHALLENGE -> PUSH_CHALLENGE;
             };
index e827e3f559de34f4873358eb44346a1d155a182d..62aedaf6e599712bbcb1c2d18380a5ac0b29b121 100644 (file)
@@ -27,19 +27,8 @@ public class ServiceConfig {
     public static final long UNREGISTERED_LIFESPAN = TimeUnit.DAYS.toMillis(30);
 
     public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) {
-        final var giftBadges = !isPrimaryDevice;
-        final var pni = !isPrimaryDevice;
-        final var paymentActivation = !isPrimaryDevice;
         final var deleteSync = !isPrimaryDevice;
-        return new AccountAttributes.Capabilities(true,
-                true,
-                true,
-                true,
-                true,
-                giftBadges,
-                pni,
-                paymentActivation,
-                deleteSync);
+        return new AccountAttributes.Capabilities(true, deleteSync);
     }
 
     public static ServiceEnvironmentConfig getServiceEnvironmentConfig(
index 7cc9fef8f47465c6ddffdc4934d21673d9e96d50..62291a3ab36d74c44eac3378f660ff1e4320cd20 100644 (file)
@@ -33,13 +33,16 @@ import org.signal.libsignal.zkgroup.groups.GroupMasterKey;
 import org.signal.libsignal.zkgroup.groups.GroupSecretParams;
 import org.signal.libsignal.zkgroup.profiles.ProfileKey;
 import org.signal.storageservice.protos.groups.GroupChange;
+import org.signal.storageservice.protos.groups.GroupChangeResponse;
 import org.signal.storageservice.protos.groups.local.DecryptedGroup;
 import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
 import org.signal.storageservice.protos.groups.local.DecryptedGroupJoinInfo;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupChangeLog;
+import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupResponse;
 import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
+import org.whispersystems.signalservice.api.groupsv2.ReceivedGroupSendEndorsements;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
 import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
 import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
@@ -133,9 +136,10 @@ public class GroupHelper {
             }
             if (group == null) {
                 try {
-                    group = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
+                    final var response = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
 
-                    if (group != null) {
+                    if (response != null) {
+                        group = handleDecryptedGroupResponse(groupInfoV2, response);
                         storeProfileKeysFromHistory(groupSecretParams, groupInfoV2, group);
                     }
                 } catch (NotAGroupMemberException ignored) {
@@ -156,6 +160,35 @@ public class GroupHelper {
         return groupInfoV2;
     }
 
+    private DecryptedGroup handleDecryptedGroupResponse(
+            GroupInfoV2 groupInfoV2, final DecryptedGroupResponse decryptedGroupResponse
+    ) {
+        final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
+        ReceivedGroupSendEndorsements groupSendEndorsements = dependencies.getGroupsV2Operations()
+                .forGroup(groupSecretParams)
+                .receiveGroupSendEndorsements(account.getAci(),
+                        decryptedGroupResponse.getGroup(),
+                        decryptedGroupResponse.getGroupSendEndorsementsResponse());
+
+        // TODO save group endorsements
+
+        return decryptedGroupResponse.getGroup();
+    }
+
+    private GroupChange handleGroupChangeResponse(
+            final GroupInfoV2 groupInfoV2, final GroupChangeResponse groupChangeResponse
+    ) {
+        ReceivedGroupSendEndorsements groupSendEndorsements = dependencies.getGroupsV2Operations()
+                .forGroup(GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey()))
+                .receiveGroupSendEndorsements(account.getAci(),
+                        groupInfoV2.getGroup(),
+                        groupChangeResponse.groupSendEndorsementsResponse);
+
+        // TODO save group endorsements
+
+        return groupChangeResponse.groupChange;
+    }
+
     public Pair<GroupId, SendGroupMessageResults> createGroup(
             String name, Set<RecipientId> members, String avatarFile
     ) throws IOException, AttachmentInvalidException {
@@ -181,7 +214,7 @@ public class GroupHelper {
         final var gv2 = gv2Pair.first();
         final var decryptedGroup = gv2Pair.second();
 
-        gv2.setGroup(decryptedGroup);
+        gv2.setGroup(handleDecryptedGroupResponse(gv2, decryptedGroup));
         gv2.setProfileSharingEnabled(true);
         if (avatarBytes != null) {
             context.getAvatarStore()
@@ -277,7 +310,7 @@ public class GroupHelper {
         var group = getGroupForUpdating(groupId);
 
         if (group instanceof GroupInfoV2 groupInfoV2) {
-            Pair<DecryptedGroup, GroupChange> groupChangePair;
+            Pair<DecryptedGroup, GroupChangeResponse> groupChangePair;
             try {
                 groupChangePair = context.getGroupV2Helper().updateSelfProfileKey(groupInfoV2);
             } catch (ConflictException e) {
@@ -286,7 +319,9 @@ public class GroupHelper {
                 groupChangePair = context.getGroupV2Helper().updateSelfProfileKey(groupInfoV2);
             }
             if (groupChangePair != null) {
-                sendUpdateGroupV2Message(groupInfoV2, groupChangePair.first(), groupChangePair.second());
+                sendUpdateGroupV2Message(groupInfoV2,
+                        groupChangePair.first(),
+                        handleGroupChangeResponse(groupInfoV2, groupChangePair.second()));
             }
         }
     }
@@ -304,11 +339,12 @@ public class GroupHelper {
         if (groupJoinInfo.pendingAdminApproval) {
             throw new PendingAdminApprovalException("You have already requested to join the group.");
         }
-        final var groupChange = context.getGroupV2Helper()
+        final var changeResponse = context.getGroupV2Helper()
                 .joinGroup(inviteLinkUrl.getGroupMasterKey(), inviteLinkUrl.getPassword(), groupJoinInfo);
         final var group = getOrMigrateGroup(inviteLinkUrl.getGroupMasterKey(),
                 groupJoinInfo.revision + 1,
-                groupChange.encode());
+                changeResponse.groupChange == null ? null : changeResponse.groupChange.encode());
+        final var groupChange = handleGroupChangeResponse(group, changeResponse);
 
         if (group.getGroup() == null) {
             // Only requested member, can't send update to group members
@@ -404,17 +440,17 @@ public class GroupHelper {
         final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
         DecryptedGroup decryptedGroup;
         try {
-            decryptedGroup = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
+            final var response = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
+            if (response == null) {
+                return;
+            }
+            decryptedGroup = handleDecryptedGroupResponse(groupInfoV2, response);
         } catch (NotAGroupMemberException e) {
             groupInfoV2.setPermissionDenied(true);
             account.getGroupStore().updateGroup(group);
             return;
         }
 
-        if (decryptedGroup == null) {
-            return;
-        }
-
         try {
             storeProfileKeysFromHistory(groupSecretParams, groupInfoV2, decryptedGroup);
         } catch (NotAGroupMemberException ignored) {
@@ -496,10 +532,12 @@ public class GroupHelper {
     ) throws NotAGroupMemberException {
         final var revisionWeWereAdded = context.getGroupV2Helper().findRevisionWeWereAdded(newDecryptedGroup);
         final var localRevision = localGroup.getGroup() == null ? 0 : localGroup.getGroup().revision;
+        final var sendEndorsementsExpirationMs = 0L;// TODO store expiration localGroup.getGroup() == null ? 0 : localGroup.getGroup().revision;
         var fromRevision = Math.max(revisionWeWereAdded, localRevision);
         final var newProfileKeys = new HashMap<RecipientId, ProfileKey>();
         while (true) {
-            final var page = context.getGroupV2Helper().getDecryptedGroupHistoryPage(groupSecretParams, fromRevision);
+            final var page = context.getGroupV2Helper()
+                    .getDecryptedGroupHistoryPage(groupSecretParams, fromRevision, sendEndorsementsExpirationMs);
             page.getChangeLogs()
                     .stream()
                     .map(DecryptedGroupChangeLog::getChange)
@@ -606,7 +644,9 @@ public class GroupHelper {
         final var groupV2Helper = context.getGroupV2Helper();
         if (group.isPendingMember(account.getSelfRecipientId())) {
             var groupGroupChangePair = groupV2Helper.acceptInvite(group);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (members != null) {
@@ -614,14 +654,18 @@ public class GroupHelper {
             requestingMembers.retainAll(group.getRequestingMembers());
             if (!requestingMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.approveJoinRequestMembers(group, requestingMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
             final var newMembers = new HashSet<>(members);
             newMembers.removeAll(group.getMembers());
             newMembers.removeAll(group.getRequestingMembers());
             if (!newMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.addMembers(group, newMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
         }
 
@@ -637,20 +681,26 @@ public class GroupHelper {
             existingRemoveMembers.remove(account.getSelfRecipientId());// self can be removed with sendQuitGroupMessage
             if (!existingRemoveMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.removeMembers(group, existingRemoveMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
 
             var pendingRemoveMembers = new HashSet<>(removeMembers);
             pendingRemoveMembers.retainAll(group.getPendingMembers());
             if (!pendingRemoveMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.revokeInvitedMembers(group, pendingRemoveMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
             var requestingRemoveMembers = new HashSet<>(removeMembers);
             requestingRemoveMembers.retainAll(group.getRequestingMembers());
             if (!requestingRemoveMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.refuseJoinRequestMembers(group, requestingRemoveMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
         }
 
@@ -663,7 +713,7 @@ public class GroupHelper {
                     var groupGroupChangePair = groupV2Helper.setMemberAdmin(group, admin, true);
                     result = sendUpdateGroupV2Message(group,
                             groupGroupChangePair.first(),
-                            groupGroupChangePair.second());
+                            handleGroupChangeResponse(group, groupGroupChangePair.second()));
                 }
             }
         }
@@ -676,7 +726,7 @@ public class GroupHelper {
                     var groupGroupChangePair = groupV2Helper.setMemberAdmin(group, admin, false);
                     result = sendUpdateGroupV2Message(group,
                             groupGroupChangePair.first(),
-                            groupGroupChangePair.second());
+                            handleGroupChangeResponse(group, groupGroupChangePair.second()));
                 }
             }
         }
@@ -686,7 +736,9 @@ public class GroupHelper {
             newlyBannedMembers.removeAll(group.getBannedMembers());
             if (!newlyBannedMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.banMembers(group, newlyBannedMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
         }
 
@@ -695,38 +747,52 @@ public class GroupHelper {
             existingUnbanMembers.retainAll(group.getBannedMembers());
             if (!existingUnbanMembers.isEmpty()) {
                 var groupGroupChangePair = groupV2Helper.unbanMembers(group, existingUnbanMembers);
-                result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+                result = sendUpdateGroupV2Message(group,
+                        groupGroupChangePair.first(),
+                        handleGroupChangeResponse(group, groupGroupChangePair.second()));
             }
         }
 
         if (resetGroupLink) {
             var groupGroupChangePair = groupV2Helper.resetGroupLinkPassword(group);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (groupLinkState != null) {
             var groupGroupChangePair = groupV2Helper.setGroupLinkState(group, groupLinkState);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (addMemberPermission != null) {
             var groupGroupChangePair = groupV2Helper.setAddMemberPermission(group, addMemberPermission);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (editDetailsPermission != null) {
             var groupGroupChangePair = groupV2Helper.setEditDetailsPermission(group, editDetailsPermission);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (expirationTimer != null) {
             var groupGroupChangePair = groupV2Helper.setMessageExpirationTimer(group, expirationTimer);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (isAnnouncementGroup != null) {
             var groupGroupChangePair = groupV2Helper.setIsAnnouncementGroup(group, isAnnouncementGroup);
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         if (name != null || description != null || avatarFile != null) {
@@ -735,7 +801,9 @@ public class GroupHelper {
                 context.getAvatarStore()
                         .storeGroupAvatar(group.getGroupId(), outputStream -> outputStream.write(avatarFile));
             }
-            result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
+            result = sendUpdateGroupV2Message(group,
+                    groupGroupChangePair.first(),
+                    handleGroupChangeResponse(group, groupGroupChangePair.second()));
         }
 
         return result;
@@ -771,7 +839,8 @@ public class GroupHelper {
         groupInfoV2.setGroup(groupGroupChangePair.first());
         account.getGroupStore().updateGroup(groupInfoV2);
 
-        var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().encode());
+        var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2,
+                handleGroupChangeResponse(groupInfoV2, groupGroupChangePair.second()).encode());
         return sendGroupMessage(messageBuilder,
                 groupInfoV2.getMembersIncludingPendingWithout(account.getSelfRecipientId()),
                 groupInfoV2.getDistributionId());
index 83f4992610bad695983fa6db39fef58c656bfc81..6c6acd65dc97281b6a78396d1fff5de9edd72eb1 100644 (file)
@@ -19,6 +19,7 @@ import org.signal.libsignal.zkgroup.groups.UuidCiphertext;
 import org.signal.libsignal.zkgroup.profiles.ProfileKey;
 import org.signal.storageservice.protos.groups.AccessControl;
 import org.signal.storageservice.protos.groups.GroupChange;
+import org.signal.storageservice.protos.groups.GroupChangeResponse;
 import org.signal.storageservice.protos.groups.Member;
 import org.signal.storageservice.protos.groups.local.DecryptedGroup;
 import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
@@ -27,6 +28,7 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
 import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupResponse;
 import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
 import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
 import org.whispersystems.signalservice.api.groupsv2.GroupHistoryPage;
@@ -75,7 +77,7 @@ class GroupV2Helper {
         groupApiCredentials = null;
     }
 
-    DecryptedGroup getDecryptedGroup(final GroupSecretParams groupSecretParams) throws NotAGroupMemberException {
+    DecryptedGroupResponse getDecryptedGroup(final GroupSecretParams groupSecretParams) throws NotAGroupMemberException {
         try {
             final var groupsV2AuthorizationString = getGroupAuthForToday(groupSecretParams);
             return dependencies.getGroupsV2Api().getGroup(groupSecretParams, groupsV2AuthorizationString);
@@ -85,7 +87,7 @@ class GroupV2Helper {
             }
             logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
             return null;
-        } catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
+        } catch (IOException | VerificationFailedException | InvalidGroupStateException | InvalidInputException e) {
             logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
             return null;
         }
@@ -103,19 +105,23 @@ class GroupV2Helper {
     }
 
     GroupHistoryPage getDecryptedGroupHistoryPage(
-            final GroupSecretParams groupSecretParams, int fromRevision
+            final GroupSecretParams groupSecretParams, int fromRevision, long sendEndorsementsExpirationMs
     ) throws NotAGroupMemberException {
         try {
             final var groupsV2AuthorizationString = getGroupAuthForToday(groupSecretParams);
             return dependencies.getGroupsV2Api()
-                    .getGroupHistoryPage(groupSecretParams, fromRevision, groupsV2AuthorizationString, false);
+                    .getGroupHistoryPage(groupSecretParams,
+                            fromRevision,
+                            groupsV2AuthorizationString,
+                            false,
+                            sendEndorsementsExpirationMs);
         } catch (NonSuccessfulResponseCodeException e) {
             if (e.getCode() == 403) {
                 throw new NotAGroupMemberException(GroupUtils.getGroupIdV2(groupSecretParams), null);
             }
             logger.warn("Failed to retrieve Group V2 history, ignoring: {}", e.getMessage());
             return null;
-        } catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
+        } catch (IOException | VerificationFailedException | InvalidGroupStateException | InvalidInputException e) {
             logger.warn("Failed to retrieve Group V2 history, ignoring: {}", e.getMessage());
             return null;
         }
@@ -132,7 +138,7 @@ class GroupV2Helper {
         return partialDecryptedGroup.revision;
     }
 
-    Pair<GroupInfoV2, DecryptedGroup> createGroup(
+    Pair<GroupInfoV2, DecryptedGroupResponse> createGroup(
             String name, Set<RecipientId> members, byte[] avatarFile
     ) {
         final var newGroup = buildNewGroup(name, members, avatarFile);
@@ -143,16 +149,16 @@ class GroupV2Helper {
         final var groupSecretParams = newGroup.getGroupSecretParams();
 
         final GroupsV2AuthorizationString groupAuthForToday;
-        final DecryptedGroup decryptedGroup;
+        final DecryptedGroupResponse response;
         try {
             groupAuthForToday = getGroupAuthForToday(groupSecretParams);
             dependencies.getGroupsV2Api().putNewGroup(newGroup, groupAuthForToday);
-            decryptedGroup = dependencies.getGroupsV2Api().getGroup(groupSecretParams, groupAuthForToday);
-        } catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
+            response = dependencies.getGroupsV2Api().getGroup(groupSecretParams, groupAuthForToday);
+        } catch (IOException | VerificationFailedException | InvalidGroupStateException | InvalidInputException e) {
             logger.warn("Failed to create V2 group: {}", e.getMessage());
             return null;
         }
-        if (decryptedGroup == null) {
+        if (response == null) {
             logger.warn("Failed to create V2 group, unknown error!");
             return null;
         }
@@ -161,7 +167,7 @@ class GroupV2Helper {
         final var masterKey = groupSecretParams.getMasterKey();
         var g = new GroupInfoV2(groupId, masterKey, context.getAccount().getRecipientResolver());
 
-        return new Pair<>(g, decryptedGroup);
+        return new Pair<>(g, response);
     }
 
     private GroupsV2Operations.NewGroup buildNewGroup(
@@ -195,7 +201,7 @@ class GroupV2Helper {
                         0);
     }
 
-    Pair<DecryptedGroup, GroupChange> updateGroup(
+    Pair<DecryptedGroup, GroupChangeResponse> updateGroup(
             GroupInfoV2 groupInfoV2, String name, String description, byte[] avatarFile
     ) throws IOException {
         final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
@@ -218,7 +224,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> addMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> addMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> newMembers
     ) throws IOException {
         GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -244,7 +250,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> leaveGroup(
+    Pair<DecryptedGroup, GroupChangeResponse> leaveGroup(
             GroupInfoV2 groupInfoV2, Set<RecipientId> membersToMakeAdmin
     ) throws IOException {
         var pendingMembersList = groupInfoV2.getGroup().pendingMembers;
@@ -264,7 +270,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci, adminUuids));
     }
 
-    Pair<DecryptedGroup, GroupChange> removeMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> removeMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> members
     ) throws IOException {
         final var memberUuids = members.stream()
@@ -276,7 +282,7 @@ class GroupV2Helper {
         return ejectMembers(groupInfoV2, memberUuids);
     }
 
-    Pair<DecryptedGroup, GroupChange> approveJoinRequestMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> approveJoinRequestMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> members
     ) throws IOException {
         final var memberUuids = members.stream()
@@ -287,7 +293,7 @@ class GroupV2Helper {
         return approveJoinRequest(groupInfoV2, memberUuids);
     }
 
-    Pair<DecryptedGroup, GroupChange> refuseJoinRequestMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> refuseJoinRequestMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> members
     ) throws IOException {
         final var memberUuids = members.stream()
@@ -297,7 +303,7 @@ class GroupV2Helper {
         return refuseJoinRequest(groupInfoV2, memberUuids);
     }
 
-    Pair<DecryptedGroup, GroupChange> revokeInvitedMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> revokeInvitedMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> members
     ) throws IOException {
         var pendingMembersList = groupInfoV2.getGroup().pendingMembers;
@@ -311,7 +317,7 @@ class GroupV2Helper {
         return revokeInvites(groupInfoV2, memberUuids);
     }
 
-    Pair<DecryptedGroup, GroupChange> banMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> banMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> block
     ) throws IOException {
         GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -329,7 +335,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> unbanMembers(
+    Pair<DecryptedGroup, GroupChangeResponse> unbanMembers(
             GroupInfoV2 groupInfoV2, Set<RecipientId> block
     ) throws IOException {
         GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -345,14 +351,14 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> resetGroupLinkPassword(GroupInfoV2 groupInfoV2) throws IOException {
+    Pair<DecryptedGroup, GroupChangeResponse> resetGroupLinkPassword(GroupInfoV2 groupInfoV2) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
         final var newGroupLinkPassword = GroupLinkPassword.createNew().serialize();
         final var change = groupOperations.createModifyGroupLinkPasswordChange(newGroupLinkPassword);
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> setGroupLinkState(
+    Pair<DecryptedGroup, GroupChangeResponse> setGroupLinkState(
             GroupInfoV2 groupInfoV2, GroupLinkState state
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -367,7 +373,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> setEditDetailsPermission(
+    Pair<DecryptedGroup, GroupChangeResponse> setEditDetailsPermission(
             GroupInfoV2 groupInfoV2, GroupPermission permission
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -377,7 +383,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> setAddMemberPermission(
+    Pair<DecryptedGroup, GroupChangeResponse> setAddMemberPermission(
             GroupInfoV2 groupInfoV2, GroupPermission permission
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -387,7 +393,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException {
+    Pair<DecryptedGroup, GroupChangeResponse> updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException {
         Optional<DecryptedMember> selfInGroup = groupInfoV2.getGroup() == null
                 ? Optional.empty()
                 : DecryptedGroupUtil.findMemberByAci(groupInfoV2.getGroup().members, getSelfAci());
@@ -417,7 +423,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    GroupChange joinGroup(
+    GroupChangeResponse joinGroup(
             GroupMasterKey groupMasterKey,
             GroupLinkPassword groupLinkPassword,
             DecryptedGroupJoinInfo decryptedGroupJoinInfo
@@ -444,7 +450,7 @@ class GroupV2Helper {
         return commitChange(groupSecretParams, decryptedGroupJoinInfo.revision, change, groupLinkPassword);
     }
 
-    Pair<DecryptedGroup, GroupChange> acceptInvite(GroupInfoV2 groupInfoV2) throws IOException {
+    Pair<DecryptedGroup, GroupChangeResponse> acceptInvite(GroupInfoV2 groupInfoV2) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
 
         final var selfRecipientId = context.getAccount().getSelfRecipientId();
@@ -461,7 +467,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> setMemberAdmin(
+    Pair<DecryptedGroup, GroupChangeResponse> setMemberAdmin(
             GroupInfoV2 groupInfoV2, RecipientId recipientId, boolean admin
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -475,7 +481,7 @@ class GroupV2Helper {
         }
     }
 
-    Pair<DecryptedGroup, GroupChange> setMessageExpirationTimer(
+    Pair<DecryptedGroup, GroupChangeResponse> setMessageExpirationTimer(
             GroupInfoV2 groupInfoV2, int messageExpirationTimer
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -483,7 +489,7 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, change);
     }
 
-    Pair<DecryptedGroup, GroupChange> setIsAnnouncementGroup(
+    Pair<DecryptedGroup, GroupChangeResponse> setIsAnnouncementGroup(
             GroupInfoV2 groupInfoV2, boolean isAnnouncementGroup
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -511,7 +517,7 @@ class GroupV2Helper {
         return dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
     }
 
-    private Pair<DecryptedGroup, GroupChange> revokeInvites(
+    private Pair<DecryptedGroup, GroupChangeResponse> revokeInvites(
             GroupInfoV2 groupInfoV2, Set<DecryptedPendingMember> pendingMembers
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
@@ -525,28 +531,28 @@ class GroupV2Helper {
         return commitChange(groupInfoV2, groupOperations.createRemoveInvitationChange(uuidCipherTexts));
     }
 
-    private Pair<DecryptedGroup, GroupChange> approveJoinRequest(
+    private Pair<DecryptedGroup, GroupChangeResponse> approveJoinRequest(
             GroupInfoV2 groupInfoV2, Set<UUID> uuids
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
         return commitChange(groupInfoV2, groupOperations.createApproveGroupJoinRequest(uuids));
     }
 
-    private Pair<DecryptedGroup, GroupChange> refuseJoinRequest(
+    private Pair<DecryptedGroup, GroupChangeResponse> refuseJoinRequest(
             GroupInfoV2 groupInfoV2, Set<ServiceId> serviceIds
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
         return commitChange(groupInfoV2, groupOperations.createRefuseGroupJoinRequest(serviceIds, false, List.of()));
     }
 
-    private Pair<DecryptedGroup, GroupChange> ejectMembers(
+    private Pair<DecryptedGroup, GroupChangeResponse> ejectMembers(
             GroupInfoV2 groupInfoV2, Set<ACI> members
     ) throws IOException {
         final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
         return commitChange(groupInfoV2, groupOperations.createRemoveMembersChange(members, false, List.of()));
     }
 
-    private Pair<DecryptedGroup, GroupChange> commitChange(
+    private Pair<DecryptedGroup, GroupChangeResponse> commitChange(
             GroupInfoV2 groupInfoV2, GroupChange.Actions.Builder change
     ) throws IOException {
         final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
@@ -567,10 +573,12 @@ class GroupV2Helper {
         var signedGroupChange = dependencies.getGroupsV2Api()
                 .patchGroup(changeActions, getGroupAuthForToday(groupSecretParams), Optional.empty());
 
+        groupInfoV2.setGroup(decryptedGroupState);
+
         return new Pair<>(decryptedGroupState, signedGroupChange);
     }
 
-    private GroupChange commitChange(
+    private GroupChangeResponse commitChange(
             GroupSecretParams groupSecretParams,
             int currentRevision,
             GroupChange.Actions.Builder change,
index 4a2b79bd99d5951e4c5d5b35b2418b678940b00a..03d277f94ade73b83580c7018863c2bc67ee9521 100644 (file)
@@ -16,13 +16,14 @@ import org.asamk.signal.manager.util.KeyUtils;
 import org.asamk.signal.manager.util.PaymentUtils;
 import org.asamk.signal.manager.util.ProfileUtils;
 import org.asamk.signal.manager.util.Utils;
+import org.jetbrains.annotations.Nullable;
 import org.signal.libsignal.protocol.IdentityKey;
 import org.signal.libsignal.protocol.InvalidKeyException;
 import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential;
 import org.signal.libsignal.zkgroup.profiles.ProfileKey;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
+import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
 import org.whispersystems.signalservice.api.profiles.AvatarUploadParams;
 import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
 import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
@@ -387,7 +388,7 @@ public final class ProfileHelper {
     private Single<ProfileAndCredential> retrieveProfile(
             SignalServiceAddress address,
             Optional<ProfileKey> profileKey,
-            Optional<UnidentifiedAccess> unidentifiedAccess,
+            @Nullable SealedSenderAccess unidentifiedAccess,
             SignalServiceProfile.RequestType requestType
     ) {
         final var profileService = dependencies.getProfileService();
@@ -450,13 +451,7 @@ public final class ProfileHelper {
         }
     }
 
-    private Optional<UnidentifiedAccess> getUnidentifiedAccess(RecipientId recipientId) {
-        var unidentifiedAccess = context.getUnidentifiedAccessHelper().getAccessFor(recipientId, true);
-
-        if (unidentifiedAccess.isPresent()) {
-            return unidentifiedAccess.get().getTargetUnidentifiedAccess();
-        }
-
-        return Optional.empty();
+    private @Nullable SealedSenderAccess getUnidentifiedAccess(RecipientId recipientId) {
+        return context.getUnidentifiedAccessHelper().getSealedSenderAccessFor(recipientId, true);
     }
 }
index 0ff7fd89c6de48e791c0d4f539a6220b43121402..2ac0fc9c93dacc4b27e94530245a9b8ff3166d38 100644 (file)
@@ -13,6 +13,7 @@ import org.asamk.signal.manager.storage.SignalAccount;
 import org.asamk.signal.manager.storage.groups.GroupInfo;
 import org.asamk.signal.manager.storage.recipients.RecipientId;
 import org.asamk.signal.manager.storage.sendLog.MessageSendLogEntry;
+import org.jetbrains.annotations.Nullable;
 import org.signal.libsignal.protocol.InvalidKeyException;
 import org.signal.libsignal.protocol.InvalidRegistrationIdException;
 import org.signal.libsignal.protocol.NoSessionException;
@@ -22,9 +23,10 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.SignalServiceMessageSender;
 import org.whispersystems.signalservice.api.crypto.ContentHint;
+import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
 import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
-import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
 import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
+import org.whispersystems.signalservice.api.groupsv2.GroupSendEndorsements;
 import org.whispersystems.signalservice.api.messages.SendMessageResult;
 import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
 import org.whispersystems.signalservice.api.messages.SignalServiceEditMessage;
@@ -199,7 +201,7 @@ public class SendHelper {
             return SendMessageResult.success(account.getSelfAddress(), List.of(), false, false, 0, Optional.empty());
         }
         try {
-            return messageSender.sendSyncMessage(message, context.getUnidentifiedAccessHelper().getAccessForSync());
+            return messageSender.sendSyncMessage(message);
         } catch (UnregisteredUserException e) {
             var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
             return SendMessageResult.unregisteredFailure(address);
@@ -380,10 +382,11 @@ public class SendHelper {
                                 () -> false,
                                 urgent,
                                 editTargetTimestamp.get());
-        final SenderKeySenderHandler senderKeySender = (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupDataMessage(
+        final SenderKeySenderHandler senderKeySender = (distId, recipients, unidentifiedAccess, groupSendEndorsements, isRecipientUpdate) -> messageSender.sendGroupDataMessage(
                 distId,
                 recipients,
                 unidentifiedAccess,
+                groupSendEndorsements,
                 isRecipientUpdate,
                 contentHint,
                 message,
@@ -436,9 +439,11 @@ public class SendHelper {
                         unidentifiedAccess,
                         message,
                         () -> false),
-                (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupTyping(distId,
+                (distId, recipients, unidentifiedAccess, groupSendEndorsements, isRecipientUpdate) -> messageSender.sendGroupTyping(
+                        distId,
                         recipients,
                         unidentifiedAccess,
+                        groupSendEndorsements,
                         message),
                 recipientIds,
                 distributionId);
@@ -526,8 +531,8 @@ public class SendHelper {
         final var senderKeyTargets = new HashSet<RecipientId>();
         final var recipientList = new ArrayList<>(recipientIds);
         for (final var recipientId : recipientList) {
-            final var access = context.getUnidentifiedAccessHelper().getAccessFor(recipientId);
-            if (access.isEmpty() || access.get().getTargetUnidentifiedAccess().isEmpty()) {
+            final var access = context.getUnidentifiedAccessHelper().getSealedSenderAccessFor(recipientId);
+            if (access != null) {
                 continue;
             }
 
@@ -562,7 +567,8 @@ public class SendHelper {
         final var addresses = recipientIdList.stream()
                 .map(context.getRecipientHelper()::resolveSignalServiceAddress)
                 .toList();
-        final var unidentifiedAccesses = context.getUnidentifiedAccessHelper().getAccessFor(recipientIdList);
+        final var unidentifiedAccesses = context.getUnidentifiedAccessHelper()
+                .getSealedSenderAccessFor(recipientIdList);
         try {
             final var results = sender.send(addresses, unidentifiedAccesses, isRecipientUpdate);
 
@@ -601,15 +607,14 @@ public class SendHelper {
         List<UnidentifiedAccess> unidentifiedAccesses = context.getUnidentifiedAccessHelper()
                 .getAccessFor(recipientIdList)
                 .stream()
-                .map(Optional::get)
-                .map(UnidentifiedAccessPair::getTargetUnidentifiedAccess)
-                .map(Optional::get)
                 .toList();
 
+        final GroupSendEndorsements groupSendEndorsements = null;//TODO
         try {
             List<SendMessageResult> results = sender.send(distributionId,
                     addresses,
                     unidentifiedAccesses,
+                    groupSendEndorsements,
                     isRecipientUpdate);
 
             final var successCount = results.stream().filter(SendMessageResult::isSuccess).count();
@@ -684,7 +689,7 @@ public class SendHelper {
             try {
                 return s.send(messageSender,
                         address,
-                        context.getUnidentifiedAccessHelper().getAccessFor(recipientId),
+                        context.getUnidentifiedAccessHelper().getSealedSenderAccessFor(recipientId),
                         includePniSignature);
             } catch (UnregisteredUserException e) {
                 final RecipientId newRecipientId;
@@ -696,7 +701,7 @@ public class SendHelper {
                 address = context.getRecipientHelper().resolveSignalServiceAddress(newRecipientId);
                 return s.send(messageSender,
                         address,
-                        context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId),
+                        context.getUnidentifiedAccessHelper().getSealedSenderAccessFor(newRecipientId),
                         includePniSignature);
             }
         } catch (UnregisteredUserException e) {
@@ -772,7 +777,7 @@ public class SendHelper {
         SendMessageResult send(
                 SignalServiceMessageSender messageSender,
                 SignalServiceAddress address,
-                Optional<UnidentifiedAccessPair> unidentifiedAccess,
+                @Nullable SealedSenderAccess unidentifiedAccess,
                 boolean includePniSignature
         ) throws IOException, UnregisteredUserException, ProofRequiredException, RateLimitException, org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
     }
@@ -783,6 +788,7 @@ public class SendHelper {
                 DistributionId distributionId,
                 List<SignalServiceAddress> recipients,
                 List<UnidentifiedAccess> unidentifiedAccess,
+                GroupSendEndorsements groupSendEndorsements,
                 boolean isRecipientUpdate
         ) throws IOException, UntrustedIdentityException, NoSessionException, InvalidKeyException, InvalidRegistrationIdException;
     }
@@ -791,7 +797,7 @@ public class SendHelper {
 
         List<SendMessageResult> send(
                 List<SignalServiceAddress> recipients,
-                List<Optional<UnidentifiedAccessPair>> unidentifiedAccess,
+                List<SealedSenderAccess> unidentifiedAccess,
                 boolean isRecipientUpdate
         ) throws IOException, UntrustedIdentityException;
     }
index dacc97ba6477fad7be6d0ca10c325b5eabe5e8f2..3899179c1f19ef0e297286cb0bcfcc3804aef696 100644 (file)
@@ -5,17 +5,17 @@ import org.asamk.signal.manager.api.Profile;
 import org.asamk.signal.manager.internal.SignalDependencies;
 import org.asamk.signal.manager.storage.SignalAccount;
 import org.asamk.signal.manager.storage.recipients.RecipientId;
+import org.jetbrains.annotations.Nullable;
 import org.signal.libsignal.metadata.certificate.InvalidCertificateException;
 import org.signal.libsignal.metadata.certificate.SenderCertificate;
 import org.signal.libsignal.zkgroup.profiles.ProfileKey;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.whispersystems.signalservice.api.crypto.SealedSenderAccess;
 import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
-import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
 
 import java.io.IOException;
 import java.util.List;
-import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
 public class UnidentifiedAccessHelper {
@@ -42,57 +42,49 @@ public class UnidentifiedAccessHelper {
         senderCertificate = null;
     }
 
-    public List<Optional<UnidentifiedAccessPair>> getAccessFor(List<RecipientId> recipients) {
+    public List<SealedSenderAccess> getSealedSenderAccessFor(List<RecipientId> recipients) {
+        return recipients.stream().map(this::getAccessFor).map(SealedSenderAccess::forIndividual).toList();
+    }
+
+    public @Nullable SealedSenderAccess getSealedSenderAccessFor(RecipientId recipient) {
+        return getSealedSenderAccessFor(recipient, false);
+    }
+
+    public @Nullable SealedSenderAccess getSealedSenderAccessFor(RecipientId recipient, boolean noRefresh) {
+        return SealedSenderAccess.forIndividual(getAccessFor(recipient, noRefresh));
+    }
+
+    public List<UnidentifiedAccess> getAccessFor(List<RecipientId> recipients) {
         return recipients.stream().map(this::getAccessFor).toList();
     }
 
-    public Optional<UnidentifiedAccessPair> getAccessFor(RecipientId recipient) {
+    private @Nullable UnidentifiedAccess getAccessFor(RecipientId recipient) {
         return getAccessFor(recipient, false);
     }
 
-    public Optional<UnidentifiedAccessPair> getAccessFor(RecipientId recipientId, boolean noRefresh) {
+    private @Nullable UnidentifiedAccess getAccessFor(RecipientId recipientId, boolean noRefresh) {
         var recipientUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipientId, noRefresh);
         if (recipientUnidentifiedAccessKey == null) {
             logger.trace("Unidentified access not available for {}", recipientId);
-            return Optional.empty();
+            return null;
         }
 
         var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(noRefresh);
         if (selfUnidentifiedAccessKey == null) {
             logger.trace("Unidentified access not available for self");
-            return Optional.empty();
+            return null;
         }
 
         var senderCertificate = getSenderCertificateFor(recipientId);
         if (senderCertificate == null) {
             logger.trace("Unidentified access not available due to missing sender certificate");
-            return Optional.empty();
-        }
-
-        try {
-            return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(recipientUnidentifiedAccessKey,
-                    senderCertificate,
-                    false), new UnidentifiedAccess(selfUnidentifiedAccessKey, senderCertificate, false)));
-        } catch (InvalidCertificateException e) {
-            return Optional.empty();
-        }
-    }
-
-    public Optional<UnidentifiedAccessPair> getAccessForSync() {
-        var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(false);
-        var selfUnidentifiedAccessCertificate = getSenderCertificate();
-
-        if (selfUnidentifiedAccessKey == null || selfUnidentifiedAccessCertificate == null) {
-            return Optional.empty();
+            return null;
         }
 
         try {
-            return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(selfUnidentifiedAccessKey,
-                    selfUnidentifiedAccessCertificate,
-                    false),
-                    new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate, false)));
+            return new UnidentifiedAccess(recipientUnidentifiedAccessKey, senderCertificate, false);
         } catch (InvalidCertificateException e) {
-            return Optional.empty();
+            return null;
         }
     }
 
@@ -121,7 +113,7 @@ public class UnidentifiedAccessHelper {
             privacySenderCertificate = new SenderCertificate(certificate);
             return certificate;
         } catch (IOException | InvalidCertificateException e) {
-            logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
+            logger.warn("Failed to get sender certificate (pnp), ignoring: {}", e.getMessage());
             return null;
         }
     }
index d185c4179c8d93ea37ec43bb7717880325364a8c..99018552a8183a9a6484d226dcb88b89b9c3bebe 100644 (file)
@@ -15,7 +15,7 @@ dependencyResolutionManagement {
             library("slf4j.jul", "org.slf4j", "jul-to-slf4j").versionRef("slf4j")
             library("logback", "ch.qos.logback", "logback-classic").version("1.5.6")
 
-            library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_104")
+            library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_105")
             library("sqlite", "org.xerial", "sqlite-jdbc").version("3.46.0.0")
             library("hikari", "com.zaxxer", "HikariCP").version("5.1.0")
             library("junit.jupiter", "org.junit.jupiter", "junit-jupiter").version("5.10.2")
index e234ed2fdce8ccc12ae7c5bb1791719d7762bbdd..43db05315f023eca4b8e9a486c1e4a9cc82fc450 100644 (file)
@@ -8,7 +8,7 @@ public class BaseConfig {
     public static final String PROJECT_VERSION = BaseConfig.class.getPackage().getImplementationVersion();
 
     static final String USER_AGENT_SIGNAL_ANDROID = Optional.ofNullable(System.getenv("SIGNAL_CLI_USER_AGENT"))
-            .orElse("Signal-Android/7.9.0");
+            .orElse("Signal-Android/7.12.1");
     static final String USER_AGENT_SIGNAL_CLI = PROJECT_NAME == null
             ? "signal-cli"
             : PROJECT_NAME + "/" + PROJECT_VERSION;