From 86e1079195a6001f77d6ef5e20e0bd0b8dd11959 Mon Sep 17 00:00:00 2001 From: AsamK Date: Sun, 6 Aug 2023 16:24:30 +0200 Subject: [PATCH] Update libsignal-service --- CHANGELOG.md | 1 + graalvm-config-dir/reflect-config.json | 12 +-- .../signal/manager/api/RecipientAddress.java | 6 +- .../manager/helper/AccountFileUpdater.java | 2 +- .../signal/manager/helper/AccountHelper.java | 4 +- .../signal/manager/helper/GroupHelper.java | 2 +- .../signal/manager/helper/GroupV2Helper.java | 57 ++++++------ .../helper/IncomingMessageHandler.java | 12 +-- .../signal/manager/helper/ReceiveHelper.java | 4 +- .../manager/helper/RecipientHelper.java | 6 +- .../signal/manager/helper/SendHelper.java | 59 +++++++----- .../signal/manager/helper/StorageHelper.java | 17 ++-- .../internal/AccountFileUpdaterImpl.java | 2 +- .../signal/manager/internal/ManagerImpl.java | 6 +- .../internal/RegistrationManagerImpl.java | 4 +- .../manager/storage/AccountDatabase.java | 6 +- .../signal/manager/storage/SignalAccount.java | 8 +- .../storage/accounts/AccountsStore.java | 2 +- .../storage/contacts/LegacyContactInfo.java | 4 +- .../manager/storage/groups/GroupInfoV2.java | 10 +-- .../protocol/LegacyJsonIdentityKeyStore.java | 4 +- .../protocol/LegacyJsonSessionStore.java | 4 +- .../storage/recipients/RecipientAddress.java | 9 +- .../storage/recipients/RecipientStore.java | 23 ++--- .../recipients/RecipientTrustedResolver.java | 4 +- .../recipients/MergeRecipientHelperTest.java | 90 +------------------ settings.gradle.kts | 2 +- 27 files changed, 152 insertions(+), 208 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d8cbe4fce6..08d45108dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # Changelog ## [Unreleased] +**Attention**: Now requires native libsignal-client version 0.30.0 ## [0.11.11] - 2023-05-24 **Attention**: Now requires native libsignal-client version 0.25.0 diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 676be954c2..5bb16c8788 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -1934,7 +1934,7 @@ }, { "name":"org.signal.storageservice.protos.groups.local.DecryptedBannedMember", - "fields":[{"name":"timestamp_"}, {"name":"uuid_"}] + "fields":[{"name":"serviceIdBinary_"}, {"name":"timestamp_"}, {"name":"uuid_"}] }, { "name":"org.signal.storageservice.protos.groups.local.DecryptedGroup", @@ -1958,7 +1958,7 @@ }, { "name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMember", - "fields":[{"name":"addedByUuid_"}, {"name":"role_"}, {"name":"timestamp_"}, {"name":"uuidCipherText_"}, {"name":"uuid_"}] + "fields":[{"name":"addedByUuid_"}, {"name":"role_"}, {"name":"serviceIdBinary_"}, {"name":"timestamp_"}, {"name":"uuidCipherText_"}, {"name":"uuid_"}] }, { "name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval", @@ -2517,7 +2517,7 @@ }, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$ContactDetails", - "fields":[{"name":"archived_"}, {"name":"avatar_"}, {"name":"bitField0_"}, {"name":"blocked_"}, {"name":"color_"}, {"name":"expireTimer_"}, {"name":"inboxPosition_"}, {"name":"name_"}, {"name":"number_"}, {"name":"profileKey_"}, {"name":"uuid_"}, {"name":"verified_"}] + "fields":[{"name":"aci_"}, {"name":"archived_"}, {"name":"avatar_"}, {"name":"bitField0_"}, {"name":"blocked_"}, {"name":"color_"}, {"name":"expireTimer_"}, {"name":"inboxPosition_"}, {"name":"name_"}, {"name":"number_"}, {"name":"profileKey_"}, {"name":"uuid_"}, {"name":"verified_"}] }, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$ContactDetails$Avatar", @@ -2661,7 +2661,7 @@ }, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$Blocked", - "fields":[{"name":"groupIds_"}, {"name":"numbers_"}, {"name":"uuids_"}] + "fields":[{"name":"acis_"}, {"name":"groupIds_"}, {"name":"numbers_"}, {"name":"uuids_"}] }, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$CallEvent", @@ -2745,7 +2745,7 @@ }, { "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$Verified", - "fields":[{"name":"bitField0_"}, {"name":"destinationUuid_"}, {"name":"identityKey_"}, {"name":"nullMessage_"}, {"name":"state_"}] + "fields":[{"name":"bitField0_"}, {"name":"destinationAci_"}, {"name":"destinationUuid_"}, {"name":"identityKey_"}, {"name":"nullMessage_"}, {"name":"state_"}] }, { "name":"org.whispersystems.signalservice.internal.push.StaleDevices", @@ -2812,7 +2812,7 @@ }, { "name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation$Contact", - "fields":[{"name":"e164_"}, {"name":"uuid_"}] + "fields":[{"name":"e164_"}, {"name":"serviceId_"}, {"name":"uuid_"}] }, { "name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord", diff --git a/lib/src/main/java/org/asamk/signal/manager/api/RecipientAddress.java b/lib/src/main/java/org/asamk/signal/manager/api/RecipientAddress.java index f500e3a93e..f042f8fbab 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/RecipientAddress.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/RecipientAddress.java @@ -1,14 +1,14 @@ package org.asamk.signal.manager.api; -import org.whispersystems.signalservice.api.push.ServiceId; import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.api.util.UuidUtil; import java.util.Optional; import java.util.UUID; public record RecipientAddress(Optional uuid, Optional number, Optional username) { - public static final UUID UNKNOWN_UUID = ServiceId.UNKNOWN.uuid(); + public static final UUID UNKNOWN_UUID = UuidUtil.UNKNOWN_UUID; /** * Construct a RecipientAddress. @@ -32,7 +32,7 @@ public RecipientAddress(UUID uuid, String e164, String username) { } public RecipientAddress(SignalServiceAddress address) { - this(Optional.of(address.getServiceId().uuid()), address.getNumber(), Optional.empty()); + this(Optional.of(address.getServiceId().getRawUuid()), address.getNumber(), Optional.empty()); } public RecipientAddress(UUID uuid) { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AccountFileUpdater.java b/lib/src/main/java/org/asamk/signal/manager/helper/AccountFileUpdater.java index a983e4b529..8edd5a4e0e 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AccountFileUpdater.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AccountFileUpdater.java @@ -1,6 +1,6 @@ package org.asamk.signal.manager.helper; -import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; public interface AccountFileUpdater { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java index 4841bdbda0..485990ed34 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/AccountHelper.java @@ -21,8 +21,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.SignedPreKeyEntity; import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException; diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index d987d3d1e4..eb54780ed6 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -447,7 +447,7 @@ private void retrieveGroupV2Avatar( private void storeProfileKeysFromMembers(final DecryptedGroup group) { for (var member : group.getMembersList()) { - final var serviceId = ServiceId.fromByteString(member.getUuid()); + final var serviceId = ServiceId.parseOrThrow(member.getUuid()); final var recipientId = account.getRecipientResolver().resolveRecipient(serviceId); final var profileStore = account.getProfileStore(); if (profileStore.getProfileKey(recipientId) != null) { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java index 7cc28d6afd..c817f01fe0 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java @@ -39,9 +39,9 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException; import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -124,7 +124,7 @@ GroupHistoryPage getDecryptedGroupHistoryPage( } int findRevisionWeWereAdded(DecryptedGroup partialDecryptedGroup) { - ByteString bytes = UuidUtil.toByteString(getSelfAci().uuid()); + ByteString bytes = getSelfAci().toByteString(); for (DecryptedMember decryptedMember : partialDecryptedGroup.getMembersList()) { if (decryptedMember.getUuid().equals(bytes)) { return decryptedMember.getJoinedAtRevision(); @@ -175,11 +175,11 @@ private GroupsV2Operations.NewGroup buildNewGroup( return null; } - final var self = new GroupCandidate(getSelfAci().uuid(), Optional.of(profileKeyCredential)); + final var self = new GroupCandidate(getSelfAci(), Optional.of(profileKeyCredential)); final var memberList = new ArrayList<>(members); final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream(); final var uuids = memberList.stream() - .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()); + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId()); var candidates = Utils.zip(uuids, credentials, (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential))) @@ -227,18 +227,18 @@ Pair addMembers( final var memberList = new ArrayList<>(newMembers); final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream(); final var uuids = memberList.stream() - .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()); + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId()); var candidates = Utils.zip(uuids, credentials, (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential))) .collect(Collectors.toSet()); final var bannedUuids = groupInfoV2.getBannedMembers() .stream() - .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId()) .collect(Collectors.toSet()); final var aci = getSelfAci(); - final var change = groupOperations.createModifyGroupMembershipChange(candidates, bannedUuids, aci.uuid()); + final var change = groupOperations.createModifyGroupMembershipChange(candidates, bannedUuids, aci); change.setSourceUuid(getSelfAci().toByteString()); @@ -250,7 +250,7 @@ Pair leaveGroup( ) throws IOException { var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList(); final var selfAci = getSelfAci(); - var selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfAci.uuid()); + var selfPendingMember = DecryptedGroupUtil.findPendingByServiceId(pendingMembersList, selfAci); if (selfPendingMember.isPresent()) { return revokeInvites(groupInfoV2, Set.of(selfPendingMember.get())); @@ -259,11 +259,11 @@ Pair leaveGroup( final var adminUuids = membersToMakeAdmin.stream() .map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(SignalServiceAddress::getServiceId) - .map(ServiceId::uuid) + .map(ServiceId::getRawUuid) .toList(); final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); return commitChange(groupInfoV2, - groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(), adminUuids)); + groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.getRawUuid(), adminUuids)); } Pair removeMembers( @@ -272,7 +272,7 @@ Pair removeMembers( final var memberUuids = members.stream() .map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(SignalServiceAddress::getServiceId) - .map(ServiceId::uuid) + .map(ServiceId::getRawUuid) .collect(Collectors.toSet()); return ejectMembers(groupInfoV2, memberUuids); } @@ -283,7 +283,7 @@ Pair approveJoinRequestMembers( final var memberUuids = members.stream() .map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(SignalServiceAddress::getServiceId) - .map(ServiceId::uuid) + .map(ServiceId::getRawUuid) .collect(Collectors.toSet()); return approveJoinRequest(groupInfoV2, memberUuids); } @@ -294,7 +294,7 @@ Pair refuseJoinRequestMembers( final var memberUuids = members.stream() .map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(SignalServiceAddress::getServiceId) - .map(ServiceId::uuid) + .map(ServiceId::getRawUuid) .collect(Collectors.toSet()); return refuseJoinRequest(groupInfoV2, memberUuids); } @@ -306,8 +306,7 @@ Pair revokeInvitedMembers( final var memberUuids = members.stream() .map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(SignalServiceAddress::getServiceId) - .map(ServiceId::uuid) - .map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid)) + .map(uuid -> DecryptedGroupUtil.findPendingByServiceId(pendingMembersList, uuid)) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toSet()); @@ -320,7 +319,10 @@ Pair banMembers( GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final var uuids = block.stream() - .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + .map(member -> context.getRecipientHelper() + .resolveSignalServiceAddress(member) + .getServiceId() + .getRawUuid()) .collect(Collectors.toSet()); final var change = groupOperations.createBanUuidsChange(uuids, @@ -337,11 +339,11 @@ Pair unbanMembers( ) throws IOException { GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); - final var uuids = block.stream() - .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + final var serviceIds = block.stream() + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId()) .collect(Collectors.toSet()); - final var change = groupOperations.createUnbanUuidsChange(uuids); + final var change = groupOperations.createUnbanServiceIdsChange(serviceIds); change.setSourceUuid(getSelfAci().toByteString()); @@ -394,7 +396,8 @@ Pair setAddMemberPermission( Pair updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException { Optional selfInGroup = groupInfoV2.getGroup() == null ? Optional.empty() - : DecryptedGroupUtil.findMemberByUuid(groupInfoV2.getGroup().getMembersList(), getSelfAci().uuid()); + : DecryptedGroupUtil.findMemberByUuid(groupInfoV2.getGroup().getMembersList(), + getSelfAci().getRawUuid()); if (selfInGroup.isEmpty()) { logger.trace("Not updating group, self not in group " + groupInfoV2.getGroupId().toBase64()); return null; @@ -471,8 +474,12 @@ Pair setMemberAdmin( final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId); final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT; - final var change = groupOperations.createChangeMemberRole(address.getServiceId().uuid(), newRole); - return commitChange(groupInfoV2, change); + if (address.getServiceId() instanceof ACI aci) { + final var change = groupOperations.createChangeMemberRole(aci, newRole); + return commitChange(groupInfoV2, change); + } else { + throw new IllegalArgumentException("Can't make a PNI a group admin."); + } } Pair setMessageExpirationTimer( @@ -558,7 +565,7 @@ private Pair commitChange( final DecryptedGroup decryptedGroupState; try { - decryptedChange = groupOperations.decryptChange(changeActions, getSelfAci().uuid()); + decryptedChange = groupOperations.decryptChange(changeActions, getSelfAci()); decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange); } catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) { throw new IOException(e); @@ -610,7 +617,7 @@ Pair getAuthoritativeProfileKeyFromChange(final Decrypted return null; } - return new Pair<>(ServiceId.from(editor), profileKey); + return new Pair<>(ACI.from(editor), profileKey); } DecryptedGroup getUpdatedDecryptedGroup(DecryptedGroup group, DecryptedGroupChange decryptedGroupChange) { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java index b45f21d399..6ffa08fb66 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/IncomingMessageHandler.java @@ -66,9 +66,9 @@ import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; @@ -139,7 +139,7 @@ public Pair, Exception> handleEnvelope( final var actions = new ArrayList(); if (envelope.hasSourceServiceId()) { // Store uuid if we don't have it already - // address/uuid in envelope is sent by server + // uuid in envelope is sent by server account.getRecipientTrustedResolver().resolveRecipientTrusted(envelope.getSourceAddress()); } SignalServiceContent content = null; @@ -409,7 +409,7 @@ public List handleMessage( private boolean handlePniSignatureMessage( final SignalServicePniSignatureMessage message, final SignalServiceAddress senderAddress ) { - final var aci = ACI.from(senderAddress.getServiceId()); + final var aci = senderAddress.getServiceId(); final var aciIdentity = account.getIdentityKeyStore().getIdentityInfo(aci); final var pni = message.getPni(); final var pniIdentity = account.getIdentityKeyStore().getIdentityInfo(pni); @@ -428,7 +428,9 @@ private boolean handlePniSignatureMessage( logger.debug("Verified association of ACI {} with PNI {}", aci, pni); account.getRecipientTrustedResolver() - .resolveRecipientTrusted(Optional.of(aci), Optional.of(pni), senderAddress.getNumber()); + .resolveRecipientTrusted(Optional.of(ACI.from(aci.getRawUuid())), + Optional.of(pni), + senderAddress.getNumber()); return true; } diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/ReceiveHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/ReceiveHelper.java index 55c93e579f..b733507da4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/ReceiveHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/ReceiveHelper.java @@ -12,7 +12,7 @@ import org.slf4j.LoggerFactory; import org.whispersystems.signalservice.api.SignalWebSocket; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; -import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState; import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException; @@ -228,7 +228,7 @@ private void receiveMessagesInternal( final var address = ((UntrustedIdentityException) exception).getSender(); if (!envelope.hasSourceServiceId() && address.uuid().isPresent()) { final var recipientId = account.getRecipientResolver() - .resolveRecipient(ServiceId.from(address.uuid().get())); + .resolveRecipient(ACI.from(address.uuid().get())); try { cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId); } catch (IOException ioException) { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java index a0f03b79e2..aff45ed2a3 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/RecipientHelper.java @@ -10,9 +10,9 @@ import org.signal.libsignal.usernames.Username; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.services.CdsiV2Service; import org.whispersystems.util.Base64UrlSafe; @@ -80,7 +80,7 @@ public Set resolveRecipients(Collection public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws UnregisteredRecipientException { if (recipient instanceof RecipientIdentifier.Uuid uuidRecipient) { - return account.getRecipientResolver().resolveRecipient(ServiceId.from(uuidRecipient.uuid())); + return account.getRecipientResolver().resolveRecipient(ACI.from(uuidRecipient.uuid())); } else if (recipient instanceof RecipientIdentifier.Number numberRecipient) { final var number = numberRecipient.number(); return account.getRecipientStore().resolveRecipientByNumber(number, () -> { diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java index 666867fe68..c1ba113a66 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/SendHelper.java @@ -41,6 +41,7 @@ import org.whispersystems.signalservice.api.push.exceptions.RateLimitException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException; +import org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener; import java.io.IOException; import java.time.Duration; @@ -330,29 +331,41 @@ private List sendGroupMessage( final AtomicLong entryId = new AtomicLong(-1); final var urgent = true; - final LegacySenderHandler legacySender = (recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendDataMessage( - recipients, - unidentifiedAccess, - isRecipientUpdate, - contentHint, - message, - SignalServiceMessageSender.LegacyGroupEvents.EMPTY, - sendResult -> { - logger.trace("Partial message send result: {}", sendResult.isSuccess()); - synchronized (entryId) { - if (entryId.get() == -1) { - final var newId = messageSendLogStore.insertIfPossible(message.getTimestamp(), - sendResult, - contentHint, - urgent); - entryId.set(newId); - } else { - messageSendLogStore.addRecipientToExistingEntryIfPossible(entryId.get(), sendResult); - } - } - }, - () -> false, - urgent); + final PartialSendCompleteListener partialSendCompleteListener = sendResult -> { + logger.trace("Partial message send result: {}", sendResult.isSuccess()); + synchronized (entryId) { + if (entryId.get() == -1) { + final var newId = messageSendLogStore.insertIfPossible(message.getTimestamp(), + sendResult, + contentHint, + urgent); + entryId.set(newId); + } else { + messageSendLogStore.addRecipientToExistingEntryIfPossible(entryId.get(), sendResult); + } + } + }; + final LegacySenderHandler legacySender = (recipients, unidentifiedAccess, isRecipientUpdate) -> + editTargetTimestamp.isEmpty() + ? messageSender.sendDataMessage(recipients, + unidentifiedAccess, + isRecipientUpdate, + contentHint, + message, + SignalServiceMessageSender.LegacyGroupEvents.EMPTY, + partialSendCompleteListener, + () -> false, + urgent) + : messageSender.sendEditMessage(recipients, + unidentifiedAccess, + isRecipientUpdate, + contentHint, + message, + SignalServiceMessageSender.LegacyGroupEvents.EMPTY, + partialSendCompleteListener, + () -> false, + urgent, + editTargetTimestamp.get()); final SenderKeySenderHandler senderKeySender = (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupDataMessage( distId, recipients, diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java index fc084f28b4..863bdf99f4 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/StorageHelper.java @@ -101,15 +101,16 @@ private void readContactRecord(final SignalStorageRecord record) { } final var contactRecord = record.getContact().get(); - final var serviceId = contactRecord.getServiceId(); - if (contactRecord.getNumber().isEmpty() && serviceId.isUnknown()) { + final var aci = contactRecord.getAci(); + final var pni = contactRecord.getPni().orElse(null); + if (contactRecord.getNumber().isEmpty() && aci.isUnknown()) { return; } - final var address = new RecipientAddress(serviceId, contactRecord.getNumber().orElse(null)); + final var address = new RecipientAddress(aci, pni, contactRecord.getNumber().orElse(null)); var recipientId = account.getRecipientResolver().resolveRecipient(address); - if (serviceId.isValid() && contactRecord.getUsername().isPresent()) { + if (aci.isValid() && contactRecord.getUsername().isPresent()) { recipientId = account.getRecipientTrustedResolver() - .resolveRecipientTrusted(serviceId, contactRecord.getUsername().get()); + .resolveRecipientTrusted(aci, contactRecord.getUsername().get()); } final var contact = account.getContactStore().getContact(recipientId); @@ -170,15 +171,15 @@ private void readContactRecord(final SignalStorageRecord record) { logger.warn("Received invalid contact profile key from storage"); } } - if (contactRecord.getIdentityKey().isPresent() && serviceId.isValid()) { + if (contactRecord.getIdentityKey().isPresent() && aci.isValid()) { try { logger.trace("Storing identity key {}", recipientId); final var identityKey = new IdentityKey(contactRecord.getIdentityKey().get()); - account.getIdentityKeyStore().saveIdentity(serviceId, identityKey); + account.getIdentityKeyStore().saveIdentity(aci, identityKey); final var trustLevel = TrustLevel.fromIdentityState(contactRecord.getIdentityState()); if (trustLevel != null) { - account.getIdentityKeyStore().setIdentityTrustLevel(serviceId, identityKey, trustLevel); + account.getIdentityKeyStore().setIdentityTrustLevel(aci, identityKey, trustLevel); } } catch (InvalidKeyException e) { logger.warn("Received invalid contact identity key from storage"); diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/AccountFileUpdaterImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/AccountFileUpdaterImpl.java index 5c99d0c1ca..35564362e2 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/AccountFileUpdaterImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/AccountFileUpdaterImpl.java @@ -2,7 +2,7 @@ import org.asamk.signal.manager.helper.AccountFileUpdater; import org.asamk.signal.manager.storage.accounts.AccountsStore; -import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; public class AccountFileUpdaterImpl implements AccountFileUpdater { diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java index 4e2fd82ce0..36051333a3 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/ManagerImpl.java @@ -80,8 +80,8 @@ import org.whispersystems.signalservice.api.messages.SignalServicePreview; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; -import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.util.DeviceNameUtil; import org.whispersystems.signalservice.api.util.InvalidNumberException; @@ -239,7 +239,7 @@ public Map getUserStatus(Set numbers) throws IOExcep : context.getProfileHelper() .getRecipientProfile(account.getRecipientResolver().resolveRecipient(serviceId)); return new UserStatus(number.isEmpty() ? null : number, - serviceId == null ? null : serviceId.uuid(), + serviceId == null ? null : serviceId.getRawUuid(), profile != null && profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED); })); @@ -700,7 +700,7 @@ public SendMessageResults sendRemoteDeleteMessage( for (final var recipient : recipients) { if (recipient instanceof RecipientIdentifier.Uuid u) { account.getMessageSendLogStore() - .deleteEntryForRecipientNonGroup(targetSentTimestamp, ServiceId.from(u.uuid())); + .deleteEntryForRecipientNonGroup(targetSentTimestamp, ACI.from(u.uuid())); } else if (recipient instanceof RecipientIdentifier.Single r) { try { final var recipientId = context.getRecipientHelper().resolveRecipient(r); diff --git a/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java index bf53a9b88c..720b2de159 100644 --- a/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/internal/RegistrationManagerImpl.java @@ -39,8 +39,8 @@ import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException; diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java b/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java index 7f6babe6fc..f40e23ab54 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/AccountDatabase.java @@ -15,7 +15,7 @@ import org.asamk.signal.manager.storage.stickers.StickerStore; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import java.io.File; import java.sql.Connection; @@ -315,7 +315,7 @@ INSERT INTO session2 (_id, account_id_type, uuid, device_id, record) WHERE i.uuid = ? """; try (final var statement = connection.prepareStatement(sql)) { - statement.setBytes(1, ServiceId.UNKNOWN.toByteArray()); + statement.setBytes(1, ACI.UNKNOWN.toByteArray()); statement.executeUpdate(); } } @@ -325,7 +325,7 @@ INSERT INTO session2 (_id, account_id_type, uuid, device_id, record) WHERE i.uuid = ? """; try (final var statement = connection.prepareStatement(sql)) { - statement.setBytes(1, ServiceId.UNKNOWN.toByteArray()); + statement.setBytes(1, ACI.UNKNOWN.toByteArray()); statement.executeUpdate(); } } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java index c9974e861f..647e9ee098 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/SignalAccount.java @@ -67,9 +67,9 @@ import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.kbs.MasterKey; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.storage.SignalStorageManifest; @@ -558,7 +558,7 @@ private void load( } if (rootNode.hasNonNull("pni")) { try { - pni = PNI.parseOrThrow(rootNode.get("pni").asText()); + pni = PNI.from(UuidUtil.parseOrThrow(rootNode.get("pni").asText())); } catch (IllegalArgumentException e) { throw new IOException("Config file contains an invalid pni, needs to be a valid UUID", e); } @@ -967,7 +967,7 @@ private void save() { .put("serviceEnvironment", serviceEnvironment == null ? null : serviceEnvironment.name()) .put("usernameIdentifier", username) .put("uuid", aci == null ? null : aci.toString()) - .put("pni", pni == null ? null : pni.toString()) + .put("pni", pni == null ? null : pni.getRawUuid().toString()) .put("sessionId", sessionId) .put("sessionNumber", sessionNumber) .put("deviceName", encryptedDeviceName) diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/accounts/AccountsStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/accounts/AccountsStore.java index e7297c6b59..0e9fc5fcad 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/accounts/AccountsStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/accounts/AccountsStore.java @@ -9,7 +9,7 @@ import org.asamk.signal.manager.util.IOUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.signalservice.api.push.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.util.PhoneNumberFormatter; import java.io.ByteArrayInputStream; diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/contacts/LegacyContactInfo.java b/lib/src/main/java/org/asamk/signal/manager/storage/contacts/LegacyContactInfo.java index 0d297e7f62..50dcd91ef2 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/contacts/LegacyContactInfo.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/contacts/LegacyContactInfo.java @@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty; import org.asamk.signal.manager.storage.recipients.RecipientAddress; -import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import java.util.UUID; @@ -44,6 +44,6 @@ public LegacyContactInfo() { @JsonIgnore public RecipientAddress getAddress() { - return new RecipientAddress(uuid == null ? null : ServiceId.from(uuid), number); + return new RecipientAddress(uuid == null ? null : ACI.from(uuid), number); } } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java index 3e5eac7aff..199a9da0cb 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java @@ -114,7 +114,7 @@ public Set getMembers() { } return group.getMembersList() .stream() - .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(m -> ServiceId.parseOrThrow(m.getUuid())) .map(recipientResolver::resolveRecipient) .collect(Collectors.toSet()); } @@ -126,7 +126,7 @@ public Set getBannedMembers() { } return group.getBannedMembersList() .stream() - .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(m -> ServiceId.parseOrThrow(m.getServiceIdBinary())) .map(recipientResolver::resolveRecipient) .collect(Collectors.toSet()); } @@ -138,7 +138,7 @@ public Set getPendingMembers() { } return group.getPendingMembersList() .stream() - .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(m -> ServiceId.parseOrThrow(m.getServiceIdBinary())) .map(recipientResolver::resolveRecipient) .collect(Collectors.toSet()); } @@ -150,7 +150,7 @@ public Set getRequestingMembers() { } return group.getRequestingMembersList() .stream() - .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(m -> ServiceId.parseOrThrow(m.getUuid())) .map(recipientResolver::resolveRecipient) .collect(Collectors.toSet()); } @@ -163,7 +163,7 @@ public Set getAdminMembers() { return group.getMembersList() .stream() .filter(m -> m.getRole() == Member.Role.ADMINISTRATOR) - .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(m -> ServiceId.parseOrThrow(m.getUuid())) .map(recipientResolver::resolveRecipient) .collect(Collectors.toSet()); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonIdentityKeyStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonIdentityKeyStore.java index 4d94b455ed..56986333a3 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonIdentityKeyStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonIdentityKeyStore.java @@ -13,7 +13,7 @@ import org.signal.libsignal.protocol.InvalidKeyException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.IOException; @@ -101,7 +101,7 @@ public LegacyJsonIdentityKeyStore deserialize( : null; final var address = uuid == null ? Utils.getRecipientAddressFromIdentifier(trustedKeyName) - : new RecipientAddress(ServiceId.from(uuid), trustedKeyName); + : new RecipientAddress(ACI.from(uuid), trustedKeyName); try { var id = new IdentityKey(Base64.getDecoder().decode(trustedKey.get("identityKey").asText()), 0); var trustLevel = trustedKey.hasNonNull("trustLevel") ? TrustLevel.fromInt(trustedKey.get( diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonSessionStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonSessionStore.java index df8f5cdada..73a85f76a5 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonSessionStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/protocol/LegacyJsonSessionStore.java @@ -7,7 +7,7 @@ import org.asamk.signal.manager.storage.Utils; import org.asamk.signal.manager.storage.recipients.RecipientAddress; -import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.util.UuidUtil; import java.io.IOException; @@ -48,7 +48,7 @@ public LegacyJsonSessionStore deserialize( var uuid = session.hasNonNull("uuid") ? UuidUtil.parseOrNull(session.get("uuid").asText()) : null; final var address = uuid == null ? Utils.getRecipientAddressFromIdentifier(sessionName) - : new RecipientAddress(ServiceId.from(uuid), sessionName); + : new RecipientAddress(ACI.from(uuid), sessionName); final var deviceId = session.get("deviceId").asInt(); final var record = Base64.getDecoder().decode(session.get("record").asText()); var sessionInfo = new LegacySessionInfo(address, deviceId, record); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientAddress.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientAddress.java index f323a5cb2c..86ada86ab3 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientAddress.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientAddress.java @@ -1,7 +1,8 @@ package org.asamk.signal.manager.storage.recipients; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.util.Optional; @@ -63,7 +64,7 @@ public RecipientAddress(SignalServiceAddress address) { } public RecipientAddress(org.asamk.signal.manager.api.RecipientAddress address) { - this(address.uuid().map(ServiceId::from), Optional.empty(), address.number(), address.username()); + this(address.uuid().map(ACI::from), Optional.empty(), address.number(), address.username()); } public RecipientAddress(ServiceId serviceId) { @@ -169,11 +170,11 @@ public boolean isServiceIdPNI() { } public SignalServiceAddress toSignalServiceAddress() { - return new SignalServiceAddress(serviceId.orElse(ServiceId.UNKNOWN), number); + return new SignalServiceAddress(serviceId.orElse(ACI.UNKNOWN), number); } public org.asamk.signal.manager.api.RecipientAddress toApiRecipientAddress() { - return new org.asamk.signal.manager.api.RecipientAddress(serviceId().map(ServiceId::uuid), + return new org.asamk.signal.manager.api.RecipientAddress(serviceId().map(ServiceId::getRawUuid), number(), username()); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java index 9c13459b87..5a112c7904 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientStore.java @@ -13,9 +13,9 @@ import org.signal.libsignal.zkgroup.profiles.ProfileKey; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.util.UuidUtil; @@ -509,7 +509,7 @@ void addLegacyRecipients(final Map recipients) { statement.setBytes(3, recipient.getAddress() .serviceId() - .map(ServiceId::uuid) + .map(ServiceId::getRawUuid) .map(UuidUtil::toByteArray) .orElse(null)); statement.executeUpdate(); @@ -754,8 +754,9 @@ private RecipientId addNewRecipient( ).formatted(TABLE_RECIPIENT); try (final var statement = connection.prepareStatement(sql)) { statement.setString(1, address.number().orElse(null)); - statement.setBytes(2, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); - statement.setBytes(3, address.pni().map(PNI::uuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(2, + address.serviceId().map(ServiceId::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(3, address.pni().map(PNI::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); statement.executeUpdate(); final var generatedKeys = statement.getGeneratedKeys(); if (generatedKeys.next()) { @@ -794,8 +795,9 @@ private void updateRecipientAddress( ).formatted(TABLE_RECIPIENT); try (final var statement = connection.prepareStatement(sql)) { statement.setString(1, address.number().orElse(null)); - statement.setBytes(2, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); - statement.setBytes(3, address.pni().map(PNI::uuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(2, + address.serviceId().map(ServiceId::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(3, address.pni().map(PNI::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); statement.setString(4, address.username().orElse(null)); statement.setLong(5, recipientId.id()); statement.executeUpdate(); @@ -886,7 +888,7 @@ private Optional findByServiceId( LIMIT 1 """.formatted(TABLE_RECIPIENT); try (final var statement = connection.prepareStatement(sql)) { - statement.setBytes(1, UuidUtil.toByteArray(serviceId.uuid())); + statement.setBytes(1, UuidUtil.toByteArray(serviceId.getRawUuid())); return Utils.executeQueryForOptional(statement, this::getRecipientWithAddressFromResultSet); } } @@ -903,8 +905,9 @@ private Set findAllByAddress( r.username = ?4 """.formatted(TABLE_RECIPIENT); try (final var statement = connection.prepareStatement(sql)) { - statement.setBytes(1, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); - statement.setBytes(2, address.pni().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(1, + address.serviceId().map(ServiceId::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); + statement.setBytes(2, address.pni().map(ServiceId::getRawUuid).map(UuidUtil::toByteArray).orElse(null)); statement.setString(3, address.number().orElse(null)); statement.setString(4, address.username().orElse(null)); return Utils.executeQueryForStream(statement, this::getRecipientWithAddressFromResultSet) diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java index 9fc46d675f..54e5d5d15b 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/recipients/RecipientTrustedResolver.java @@ -1,8 +1,8 @@ package org.asamk.signal.manager.storage.recipients; -import org.whispersystems.signalservice.api.push.ACI; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.ACI; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import java.util.Optional; diff --git a/lib/src/test/java/org/asamk/signal/manager/storage/recipients/MergeRecipientHelperTest.java b/lib/src/test/java/org/asamk/signal/manager/storage/recipients/MergeRecipientHelperTest.java index 42a57d3577..a617ce93c6 100644 --- a/lib/src/test/java/org/asamk/signal/manager/storage/recipients/MergeRecipientHelperTest.java +++ b/lib/src/test/java/org/asamk/signal/manager/storage/recipients/MergeRecipientHelperTest.java @@ -3,8 +3,8 @@ import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; -import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId; +import org.whispersystems.signalservice.api.push.ServiceId.PNI; import java.util.Arrays; import java.util.HashSet; @@ -17,170 +17,90 @@ class MergeRecipientHelperTest { - static final ServiceId SERVICE_ID_A = ServiceId.from(UUID.randomUUID()); - static final ServiceId SERVICE_ID_B = ServiceId.from(UUID.randomUUID()); - static final ServiceId SERVICE_ID_C = ServiceId.from(UUID.randomUUID()); + static final ServiceId SERVICE_ID_A = ServiceId.ACI.from(UUID.randomUUID()); + static final ServiceId SERVICE_ID_B = ServiceId.ACI.from(UUID.randomUUID()); static final PNI PNI_A = PNI.from(UUID.randomUUID()); static final PNI PNI_B = PNI.from(UUID.randomUUID()); - static final PNI PNI_C = PNI.from(UUID.randomUUID()); static final String NUMBER_A = "+AAA"; static final String NUMBER_B = "+BBB"; - static final String NUMBER_C = "+CCC"; static final PartialAddresses ADDR_A = new PartialAddresses(SERVICE_ID_A, PNI_A, NUMBER_A); static final PartialAddresses ADDR_B = new PartialAddresses(SERVICE_ID_B, PNI_B, NUMBER_B); static T[] testInstancesNone = new T[]{ - // 1 new T(Set.of(), ADDR_A.FULL, Set.of(rec(1000000, ADDR_A.FULL))), new T(Set.of(), ADDR_A.ACI_NUM, Set.of(rec(1000000, ADDR_A.ACI_NUM))), new T(Set.of(), ADDR_A.ACI_PNI, Set.of(rec(1000000, ADDR_A.ACI_PNI))), - new T(Set.of(), ADDR_A.PNI_S_NUM, Set.of(rec(1000000, ADDR_A.PNI_S_NUM))), new T(Set.of(), ADDR_A.PNI_NUM, Set.of(rec(1000000, ADDR_A.PNI_NUM))), }; static T[] testInstancesSingle = new T[]{ - // 1 new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.PNI)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI_NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.PNI_NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S_NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI_PNI)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - // 10 new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.PNI), rec(1000000, ADDR_A.ACI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S)), - ADDR_A.ACI_NUM, - Set.of(rec(1, ADDR_A.PNI_S), rec(1000000, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.ACI_NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI_NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.PNI), rec(1000000, ADDR_A.ACI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S_NUM)), - ADDR_A.ACI_NUM, - Set.of(rec(1, ADDR_A.PNI_S), rec(1000000, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.ACI_PNI)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.FULL))), - // 19 new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.ACI), rec(1000000, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.ACI_NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.ACI), rec(1000000, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI_NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S_NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.ACI_PNI)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.FULL))), - // 28 - new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.ACI)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.ACI), rec(1000000, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.NUM)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.ACI_NUM)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.ACI), rec(1000000, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_NUM)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S_NUM)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.ACI_PNI)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.FULL))), - - // 37 new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), new T(Set.of(rec(1, ADDR_A.PNI)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), - new T(Set.of(rec(1, ADDR_A.PNI_S)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), new T(Set.of(rec(1, ADDR_A.NUM)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.NUM), rec(1000000, ADDR_A.ACI_PNI))), new T(Set.of(rec(1, ADDR_A.ACI_NUM)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.PNI_NUM)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S_NUM)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI_PNI)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), new T(Set.of(rec(1, ADDR_A.FULL)), ADDR_B.FULL, Set.of(rec(1, ADDR_A.FULL), rec(1000000, ADDR_B.FULL))), }; static T[] testInstancesTwo = new T[]{ - // 1 new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.ACI_NUM)), ADDR_A.FULL, Set.of(rec(2, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.ACI_NUM)), ADDR_A.FULL, Set.of(rec(2, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.PNI_S)), ADDR_A.FULL, Set.of(rec(2, ADDR_A.FULL))), new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.ACI_PNI)), ADDR_A.FULL, Set.of(rec(2, ADDR_A.FULL))), - // 12 new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.ACI_NUM))), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM)), - ADDR_A.ACI_NUM, - Set.of(rec(1, ADDR_A.ACI_NUM), rec(2, ADDR_A.PNI_S))), new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.ACI_PNI)), ADDR_A.ACI_NUM, Set.of(rec(2, ADDR_A.FULL))), - // 16 new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM)), - ADDR_A.PNI_NUM, - Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.ACI_NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM), rec(2, ADDR_A.ACI))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.ACI_NUM)), - ADDR_A.PNI_NUM, - Set.of(rec(1, ADDR_A.PNI_NUM), rec(2, ADDR_A.ACI))), - new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.PNI_S)), ADDR_A.PNI_NUM, Set.of(rec(2, ADDR_A.PNI_NUM))), new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.ACI_PNI)), ADDR_A.PNI_NUM, Set.of(rec(2, ADDR_A.FULL))), - // 24 - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.NUM)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.ACI_NUM)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.PNI_NUM), rec(2, ADDR_A.ACI))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.NUM)), ADDR_A.PNI_S_NUM, Set.of(rec(1, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.ACI_NUM)), - ADDR_A.PNI_S_NUM, - Set.of(rec(1, ADDR_A.PNI_S_NUM), rec(2, ADDR_A.ACI))), - new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.PNI_S)), ADDR_A.PNI_S_NUM, Set.of(rec(2, ADDR_A.PNI_S_NUM))), - new T(Set.of(rec(1, ADDR_A.NUM), rec(2, ADDR_A.ACI_PNI)), ADDR_A.PNI_S_NUM, Set.of(rec(2, ADDR_A.FULL))), - - // 32 new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.ACI_PNI))), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)), ADDR_A.ACI_PNI, Set.of(rec(1, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_S_NUM)), - ADDR_A.ACI_PNI, - Set.of(rec(1, ADDR_A.ACI_PNI), rec(2, ADDR_A.NUM))), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.ACI_NUM)), ADDR_A.ACI_PNI, Set.of(rec(2, ADDR_A.FULL))), - new T(Set.of(rec(1, ADDR_A.PNI_S), rec(2, ADDR_A.ACI_NUM)), ADDR_A.ACI_PNI, Set.of(rec(2, ADDR_A.FULL))), }; static T[] testInstancesThree = new T[]{ - // 1 new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI), rec(3, ADDR_A.NUM)), ADDR_A.FULL, Set.of(rec(1, ADDR_A.FULL))), @@ -307,11 +227,9 @@ private record PartialAddresses( RecipientAddress FULL, RecipientAddress ACI, RecipientAddress PNI, - RecipientAddress PNI_S, RecipientAddress NUM, RecipientAddress ACI_NUM, RecipientAddress PNI_NUM, - RecipientAddress PNI_S_NUM, RecipientAddress ACI_PNI ) { @@ -319,11 +237,9 @@ private record PartialAddresses( this(new RecipientAddress(serviceId, pni, number), new RecipientAddress(serviceId, null, null), new RecipientAddress(null, pni, null), - new RecipientAddress(ServiceId.from(pni.uuid()), null, null), new RecipientAddress(null, null, number), new RecipientAddress(serviceId, null, number), new RecipientAddress(null, pni, number), - new RecipientAddress(ServiceId.from(pni.uuid()), null, number), new RecipientAddress(serviceId, pni, null)); } } diff --git a/settings.gradle.kts b/settings.gradle.kts index 941d9ce040..14a476ce0f 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -16,7 +16,7 @@ dependencyResolutionManagement { library("logback", "ch.qos.logback", "logback-classic").version("1.4.8") - library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_76") + library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_77") library("protobuf", "com.google.protobuf", "protobuf-javalite").version("3.23.0") library("sqlite", "org.xerial", "sqlite-jdbc").version("3.42.0.0") library("hikari", "com.zaxxer", "HikariCP").version("5.0.1")