Update libsignal-service

This commit is contained in:
AsamK 2023-08-06 16:24:30 +02:00
parent 409a707baa
commit 86e1079195
27 changed files with 152 additions and 208 deletions

View file

@ -1,6 +1,7 @@
# Changelog # Changelog
## [Unreleased] ## [Unreleased]
**Attention**: Now requires native libsignal-client version 0.30.0
## [0.11.11] - 2023-05-24 ## [0.11.11] - 2023-05-24
**Attention**: Now requires native libsignal-client version 0.25.0 **Attention**: Now requires native libsignal-client version 0.25.0

View file

@ -1934,7 +1934,7 @@
}, },
{ {
"name":"org.signal.storageservice.protos.groups.local.DecryptedBannedMember", "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", "name":"org.signal.storageservice.protos.groups.local.DecryptedGroup",
@ -1958,7 +1958,7 @@
}, },
{ {
"name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMember", "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", "name":"org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval",
@ -2517,7 +2517,7 @@
}, },
{ {
"name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$ContactDetails", "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", "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$ContactDetails$Avatar",
@ -2661,7 +2661,7 @@
}, },
{ {
"name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$Blocked", "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", "name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$SyncMessage$CallEvent",
@ -2745,7 +2745,7 @@
}, },
{ {
"name":"org.whispersystems.signalservice.internal.push.SignalServiceProtos$Verified", "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", "name":"org.whispersystems.signalservice.internal.push.StaleDevices",
@ -2812,7 +2812,7 @@
}, },
{ {
"name":"org.whispersystems.signalservice.internal.storage.protos.AccountRecord$PinnedConversation$Contact", "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", "name":"org.whispersystems.signalservice.internal.storage.protos.ContactRecord",

View file

@ -1,14 +1,14 @@
package org.asamk.signal.manager.api; 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.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
public record RecipientAddress(Optional<UUID> uuid, Optional<String> number, Optional<String> username) { public record RecipientAddress(Optional<UUID> uuid, Optional<String> number, Optional<String> username) {
public static final UUID UNKNOWN_UUID = ServiceId.UNKNOWN.uuid(); public static final UUID UNKNOWN_UUID = UuidUtil.UNKNOWN_UUID;
/** /**
* Construct a RecipientAddress. * Construct a RecipientAddress.
@ -32,7 +32,7 @@ public record RecipientAddress(Optional<UUID> uuid, Optional<String> number, Opt
} }
public RecipientAddress(SignalServiceAddress address) { 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) { public RecipientAddress(UUID uuid) {

View file

@ -1,6 +1,6 @@
package org.asamk.signal.manager.helper; package org.asamk.signal.manager.helper;
import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ServiceId.ACI;
public interface AccountFileUpdater { public interface AccountFileUpdater {

View file

@ -21,8 +21,8 @@ import org.signal.libsignal.usernames.Username;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest; import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest;
import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId.PNI;
import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.SignedPreKeyEntity; import org.whispersystems.signalservice.api.push.SignedPreKeyEntity;
import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException; import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException;

View file

@ -447,7 +447,7 @@ public class GroupHelper {
private void storeProfileKeysFromMembers(final DecryptedGroup group) { private void storeProfileKeysFromMembers(final DecryptedGroup group) {
for (var member : group.getMembersList()) { 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 recipientId = account.getRecipientResolver().resolveRecipient(serviceId);
final var profileStore = account.getProfileStore(); final var profileStore = account.getProfileStore();
if (profileStore.getProfileKey(recipientId) != null) { if (profileStore.getProfileKey(recipientId) != null) {

View file

@ -39,9 +39,9 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException; import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
import org.whispersystems.signalservice.api.groupsv2.NotAbleToApplyGroupV2ChangeException; 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;
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.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException; import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException;
import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.api.util.UuidUtil;
@ -124,7 +124,7 @@ class GroupV2Helper {
} }
int findRevisionWeWereAdded(DecryptedGroup partialDecryptedGroup) { int findRevisionWeWereAdded(DecryptedGroup partialDecryptedGroup) {
ByteString bytes = UuidUtil.toByteString(getSelfAci().uuid()); ByteString bytes = getSelfAci().toByteString();
for (DecryptedMember decryptedMember : partialDecryptedGroup.getMembersList()) { for (DecryptedMember decryptedMember : partialDecryptedGroup.getMembersList()) {
if (decryptedMember.getUuid().equals(bytes)) { if (decryptedMember.getUuid().equals(bytes)) {
return decryptedMember.getJoinedAtRevision(); return decryptedMember.getJoinedAtRevision();
@ -175,11 +175,11 @@ class GroupV2Helper {
return null; 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 memberList = new ArrayList<>(members);
final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream(); final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream();
final var uuids = 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, var candidates = Utils.zip(uuids,
credentials, credentials,
(uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential))) (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential)))
@ -227,18 +227,18 @@ class GroupV2Helper {
final var memberList = new ArrayList<>(newMembers); final var memberList = new ArrayList<>(newMembers);
final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream(); final var credentials = context.getProfileHelper().getExpiringProfileKeyCredential(memberList).stream();
final var uuids = 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, var candidates = Utils.zip(uuids,
credentials, credentials,
(uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential))) (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential)))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var bannedUuids = groupInfoV2.getBannedMembers() final var bannedUuids = groupInfoV2.getBannedMembers()
.stream() .stream()
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var aci = getSelfAci(); 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()); change.setSourceUuid(getSelfAci().toByteString());
@ -250,7 +250,7 @@ class GroupV2Helper {
) throws IOException { ) throws IOException {
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList(); var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
final var selfAci = getSelfAci(); final var selfAci = getSelfAci();
var selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList, selfAci.uuid()); var selfPendingMember = DecryptedGroupUtil.findPendingByServiceId(pendingMembersList, selfAci);
if (selfPendingMember.isPresent()) { if (selfPendingMember.isPresent()) {
return revokeInvites(groupInfoV2, Set.of(selfPendingMember.get())); return revokeInvites(groupInfoV2, Set.of(selfPendingMember.get()));
@ -259,11 +259,11 @@ class GroupV2Helper {
final var adminUuids = membersToMakeAdmin.stream() final var adminUuids = membersToMakeAdmin.stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getServiceId) .map(SignalServiceAddress::getServiceId)
.map(ServiceId::uuid) .map(ServiceId::getRawUuid)
.toList(); .toList();
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
return commitChange(groupInfoV2, return commitChange(groupInfoV2,
groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.uuid(), adminUuids)); groupOperations.createLeaveAndPromoteMembersToAdmin(selfAci.getRawUuid(), adminUuids));
} }
Pair<DecryptedGroup, GroupChange> removeMembers( Pair<DecryptedGroup, GroupChange> removeMembers(
@ -272,7 +272,7 @@ class GroupV2Helper {
final var memberUuids = members.stream() final var memberUuids = members.stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getServiceId) .map(SignalServiceAddress::getServiceId)
.map(ServiceId::uuid) .map(ServiceId::getRawUuid)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return ejectMembers(groupInfoV2, memberUuids); return ejectMembers(groupInfoV2, memberUuids);
} }
@ -283,7 +283,7 @@ class GroupV2Helper {
final var memberUuids = members.stream() final var memberUuids = members.stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getServiceId) .map(SignalServiceAddress::getServiceId)
.map(ServiceId::uuid) .map(ServiceId::getRawUuid)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return approveJoinRequest(groupInfoV2, memberUuids); return approveJoinRequest(groupInfoV2, memberUuids);
} }
@ -294,7 +294,7 @@ class GroupV2Helper {
final var memberUuids = members.stream() final var memberUuids = members.stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getServiceId) .map(SignalServiceAddress::getServiceId)
.map(ServiceId::uuid) .map(ServiceId::getRawUuid)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
return refuseJoinRequest(groupInfoV2, memberUuids); return refuseJoinRequest(groupInfoV2, memberUuids);
} }
@ -306,8 +306,7 @@ class GroupV2Helper {
final var memberUuids = members.stream() final var memberUuids = members.stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getServiceId) .map(SignalServiceAddress::getServiceId)
.map(ServiceId::uuid) .map(uuid -> DecryptedGroupUtil.findPendingByServiceId(pendingMembersList, uuid))
.map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid))
.filter(Optional::isPresent) .filter(Optional::isPresent)
.map(Optional::get) .map(Optional::get)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
@ -320,7 +319,10 @@ class GroupV2Helper {
GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
final var uuids = block.stream() final var uuids = block.stream()
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) .map(member -> context.getRecipientHelper()
.resolveSignalServiceAddress(member)
.getServiceId()
.getRawUuid())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var change = groupOperations.createBanUuidsChange(uuids, final var change = groupOperations.createBanUuidsChange(uuids,
@ -337,11 +339,11 @@ class GroupV2Helper {
) throws IOException { ) throws IOException {
GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
final var uuids = block.stream() final var serviceIds = block.stream()
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId())
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var change = groupOperations.createUnbanUuidsChange(uuids); final var change = groupOperations.createUnbanServiceIdsChange(serviceIds);
change.setSourceUuid(getSelfAci().toByteString()); change.setSourceUuid(getSelfAci().toByteString());
@ -394,7 +396,8 @@ class GroupV2Helper {
Pair<DecryptedGroup, GroupChange> updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException { Pair<DecryptedGroup, GroupChange> updateSelfProfileKey(GroupInfoV2 groupInfoV2) throws IOException {
Optional<DecryptedMember> selfInGroup = groupInfoV2.getGroup() == null Optional<DecryptedMember> selfInGroup = groupInfoV2.getGroup() == null
? Optional.empty() ? Optional.empty()
: DecryptedGroupUtil.findMemberByUuid(groupInfoV2.getGroup().getMembersList(), getSelfAci().uuid()); : DecryptedGroupUtil.findMemberByUuid(groupInfoV2.getGroup().getMembersList(),
getSelfAci().getRawUuid());
if (selfInGroup.isEmpty()) { if (selfInGroup.isEmpty()) {
logger.trace("Not updating group, self not in group " + groupInfoV2.getGroupId().toBase64()); logger.trace("Not updating group, self not in group " + groupInfoV2.getGroupId().toBase64());
return null; return null;
@ -471,8 +474,12 @@ class GroupV2Helper {
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId); final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT; final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT;
final var change = groupOperations.createChangeMemberRole(address.getServiceId().uuid(), newRole); if (address.getServiceId() instanceof ACI aci) {
final var change = groupOperations.createChangeMemberRole(aci, newRole);
return commitChange(groupInfoV2, change); return commitChange(groupInfoV2, change);
} else {
throw new IllegalArgumentException("Can't make a PNI a group admin.");
}
} }
Pair<DecryptedGroup, GroupChange> setMessageExpirationTimer( Pair<DecryptedGroup, GroupChange> setMessageExpirationTimer(
@ -558,7 +565,7 @@ class GroupV2Helper {
final DecryptedGroup decryptedGroupState; final DecryptedGroup decryptedGroupState;
try { try {
decryptedChange = groupOperations.decryptChange(changeActions, getSelfAci().uuid()); decryptedChange = groupOperations.decryptChange(changeActions, getSelfAci());
decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange); decryptedGroupState = DecryptedGroupUtil.apply(previousGroupState, decryptedChange);
} catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) { } catch (VerificationFailedException | InvalidGroupStateException | NotAbleToApplyGroupV2ChangeException e) {
throw new IOException(e); throw new IOException(e);
@ -610,7 +617,7 @@ class GroupV2Helper {
return null; return null;
} }
return new Pair<>(ServiceId.from(editor), profileKey); return new Pair<>(ACI.from(editor), profileKey);
} }
DecryptedGroup getUpdatedDecryptedGroup(DecryptedGroup group, DecryptedGroupChange decryptedGroupChange) { DecryptedGroup getUpdatedDecryptedGroup(DecryptedGroup group, DecryptedGroupChange decryptedGroupChange) {

View file

@ -66,9 +66,9 @@ import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage
import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessage; import org.whispersystems.signalservice.api.messages.SignalServiceStoryMessage;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOperationMessage; 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;
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.SignalServiceAddress;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException; import org.whispersystems.signalservice.internal.push.UnsupportedDataMessageException;
@ -139,7 +139,7 @@ public final class IncomingMessageHandler {
final var actions = new ArrayList<HandleAction>(); final var actions = new ArrayList<HandleAction>();
if (envelope.hasSourceServiceId()) { if (envelope.hasSourceServiceId()) {
// Store uuid if we don't have it already // 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()); account.getRecipientTrustedResolver().resolveRecipientTrusted(envelope.getSourceAddress());
} }
SignalServiceContent content = null; SignalServiceContent content = null;
@ -409,7 +409,7 @@ public final class IncomingMessageHandler {
private boolean handlePniSignatureMessage( private boolean handlePniSignatureMessage(
final SignalServicePniSignatureMessage message, final SignalServiceAddress senderAddress 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 aciIdentity = account.getIdentityKeyStore().getIdentityInfo(aci);
final var pni = message.getPni(); final var pni = message.getPni();
final var pniIdentity = account.getIdentityKeyStore().getIdentityInfo(pni); final var pniIdentity = account.getIdentityKeyStore().getIdentityInfo(pni);
@ -428,7 +428,9 @@ public final class IncomingMessageHandler {
logger.debug("Verified association of ACI {} with PNI {}", aci, pni); logger.debug("Verified association of ACI {} with PNI {}", aci, pni);
account.getRecipientTrustedResolver() 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; return true;
} }

View file

@ -12,7 +12,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.SignalWebSocket; import org.whispersystems.signalservice.api.SignalWebSocket;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; 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.WebSocketConnectionState;
import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException; import org.whispersystems.signalservice.api.websocket.WebSocketUnavailableException;
@ -228,7 +228,7 @@ public class ReceiveHelper {
final var address = ((UntrustedIdentityException) exception).getSender(); final var address = ((UntrustedIdentityException) exception).getSender();
if (!envelope.hasSourceServiceId() && address.uuid().isPresent()) { if (!envelope.hasSourceServiceId() && address.uuid().isPresent()) {
final var recipientId = account.getRecipientResolver() final var recipientId = account.getRecipientResolver()
.resolveRecipient(ServiceId.from(address.uuid().get())); .resolveRecipient(ACI.from(address.uuid().get()));
try { try {
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId); cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
} catch (IOException ioException) { } catch (IOException ioException) {

View file

@ -10,9 +10,9 @@ import org.signal.libsignal.usernames.BaseUsernameException;
import org.signal.libsignal.usernames.Username; import org.signal.libsignal.usernames.Username;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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;
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.SignalServiceAddress;
import org.whispersystems.signalservice.api.services.CdsiV2Service; import org.whispersystems.signalservice.api.services.CdsiV2Service;
import org.whispersystems.util.Base64UrlSafe; import org.whispersystems.util.Base64UrlSafe;
@ -80,7 +80,7 @@ public class RecipientHelper {
public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws UnregisteredRecipientException { public RecipientId resolveRecipient(final RecipientIdentifier.Single recipient) throws UnregisteredRecipientException {
if (recipient instanceof RecipientIdentifier.Uuid uuidRecipient) { 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) { } else if (recipient instanceof RecipientIdentifier.Number numberRecipient) {
final var number = numberRecipient.number(); final var number = numberRecipient.number();
return account.getRecipientStore().resolveRecipientByNumber(number, () -> { return account.getRecipientStore().resolveRecipientByNumber(number, () -> {

View file

@ -41,6 +41,7 @@ import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredExcepti
import org.whispersystems.signalservice.api.push.exceptions.RateLimitException; import org.whispersystems.signalservice.api.push.exceptions.RateLimitException;
import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException;
import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException; import org.whispersystems.signalservice.internal.push.exceptions.InvalidUnidentifiedAccessHeaderException;
import org.whispersystems.signalservice.internal.push.http.PartialSendCompleteListener;
import java.io.IOException; import java.io.IOException;
import java.time.Duration; import java.time.Duration;
@ -330,14 +331,7 @@ public class SendHelper {
final AtomicLong entryId = new AtomicLong(-1); final AtomicLong entryId = new AtomicLong(-1);
final var urgent = true; final var urgent = true;
final LegacySenderHandler legacySender = (recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendDataMessage( final PartialSendCompleteListener partialSendCompleteListener = sendResult -> {
recipients,
unidentifiedAccess,
isRecipientUpdate,
contentHint,
message,
SignalServiceMessageSender.LegacyGroupEvents.EMPTY,
sendResult -> {
logger.trace("Partial message send result: {}", sendResult.isSuccess()); logger.trace("Partial message send result: {}", sendResult.isSuccess());
synchronized (entryId) { synchronized (entryId) {
if (entryId.get() == -1) { if (entryId.get() == -1) {
@ -350,9 +344,28 @@ public class SendHelper {
messageSendLogStore.addRecipientToExistingEntryIfPossible(entryId.get(), sendResult); 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, () -> false,
urgent); 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( final SenderKeySenderHandler senderKeySender = (distId, recipients, unidentifiedAccess, isRecipientUpdate) -> messageSender.sendGroupDataMessage(
distId, distId,
recipients, recipients,

View file

@ -101,15 +101,16 @@ public class StorageHelper {
} }
final var contactRecord = record.getContact().get(); final var contactRecord = record.getContact().get();
final var serviceId = contactRecord.getServiceId(); final var aci = contactRecord.getAci();
if (contactRecord.getNumber().isEmpty() && serviceId.isUnknown()) { final var pni = contactRecord.getPni().orElse(null);
if (contactRecord.getNumber().isEmpty() && aci.isUnknown()) {
return; 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); var recipientId = account.getRecipientResolver().resolveRecipient(address);
if (serviceId.isValid() && contactRecord.getUsername().isPresent()) { if (aci.isValid() && contactRecord.getUsername().isPresent()) {
recipientId = account.getRecipientTrustedResolver() recipientId = account.getRecipientTrustedResolver()
.resolveRecipientTrusted(serviceId, contactRecord.getUsername().get()); .resolveRecipientTrusted(aci, contactRecord.getUsername().get());
} }
final var contact = account.getContactStore().getContact(recipientId); final var contact = account.getContactStore().getContact(recipientId);
@ -170,15 +171,15 @@ public class StorageHelper {
logger.warn("Received invalid contact profile key from storage"); logger.warn("Received invalid contact profile key from storage");
} }
} }
if (contactRecord.getIdentityKey().isPresent() && serviceId.isValid()) { if (contactRecord.getIdentityKey().isPresent() && aci.isValid()) {
try { try {
logger.trace("Storing identity key {}", recipientId); logger.trace("Storing identity key {}", recipientId);
final var identityKey = new IdentityKey(contactRecord.getIdentityKey().get()); 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()); final var trustLevel = TrustLevel.fromIdentityState(contactRecord.getIdentityState());
if (trustLevel != null) { if (trustLevel != null) {
account.getIdentityKeyStore().setIdentityTrustLevel(serviceId, identityKey, trustLevel); account.getIdentityKeyStore().setIdentityTrustLevel(aci, identityKey, trustLevel);
} }
} catch (InvalidKeyException e) { } catch (InvalidKeyException e) {
logger.warn("Received invalid contact identity key from storage"); logger.warn("Received invalid contact identity key from storage");

View file

@ -2,7 +2,7 @@ package org.asamk.signal.manager.internal;
import org.asamk.signal.manager.helper.AccountFileUpdater; import org.asamk.signal.manager.helper.AccountFileUpdater;
import org.asamk.signal.manager.storage.accounts.AccountsStore; 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 { public class AccountFileUpdaterImpl implements AccountFileUpdater {

View file

@ -80,8 +80,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServicePreview; import org.whispersystems.signalservice.api.messages.SignalServicePreview;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceTypingMessage; 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;
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.util.DeviceNameUtil; import org.whispersystems.signalservice.api.util.DeviceNameUtil;
import org.whispersystems.signalservice.api.util.InvalidNumberException; import org.whispersystems.signalservice.api.util.InvalidNumberException;
@ -239,7 +239,7 @@ public class ManagerImpl implements Manager {
: context.getProfileHelper() : context.getProfileHelper()
.getRecipientProfile(account.getRecipientResolver().resolveRecipient(serviceId)); .getRecipientProfile(account.getRecipientResolver().resolveRecipient(serviceId));
return new UserStatus(number.isEmpty() ? null : number, return new UserStatus(number.isEmpty() ? null : number,
serviceId == null ? null : serviceId.uuid(), serviceId == null ? null : serviceId.getRawUuid(),
profile != null profile != null
&& profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED); && profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED);
})); }));
@ -700,7 +700,7 @@ public class ManagerImpl implements Manager {
for (final var recipient : recipients) { for (final var recipient : recipients) {
if (recipient instanceof RecipientIdentifier.Uuid u) { if (recipient instanceof RecipientIdentifier.Uuid u) {
account.getMessageSendLogStore() account.getMessageSendLogStore()
.deleteEntryForRecipientNonGroup(targetSentTimestamp, ServiceId.from(u.uuid())); .deleteEntryForRecipientNonGroup(targetSentTimestamp, ACI.from(u.uuid()));
} else if (recipient instanceof RecipientIdentifier.Single r) { } else if (recipient instanceof RecipientIdentifier.Single r) {
try { try {
final var recipientId = context.getRecipientHelper().resolveRecipient(r); final var recipientId = context.getRecipientHelper().resolveRecipient(r);

View file

@ -39,8 +39,8 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.account.PreKeyCollection;
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ServiceId.ACI;
import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.ServiceId.PNI;
import org.whispersystems.signalservice.api.push.ServiceIdType; import org.whispersystems.signalservice.api.push.ServiceIdType;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException; import org.whispersystems.signalservice.api.push.exceptions.AlreadyVerifiedException;

View file

@ -15,7 +15,7 @@ import org.asamk.signal.manager.storage.sessions.SessionStore;
import org.asamk.signal.manager.storage.stickers.StickerStore; import org.asamk.signal.manager.storage.stickers.StickerStore;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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.io.File;
import java.sql.Connection; import java.sql.Connection;
@ -315,7 +315,7 @@ public class AccountDatabase extends Database {
WHERE i.uuid = ? WHERE i.uuid = ?
"""; """;
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
statement.setBytes(1, ServiceId.UNKNOWN.toByteArray()); statement.setBytes(1, ACI.UNKNOWN.toByteArray());
statement.executeUpdate(); statement.executeUpdate();
} }
} }
@ -325,7 +325,7 @@ public class AccountDatabase extends Database {
WHERE i.uuid = ? WHERE i.uuid = ?
"""; """;
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
statement.setBytes(1, ServiceId.UNKNOWN.toByteArray()); statement.setBytes(1, ACI.UNKNOWN.toByteArray());
statement.executeUpdate(); statement.executeUpdate();
} }
} }

View file

@ -67,9 +67,9 @@ import org.whispersystems.signalservice.api.account.AccountAttributes;
import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.account.PreKeyCollection;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.kbs.MasterKey; 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;
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.ServiceIdType;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest; import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
@ -558,7 +558,7 @@ public class SignalAccount implements Closeable {
} }
if (rootNode.hasNonNull("pni")) { if (rootNode.hasNonNull("pni")) {
try { try {
pni = PNI.parseOrThrow(rootNode.get("pni").asText()); pni = PNI.from(UuidUtil.parseOrThrow(rootNode.get("pni").asText()));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new IOException("Config file contains an invalid pni, needs to be a valid UUID", e); throw new IOException("Config file contains an invalid pni, needs to be a valid UUID", e);
} }
@ -967,7 +967,7 @@ public class SignalAccount implements Closeable {
.put("serviceEnvironment", serviceEnvironment == null ? null : serviceEnvironment.name()) .put("serviceEnvironment", serviceEnvironment == null ? null : serviceEnvironment.name())
.put("usernameIdentifier", username) .put("usernameIdentifier", username)
.put("uuid", aci == null ? null : aci.toString()) .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("sessionId", sessionId)
.put("sessionNumber", sessionNumber) .put("sessionNumber", sessionNumber)
.put("deviceName", encryptedDeviceName) .put("deviceName", encryptedDeviceName)

View file

@ -9,7 +9,7 @@ import org.asamk.signal.manager.storage.Utils;
import org.asamk.signal.manager.util.IOUtils; import org.asamk.signal.manager.util.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import java.io.ByteArrayInputStream; import java.io.ByteArrayInputStream;

View file

@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import org.asamk.signal.manager.storage.recipients.RecipientAddress; 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; import java.util.UUID;
@ -44,6 +44,6 @@ public class LegacyContactInfo {
@JsonIgnore @JsonIgnore
public RecipientAddress getAddress() { public RecipientAddress getAddress() {
return new RecipientAddress(uuid == null ? null : ServiceId.from(uuid), number); return new RecipientAddress(uuid == null ? null : ACI.from(uuid), number);
} }
} }

View file

@ -114,7 +114,7 @@ public final class GroupInfoV2 extends GroupInfo {
} }
return group.getMembersList() return group.getMembersList()
.stream() .stream()
.map(m -> ServiceId.fromByteString(m.getUuid())) .map(m -> ServiceId.parseOrThrow(m.getUuid()))
.map(recipientResolver::resolveRecipient) .map(recipientResolver::resolveRecipient)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@ -126,7 +126,7 @@ public final class GroupInfoV2 extends GroupInfo {
} }
return group.getBannedMembersList() return group.getBannedMembersList()
.stream() .stream()
.map(m -> ServiceId.fromByteString(m.getUuid())) .map(m -> ServiceId.parseOrThrow(m.getServiceIdBinary()))
.map(recipientResolver::resolveRecipient) .map(recipientResolver::resolveRecipient)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@ -138,7 +138,7 @@ public final class GroupInfoV2 extends GroupInfo {
} }
return group.getPendingMembersList() return group.getPendingMembersList()
.stream() .stream()
.map(m -> ServiceId.fromByteString(m.getUuid())) .map(m -> ServiceId.parseOrThrow(m.getServiceIdBinary()))
.map(recipientResolver::resolveRecipient) .map(recipientResolver::resolveRecipient)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@ -150,7 +150,7 @@ public final class GroupInfoV2 extends GroupInfo {
} }
return group.getRequestingMembersList() return group.getRequestingMembersList()
.stream() .stream()
.map(m -> ServiceId.fromByteString(m.getUuid())) .map(m -> ServiceId.parseOrThrow(m.getUuid()))
.map(recipientResolver::resolveRecipient) .map(recipientResolver::resolveRecipient)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@ -163,7 +163,7 @@ public final class GroupInfoV2 extends GroupInfo {
return group.getMembersList() return group.getMembersList()
.stream() .stream()
.filter(m -> m.getRole() == Member.Role.ADMINISTRATOR) .filter(m -> m.getRole() == Member.Role.ADMINISTRATOR)
.map(m -> ServiceId.fromByteString(m.getUuid())) .map(m -> ServiceId.parseOrThrow(m.getUuid()))
.map(recipientResolver::resolveRecipient) .map(recipientResolver::resolveRecipient)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }

View file

@ -13,7 +13,7 @@ import org.signal.libsignal.protocol.IdentityKeyPair;
import org.signal.libsignal.protocol.InvalidKeyException; import org.signal.libsignal.protocol.InvalidKeyException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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 org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.IOException; import java.io.IOException;
@ -101,7 +101,7 @@ public class LegacyJsonIdentityKeyStore {
: null; : null;
final var address = uuid == null final var address = uuid == null
? Utils.getRecipientAddressFromIdentifier(trustedKeyName) ? Utils.getRecipientAddressFromIdentifier(trustedKeyName)
: new RecipientAddress(ServiceId.from(uuid), trustedKeyName); : new RecipientAddress(ACI.from(uuid), trustedKeyName);
try { try {
var id = new IdentityKey(Base64.getDecoder().decode(trustedKey.get("identityKey").asText()), 0); var id = new IdentityKey(Base64.getDecoder().decode(trustedKey.get("identityKey").asText()), 0);
var trustLevel = trustedKey.hasNonNull("trustLevel") ? TrustLevel.fromInt(trustedKey.get( var trustLevel = trustedKey.hasNonNull("trustLevel") ? TrustLevel.fromInt(trustedKey.get(

View file

@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import org.asamk.signal.manager.storage.Utils; import org.asamk.signal.manager.storage.Utils;
import org.asamk.signal.manager.storage.recipients.RecipientAddress; 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 org.whispersystems.signalservice.api.util.UuidUtil;
import java.io.IOException; import java.io.IOException;
@ -48,7 +48,7 @@ public class LegacyJsonSessionStore {
var uuid = session.hasNonNull("uuid") ? UuidUtil.parseOrNull(session.get("uuid").asText()) : null; var uuid = session.hasNonNull("uuid") ? UuidUtil.parseOrNull(session.get("uuid").asText()) : null;
final var address = uuid == null final var address = uuid == null
? Utils.getRecipientAddressFromIdentifier(sessionName) ? Utils.getRecipientAddressFromIdentifier(sessionName)
: new RecipientAddress(ServiceId.from(uuid), sessionName); : new RecipientAddress(ACI.from(uuid), sessionName);
final var deviceId = session.get("deviceId").asInt(); final var deviceId = session.get("deviceId").asInt();
final var record = Base64.getDecoder().decode(session.get("record").asText()); final var record = Base64.getDecoder().decode(session.get("record").asText());
var sessionInfo = new LegacySessionInfo(address, deviceId, record); var sessionInfo = new LegacySessionInfo(address, deviceId, record);

View file

@ -1,7 +1,8 @@
package org.asamk.signal.manager.storage.recipients; 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;
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.SignalServiceAddress;
import java.util.Optional; import java.util.Optional;
@ -63,7 +64,7 @@ public record RecipientAddress(
} }
public RecipientAddress(org.asamk.signal.manager.api.RecipientAddress 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) { public RecipientAddress(ServiceId serviceId) {
@ -169,11 +170,11 @@ public record RecipientAddress(
} }
public SignalServiceAddress toSignalServiceAddress() { 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() { 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(), number(),
username()); username());
} }

View file

@ -13,9 +13,9 @@ import org.signal.libsignal.zkgroup.profiles.ExpiringProfileKeyCredential;
import org.signal.libsignal.zkgroup.profiles.ProfileKey; import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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;
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.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.api.util.UuidUtil;
@ -509,7 +509,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
statement.setBytes(3, statement.setBytes(3,
recipient.getAddress() recipient.getAddress()
.serviceId() .serviceId()
.map(ServiceId::uuid) .map(ServiceId::getRawUuid)
.map(UuidUtil::toByteArray) .map(UuidUtil::toByteArray)
.orElse(null)); .orElse(null));
statement.executeUpdate(); statement.executeUpdate();
@ -754,8 +754,9 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
).formatted(TABLE_RECIPIENT); ).formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
statement.setString(1, address.number().orElse(null)); statement.setString(1, address.number().orElse(null));
statement.setBytes(2, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); statement.setBytes(2,
statement.setBytes(3, address.pni().map(PNI::uuid).map(UuidUtil::toByteArray).orElse(null)); 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(); statement.executeUpdate();
final var generatedKeys = statement.getGeneratedKeys(); final var generatedKeys = statement.getGeneratedKeys();
if (generatedKeys.next()) { if (generatedKeys.next()) {
@ -794,8 +795,9 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
).formatted(TABLE_RECIPIENT); ).formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
statement.setString(1, address.number().orElse(null)); statement.setString(1, address.number().orElse(null));
statement.setBytes(2, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); statement.setBytes(2,
statement.setBytes(3, address.pni().map(PNI::uuid).map(UuidUtil::toByteArray).orElse(null)); 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.setString(4, address.username().orElse(null));
statement.setLong(5, recipientId.id()); statement.setLong(5, recipientId.id());
statement.executeUpdate(); statement.executeUpdate();
@ -886,7 +888,7 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
LIMIT 1 LIMIT 1
""".formatted(TABLE_RECIPIENT); """.formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) { 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); return Utils.executeQueryForOptional(statement, this::getRecipientWithAddressFromResultSet);
} }
} }
@ -903,8 +905,9 @@ public class RecipientStore implements RecipientIdCreator, RecipientResolver, Re
r.username = ?4 r.username = ?4
""".formatted(TABLE_RECIPIENT); """.formatted(TABLE_RECIPIENT);
try (final var statement = connection.prepareStatement(sql)) { try (final var statement = connection.prepareStatement(sql)) {
statement.setBytes(1, address.serviceId().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); statement.setBytes(1,
statement.setBytes(2, address.pni().map(ServiceId::uuid).map(UuidUtil::toByteArray).orElse(null)); 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(3, address.number().orElse(null));
statement.setString(4, address.username().orElse(null)); statement.setString(4, address.username().orElse(null));
return Utils.executeQueryForStream(statement, this::getRecipientWithAddressFromResultSet) return Utils.executeQueryForStream(statement, this::getRecipientWithAddressFromResultSet)

View file

@ -1,8 +1,8 @@
package org.asamk.signal.manager.storage.recipients; 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;
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.SignalServiceAddress;
import java.util.Optional; import java.util.Optional;

View file

@ -3,8 +3,8 @@ package org.asamk.signal.manager.storage.recipients;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource; 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;
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -17,170 +17,90 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
class MergeRecipientHelperTest { class MergeRecipientHelperTest {
static final ServiceId SERVICE_ID_A = ServiceId.from(UUID.randomUUID()); static final ServiceId SERVICE_ID_A = ServiceId.ACI.from(UUID.randomUUID());
static final ServiceId SERVICE_ID_B = ServiceId.from(UUID.randomUUID()); static final ServiceId SERVICE_ID_B = ServiceId.ACI.from(UUID.randomUUID());
static final ServiceId SERVICE_ID_C = ServiceId.from(UUID.randomUUID());
static final PNI PNI_A = PNI.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_B = PNI.from(UUID.randomUUID());
static final PNI PNI_C = PNI.from(UUID.randomUUID());
static final String NUMBER_A = "+AAA"; static final String NUMBER_A = "+AAA";
static final String NUMBER_B = "+BBB"; 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_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 final PartialAddresses ADDR_B = new PartialAddresses(SERVICE_ID_B, PNI_B, NUMBER_B);
static T[] testInstancesNone = new T[]{ 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.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_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.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))), new T(Set.of(), ADDR_A.PNI_NUM, Set.of(rec(1000000, ADDR_A.PNI_NUM))),
}; };
static T[] testInstancesSingle = new T[]{ 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.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.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)), 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.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.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_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))), 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.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.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)), 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.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.ACI_NUM)), ADDR_A.ACI_NUM, Set.of(rec(1, ADDR_A.ACI_NUM))),
new T(Set.of(rec(1, ADDR_A.PNI_NUM)), new T(Set.of(rec(1, ADDR_A.PNI_NUM)),
ADDR_A.ACI_NUM, ADDR_A.ACI_NUM,
Set.of(rec(1, ADDR_A.PNI), rec(1000000, 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))), 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.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.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)), 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.NUM)), ADDR_A.PNI_NUM, Set.of(rec(1, ADDR_A.PNI_NUM))),
new T(Set.of(rec(1, ADDR_A.ACI_NUM)), new T(Set.of(rec(1, ADDR_A.ACI_NUM)),
ADDR_A.PNI_NUM, ADDR_A.PNI_NUM,
Set.of(rec(1, ADDR_A.ACI), rec(1000000, 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_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))), 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.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.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)), 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.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.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_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.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))), 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[]{ 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)), 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.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_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.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), 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))), 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.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_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))), 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)), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI_NUM)),
ADDR_A.PNI_NUM, ADDR_A.PNI_NUM,
Set.of(rec(1, ADDR_A.ACI), rec(2, 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.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)), new T(Set.of(rec(1, ADDR_A.PNI), rec(2, ADDR_A.ACI_NUM)),
ADDR_A.PNI_NUM, ADDR_A.PNI_NUM,
Set.of(rec(1, ADDR_A.PNI_NUM), rec(2, ADDR_A.ACI))), 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))), 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)), 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_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), 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[]{ 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)), new T(Set.of(rec(1, ADDR_A.ACI), rec(2, ADDR_A.PNI), rec(3, ADDR_A.NUM)),
ADDR_A.FULL, ADDR_A.FULL,
Set.of(rec(1, ADDR_A.FULL))), Set.of(rec(1, ADDR_A.FULL))),
@ -307,11 +227,9 @@ class MergeRecipientHelperTest {
RecipientAddress FULL, RecipientAddress FULL,
RecipientAddress ACI, RecipientAddress ACI,
RecipientAddress PNI, RecipientAddress PNI,
RecipientAddress PNI_S,
RecipientAddress NUM, RecipientAddress NUM,
RecipientAddress ACI_NUM, RecipientAddress ACI_NUM,
RecipientAddress PNI_NUM, RecipientAddress PNI_NUM,
RecipientAddress PNI_S_NUM,
RecipientAddress ACI_PNI RecipientAddress ACI_PNI
) { ) {
@ -319,11 +237,9 @@ class MergeRecipientHelperTest {
this(new RecipientAddress(serviceId, pni, number), this(new RecipientAddress(serviceId, pni, number),
new RecipientAddress(serviceId, null, null), new RecipientAddress(serviceId, null, null),
new RecipientAddress(null, pni, null), new RecipientAddress(null, pni, null),
new RecipientAddress(ServiceId.from(pni.uuid()), null, null),
new RecipientAddress(null, null, number), new RecipientAddress(null, null, number),
new RecipientAddress(serviceId, null, number), new RecipientAddress(serviceId, null, number),
new RecipientAddress(null, pni, number), new RecipientAddress(null, pni, number),
new RecipientAddress(ServiceId.from(pni.uuid()), null, number),
new RecipientAddress(serviceId, pni, null)); new RecipientAddress(serviceId, pni, null));
} }
} }

View file

@ -16,7 +16,7 @@ dependencyResolutionManagement {
library("logback", "ch.qos.logback", "logback-classic").version("1.4.8") 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("protobuf", "com.google.protobuf", "protobuf-javalite").version("3.23.0")
library("sqlite", "org.xerial", "sqlite-jdbc").version("3.42.0.0") library("sqlite", "org.xerial", "sqlite-jdbc").version("3.42.0.0")
library("hikari", "com.zaxxer", "HikariCP").version("5.0.1") library("hikari", "com.zaxxer", "HikariCP").version("5.0.1")