Update libsignal-service-java

This commit is contained in:
AsamK 2022-03-17 23:24:30 +01:00
parent fd25ef539f
commit 9eb97746c1
32 changed files with 242 additions and 288 deletions

View file

@ -1573,12 +1573,17 @@
{"name":"signature_"} {"name":"signature_"}
] ]
}, },
{
"name":"org.signal.storageservice.protos.groups.BannedMember",
"fields":[{"name":"userId_"}]
},
{ {
"name":"org.signal.storageservice.protos.groups.Group", "name":"org.signal.storageservice.protos.groups.Group",
"fields":[ "fields":[
{"name":"accessControl_"}, {"name":"accessControl_"},
{"name":"announcementsOnly_"}, {"name":"announcementsOnly_"},
{"name":"avatar_"}, {"name":"avatar_"},
{"name":"bannedMembers_"},
{"name":"description_"}, {"name":"description_"},
{"name":"disappearingMessagesTimer_"}, {"name":"disappearingMessagesTimer_"},
{"name":"inviteLinkPassword_"}, {"name":"inviteLinkPassword_"},
@ -1608,9 +1613,11 @@
{ {
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions", "name":"org.signal.storageservice.protos.groups.GroupChange$Actions",
"fields":[ "fields":[
{"name":"addBannedMembers_"},
{"name":"addMembers_"}, {"name":"addMembers_"},
{"name":"addPendingMembers_"}, {"name":"addPendingMembers_"},
{"name":"addRequestingMembers_"}, {"name":"addRequestingMembers_"},
{"name":"deleteBannedMembers_"},
{"name":"deleteMembers_"}, {"name":"deleteMembers_"},
{"name":"deletePendingMembers_"}, {"name":"deletePendingMembers_"},
{"name":"deleteRequestingMembers_"}, {"name":"deleteRequestingMembers_"},
@ -1631,6 +1638,10 @@
{"name":"sourceUuid_"} {"name":"sourceUuid_"}
] ]
}, },
{
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddBannedMemberAction",
"fields":[{"name":"added_"}]
},
{ {
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddMemberAction", "name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddMemberAction",
"fields":[ "fields":[
@ -1646,6 +1657,10 @@
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddRequestingMemberAction", "name":"org.signal.storageservice.protos.groups.GroupChange$Actions$AddRequestingMemberAction",
"fields":[{"name":"added_"}] "fields":[{"name":"added_"}]
}, },
{
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteBannedMemberAction",
"fields":[{"name":"deletedUserId_"}]
},
{ {
"name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteMemberAction", "name":"org.signal.storageservice.protos.groups.GroupChange$Actions$DeleteMemberAction",
"fields":[{"name":"deletedUserId_"}] "fields":[{"name":"deletedUserId_"}]
@ -1777,11 +1792,16 @@
{"name":"uuid_"} {"name":"uuid_"}
] ]
}, },
{
"name":"org.signal.storageservice.protos.groups.local.DecryptedBannedMember",
"fields":[{"name":"uuid_"}]
},
{ {
"name":"org.signal.storageservice.protos.groups.local.DecryptedGroup", "name":"org.signal.storageservice.protos.groups.local.DecryptedGroup",
"fields":[ "fields":[
{"name":"accessControl_"}, {"name":"accessControl_"},
{"name":"avatar_"}, {"name":"avatar_"},
{"name":"bannedMembers_"},
{"name":"description_"}, {"name":"description_"},
{"name":"disappearingMessagesTimer_"}, {"name":"disappearingMessagesTimer_"},
{"name":"inviteLinkPassword_"}, {"name":"inviteLinkPassword_"},
@ -1796,6 +1816,7 @@
{ {
"name":"org.signal.storageservice.protos.groups.local.DecryptedGroupChange", "name":"org.signal.storageservice.protos.groups.local.DecryptedGroupChange",
"fields":[ "fields":[
{"name":"deleteBannedMembers_"},
{"name":"deleteMembers_"}, {"name":"deleteMembers_"},
{"name":"deletePendingMembers_"}, {"name":"deletePendingMembers_"},
{"name":"deleteRequestingMembers_"}, {"name":"deleteRequestingMembers_"},
@ -1804,6 +1825,7 @@
{"name":"modifyMemberRoles_"}, {"name":"modifyMemberRoles_"},
{"name":"newAttributeAccess_"}, {"name":"newAttributeAccess_"},
{"name":"newAvatar_"}, {"name":"newAvatar_"},
{"name":"newBannedMembers_"},
{"name":"newDescription_"}, {"name":"newDescription_"},
{"name":"newInviteLinkAccess_"}, {"name":"newInviteLinkAccess_"},
{"name":"newInviteLinkPassword_"}, {"name":"newInviteLinkPassword_"},

View file

@ -14,7 +14,7 @@ repositories {
} }
dependencies { dependencies {
implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_44") implementation("com.github.turasa", "signal-service-java", "2.15.3_unofficial_45")
implementation("com.fasterxml.jackson.core", "jackson-databind", "2.13.1") implementation("com.fasterxml.jackson.core", "jackson-databind", "2.13.1")
implementation("com.google.protobuf", "protobuf-javalite", "3.11.4") implementation("com.google.protobuf", "protobuf-javalite", "3.11.4")
implementation("org.bouncycastle", "bcprov-jdk15on", "1.70") implementation("org.bouncycastle", "bcprov-jdk15on", "1.70")

View file

@ -62,7 +62,6 @@ import org.asamk.signal.manager.util.KeyUtils;
import org.asamk.signal.manager.util.StickerUtils; import org.asamk.signal.manager.util.StickerUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalSessionLock; import org.whispersystems.signalservice.api.SignalSessionLock;
import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage; import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
@ -82,6 +81,7 @@ import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@ -246,14 +246,9 @@ class ManagerImpl implements Manager {
@Override @Override
public void setProfile( public void setProfile(
String givenName, final String familyName, String about, String aboutEmoji, java.util.Optional<File> avatar String givenName, final String familyName, String about, String aboutEmoji, Optional<File> avatar
) throws IOException { ) throws IOException {
context.getProfileHelper() context.getProfileHelper().setProfile(givenName, familyName, about, aboutEmoji, avatar);
.setProfile(givenName,
familyName,
about,
aboutEmoji,
avatar == null ? null : Optional.fromNullable(avatar.orElse(null)));
context.getSyncHelper().sendSyncFetchProfileMessage(); context.getSyncHelper().sendSyncFetchProfileMessage();
} }
@ -308,7 +303,7 @@ class ManagerImpl implements Manager {
} }
@Override @Override
public void setRegistrationLockPin(java.util.Optional<String> pin) throws IOException, NotMasterDeviceException { public void setRegistrationLockPin(Optional<String> pin) throws IOException, NotMasterDeviceException {
if (!account.isMasterDevice()) { if (!account.isMasterDevice()) {
throw new NotMasterDeviceException(); throw new NotMasterDeviceException();
} }
@ -442,7 +437,7 @@ class ManagerImpl implements Manager {
final var timestamp = System.currentTimeMillis(); final var timestamp = System.currentTimeMillis();
for (var recipient : recipients) { for (var recipient : recipients) {
if (recipient instanceof RecipientIdentifier.Single single) { if (recipient instanceof RecipientIdentifier.Single single) {
final var message = new SignalServiceTypingMessage(action, timestamp, Optional.absent()); final var message = new SignalServiceTypingMessage(action, timestamp, Optional.empty());
try { try {
final var recipientId = context.getRecipientHelper().resolveRecipient(single); final var recipientId = context.getRecipientHelper().resolveRecipient(single);
final var result = context.getSendHelper().sendTypingMessage(message, recipientId); final var result = context.getSendHelper().sendTypingMessage(message, recipientId);
@ -558,7 +553,7 @@ class ManagerImpl implements Manager {
stickerPack.getPackKey(), stickerPack.getPackKey(),
stickerId, stickerId,
manifestSticker.emoji(), manifestSticker.emoji(),
AttachmentUtils.createAttachment(streamDetails, Optional.absent()))); AttachmentUtils.createAttachment(streamDetails, Optional.empty())));
} }
} }
@ -719,7 +714,7 @@ class ManagerImpl implements Manager {
pack.isInstalled(), pack.isInstalled(),
manifest.title(), manifest.title(),
manifest.author(), manifest.author(),
java.util.Optional.ofNullable(manifest.cover() == null ? null : manifest.cover().toApi()), Optional.ofNullable(manifest.cover() == null ? null : manifest.cover().toApi()),
manifest.stickers().stream().map(JsonStickerPack.JsonSticker::toApi).toList()); manifest.stickers().stream().map(JsonStickerPack.JsonSticker::toApi).toList());
} catch (Exception e) { } catch (Exception e) {
logger.warn("Failed to read local sticker pack manifest: {}", e.getMessage(), e); logger.warn("Failed to read local sticker pack manifest: {}", e.getMessage(), e);

View file

@ -4,7 +4,6 @@ import org.asamk.signal.manager.config.ServiceConfig;
import org.asamk.signal.manager.config.ServiceEnvironmentConfig; import org.asamk.signal.manager.config.ServiceEnvironmentConfig;
import org.signal.libsignal.metadata.certificate.CertificateValidator; import org.signal.libsignal.metadata.certificate.CertificateValidator;
import org.signal.zkgroup.profiles.ClientZkProfileOperations; import org.signal.zkgroup.profiles.ClientZkProfileOperations;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.KeyBackupService; import org.whispersystems.signalservice.api.KeyBackupService;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.SignalServiceDataStore; import org.whispersystems.signalservice.api.SignalServiceDataStore;
@ -23,6 +22,7 @@ import org.whispersystems.signalservice.api.util.UptimeSleepTimer;
import org.whispersystems.signalservice.api.websocket.WebSocketFactory; import org.whispersystems.signalservice.api.websocket.WebSocketFactory;
import org.whispersystems.signalservice.internal.websocket.WebSocketConnection; import org.whispersystems.signalservice.internal.websocket.WebSocketConnection;
import java.util.Optional;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -137,7 +137,7 @@ public class SignalDependencies {
public WebSocketConnection createUnidentifiedWebSocket() { public WebSocketConnection createUnidentifiedWebSocket() {
return new WebSocketConnection("unidentified", return new WebSocketConnection("unidentified",
serviceEnvironmentConfig.getSignalServiceConfiguration(), serviceEnvironmentConfig.getSignalServiceConfiguration(),
Optional.absent(), Optional.empty(),
userAgent, userAgent,
healthMonitor); healthMonitor);
} }
@ -164,7 +164,7 @@ public class SignalDependencies {
sessionLock, sessionLock,
userAgent, userAgent,
getSignalWebSocket(), getSignalWebSocket(),
Optional.absent(), Optional.empty(),
getClientZkProfileOperations(), getClientZkProfileOperations(),
executor, executor,
ServiceConfig.MAX_ENVELOPE_SIZE, ServiceConfig.MAX_ENVELOPE_SIZE,

View file

@ -2,8 +2,8 @@ package org.asamk.signal.manager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.guava.Preconditions;
import org.whispersystems.signalservice.api.SignalWebSocket; import org.whispersystems.signalservice.api.SignalWebSocket;
import org.whispersystems.signalservice.api.util.Preconditions;
import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.SleepTimer;
import org.whispersystems.signalservice.api.websocket.HealthMonitor; import org.whispersystems.signalservice.api.websocket.HealthMonitor;
import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState; import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState;

View file

@ -6,10 +6,11 @@ import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.signal.libsignal.metadata.ProtocolException; import org.signal.libsignal.metadata.ProtocolException;
import org.whispersystems.libsignal.protocol.CiphertextMessage; import org.whispersystems.libsignal.protocol.CiphertextMessage;
import org.whispersystems.libsignal.protocol.DecryptionErrorMessage; import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope;
import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.internal.push.SignalServiceProtos;
import java.util.Optional;
public class SendRetryMessageRequestAction implements HandleAction { public class SendRetryMessageRequestAction implements HandleAction {
private final RecipientId recipientId; private final RecipientId recipientId;
@ -32,7 +33,7 @@ public class SendRetryMessageRequestAction implements HandleAction {
int senderDevice = protocolException.getSenderDevice(); int senderDevice = protocolException.getSenderDevice();
Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion( Optional<GroupId> groupId = protocolException.getGroupId().isPresent() ? Optional.of(GroupId.unknownVersion(
protocolException.getGroupId().get())) : Optional.absent(); protocolException.getGroupId().get())) : Optional.empty();
byte[] originalContent; byte[] originalContent;
int envelopeType; int envelopeType;

View file

@ -82,7 +82,7 @@ public record MessageEnvelope(
public static Typing from(final SignalServiceTypingMessage typingMessage) { public static Typing from(final SignalServiceTypingMessage typingMessage) {
return new Typing(typingMessage.getTimestamp(), return new Typing(typingMessage.getTimestamp(),
typingMessage.isTypingStarted() ? Type.STARTED : Type.STOPPED, typingMessage.isTypingStarted() ? Type.STARTED : Type.STOPPED,
Optional.ofNullable(typingMessage.getGroupId().transform(GroupId::unknownVersion).orNull())); typingMessage.getGroupId().map(GroupId::unknownVersion));
} }
public enum Type { public enum Type {
@ -119,43 +119,33 @@ public record MessageEnvelope(
final AttachmentFileProvider fileProvider final AttachmentFileProvider fileProvider
) { ) {
return new Data(dataMessage.getTimestamp(), return new Data(dataMessage.getTimestamp(),
Optional.ofNullable(dataMessage.getGroupContext().transform(GroupContext::from).orNull()), dataMessage.getGroupContext().map(GroupContext::from),
Optional.ofNullable(dataMessage.getGroupCallUpdate().transform(GroupCallUpdate::from).orNull()), dataMessage.getGroupCallUpdate().map(GroupCallUpdate::from),
Optional.ofNullable(dataMessage.getBody().orNull()), dataMessage.getBody(),
dataMessage.getExpiresInSeconds(), dataMessage.getExpiresInSeconds(),
dataMessage.isExpirationUpdate(), dataMessage.isExpirationUpdate(),
dataMessage.isViewOnce(), dataMessage.isViewOnce(),
dataMessage.isEndSession(), dataMessage.isEndSession(),
dataMessage.getProfileKey().isPresent(), dataMessage.getProfileKey().isPresent(),
Optional.ofNullable(dataMessage.getReaction() dataMessage.getReaction().map(r -> Reaction.from(r, recipientResolver, addressResolver)),
.transform(r -> Reaction.from(r, recipientResolver, addressResolver)) dataMessage.getQuote().map(q -> Quote.from(q, recipientResolver, addressResolver, fileProvider)),
.orNull()), dataMessage.getPayment().map(p -> p.getPaymentNotification().isPresent() ? Payment.from(p) : null),
Optional.ofNullable(dataMessage.getQuote()
.transform(q -> Quote.from(q, recipientResolver, addressResolver, fileProvider))
.orNull()),
Optional.ofNullable(dataMessage.getPayment()
.transform(p -> p.getPaymentNotification().isPresent() ? Payment.from(p) : null)
.orNull()),
dataMessage.getAttachments() dataMessage.getAttachments()
.transform(a -> a.stream().map(as -> Attachment.from(as, fileProvider)).toList()) .map(a -> a.stream().map(as -> Attachment.from(as, fileProvider)).toList())
.or(List.of()), .orElse(List.of()),
Optional.ofNullable(dataMessage.getRemoteDelete() dataMessage.getRemoteDelete().map(SignalServiceDataMessage.RemoteDelete::getTargetSentTimestamp),
.transform(SignalServiceDataMessage.RemoteDelete::getTargetSentTimestamp) dataMessage.getSticker().map(Sticker::from),
.orNull()),
Optional.ofNullable(dataMessage.getSticker().transform(Sticker::from).orNull()),
dataMessage.getSharedContacts() dataMessage.getSharedContacts()
.transform(a -> a.stream() .map(a -> a.stream()
.map(sharedContact -> SharedContact.from(sharedContact, fileProvider)) .map(sharedContact -> SharedContact.from(sharedContact, fileProvider))
.toList()) .toList())
.or(List.of()), .orElse(List.of()),
dataMessage.getMentions() dataMessage.getMentions()
.transform(a -> a.stream() .map(a -> a.stream().map(m -> Mention.from(m, recipientResolver, addressResolver)).toList())
.map(m -> Mention.from(m, recipientResolver, addressResolver)) .orElse(List.of()),
.toList())
.or(List.of()),
dataMessage.getPreviews() dataMessage.getPreviews()
.transform(a -> a.stream().map(preview -> Preview.from(preview, fileProvider)).toList()) .map(a -> a.stream().map(preview -> Preview.from(preview, fileProvider)).toList())
.or(List.of())); .orElse(List.of()));
} }
public record GroupContext(GroupId groupId, boolean isGroupUpdate, int revision) { public record GroupContext(GroupId groupId, boolean isGroupUpdate, int revision) {
@ -271,13 +261,13 @@ public record MessageEnvelope(
final var a = attachment.asPointer(); final var a = attachment.asPointer();
return new Attachment(Optional.of(a.getRemoteId().toString()), return new Attachment(Optional.of(a.getRemoteId().toString()),
Optional.of(fileProvider.getFile(a.getRemoteId())), Optional.of(fileProvider.getFile(a.getRemoteId())),
Optional.ofNullable(a.getFileName().orNull()), a.getFileName(),
a.getContentType(), a.getContentType(),
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()), a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
Optional.ofNullable(a.getSize().transform(Integer::longValue).orNull()), a.getSize().map(Integer::longValue),
Optional.ofNullable(a.getPreview().orNull()), a.getPreview(),
Optional.empty(), Optional.empty(),
Optional.ofNullable(a.getCaption().orNull()), a.getCaption(),
a.getWidth() == 0 ? Optional.empty() : Optional.of(a.getWidth()), a.getWidth() == 0 ? Optional.empty() : Optional.of(a.getWidth()),
a.getHeight() == 0 ? Optional.empty() : Optional.of(a.getHeight()), a.getHeight() == 0 ? Optional.empty() : Optional.of(a.getHeight()),
a.getVoiceNote(), a.getVoiceNote(),
@ -287,13 +277,13 @@ public record MessageEnvelope(
final var a = attachment.asStream(); final var a = attachment.asStream();
return new Attachment(Optional.empty(), return new Attachment(Optional.empty(),
Optional.empty(), Optional.empty(),
Optional.ofNullable(a.getFileName().orNull()), a.getFileName(),
a.getContentType(), a.getContentType(),
a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()), a.getUploadTimestamp() == 0 ? Optional.empty() : Optional.of(a.getUploadTimestamp()),
Optional.of(a.getLength()), Optional.of(a.getLength()),
Optional.ofNullable(a.getPreview().orNull()), a.getPreview(),
Optional.empty(), Optional.empty(),
Optional.ofNullable(a.getCaption().orNull()), a.getCaption(),
a.getWidth() == 0 ? Optional.empty() : Optional.of(a.getWidth()), a.getWidth() == 0 ? Optional.empty() : Optional.of(a.getWidth()),
a.getHeight() == 0 ? Optional.empty() : Optional.of(a.getHeight()), a.getHeight() == 0 ? Optional.empty() : Optional.of(a.getHeight()),
a.getVoiceNote(), a.getVoiceNote(),
@ -347,13 +337,11 @@ public record MessageEnvelope(
final AttachmentFileProvider fileProvider final AttachmentFileProvider fileProvider
) { ) {
return new SharedContact(Name.from(sharedContact.getName()), return new SharedContact(Name.from(sharedContact.getName()),
Optional.ofNullable(sharedContact.getAvatar() sharedContact.getAvatar().map(avatar1 -> Avatar.from(avatar1, fileProvider)),
.transform(avatar1 -> Avatar.from(avatar1, fileProvider)) sharedContact.getPhone().map(p -> p.stream().map(Phone::from).toList()).orElse(List.of()),
.orNull()), sharedContact.getEmail().map(p -> p.stream().map(Email::from).toList()).orElse(List.of()),
sharedContact.getPhone().transform(p -> p.stream().map(Phone::from).toList()).or(List.of()), sharedContact.getAddress().map(p -> p.stream().map(Address::from).toList()).orElse(List.of()),
sharedContact.getEmail().transform(p -> p.stream().map(Email::from).toList()).or(List.of()), sharedContact.getOrganization());
sharedContact.getAddress().transform(p -> p.stream().map(Address::from).toList()).or(List.of()),
Optional.ofNullable(sharedContact.getOrganization().orNull()));
} }
public record Name( public record Name(
@ -366,12 +354,12 @@ public record MessageEnvelope(
) { ) {
static Name from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Name name) { static Name from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Name name) {
return new Name(Optional.ofNullable(name.getDisplay().orNull()), return new Name(name.getDisplay(),
Optional.ofNullable(name.getGiven().orNull()), name.getGiven(),
Optional.ofNullable(name.getFamily().orNull()), name.getFamily(),
Optional.ofNullable(name.getPrefix().orNull()), name.getPrefix(),
Optional.ofNullable(name.getSuffix().orNull()), name.getSuffix(),
Optional.ofNullable(name.getMiddle().orNull())); name.getMiddle());
} }
} }
@ -390,9 +378,7 @@ public record MessageEnvelope(
) { ) {
static Phone from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Phone phone) { static Phone from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Phone phone) {
return new Phone(phone.getValue(), return new Phone(phone.getValue(), Type.from(phone.getType()), phone.getLabel());
Type.from(phone.getType()),
Optional.ofNullable(phone.getLabel().orNull()));
} }
public enum Type { public enum Type {
@ -417,9 +403,7 @@ public record MessageEnvelope(
) { ) {
static Email from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Email email) { static Email from(org.whispersystems.signalservice.api.messages.shared.SharedContact.Email email) {
return new Email(email.getValue(), return new Email(email.getValue(), Type.from(email.getType()), email.getLabel());
Type.from(email.getType()),
Optional.ofNullable(email.getLabel().orNull()));
} }
public enum Type { public enum Type {
@ -453,14 +437,14 @@ public record MessageEnvelope(
static Address from(org.whispersystems.signalservice.api.messages.shared.SharedContact.PostalAddress address) { static Address from(org.whispersystems.signalservice.api.messages.shared.SharedContact.PostalAddress address) {
return new Address(Address.Type.from(address.getType()), return new Address(Address.Type.from(address.getType()),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull()), address.getLabel(),
Optional.ofNullable(address.getLabel().orNull())); address.getLabel());
} }
public enum Type { public enum Type {
@ -488,9 +472,7 @@ public record MessageEnvelope(
preview.getDescription(), preview.getDescription(),
preview.getDate(), preview.getDate(),
preview.getUrl(), preview.getUrl(),
Optional.ofNullable(preview.getImage() preview.getImage().map(as -> Attachment.from(as, fileProvider)));
.transform(as -> Attachment.from(as, fileProvider))
.orNull()));
} }
} }
} }
@ -512,30 +494,22 @@ public record MessageEnvelope(
RecipientAddressResolver addressResolver, RecipientAddressResolver addressResolver,
final AttachmentFileProvider fileProvider final AttachmentFileProvider fileProvider
) { ) {
return new Sync(Optional.ofNullable(syncMessage.getSent() return new Sync(syncMessage.getSent()
.transform(s -> Sent.from(s, recipientResolver, addressResolver, fileProvider)) .map(s -> Sent.from(s, recipientResolver, addressResolver, fileProvider)),
.orNull()), syncMessage.getBlockedList().map(b -> Blocked.from(b, recipientResolver, addressResolver)),
Optional.ofNullable(syncMessage.getBlockedList()
.transform(b -> Blocked.from(b, recipientResolver, addressResolver))
.orNull()),
syncMessage.getRead() syncMessage.getRead()
.transform(r -> r.stream() .map(r -> r.stream().map(rm -> Read.from(rm, recipientResolver, addressResolver)).toList())
.map(rm -> Read.from(rm, recipientResolver, addressResolver)) .orElse(List.of()),
.toList())
.or(List.of()),
syncMessage.getViewed() syncMessage.getViewed()
.transform(r -> r.stream() .map(r -> r.stream()
.map(rm -> Viewed.from(rm, recipientResolver, addressResolver)) .map(rm -> Viewed.from(rm, recipientResolver, addressResolver))
.toList()) .toList())
.or(List.of()), .orElse(List.of()),
Optional.ofNullable(syncMessage.getViewOnceOpen() syncMessage.getViewOnceOpen().map(rm -> ViewOnceOpen.from(rm, recipientResolver, addressResolver)),
.transform(rm -> ViewOnceOpen.from(rm, recipientResolver, addressResolver)) syncMessage.getContacts().map(Contacts::from),
.orNull()), syncMessage.getGroups().map(Groups::from),
Optional.ofNullable(syncMessage.getContacts().transform(Contacts::from).orNull()), syncMessage.getMessageRequestResponse()
Optional.ofNullable(syncMessage.getGroups().transform(Groups::from).orNull()), .map(m -> MessageRequestResponse.from(m, recipientResolver, addressResolver)));
Optional.ofNullable(syncMessage.getMessageRequestResponse()
.transform(m -> MessageRequestResponse.from(m, recipientResolver, addressResolver))
.orNull()));
} }
public record Sent( public record Sent(
@ -554,10 +528,8 @@ public record MessageEnvelope(
) { ) {
return new Sent(sentMessage.getTimestamp(), return new Sent(sentMessage.getTimestamp(),
sentMessage.getExpirationStartTimestamp(), sentMessage.getExpirationStartTimestamp(),
Optional.ofNullable(sentMessage.getDestination() sentMessage.getDestination()
.transform(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient( .map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d))),
d)))
.orNull()),
sentMessage.getRecipients() sentMessage.getRecipients()
.stream() .stream()
.map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d))) .map(d -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(d)))
@ -638,13 +610,9 @@ public record MessageEnvelope(
RecipientAddressResolver addressResolver RecipientAddressResolver addressResolver
) { ) {
return new MessageRequestResponse(Type.from(messageRequestResponse.getType()), return new MessageRequestResponse(Type.from(messageRequestResponse.getType()),
Optional.ofNullable(messageRequestResponse.getGroupId() messageRequestResponse.getGroupId().map(GroupId::unknownVersion),
.transform(GroupId::unknownVersion) messageRequestResponse.getPerson()
.orNull()), .map(p -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(p))));
Optional.ofNullable(messageRequestResponse.getPerson()
.transform(p -> addressResolver.resolveRecipientAddress(recipientResolver.resolveRecipient(
p)))
.orNull()));
} }
public enum Type { public enum Type {
@ -682,17 +650,17 @@ public record MessageEnvelope(
) { ) {
public static Call from(final SignalServiceCallMessage callMessage) { public static Call from(final SignalServiceCallMessage callMessage) {
return new Call(Optional.ofNullable(callMessage.getDestinationDeviceId().orNull()), return new Call(callMessage.getDestinationDeviceId(),
Optional.ofNullable(callMessage.getGroupId().transform(GroupId::unknownVersion).orNull()), callMessage.getGroupId().map(GroupId::unknownVersion),
Optional.ofNullable(callMessage.getTimestamp().orNull()), callMessage.getTimestamp(),
Optional.ofNullable(callMessage.getOfferMessage().transform(Offer::from).orNull()), callMessage.getOfferMessage().map(Offer::from),
Optional.ofNullable(callMessage.getAnswerMessage().transform(Answer::from).orNull()), callMessage.getAnswerMessage().map(Answer::from),
Optional.ofNullable(callMessage.getHangupMessage().transform(Hangup::from).orNull()), callMessage.getHangupMessage().map(Hangup::from),
Optional.ofNullable(callMessage.getBusyMessage().transform(Busy::from).orNull()), callMessage.getBusyMessage().map(Busy::from),
callMessage.getIceUpdateMessages() callMessage.getIceUpdateMessages()
.transform(m -> m.stream().map(IceUpdate::from).toList()) .map(m -> m.stream().map(IceUpdate::from).toList())
.or(List.of()), .orElse(List.of()),
Optional.ofNullable(callMessage.getOpaqueMessage().transform(Opaque::from).orNull())); callMessage.getOpaqueMessage().map(Opaque::from));
} }
public record Offer(long id, String sdp, Type type, byte[] opaque) { public record Offer(long id, String sdp, Type type, byte[] opaque) {
@ -813,15 +781,12 @@ public record MessageEnvelope(
Optional<Sync> sync; Optional<Sync> sync;
Optional<Call> call; Optional<Call> call;
if (content != null) { if (content != null) {
receipt = Optional.ofNullable(content.getReceiptMessage().transform(Receipt::from).orNull()); receipt = content.getReceiptMessage().map(Receipt::from);
typing = Optional.ofNullable(content.getTypingMessage().transform(Typing::from).orNull()); typing = content.getTypingMessage().map(Typing::from);
data = Optional.ofNullable(content.getDataMessage() data = content.getDataMessage()
.transform(dataMessage -> Data.from(dataMessage, recipientResolver, addressResolver, fileProvider)) .map(dataMessage -> Data.from(dataMessage, recipientResolver, addressResolver, fileProvider));
.orNull()); sync = content.getSyncMessage().map(s -> Sync.from(s, recipientResolver, addressResolver, fileProvider));
sync = Optional.ofNullable(content.getSyncMessage() call = content.getCallMessage().map(Call::from);
.transform(s -> Sync.from(s, recipientResolver, addressResolver, fileProvider))
.orNull());
call = Optional.ofNullable(content.getCallMessage().transform(Call::from).orNull());
} else { } else {
receipt = envelope.isReceipt() ? Optional.of(new Receipt(envelope.getServerReceivedTimestamp(), receipt = envelope.isReceipt() ? Optional.of(new Receipt(envelope.getServerReceivedTimestamp(),
Receipt.Type.DELIVERY, Receipt.Type.DELIVERY,

View file

@ -4,7 +4,6 @@ import org.bouncycastle.util.encoders.Hex;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECPublicKey; import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl;
import org.whispersystems.signalservice.internal.configuration.SignalCdshUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdshUrl;
@ -18,6 +17,7 @@ import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import okhttp3.Dns; import okhttp3.Dns;
import okhttp3.Interceptor; import okhttp3.Interceptor;
@ -42,8 +42,8 @@ class LiveConfig {
private final static String SIGNAL_CDSH_URL = ""; private final static String SIGNAL_CDSH_URL = "";
private final static TrustStore TRUST_STORE = new WhisperTrustStore(); private final static TrustStore TRUST_STORE = new WhisperTrustStore();
private final static Optional<Dns> dns = Optional.absent(); private final static Optional<Dns> dns = Optional.empty();
private final static Optional<SignalProxy> proxy = Optional.absent(); private final static Optional<SignalProxy> proxy = Optional.empty();
private final static byte[] zkGroupServerPublicParams = Base64.getDecoder() private final static byte[] zkGroupServerPublicParams = Base64.getDecoder()
.decode("AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXQ=="); .decode("AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXQ==");

View file

@ -4,7 +4,6 @@ import org.bouncycastle.util.encoders.Hex;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.ecc.Curve; import org.whispersystems.libsignal.ecc.Curve;
import org.whispersystems.libsignal.ecc.ECPublicKey; import org.whispersystems.libsignal.ecc.ECPublicKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.push.TrustStore; import org.whispersystems.signalservice.api.push.TrustStore;
import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdnUrl;
import org.whispersystems.signalservice.internal.configuration.SignalCdshUrl; import org.whispersystems.signalservice.internal.configuration.SignalCdshUrl;
@ -18,6 +17,7 @@ import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import okhttp3.Dns; import okhttp3.Dns;
import okhttp3.Interceptor; import okhttp3.Interceptor;
@ -42,8 +42,8 @@ class StagingConfig {
private final static String SIGNAL_CDSH_URL = "https://cdsh.staging.signal.org"; private final static String SIGNAL_CDSH_URL = "https://cdsh.staging.signal.org";
private final static TrustStore TRUST_STORE = new WhisperTrustStore(); private final static TrustStore TRUST_STORE = new WhisperTrustStore();
private final static Optional<Dns> dns = Optional.absent(); private final static Optional<Dns> dns = Optional.empty();
private final static Optional<SignalProxy> proxy = Optional.absent(); private final static Optional<SignalProxy> proxy = Optional.empty();
private final static byte[] zkGroupServerPublicParams = Base64.getDecoder() private final static byte[] zkGroupServerPublicParams = Base64.getDecoder()
.decode("ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdlukrpzzsCIvEwjwQlJYVPOQPj4V0F4UXXBdHSLK05uoPBCQG8G9rYIGedYsClJXnbrgGYG3eMTG5hnx4X4ntARBgELuMWWUEEfSK0mjXg+/2lPmWcTZWR9nkqgQQP0tbzuiPm74H2wMO4u1Wafe+UwyIlIT9L7KLS19Aw8r4sPrXQ=="); .decode("ABSY21VckQcbSXVNCGRYJcfWHiAMZmpTtTELcDmxgdFbtp/bWsSxZdMKzfCp8rvIs8ocCU3B37fT3r4Mi5qAemeGeR2X+/YmOGR5ofui7tD5mDQfstAI9i+4WpMtIe8KC3wU5w3Inq3uNWVmoGtpKndsNfwJrCg0Hd9zmObhypUnSkfYn2ooMOOnBpfdanRtrvetZUayDMSC5iSRcXKpdlukrpzzsCIvEwjwQlJYVPOQPj4V0F4UXXBdHSLK05uoPBCQG8G9rYIGedYsClJXnbrgGYG3eMTG5hnx4X4ntARBgELuMWWUEEfSK0mjXg+/2lPmWcTZWR9nkqgQQP0tbzuiPm74H2wMO4u1Wafe+UwyIlIT9L7KLS19Aw8r4sPrXQ==");

View file

@ -13,13 +13,13 @@ import org.asamk.signal.manager.util.NumberVerificationUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.push.ACI; import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI; import org.whispersystems.signalservice.api.push.PNI;
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException; import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
import org.whispersystems.signalservice.api.util.DeviceNameUtil; import org.whispersystems.signalservice.api.util.DeviceNameUtil;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class AccountHelper { public class AccountHelper {
@ -176,7 +176,7 @@ public class AccountHelper {
// When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false. // When setting an empty GCM id, the Signal-Server also sets the fetchesMessages property to false.
// If this is the master device, other users can't send messages to this number anymore. // If this is the master device, other users can't send messages to this number anymore.
// If this is a linked device, other users can still send messages, but this device doesn't receive them anymore. // If this is a linked device, other users can still send messages, but this device doesn't receive them anymore.
dependencies.getAccountManager().setGcmId(Optional.absent()); dependencies.getAccountManager().setGcmId(Optional.empty());
account.setRegistered(false); account.setRegistered(false);
unregisteredListener.call(); unregisteredListener.call();

View file

@ -34,7 +34,6 @@ import org.signal.zkgroup.groups.GroupSecretParams;
import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKey;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException; import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
@ -53,6 +52,7 @@ import java.nio.file.Files;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
public class GroupHelper { public class GroupHelper {
@ -91,10 +91,10 @@ public class GroupHelper {
public Optional<SignalServiceAttachmentStream> createGroupAvatarAttachment(GroupIdV1 groupId) throws IOException { public Optional<SignalServiceAttachmentStream> createGroupAvatarAttachment(GroupIdV1 groupId) throws IOException {
final var streamDetails = context.getAvatarStore().retrieveGroupAvatar(groupId); final var streamDetails = context.getAvatarStore().retrieveGroupAvatar(groupId);
if (streamDetails == null) { if (streamDetails == null) {
return Optional.absent(); return Optional.empty();
} }
return Optional.of(AttachmentUtils.createAttachment(streamDetails, Optional.absent())); return Optional.of(AttachmentUtils.createAttachment(streamDetails, Optional.empty()));
} }
public GroupInfoV2 getOrMigrateGroup( public GroupInfoV2 getOrMigrateGroup(
@ -625,9 +625,7 @@ public class GroupHelper {
try { try {
final var attachment = createGroupAvatarAttachment(g.getGroupId()); final var attachment = createGroupAvatarAttachment(g.getGroupId());
if (attachment.isPresent()) { attachment.ifPresent(group::withAvatar);
group.withAvatar(attachment.get());
}
} catch (IOException e) { } catch (IOException e) {
throw new AttachmentInvalidException(g.getGroupId().toBase64(), e); throw new AttachmentInvalidException(g.getGroupId().toBase64(), e);
} }

View file

@ -10,7 +10,6 @@ import org.asamk.signal.manager.groups.GroupPermission;
import org.asamk.signal.manager.groups.GroupUtils; import org.asamk.signal.manager.groups.GroupUtils;
import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.groups.NotAGroupMemberException;
import org.asamk.signal.manager.storage.groups.GroupInfoV2; import org.asamk.signal.manager.storage.groups.GroupInfoV2;
import org.asamk.signal.manager.storage.recipients.Profile;
import org.asamk.signal.manager.storage.recipients.RecipientId; import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.asamk.signal.manager.util.IOUtils; import org.asamk.signal.manager.util.IOUtils;
import org.asamk.signal.manager.util.Utils; import org.asamk.signal.manager.util.Utils;
@ -29,7 +28,6 @@ import org.signal.zkgroup.groups.GroupSecretParams;
import org.signal.zkgroup.groups.UuidCiphertext; import org.signal.zkgroup.groups.UuidCiphertext;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil; import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
import org.whispersystems.signalservice.api.groupsv2.GroupCandidate; import org.whispersystems.signalservice.api.groupsv2.GroupCandidate;
import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException; import org.whispersystems.signalservice.api.groupsv2.GroupLinkNotActiveException;
@ -48,6 +46,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -90,7 +89,7 @@ class GroupV2Helper {
return dependencies.getGroupsV2Api() return dependencies.getGroupsV2Api()
.getGroupJoinInfo(groupSecretParams, .getGroupJoinInfo(groupSecretParams,
Optional.fromNullable(password).transform(GroupLinkPassword::serialize), Optional.ofNullable(password).map(GroupLinkPassword::serialize),
getGroupAuthForToday(groupSecretParams)); getGroupAuthForToday(groupSecretParams));
} }
@ -145,44 +144,27 @@ class GroupV2Helper {
return null; return null;
} }
if (!areMembersValid(members)) return null; final var self = new GroupCandidate(getSelfAci().uuid(), Optional.of(profileKeyCredential));
final var self = new GroupCandidate(getSelfAci().uuid(), Optional.fromNullable(profileKeyCredential));
final var memberList = new ArrayList<>(members); final var memberList = new ArrayList<>(members);
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream(); final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(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().uuid());
var candidates = Utils.zip(uuids, var candidates = Utils.zip(uuids,
credentials, credentials,
(uuid, credential) -> new GroupCandidate(uuid, Optional.fromNullable(credential))) (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential)))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var groupSecretParams = GroupSecretParams.generate(); final var groupSecretParams = GroupSecretParams.generate();
return dependencies.getGroupsV2Operations() return dependencies.getGroupsV2Operations()
.createNewGroup(groupSecretParams, .createNewGroup(groupSecretParams,
name, name,
Optional.fromNullable(avatar), Optional.ofNullable(avatar),
self, self,
candidates, candidates,
Member.Role.DEFAULT, Member.Role.DEFAULT,
0); 0);
} }
private boolean areMembersValid(final Set<RecipientId> members) {
final var noGv2Capability = context.getProfileHelper()
.getRecipientProfile(new ArrayList<>(members))
.stream()
.filter(profile -> profile != null && !profile.getCapabilities().contains(Profile.Capability.gv2))
.collect(Collectors.toSet());
if (noGv2Capability.size() > 0) {
logger.warn("Cannot create a V2 group as some members don't support Groups V2: {}",
noGv2Capability.stream().map(Profile::getDisplayName).collect(Collectors.joining(", ")));
return false;
}
return true;
}
Pair<DecryptedGroup, GroupChange> updateGroup( Pair<DecryptedGroup, GroupChange> updateGroup(
GroupInfoV2 groupInfoV2, String name, String description, File avatarFile GroupInfoV2 groupInfoV2, String name, String description, File avatarFile
) throws IOException { ) throws IOException {
@ -212,21 +194,17 @@ class GroupV2Helper {
) throws IOException { ) throws IOException {
GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
if (!areMembersValid(newMembers)) {
throw new IOException("Failed to update group");
}
final var memberList = new ArrayList<>(newMembers); final var memberList = new ArrayList<>(newMembers);
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream(); final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(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().uuid());
var candidates = Utils.zip(uuids, var candidates = Utils.zip(uuids,
credentials, credentials,
(uuid, credential) -> new GroupCandidate(uuid, Optional.fromNullable(credential))) (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential)))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
final var aci = getSelfAci(); final var aci = getSelfAci();
final var change = groupOperations.createModifyGroupMembershipChange(candidates, aci.uuid()); final var change = groupOperations.createModifyGroupMembershipChange(candidates, Set.of(), aci.uuid());
change.setSourceUuid(getSelfAci().toByteString()); change.setSourceUuid(getSelfAci().toByteString());
@ -431,7 +409,7 @@ class GroupV2Helper {
GroupInfoV2 groupInfoV2, Set<UUID> uuids GroupInfoV2 groupInfoV2, Set<UUID> uuids
) throws IOException { ) throws IOException {
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
return commitChange(groupInfoV2, groupOperations.createRemoveMembersChange(uuids)); return commitChange(groupInfoV2, groupOperations.createRemoveMembersChange(uuids, false));
} }
private Pair<DecryptedGroup, GroupChange> commitChange( private Pair<DecryptedGroup, GroupChange> commitChange(
@ -453,7 +431,7 @@ class GroupV2Helper {
} }
var signedGroupChange = dependencies.getGroupsV2Api() var signedGroupChange = dependencies.getGroupsV2Api()
.patchGroup(changeActions, getGroupAuthForToday(groupSecretParams), Optional.absent()); .patchGroup(changeActions, getGroupAuthForToday(groupSecretParams), Optional.empty());
return new Pair<>(decryptedGroupState, signedGroupChange); return new Pair<>(decryptedGroupState, signedGroupChange);
} }
@ -470,7 +448,7 @@ class GroupV2Helper {
return dependencies.getGroupsV2Api() return dependencies.getGroupsV2Api()
.patchGroup(changeActions, .patchGroup(changeActions,
getGroupAuthForToday(groupSecretParams), getGroupAuthForToday(groupSecretParams),
Optional.fromNullable(password).transform(GroupLinkPassword::serialize)); Optional.ofNullable(password).map(GroupLinkPassword::serialize));
} }
DecryptedGroup getUpdatedDecryptedGroup( DecryptedGroup getUpdatedDecryptedGroup(
@ -493,7 +471,7 @@ class GroupV2Helper {
.forGroup(GroupSecretParams.deriveFromMasterKey(groupMasterKey)); .forGroup(GroupSecretParams.deriveFromMasterKey(groupMasterKey));
try { try {
return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orNull(); return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orElse(null);
} catch (VerificationFailedException | InvalidGroupStateException | InvalidProtocolBufferException e) { } catch (VerificationFailedException | InvalidGroupStateException | InvalidProtocolBufferException e) {
return null; return null;
} }

View file

@ -270,7 +270,7 @@ public final class IncomingMessageHandler {
final DecryptionErrorMessage message final DecryptionErrorMessage message
) { ) {
final var logEntries = account.getMessageSendLogStore() final var logEntries = account.getMessageSendLogStore()
.findMessages(sender, senderDeviceId, message.getTimestamp(), !message.getRatchetKey().isPresent()); .findMessages(sender, senderDeviceId, message.getTimestamp(), message.getRatchetKey().isEmpty());
for (final var logEntry : logEntries) { for (final var logEntry : logEntries) {
actions.add(new ResendMessageAction(sender, message.getTimestamp(), logEntry)); actions.add(new ResendMessageAction(sender, message.getTimestamp(), logEntry));
@ -318,7 +318,7 @@ public final class IncomingMessageHandler {
account.setMultiDevice(true); account.setMultiDevice(true);
if (syncMessage.getSent().isPresent()) { if (syncMessage.getSent().isPresent()) {
var message = syncMessage.getSent().get(); var message = syncMessage.getSent().get();
final var destination = message.getDestination().orNull(); final var destination = message.getDestination().orElse(null);
actions.addAll(handleSignalServiceDataMessage(message.getMessage(), actions.addAll(handleSignalServiceDataMessage(message.getMessage(),
true, true,
sender, sender,
@ -388,11 +388,11 @@ public final class IncomingMessageHandler {
if (syncMessage.getStickerPackOperations().isPresent()) { if (syncMessage.getStickerPackOperations().isPresent()) {
final var stickerPackOperationMessages = syncMessage.getStickerPackOperations().get(); final var stickerPackOperationMessages = syncMessage.getStickerPackOperations().get();
for (var m : stickerPackOperationMessages) { for (var m : stickerPackOperationMessages) {
if (!m.getPackId().isPresent()) { if (m.getPackId().isEmpty()) {
continue; continue;
} }
final var stickerPackId = StickerPackId.deserialize(m.getPackId().get()); final var stickerPackId = StickerPackId.deserialize(m.getPackId().get());
final var installed = !m.getType().isPresent() final var installed = m.getType().isEmpty()
|| m.getType().get() == StickerPackOperationMessage.Type.INSTALL; || m.getType().get() == StickerPackOperationMessage.Type.INSTALL;
var sticker = account.getStickerStore().getStickerPack(stickerPackId); var sticker = account.getStickerStore().getStickerPack(stickerPackId);
@ -488,12 +488,12 @@ public final class IncomingMessageHandler {
return false; return false;
} }
if (content == null || !content.getDataMessage().isPresent()) { if (content == null || content.getDataMessage().isEmpty()) {
return false; return false;
} }
var message = content.getDataMessage().get(); var message = content.getDataMessage().get();
if (!message.getGroupContext().isPresent()) { if (message.getGroupContext().isEmpty()) {
return false; return false;
} }

View file

@ -15,8 +15,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.profiles.AvatarUploadParams;
import org.whispersystems.signalservice.api.profiles.ProfileAndCredential; import org.whispersystems.signalservice.api.profiles.ProfileAndCredential;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile; import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
@ -33,6 +33,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects; import java.util.Objects;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import io.reactivex.rxjava3.core.Flowable; import io.reactivex.rxjava3.core.Flowable;
@ -130,20 +131,23 @@ public final class ProfileHelper {
var newProfile = builder.build(); var newProfile = builder.build();
if (uploadProfile) { if (uploadProfile) {
try (final var streamDetails = avatar == null try (final var streamDetails = avatar != null && avatar.isPresent() ? Utils.createStreamDetailsFromFile(
? context.getAvatarStore() avatar.get()) : null) {
.retrieveProfileAvatar(account.getSelfRecipientAddress()) final var avatarUploadParams = avatar == null
: avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) { ? AvatarUploadParams.unchanged(true)
: avatar.isPresent()
? AvatarUploadParams.forAvatar(streamDetails)
: AvatarUploadParams.unchanged(false);
final var avatarPath = dependencies.getAccountManager() final var avatarPath = dependencies.getAccountManager()
.setVersionedProfile(account.getAci(), .setVersionedProfile(account.getAci(),
account.getProfileKey(), account.getProfileKey(),
newProfile.getInternalServiceName(), newProfile.getInternalServiceName(),
newProfile.getAbout() == null ? "" : newProfile.getAbout(), newProfile.getAbout() == null ? "" : newProfile.getAbout(),
newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(), newProfile.getAboutEmoji() == null ? "" : newProfile.getAboutEmoji(),
Optional.absent(), Optional.empty(),
streamDetails, avatarUploadParams,
List.of(/* TODO */)); List.of(/* TODO */));
builder.withAvatarUrlPath(avatarPath.orNull()); builder.withAvatarUrlPath(avatarPath.orElse(null));
newProfile = builder.build(); newProfile = builder.build();
} }
} }
@ -202,7 +206,7 @@ public final class ProfileHelper {
private SignalServiceProfile retrieveProfileSync(String username) throws IOException { private SignalServiceProfile retrieveProfileSync(String username) throws IOException {
final var locale = Utils.getDefaultLocale(Locale.US); final var locale = Utils.getDefaultLocale(Locale.US);
return dependencies.getMessageReceiver().retrieveProfileByUsername(username, Optional.absent(), locale); return dependencies.getMessageReceiver().retrieveProfileByUsername(username, Optional.empty(), locale);
} }
private Profile decryptProfileAndDownloadAvatar( private Profile decryptProfileAndDownloadAvatar(
@ -246,7 +250,7 @@ public final class ProfileHelper {
RecipientId recipientId, SignalServiceProfile.RequestType requestType RecipientId recipientId, SignalServiceProfile.RequestType requestType
) { ) {
var unidentifiedAccess = getUnidentifiedAccess(recipientId); var unidentifiedAccess = getUnidentifiedAccess(recipientId);
var profileKey = Optional.fromNullable(account.getProfileStore().getProfileKey(recipientId)); var profileKey = Optional.ofNullable(account.getProfileStore().getProfileKey(recipientId));
logger.trace("Retrieving profile for {} {}", logger.trace("Retrieving profile for {} {}",
recipientId, recipientId,
@ -259,7 +263,7 @@ public final class ProfileHelper {
if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL
|| account.getProfileStore().getProfileKeyCredential(recipientId) == null) { || account.getProfileStore().getProfileKeyCredential(recipientId) == null) {
logger.trace("Storing profile credential"); logger.trace("Storing profile credential");
final var profileKeyCredential = p.getProfileKeyCredential().orNull(); final var profileKeyCredential = p.getProfileKeyCredential().orElse(null);
account.getProfileStore().storeProfileKeyCredential(recipientId, profileKeyCredential); account.getProfileStore().storeProfileKeyCredential(recipientId, profileKeyCredential);
} }
@ -324,8 +328,8 @@ public final class ProfileHelper {
throw new NotFoundException("Profile not found"); throw new NotFoundException("Profile not found");
} else { } else {
throw pair.getExecutionError() throw pair.getExecutionError()
.or(pair.getApplicationError()) .or(pair::getApplicationError)
.or(new IOException("Unknown error while retrieving profile")); .orElseThrow(() -> new IOException("Unknown error while retrieving profile"));
} }
}); });
} }
@ -380,6 +384,6 @@ public final class ProfileHelper {
return unidentifiedAccess.get().getTargetUnidentifiedAccess(); return unidentifiedAccess.get().getTargetUnidentifiedAccess();
} }
return Optional.absent(); return Optional.empty();
} }
} }

View file

@ -91,7 +91,7 @@ public class RecipientHelper {
public RecipientId refreshRegisteredUser(RecipientId recipientId) throws IOException, UnregisteredRecipientException { public RecipientId refreshRegisteredUser(RecipientId recipientId) throws IOException, UnregisteredRecipientException {
final var address = resolveSignalServiceAddress(recipientId); final var address = resolveSignalServiceAddress(recipientId);
if (!address.getNumber().isPresent()) { if (address.getNumber().isEmpty()) {
return recipientId; return recipientId;
} }
final var number = address.getNumber().get(); final var number = address.getNumber().get();

View file

@ -21,7 +21,6 @@ import org.whispersystems.libsignal.InvalidRegistrationIdException;
import org.whispersystems.libsignal.NoSessionException; import org.whispersystems.libsignal.NoSessionException;
import org.whispersystems.libsignal.SignalProtocolAddress; import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.protocol.DecryptionErrorMessage; import org.whispersystems.libsignal.protocol.DecryptionErrorMessage;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.ContentHint; import org.whispersystems.signalservice.api.crypto.ContentHint;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
@ -47,6 +46,7 @@ import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicLong;
@ -138,7 +138,7 @@ public class SendHelper {
final var result = handleSendMessage(recipientId, final var result = handleSendMessage(recipientId,
(messageSender, address, unidentifiedAccess) -> messageSender.sendRetryReceipt(address, (messageSender, address, unidentifiedAccess) -> messageSender.sendRetryReceipt(address,
unidentifiedAccess, unidentifiedAccess,
groupId.transform(GroupId::serialize), groupId.map(GroupId::serialize),
errorMessage)); errorMessage));
handleSendMessageResult(result); handleSendMessageResult(result);
return result; return result;
@ -222,7 +222,7 @@ public class SendHelper {
timestamp, timestamp,
messageSendLogEntry.content(), messageSendLogEntry.content(),
messageSendLogEntry.contentHint(), messageSendLogEntry.contentHint(),
Optional.absent())); Optional.empty()));
} }
final var groupId = messageSendLogEntry.groupId().get(); final var groupId = messageSendLogEntry.groupId().get();
@ -457,7 +457,7 @@ public class SendHelper {
} }
final var access = context.getUnidentifiedAccessHelper().getAccessFor(recipientId); final var access = context.getUnidentifiedAccessHelper().getAccessFor(recipientId);
if (!access.isPresent() || !access.get().getTargetUnidentifiedAccess().isPresent()) { if (access.isEmpty() || access.get().getTargetUnidentifiedAccess().isEmpty()) {
continue; continue;
} }

View file

@ -64,14 +64,14 @@ public class StickerHelper {
context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o)); context.getStickerPackStore().storeSticker(packId, id, o -> IOUtils.copyStream(inputStream, o));
} }
final var jsonManifest = new JsonStickerPack(manifest.getTitle().orNull(), final var jsonManifest = new JsonStickerPack(manifest.getTitle().orElse(null),
manifest.getAuthor().orNull(), manifest.getAuthor().orElse(null),
manifest.getCover() manifest.getCover()
.transform(c -> new JsonStickerPack.JsonSticker(c.getId(), .map(c -> new JsonStickerPack.JsonSticker(c.getId(),
c.getEmoji(), c.getEmoji(),
String.valueOf(c.getId()), String.valueOf(c.getId()),
c.getContentType())) c.getContentType()))
.orNull(), .orElse(null),
manifest.getStickers() manifest.getStickers()
.stream() .stream()
.map(c -> new JsonStickerPack.JsonSticker(c.getId(), .map(c -> new JsonStickerPack.JsonSticker(c.getId(),

View file

@ -13,7 +13,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.InvalidKeyException;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.storage.SignalAccountRecord; import org.whispersystems.signalservice.api.storage.SignalAccountRecord;
import org.whispersystems.signalservice.api.storage.SignalStorageManifest; import org.whispersystems.signalservice.api.storage.SignalStorageManifest;
import org.whispersystems.signalservice.api.storage.SignalStorageRecord; import org.whispersystems.signalservice.api.storage.SignalStorageRecord;
@ -25,6 +24,7 @@ import java.io.IOException;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Optional;
public class StorageHelper { public class StorageHelper {
@ -51,7 +51,7 @@ public class StorageHelper {
return; return;
} }
if (!manifest.isPresent()) { if (manifest.isEmpty()) {
logger.debug("Manifest is up to date, does not exist or couldn't be decrypted, ignoring."); logger.debug("Manifest is up to date, does not exist or couldn't be decrypted, ignoring.");
return; return;
} }
@ -79,7 +79,7 @@ public class StorageHelper {
} }
private void readContactRecord(final SignalStorageRecord record) { private void readContactRecord(final SignalStorageRecord record) {
if (record == null || !record.getContact().isPresent()) { if (record == null || record.getContact().isEmpty()) {
return; return;
} }
@ -92,9 +92,9 @@ public class StorageHelper {
(contact == null || !contact.isBlocked()) && contactRecord.isBlocked() (contact == null || !contact.isBlocked()) && contactRecord.isBlocked()
)) { )) {
final var newContact = (contact == null ? Contact.newBuilder() : Contact.newBuilder(contact)).withBlocked( final var newContact = (contact == null ? Contact.newBuilder() : Contact.newBuilder(contact)).withBlocked(
contactRecord.isBlocked()) contactRecord.isBlocked()).withName((
.withName((contactRecord.getGivenName().or("") + " " + contactRecord.getFamilyName().or("")).trim()) contactRecord.getGivenName().orElse("") + " " + contactRecord.getFamilyName().orElse("")
.build(); ).trim()).build();
account.getContactStore().storeContact(recipientId, newContact); account.getContactStore().storeContact(recipientId, newContact);
} }
@ -122,7 +122,7 @@ public class StorageHelper {
} }
private void readGroupV1Record(final SignalStorageRecord record) { private void readGroupV1Record(final SignalStorageRecord record) {
if (record == null || !record.getGroupV1().isPresent()) { if (record == null || record.getGroupV1().isEmpty()) {
return; return;
} }
@ -145,7 +145,7 @@ public class StorageHelper {
} }
private void readGroupV2Record(final SignalStorageRecord record) { private void readGroupV2Record(final SignalStorageRecord record) {
if (record == null || !record.getGroupV2().isPresent()) { if (record == null || record.getGroupV2().isEmpty()) {
return; return;
} }
@ -171,7 +171,7 @@ public class StorageHelper {
private void readAccountRecord(final SignalStorageManifest manifest) throws IOException { private void readAccountRecord(final SignalStorageManifest manifest) throws IOException {
Optional<StorageId> accountId = manifest.getAccountStorageId(); Optional<StorageId> accountId = manifest.getAccountStorageId();
if (!accountId.isPresent()) { if (accountId.isEmpty()) {
logger.warn("Manifest has no account record, ignoring."); logger.warn("Manifest has no account record, ignoring.");
return; return;
} }
@ -182,7 +182,7 @@ public class StorageHelper {
return; return;
} }
SignalAccountRecord accountRecord = record.getAccount().orNull(); SignalAccountRecord accountRecord = record.getAccount().orElse(null);
if (accountRecord == null) { if (accountRecord == null) {
logger.warn("The storage record didn't actually have an account, ignoring."); logger.warn("The storage record didn't actually have an account, ignoring.");
return; return;
@ -217,15 +217,15 @@ public class StorageHelper {
} }
if (profileKey != null) { if (profileKey != null) {
account.setProfileKey(profileKey); account.setProfileKey(profileKey);
final var avatarPath = accountRecord.getAvatarUrlPath().orNull(); final var avatarPath = accountRecord.getAvatarUrlPath().orElse(null);
context.getProfileHelper().downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, profileKey); context.getProfileHelper().downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, profileKey);
} }
} }
context.getProfileHelper() context.getProfileHelper()
.setProfile(false, .setProfile(false,
accountRecord.getGivenName().orNull(), accountRecord.getGivenName().orElse(null),
accountRecord.getFamilyName().orNull(), accountRecord.getFamilyName().orElse(null),
null, null,
null, null,
null); null);

View file

@ -12,7 +12,6 @@ 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.libsignal.IdentityKey; import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage; import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
@ -37,6 +36,7 @@ import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Optional;
public class SyncHelper { public class SyncHelper {
@ -81,7 +81,7 @@ public class SyncHelper {
for (var record : account.getGroupStore().getGroups()) { for (var record : account.getGroupStore().getGroups()) {
if (record instanceof GroupInfoV1 groupInfo) { if (record instanceof GroupInfoV1 groupInfo) {
out.write(new DeviceGroup(groupInfo.getGroupId().serialize(), out.write(new DeviceGroup(groupInfo.getGroupId().serialize(),
Optional.fromNullable(groupInfo.name), Optional.ofNullable(groupInfo.name),
groupInfo.getMembers() groupInfo.getMembers()
.stream() .stream()
.map(context.getRecipientHelper()::resolveSignalServiceAddress) .map(context.getRecipientHelper()::resolveSignalServiceAddress)
@ -89,9 +89,9 @@ public class SyncHelper {
context.getGroupHelper().createGroupAvatarAttachment(groupInfo.getGroupId()), context.getGroupHelper().createGroupAvatarAttachment(groupInfo.getGroupId()),
groupInfo.isMember(account.getSelfRecipientId()), groupInfo.isMember(account.getSelfRecipientId()),
Optional.of(groupInfo.messageExpirationTime), Optional.of(groupInfo.messageExpirationTime),
Optional.fromNullable(groupInfo.color), Optional.ofNullable(groupInfo.color),
groupInfo.blocked, groupInfo.blocked,
Optional.absent(), Optional.empty(),
groupInfo.archived)); groupInfo.archived));
} }
} }
@ -139,28 +139,28 @@ public class SyncHelper {
var profileKey = account.getProfileStore().getProfileKey(recipientId); var profileKey = account.getProfileStore().getProfileKey(recipientId);
out.write(new DeviceContact(address, out.write(new DeviceContact(address,
Optional.fromNullable(contact.getName()), Optional.ofNullable(contact.getName()),
createContactAvatarAttachment(new RecipientAddress(address)), createContactAvatarAttachment(new RecipientAddress(address)),
Optional.fromNullable(contact.getColor()), Optional.ofNullable(contact.getColor()),
Optional.fromNullable(verifiedMessage), Optional.ofNullable(verifiedMessage),
Optional.fromNullable(profileKey), Optional.ofNullable(profileKey),
contact.isBlocked(), contact.isBlocked(),
Optional.of(contact.getMessageExpirationTime()), Optional.of(contact.getMessageExpirationTime()),
Optional.absent(), Optional.empty(),
contact.isArchived())); contact.isArchived()));
} }
if (account.getProfileKey() != null) { if (account.getProfileKey() != null) {
// Send our own profile key as well // Send our own profile key as well
out.write(new DeviceContact(account.getSelfAddress(), out.write(new DeviceContact(account.getSelfAddress(),
Optional.absent(), Optional.empty(),
Optional.absent(), Optional.empty(),
Optional.absent(), Optional.empty(),
Optional.absent(), Optional.empty(),
Optional.of(account.getProfileKey()), Optional.of(account.getProfileKey()),
false, false,
Optional.absent(), Optional.empty(),
Optional.absent(), Optional.empty(),
false)); false));
} }
} }
@ -215,16 +215,16 @@ public class SyncHelper {
} }
public void sendKeysMessage() { public void sendKeysMessage() {
var keysMessage = new KeysMessage(Optional.fromNullable(account.getStorageKey())); var keysMessage = new KeysMessage(Optional.ofNullable(account.getStorageKey()));
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage)); context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage));
} }
public void sendConfigurationMessage() { public void sendConfigurationMessage() {
final var config = account.getConfigurationStore(); final var config = account.getConfigurationStore();
var configurationMessage = new ConfigurationMessage(Optional.fromNullable(config.getReadReceipts()), var configurationMessage = new ConfigurationMessage(Optional.ofNullable(config.getReadReceipts()),
Optional.fromNullable(config.getUnidentifiedDeliveryIndicators()), Optional.ofNullable(config.getUnidentifiedDeliveryIndicators()),
Optional.fromNullable(config.getTypingIndicators()), Optional.ofNullable(config.getTypingIndicators()),
Optional.fromNullable(config.getLinkPreviews())); Optional.ofNullable(config.getLinkPreviews()));
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage)); context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage));
} }
@ -299,10 +299,10 @@ public class SyncHelper {
private Optional<SignalServiceAttachmentStream> createContactAvatarAttachment(RecipientAddress address) throws IOException { private Optional<SignalServiceAttachmentStream> createContactAvatarAttachment(RecipientAddress address) throws IOException {
final var streamDetails = context.getAvatarStore().retrieveContactAvatar(address); final var streamDetails = context.getAvatarStore().retrieveContactAvatar(address);
if (streamDetails == null) { if (streamDetails == null) {
return Optional.absent(); return Optional.empty();
} }
return Optional.of(AttachmentUtils.createAttachment(streamDetails, Optional.absent())); return Optional.of(AttachmentUtils.createAttachment(streamDetails, Optional.empty()));
} }
private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) { private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) {

View file

@ -10,12 +10,12 @@ import org.signal.libsignal.metadata.certificate.SenderCertificate;
import org.signal.zkgroup.profiles.ProfileKey; import org.signal.zkgroup.profiles.ProfileKey;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccess;
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair; import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
import java.io.IOException; import java.io.IOException;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class UnidentifiedAccessHelper { public class UnidentifiedAccessHelper {
@ -54,26 +54,26 @@ public class UnidentifiedAccessHelper {
var recipientUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipientId, noRefresh); var recipientUnidentifiedAccessKey = getTargetUnidentifiedAccessKey(recipientId, noRefresh);
if (recipientUnidentifiedAccessKey == null) { if (recipientUnidentifiedAccessKey == null) {
logger.trace("Unidentified access not available for {}", recipientId); logger.trace("Unidentified access not available for {}", recipientId);
return Optional.absent(); return Optional.empty();
} }
var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(noRefresh); var selfUnidentifiedAccessKey = getSelfUnidentifiedAccessKey(noRefresh);
if (selfUnidentifiedAccessKey == null) { if (selfUnidentifiedAccessKey == null) {
logger.trace("Unidentified access not available for self"); logger.trace("Unidentified access not available for self");
return Optional.absent(); return Optional.empty();
} }
var senderCertificate = getSenderCertificateFor(recipientId); var senderCertificate = getSenderCertificateFor(recipientId);
if (senderCertificate == null) { if (senderCertificate == null) {
logger.trace("Unidentified access not available due to missing sender certificate"); logger.trace("Unidentified access not available due to missing sender certificate");
return Optional.absent(); return Optional.empty();
} }
try { try {
return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(recipientUnidentifiedAccessKey, return Optional.of(new UnidentifiedAccessPair(new UnidentifiedAccess(recipientUnidentifiedAccessKey,
senderCertificate), new UnidentifiedAccess(selfUnidentifiedAccessKey, senderCertificate))); senderCertificate), new UnidentifiedAccess(selfUnidentifiedAccessKey, senderCertificate)));
} catch (InvalidCertificateException e) { } catch (InvalidCertificateException e) {
return Optional.absent(); return Optional.empty();
} }
} }
@ -82,7 +82,7 @@ public class UnidentifiedAccessHelper {
var selfUnidentifiedAccessCertificate = getSenderCertificate(); var selfUnidentifiedAccessCertificate = getSenderCertificate();
if (selfUnidentifiedAccessKey == null || selfUnidentifiedAccessCertificate == null) { if (selfUnidentifiedAccessKey == null || selfUnidentifiedAccessCertificate == null) {
return Optional.absent(); return Optional.empty();
} }
try { try {
@ -90,7 +90,7 @@ public class UnidentifiedAccessHelper {
selfUnidentifiedAccessCertificate), selfUnidentifiedAccessCertificate),
new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate))); new UnidentifiedAccess(selfUnidentifiedAccessKey, selfUnidentifiedAccessCertificate)));
} catch (InvalidCertificateException e) { } catch (InvalidCertificateException e) {
return Optional.absent(); return Optional.empty();
} }
} }

View file

@ -705,9 +705,6 @@ public class SignalAccount implements Closeable {
if (profile.getCapabilities().gv1Migration) { if (profile.getCapabilities().gv1Migration) {
capabilities.add(Profile.Capability.gv1Migration); capabilities.add(Profile.Capability.gv1Migration);
} }
if (profile.getCapabilities().gv2) {
capabilities.add(Profile.Capability.gv2);
}
if (profile.getCapabilities().storage) { if (profile.getCapabilities().storage) {
capabilities.add(Profile.Capability.storage); capabilities.add(Profile.Capability.storage);
} }

View file

@ -88,9 +88,6 @@ public class SignalProfile {
@JsonIgnore @JsonIgnore
public boolean uuid; public boolean uuid;
@JsonProperty
public boolean gv2;
@JsonProperty @JsonProperty
public boolean storage; public boolean storage;

View file

@ -142,7 +142,6 @@ public class Profile {
} }
public enum Capability { public enum Capability {
gv2,
storage, storage,
gv1Migration, gv1Migration,
senderKey, senderKey,

View file

@ -28,7 +28,7 @@ public record RecipientAddress(Optional<UUID> uuid, Optional<String> number) {
} }
public RecipientAddress(SignalServiceAddress address) { public RecipientAddress(SignalServiceAddress address) {
this(Optional.of(address.getServiceId().uuid()), Optional.ofNullable(address.getNumber().orNull())); this(Optional.of(address.getServiceId().uuid()), address.getNumber());
} }
public RecipientAddress(UUID uuid) { public RecipientAddress(UUID uuid) {
@ -62,7 +62,6 @@ public record RecipientAddress(Optional<UUID> uuid, Optional<String> number) {
} }
public SignalServiceAddress toSignalServiceAddress() { public SignalServiceAddress toSignalServiceAddress() {
return new SignalServiceAddress(ServiceId.from(uuid.orElse(UNKNOWN_UUID)), return new SignalServiceAddress(ServiceId.from(uuid.orElse(UNKNOWN_UUID)), number);
org.whispersystems.libsignal.util.guava.Optional.fromNullable(number.orElse(null)));
} }
} }

View file

@ -1,7 +1,6 @@
package org.asamk.signal.manager.util; package org.asamk.signal.manager.util;
import org.asamk.signal.manager.api.AttachmentInvalidException; import org.asamk.signal.manager.api.AttachmentInvalidException;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.api.util.StreamDetails;
@ -11,6 +10,7 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Optional;
public class AttachmentUtils { public class AttachmentUtils {
@ -39,10 +39,10 @@ public class AttachmentUtils {
) { ) {
// TODO mabybe add a parameter to set the voiceNote, borderless, preview, width, height and caption option // TODO mabybe add a parameter to set the voiceNote, borderless, preview, width, height and caption option
final var uploadTimestamp = System.currentTimeMillis(); final var uploadTimestamp = System.currentTimeMillis();
Optional<byte[]> preview = Optional.absent(); Optional<byte[]> preview = Optional.empty();
Optional<String> caption = Optional.absent(); Optional<String> caption = Optional.empty();
Optional<String> blurHash = Optional.absent(); Optional<String> blurHash = Optional.empty();
final Optional<ResumableUploadSpec> resumableUploadSpec = Optional.absent(); final Optional<ResumableUploadSpec> resumableUploadSpec = Optional.empty();
return new SignalServiceAttachmentStream(streamDetails.getStream(), return new SignalServiceAttachmentStream(streamDetails.getStream(),
streamDetails.getContentType(), streamDetails.getContentType(),
streamDetails.getLength(), streamDetails.getLength(),

View file

@ -1,6 +1,5 @@
package org.asamk.signal.manager.util; package org.asamk.signal.manager.util;
import org.whispersystems.libsignal.util.guava.Optional;
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;
import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.SignalServiceAddress;
@ -11,6 +10,7 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
public class MessageCacheUtils { public class MessageCacheUtils {
@ -59,7 +59,7 @@ public class MessageCacheUtils {
serverDeliveredTimestamp = in.readLong(); serverDeliveredTimestamp = in.readLong();
} }
Optional<SignalServiceAddress> addressOptional = sourceServiceId == null Optional<SignalServiceAddress> addressOptional = sourceServiceId == null
? Optional.absent() ? Optional.empty()
: Optional.of(new SignalServiceAddress(sourceServiceId, source)); : Optional.of(new SignalServiceAddress(sourceServiceId, source));
return new SignalServiceEnvelope(type, return new SignalServiceEnvelope(type,
addressOptional, addressOptional,

View file

@ -5,7 +5,6 @@ import org.asamk.signal.manager.api.IncorrectPinException;
import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.PinLockedException; import org.asamk.signal.manager.api.PinLockedException;
import org.asamk.signal.manager.helper.PinHelper; import org.asamk.signal.manager.helper.PinHelper;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.KbsPinData; import org.whispersystems.signalservice.api.KbsPinData;
import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.kbs.MasterKey; import org.whispersystems.signalservice.api.kbs.MasterKey;
@ -15,6 +14,7 @@ import org.whispersystems.signalservice.internal.push.RequestVerificationCodeRes
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse; import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
import java.io.IOException; import java.io.IOException;
import java.util.Optional;
public class NumberVerificationUtils { public class NumberVerificationUtils {
@ -26,14 +26,14 @@ public class NumberVerificationUtils {
final ServiceResponse<RequestVerificationCodeResponse> response; final ServiceResponse<RequestVerificationCodeResponse> response;
if (voiceVerification) { if (voiceVerification) {
response = accountManager.requestVoiceVerificationCode(Utils.getDefaultLocale(null), response = accountManager.requestVoiceVerificationCode(Utils.getDefaultLocale(null),
Optional.fromNullable(captcha), Optional.ofNullable(captcha),
Optional.absent(), Optional.empty(),
Optional.absent()); Optional.empty());
} else { } else {
response = accountManager.requestSmsVerificationCode(false, response = accountManager.requestSmsVerificationCode(false,
Optional.fromNullable(captcha), Optional.ofNullable(captcha),
Optional.absent(), Optional.empty(),
Optional.absent()); Optional.empty());
} }
try { try {
handleResponseException(response); handleResponseException(response);
@ -82,7 +82,7 @@ public class NumberVerificationUtils {
} }
private static void handleResponseException(final ServiceResponse<?> response) throws IOException { private static void handleResponseException(final ServiceResponse<?> response) throws IOException {
final var throwableOptional = response.getExecutionError().or(response.getApplicationError()); final var throwableOptional = response.getExecutionError().or(response::getApplicationError);
if (throwableOptional.isPresent()) { if (throwableOptional.isPresent()) {
if (throwableOptional.get() instanceof IOException) { if (throwableOptional.get() instanceof IOException) {
throw (IOException) throwableOptional.get(); throw (IOException) throwableOptional.get();

View file

@ -62,9 +62,6 @@ public class ProfileUtils {
if (encryptedProfile.getCapabilities().isGv1Migration()) { if (encryptedProfile.getCapabilities().isGv1Migration()) {
capabilities.add(Profile.Capability.gv1Migration); capabilities.add(Profile.Capability.gv1Migration);
} }
if (encryptedProfile.getCapabilities().isGv2()) {
capabilities.add(Profile.Capability.gv2);
}
if (encryptedProfile.getCapabilities().isStorage()) { if (encryptedProfile.getCapabilities().isStorage()) {
capabilities.add(Profile.Capability.storage); capabilities.add(Profile.Capability.storage);
} }

View file

@ -2,10 +2,9 @@ package org.asamk.signal.manager.util;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import org.asamk.signal.manager.api.StickerPackInvalidException;
import org.asamk.signal.manager.api.Pair; import org.asamk.signal.manager.api.Pair;
import org.asamk.signal.manager.api.StickerPackInvalidException;
import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack; import org.asamk.signal.manager.storage.stickerPacks.JsonStickerPack;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifestUpload; import org.whispersystems.signalservice.api.messages.SignalServiceStickerManifestUpload;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -15,6 +14,7 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.net.URLConnection; import java.net.URLConnection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Optional;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
public class StickerUtils { public class StickerUtils {
@ -61,7 +61,7 @@ public class StickerUtils {
: getContentType(rootPath, zip, sticker.file()); : getContentType(rootPath, zip, sticker.file());
var stickerInfo = new SignalServiceStickerManifestUpload.StickerInfo(data.first(), var stickerInfo = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
data.second(), data.second(),
Optional.fromNullable(sticker.emoji()).or(""), Optional.ofNullable(sticker.emoji()).orElse(""),
contentType); contentType);
stickers.add(stickerInfo); stickers.add(stickerInfo);
} }
@ -83,7 +83,7 @@ public class StickerUtils {
.contentType() : getContentType(rootPath, zip, pack.cover().file()); .contentType() : getContentType(rootPath, zip, pack.cover().file());
cover = new SignalServiceStickerManifestUpload.StickerInfo(data.first(), cover = new SignalServiceStickerManifestUpload.StickerInfo(data.first(),
data.second(), data.second(),
Optional.fromNullable(pack.cover().emoji()).or(""), Optional.ofNullable(pack.cover().emoji()).orElse(""),
contentType); contentType);
} }

View file

@ -70,7 +70,7 @@ public class Utils {
} else { } else {
// Version 1: E164 user // Version 1: E164 user
version = 1; version = 1;
if (!ownAddress.getNumber().isPresent() || !theirAddress.getNumber().isPresent()) { if (ownAddress.getNumber().isEmpty() || theirAddress.getNumber().isEmpty()) {
return null; return null;
} }
ownId = ownAddress.getNumber().get().getBytes(); ownId = ownAddress.getNumber().get().getBytes();
@ -102,7 +102,7 @@ public class Utils {
public static <L, R, T> Stream<T> zip(Stream<L> leftStream, Stream<R> rightStream, BiFunction<L, R, T> combiner) { public static <L, R, T> Stream<T> zip(Stream<L> leftStream, Stream<R> rightStream, BiFunction<L, R, T> combiner) {
Spliterator<L> lefts = leftStream.spliterator(); Spliterator<L> lefts = leftStream.spliterator();
Spliterator<R> rights = rightStream.spliterator(); Spliterator<R> rights = rightStream.spliterator();
return StreamSupport.stream(new Spliterators.AbstractSpliterator<T>(Long.min(lefts.estimateSize(), return StreamSupport.stream(new Spliterators.AbstractSpliterator<>(Long.min(lefts.estimateSize(),
rights.estimateSize()), lefts.characteristics() & rights.characteristics()) { rights.estimateSize()), lefts.characteristics() & rights.characteristics()) {
@Override @Override
public boolean tryAdvance(Consumer<? super T> action) { public boolean tryAdvance(Consumer<? super T> action) {

View file

@ -67,9 +67,10 @@ This can be piped to a QR encoder to create a display that can be captured by a
For example: For example:
``` [source]
----
dbus-send --session --dest=org.asamk.Signal --type=method_call --print-reply /org/asamk/Signal org.asamk.Signal.link string:"My secondary client" | tr '\n' '\0' | sed 's/.*string //g' | sed 's/\"//g' | qrencode -s10 -tANSI256 dbus-send --session --dest=org.asamk.Signal --type=method_call --print-reply /org/asamk/Signal org.asamk.Signal.link string:"My secondary client" | tr '\n' '\0' | sed 's/.*string //g' | sed 's/\"//g' | qrencode -s10 -tANSI256
``` ----
listAccounts() -> accountList<as>:: listAccounts() -> accountList<as>::
* accountList : Array of all attached accounts in DBus object path form * accountList : Array of all attached accounts in DBus object path form

View file

@ -7,6 +7,7 @@ import org.freedesktop.dbus.types.Variant;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public abstract class DbusProperties implements Properties { public abstract class DbusProperties implements Properties {
@ -25,7 +26,7 @@ public abstract class DbusProperties implements Properties {
return handler.get(); return handler.get();
} }
private java.util.Optional<DbusInterfacePropertiesHandler> getHandlerOptional(final String interfaceName) { private Optional<DbusInterfacePropertiesHandler> getHandlerOptional(final String interfaceName) {
return handlers.stream().filter(h -> h.getInterfaceName().equals(interfaceName)).findFirst(); return handlers.stream().filter(h -> h.getInterfaceName().equals(interfaceName)).findFirst();
} }