## [Unreleased]
-Requires libsignal-client version 0.52.5
+Requires libsignal-client version 0.56.0
### Fixed
"allDeclaredFields":true,
"allDeclaredMethods":true,
"allDeclaredConstructors":true,
- "methods":[{"name":"getAnnouncementGroup","parameterTypes":[] }, {"name":"getChangeNumber","parameterTypes":[] }, {"name":"getDeleteSync","parameterTypes":[] }, {"name":"getGiftBadges","parameterTypes":[] }, {"name":"getPaymentActivation","parameterTypes":[] }, {"name":"getPni","parameterTypes":[] }, {"name":"getSenderKey","parameterTypes":[] }, {"name":"getStorage","parameterTypes":[] }, {"name":"getStories","parameterTypes":[] }]
+ "methods":[{"name":"getAnnouncementGroup","parameterTypes":[] }, {"name":"getChangeNumber","parameterTypes":[] }, {"name":"getDeleteSync","parameterTypes":[] }, {"name":"getGiftBadges","parameterTypes":[] }, {"name":"getPaymentActivation","parameterTypes":[] }, {"name":"getPni","parameterTypes":[] }, {"name":"getSenderKey","parameterTypes":[] }, {"name":"getStorage","parameterTypes":[] }, {"name":"getStories","parameterTypes":[] }, {"name":"getVersionedExpirationTimer","parameterTypes":[] }]
},
{
"name":"org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest",
"pattern":"\\Qlibsignal_jni.dylib\\E"
}, {
"pattern":"\\Qlibsignal_jni.so\\E"
+ }, {
+ "pattern":"\\Qlibsignal_jni_amd64.so\\E"
}, {
"pattern":"\\Qorg/asamk/signal/manager/config/ias.store\\E"
}, {
public static AccountAttributes.Capabilities getCapabilities(boolean isPrimaryDevice) {
final var deleteSync = !isPrimaryDevice;
- return new AccountAttributes.Capabilities(true, deleteSync);
+ final var versionedExpirationTimer = !isPrimaryDevice;
+ return new AccountAttributes.Capabilities(true, deleteSync, versionedExpirationTimer);
}
public static ServiceEnvironmentConfig getServiceEnvironmentConfig(
final var messageSender = dependencies.getMessageSender();
for (final var deviceId : deviceIds) {
// Signed Prekey
- final var signedPreKeyRecord = KeyUtils.generateSignedPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID),
- pniIdentity.getPrivateKey());
- final var signedPreKeyEntity = new SignedPreKeyEntity(signedPreKeyRecord.getId(),
- signedPreKeyRecord.getKeyPair().getPublicKey(),
- signedPreKeyRecord.getSignature());
- devicePniSignedPreKeys.put(deviceId, signedPreKeyEntity);
+ final SignedPreKeyRecord signedPreKeyRecord;
+ try {
+ signedPreKeyRecord = KeyUtils.generateSignedPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID),
+ pniIdentity.getPrivateKey());
+ final var signedPreKeyEntity = new SignedPreKeyEntity(signedPreKeyRecord.getId(),
+ signedPreKeyRecord.getKeyPair().getPublicKey(),
+ signedPreKeyRecord.getSignature());
+ devicePniSignedPreKeys.put(deviceId, signedPreKeyEntity);
+ } catch (InvalidKeyException e) {
+ throw new AssertionError("unexpected invalid key", e);
+ }
// Last-resort kyber prekey
- final var lastResortKyberPreKeyRecord = KeyUtils.generateKyberPreKeyRecord(KeyUtils.getRandomInt(
- PREKEY_MAXIMUM_ID), pniIdentity.getPrivateKey());
- final var kyberPreKeyEntity = new KyberPreKeyEntity(lastResortKyberPreKeyRecord.getId(),
- lastResortKyberPreKeyRecord.getKeyPair().getPublicKey(),
- lastResortKyberPreKeyRecord.getSignature());
- devicePniLastResortKyberPreKeys.put(deviceId, kyberPreKeyEntity);
+ final KyberPreKeyRecord lastResortKyberPreKeyRecord;
+ try {
+ lastResortKyberPreKeyRecord = KeyUtils.generateKyberPreKeyRecord(KeyUtils.getRandomInt(PREKEY_MAXIMUM_ID),
+ pniIdentity.getPrivateKey());
+ final var kyberPreKeyEntity = new KyberPreKeyEntity(lastResortKyberPreKeyRecord.getId(),
+ lastResortKyberPreKeyRecord.getKeyPair().getPublicKey(),
+ lastResortKyberPreKeyRecord.getSignature());
+ devicePniLastResortKyberPreKeys.put(deviceId, kyberPreKeyEntity);
+ } catch (InvalidKeyException e) {
+ throw new AssertionError("unexpected invalid key", e);
+ }
// Registration Id
var pniRegistrationId = -1;
import org.asamk.signal.manager.storage.recipients.RecipientAddress;
import org.asamk.signal.manager.storage.recipients.RecipientId;
import org.asamk.signal.manager.storage.stickers.StickerPack;
-import org.asamk.signal.manager.util.AttachmentUtils;
import org.asamk.signal.manager.util.IOUtils;
import org.asamk.signal.manager.util.MimeUtils;
import org.jetbrains.annotations.NotNull;
import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.messages.SendMessageResult;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
-import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.messages.SignalServiceReceiptMessage;
import org.whispersystems.signalservice.api.messages.multidevice.BlockedListMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ConfigurationMessage;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
+import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactAvatar;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsInputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceGroup;
final var contact = contactPair.second();
final var address = account.getRecipientAddressResolver().resolveRecipientAddress(recipientId);
- out.write(getDeviceContact(address, recipientId, contact));
+ final var deviceContact = getDeviceContact(address, recipientId, contact);
+ out.write(deviceContact);
+ deviceContact.getAvatar().ifPresent(a -> {
+ try {
+ a.getInputStream().close();
+ } catch (IOException ignored) {
+ }
+ });
}
if (account.getProfileKey() != null) {
final var address = account.getSelfRecipientAddress();
final var recipientId = account.getSelfRecipientId();
final var contact = account.getContactStore().getContact(recipientId);
- out.write(getDeviceContact(address, recipientId, contact));
+ final var deviceContact = getDeviceContact(address, recipientId, contact);
+ out.write(deviceContact);
+ deviceContact.getAvatar().ifPresent(a -> {
+ try {
+ a.getInputStream().close();
+ } catch (IOException ignored) {
+ }
+ });
}
}
Optional.ofNullable(profileKey),
Optional.ofNullable(contact == null ? null : contact.messageExpirationTime()),
Optional.empty(),
+ Optional.empty(),
contact != null && contact.isArchived());
}
account.getContactStore().storeContact(recipientId, builder.build());
if (c.getAvatar().isPresent()) {
- downloadContactAvatar(c.getAvatar().get(), address);
+ storeContactAvatar(c.getAvatar().get(), address);
}
}
}
return context.getSendHelper().sendSyncMessage(message);
}
- private Optional<SignalServiceAttachmentStream> createContactAvatarAttachment(RecipientAddress address) throws IOException {
+ private Optional<DeviceContactAvatar> createContactAvatarAttachment(RecipientAddress address) throws IOException {
final var streamDetails = context.getAvatarStore().retrieveContactAvatar(address);
if (streamDetails == null) {
return Optional.empty();
}
- final var uploadSpec = context.getDependencies().getMessageSender().getResumableUploadSpec().toProto();
- return Optional.of(AttachmentUtils.createAttachmentStream(streamDetails, Optional.empty(), uploadSpec));
+ return Optional.of(new DeviceContactAvatar(streamDetails.getStream(),
+ streamDetails.getLength(),
+ streamDetails.getContentType()));
}
- private void downloadContactAvatar(SignalServiceAttachment avatar, RecipientAddress address) {
+ private void storeContactAvatar(DeviceContactAvatar avatar, RecipientAddress address) {
try {
context.getAvatarStore()
.storeContactAvatar(address,
- outputStream -> context.getAttachmentHelper().retrieveAttachment(avatar, outputStream));
+ outputStream -> IOUtils.copyStream(avatar.getInputStream(), outputStream));
} catch (IOException e) {
logger.warn("Failed to download avatar for contact {}, ignoring: {}", address, e.getMessage());
}
try (final var statement = connection.prepareStatement(sql)) {
statement.setInt(1, accountIdType);
statement.setInt(2, signedPreKeyId);
- final var keyPair = record.getKeyPair();
- statement.setBytes(3, keyPair.getPublicKey().serialize());
- statement.setBytes(4, keyPair.getPrivateKey().serialize());
+ try {
+ final var keyPair = record.getKeyPair();
+ statement.setBytes(3, keyPair.getPublicKey().serialize());
+ statement.setBytes(4, keyPair.getPrivateKey().serialize());
+ } catch (InvalidKeyException e) {
+ throw new AssertionError("unexpected invalid key", e);
+ }
statement.setBytes(5, record.getSignature());
statement.setLong(6, record.getTimestamp());
statement.executeUpdate();
for (final var record : signedPreKeys) {
statement.setInt(1, accountIdType);
statement.setInt(2, record.getId());
- final var keyPair = record.getKeyPair();
- statement.setBytes(3, keyPair.getPublicKey().serialize());
- statement.setBytes(4, keyPair.getPrivateKey().serialize());
+ try {
+ final var keyPair = record.getKeyPair();
+ statement.setBytes(3, keyPair.getPublicKey().serialize());
+ statement.setBytes(4, keyPair.getPrivateKey().serialize());
+ } catch (InvalidKeyException e) {
+ throw new AssertionError("unexpected invalid key", e);
+ }
statement.setBytes(5, record.getSignature());
statement.setLong(6, record.getTimestamp());
statement.executeUpdate();
library("slf4j.jul", "org.slf4j", "jul-to-slf4j").versionRef("slf4j")
library("logback", "ch.qos.logback", "logback-classic").version("1.5.6")
- library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_106")
+ library("signalservice", "com.github.turasa", "signal-service-java").version("2.15.3_unofficial_107")
library("sqlite", "org.xerial", "sqlite-jdbc").version("3.46.0.0")
library("hikari", "com.zaxxer", "HikariCP").version("5.1.0")
library("junit.jupiter", "org.junit.jupiter", "junit-jupiter").version("5.10.2")
public static final String PROJECT_VERSION = BaseConfig.class.getPackage().getImplementationVersion();
static final String USER_AGENT_SIGNAL_ANDROID = Optional.ofNullable(System.getenv("SIGNAL_CLI_USER_AGENT"))
- .orElse("Signal-Android/7.14.1");
+ .orElse("Signal-Android/7.16.2");
static final String USER_AGENT_SIGNAL_CLI = PROJECT_NAME == null
? "signal-cli"
: PROJECT_NAME + "/" + PROJECT_VERSION;