mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 02:20:39 +00:00
Refactor Context to create helpers lazily
This commit is contained in:
parent
c88c92086e
commit
c7a7d00da5
41 changed files with 559 additions and 762 deletions
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager;
|
package org.asamk.signal.manager;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.jobs.Job;
|
import org.asamk.signal.manager.jobs.Job;
|
||||||
|
|
||||||
public class JobExecutor {
|
public class JobExecutor {
|
||||||
|
|
|
@ -39,21 +39,7 @@ import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||||
import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
|
import org.asamk.signal.manager.groups.GroupSendingNotAllowedException;
|
||||||
import org.asamk.signal.manager.groups.LastGroupAdminException;
|
import org.asamk.signal.manager.groups.LastGroupAdminException;
|
||||||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||||
import org.asamk.signal.manager.helper.AttachmentHelper;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.helper.ContactHelper;
|
|
||||||
import org.asamk.signal.manager.helper.GroupHelper;
|
|
||||||
import org.asamk.signal.manager.helper.GroupV2Helper;
|
|
||||||
import org.asamk.signal.manager.helper.IdentityHelper;
|
|
||||||
import org.asamk.signal.manager.helper.IncomingMessageHandler;
|
|
||||||
import org.asamk.signal.manager.helper.PinHelper;
|
|
||||||
import org.asamk.signal.manager.helper.PreKeyHelper;
|
|
||||||
import org.asamk.signal.manager.helper.ProfileHelper;
|
|
||||||
import org.asamk.signal.manager.helper.RecipientHelper;
|
|
||||||
import org.asamk.signal.manager.helper.SendHelper;
|
|
||||||
import org.asamk.signal.manager.helper.StorageHelper;
|
|
||||||
import org.asamk.signal.manager.helper.SyncHelper;
|
|
||||||
import org.asamk.signal.manager.helper.UnidentifiedAccessHelper;
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
||||||
import org.asamk.signal.manager.storage.identities.IdentityInfo;
|
import org.asamk.signal.manager.storage.identities.IdentityInfo;
|
||||||
|
@ -125,20 +111,8 @@ public class ManagerImpl implements Manager {
|
||||||
|
|
||||||
private final ExecutorService executor = Executors.newCachedThreadPool();
|
private final ExecutorService executor = Executors.newCachedThreadPool();
|
||||||
|
|
||||||
private final ProfileHelper profileHelper;
|
|
||||||
private final PinHelper pinHelper;
|
|
||||||
private final StorageHelper storageHelper;
|
|
||||||
private final SendHelper sendHelper;
|
|
||||||
private final SyncHelper syncHelper;
|
|
||||||
private final AttachmentHelper attachmentHelper;
|
|
||||||
private final GroupHelper groupHelper;
|
|
||||||
private final ContactHelper contactHelper;
|
|
||||||
private final IncomingMessageHandler incomingMessageHandler;
|
|
||||||
private final PreKeyHelper preKeyHelper;
|
|
||||||
private final IdentityHelper identityHelper;
|
|
||||||
private final RecipientHelper recipientHelper;
|
|
||||||
|
|
||||||
private final Context context;
|
private final Context context;
|
||||||
|
|
||||||
private boolean hasCaughtUpWithOldMessages = false;
|
private boolean hasCaughtUpWithOldMessages = false;
|
||||||
private boolean ignoreAttachments = false;
|
private boolean ignoreAttachments = false;
|
||||||
|
|
||||||
|
@ -180,76 +154,7 @@ public class ManagerImpl implements Manager {
|
||||||
final var attachmentStore = new AttachmentStore(pathConfig.attachmentsPath());
|
final var attachmentStore = new AttachmentStore(pathConfig.attachmentsPath());
|
||||||
final var stickerPackStore = new StickerPackStore(pathConfig.stickerPacksPath());
|
final var stickerPackStore = new StickerPackStore(pathConfig.stickerPacksPath());
|
||||||
|
|
||||||
this.attachmentHelper = new AttachmentHelper(dependencies, attachmentStore);
|
this.context = new Context(account, dependencies, avatarStore, attachmentStore, stickerPackStore);
|
||||||
this.pinHelper = new PinHelper(dependencies.getKeyBackupService());
|
|
||||||
final var unidentifiedAccessHelper = new UnidentifiedAccessHelper(account,
|
|
||||||
dependencies,
|
|
||||||
account::getProfileKey,
|
|
||||||
this::getRecipientProfile);
|
|
||||||
this.recipientHelper = new RecipientHelper(account, dependencies, serviceEnvironmentConfig);
|
|
||||||
this.profileHelper = new ProfileHelper(account,
|
|
||||||
dependencies,
|
|
||||||
avatarStore,
|
|
||||||
unidentifiedAccessHelper::getAccessFor,
|
|
||||||
recipientHelper::resolveSignalServiceAddress);
|
|
||||||
final GroupV2Helper groupV2Helper = new GroupV2Helper(profileHelper,
|
|
||||||
account::getSelfRecipientId,
|
|
||||||
dependencies.getGroupsV2Operations(),
|
|
||||||
dependencies.getGroupsV2Api(),
|
|
||||||
recipientHelper::resolveSignalServiceAddress);
|
|
||||||
this.sendHelper = new SendHelper(account,
|
|
||||||
dependencies,
|
|
||||||
unidentifiedAccessHelper,
|
|
||||||
recipientHelper::resolveSignalServiceAddress,
|
|
||||||
account.getRecipientStore(),
|
|
||||||
this::handleIdentityFailure,
|
|
||||||
this::getGroupInfo,
|
|
||||||
profileHelper,
|
|
||||||
recipientHelper::refreshRegisteredUser);
|
|
||||||
this.groupHelper = new GroupHelper(account,
|
|
||||||
dependencies,
|
|
||||||
attachmentHelper,
|
|
||||||
sendHelper,
|
|
||||||
groupV2Helper,
|
|
||||||
avatarStore,
|
|
||||||
recipientHelper::resolveSignalServiceAddress,
|
|
||||||
account.getRecipientStore());
|
|
||||||
this.storageHelper = new StorageHelper(account, dependencies, groupHelper, profileHelper);
|
|
||||||
this.contactHelper = new ContactHelper(account);
|
|
||||||
this.syncHelper = new SyncHelper(account,
|
|
||||||
attachmentHelper,
|
|
||||||
sendHelper,
|
|
||||||
groupHelper,
|
|
||||||
avatarStore,
|
|
||||||
recipientHelper::resolveSignalServiceAddress);
|
|
||||||
preKeyHelper = new PreKeyHelper(account, dependencies);
|
|
||||||
|
|
||||||
this.context = new Context(account,
|
|
||||||
dependencies,
|
|
||||||
stickerPackStore,
|
|
||||||
sendHelper,
|
|
||||||
groupHelper,
|
|
||||||
syncHelper,
|
|
||||||
profileHelper,
|
|
||||||
storageHelper,
|
|
||||||
preKeyHelper);
|
|
||||||
var jobExecutor = new JobExecutor(context);
|
|
||||||
|
|
||||||
this.incomingMessageHandler = new IncomingMessageHandler(account,
|
|
||||||
dependencies,
|
|
||||||
account.getRecipientStore(),
|
|
||||||
recipientHelper::resolveSignalServiceAddress,
|
|
||||||
groupHelper,
|
|
||||||
contactHelper,
|
|
||||||
attachmentHelper,
|
|
||||||
syncHelper,
|
|
||||||
profileHelper::getRecipientProfile,
|
|
||||||
jobExecutor);
|
|
||||||
this.identityHelper = new IdentityHelper(account,
|
|
||||||
dependencies,
|
|
||||||
recipientHelper::resolveSignalServiceAddress,
|
|
||||||
syncHelper,
|
|
||||||
profileHelper);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -271,7 +176,7 @@ public class ManagerImpl implements Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
preKeyHelper.refreshPreKeysIfNecessary();
|
context.getPreKeyHelper().refreshPreKeysIfNecessary();
|
||||||
if (account.getAci() == null) {
|
if (account.getAci() == null) {
|
||||||
account.setAci(ACI.parseOrNull(dependencies.getAccountManager().getWhoAmI().getAci()));
|
account.setAci(ACI.parseOrNull(dependencies.getAccountManager().getWhoAmI().getAci()));
|
||||||
}
|
}
|
||||||
|
@ -308,7 +213,7 @@ public class ManagerImpl implements Manager {
|
||||||
.stream()
|
.stream()
|
||||||
.filter(s -> !s.isEmpty())
|
.filter(s -> !s.isEmpty())
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
final var registeredUsers = recipientHelper.getRegisteredUsers(canonicalizedNumbersSet);
|
final var registeredUsers = context.getRecipientHelper().getRegisteredUsers(canonicalizedNumbersSet);
|
||||||
|
|
||||||
return numbers.stream().collect(Collectors.toMap(n -> n, n -> {
|
return numbers.stream().collect(Collectors.toMap(n -> n, n -> {
|
||||||
final var number = canonicalizedNumbers.get(n);
|
final var number = canonicalizedNumbers.get(n);
|
||||||
|
@ -370,7 +275,7 @@ public class ManagerImpl implements Manager {
|
||||||
if (configuration.linkPreviews().isPresent()) {
|
if (configuration.linkPreviews().isPresent()) {
|
||||||
configurationStore.setLinkPreviews(configuration.linkPreviews().get());
|
configurationStore.setLinkPreviews(configuration.linkPreviews().get());
|
||||||
}
|
}
|
||||||
syncHelper.sendConfigurationMessage();
|
context.getSyncHelper().sendConfigurationMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -384,12 +289,13 @@ public class ManagerImpl implements Manager {
|
||||||
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, java.util.Optional<File> avatar
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
profileHelper.setProfile(givenName,
|
context.getProfileHelper()
|
||||||
familyName,
|
.setProfile(givenName,
|
||||||
about,
|
familyName,
|
||||||
aboutEmoji,
|
about,
|
||||||
avatar == null ? null : Optional.fromNullable(avatar.orElse(null)));
|
aboutEmoji,
|
||||||
syncHelper.sendSyncFetchProfileMessage();
|
avatar == null ? null : Optional.fromNullable(avatar.orElse(null)));
|
||||||
|
context.getSyncHelper().sendSyncFetchProfileMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -406,7 +312,7 @@ public class ManagerImpl implements Manager {
|
||||||
@Override
|
@Override
|
||||||
public void deleteAccount() throws IOException {
|
public void deleteAccount() throws IOException {
|
||||||
try {
|
try {
|
||||||
pinHelper.removeRegistrationLockPin();
|
context.getPinHelper().removeRegistrationLockPin();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to remove registration lock pin");
|
logger.warn("Failed to remove registration lock pin");
|
||||||
}
|
}
|
||||||
|
@ -490,28 +396,24 @@ public class ManagerImpl implements Manager {
|
||||||
? account.getPinMasterKey()
|
? account.getPinMasterKey()
|
||||||
: KeyUtils.createMasterKey();
|
: KeyUtils.createMasterKey();
|
||||||
|
|
||||||
pinHelper.setRegistrationLockPin(pin.get(), masterKey);
|
context.getPinHelper().setRegistrationLockPin(pin.get(), masterKey);
|
||||||
|
|
||||||
account.setRegistrationLockPin(pin.get(), masterKey);
|
account.setRegistrationLockPin(pin.get(), masterKey);
|
||||||
} else {
|
} else {
|
||||||
// Remove KBS Pin
|
// Remove KBS Pin
|
||||||
pinHelper.removeRegistrationLockPin();
|
context.getPinHelper().removeRegistrationLockPin();
|
||||||
|
|
||||||
account.setRegistrationLockPin(null, null);
|
account.setRegistrationLockPin(null, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void refreshPreKeys() throws IOException {
|
void refreshPreKeys() throws IOException {
|
||||||
preKeyHelper.refreshPreKeys();
|
context.getPreKeyHelper().refreshPreKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException {
|
public Profile getRecipientProfile(RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException {
|
||||||
return profileHelper.getRecipientProfile(recipientHelper.resolveRecipient(recipient));
|
return context.getProfileHelper().getRecipientProfile(context.getRecipientHelper().resolveRecipient(recipient));
|
||||||
}
|
|
||||||
|
|
||||||
private Profile getRecipientProfile(RecipientId recipientId) {
|
|
||||||
return profileHelper.getRecipientProfile(recipientId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -557,53 +459,59 @@ public class ManagerImpl implements Manager {
|
||||||
public SendGroupMessageResults quitGroup(
|
public SendGroupMessageResults quitGroup(
|
||||||
GroupId groupId, Set<RecipientIdentifier.Single> groupAdmins
|
GroupId groupId, Set<RecipientIdentifier.Single> groupAdmins
|
||||||
) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException, UnregisteredRecipientException {
|
) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException, UnregisteredRecipientException {
|
||||||
final var newAdmins = recipientHelper.resolveRecipients(groupAdmins);
|
final var newAdmins = context.getRecipientHelper().resolveRecipients(groupAdmins);
|
||||||
return groupHelper.quitGroup(groupId, newAdmins);
|
return context.getGroupHelper().quitGroup(groupId, newAdmins);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteGroup(GroupId groupId) throws IOException {
|
public void deleteGroup(GroupId groupId) throws IOException {
|
||||||
groupHelper.deleteGroup(groupId);
|
context.getGroupHelper().deleteGroup(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<GroupId, SendGroupMessageResults> createGroup(
|
public Pair<GroupId, SendGroupMessageResults> createGroup(
|
||||||
String name, Set<RecipientIdentifier.Single> members, File avatarFile
|
String name, Set<RecipientIdentifier.Single> members, File avatarFile
|
||||||
) throws IOException, AttachmentInvalidException, UnregisteredRecipientException {
|
) throws IOException, AttachmentInvalidException, UnregisteredRecipientException {
|
||||||
return groupHelper.createGroup(name,
|
return context.getGroupHelper()
|
||||||
members == null ? null : recipientHelper.resolveRecipients(members),
|
.createGroup(name,
|
||||||
avatarFile);
|
members == null ? null : context.getRecipientHelper().resolveRecipients(members),
|
||||||
|
avatarFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SendGroupMessageResults updateGroup(
|
public SendGroupMessageResults updateGroup(
|
||||||
final GroupId groupId, final UpdateGroup updateGroup
|
final GroupId groupId, final UpdateGroup updateGroup
|
||||||
) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException {
|
) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException {
|
||||||
return groupHelper.updateGroup(groupId,
|
return context.getGroupHelper()
|
||||||
updateGroup.getName(),
|
.updateGroup(groupId,
|
||||||
updateGroup.getDescription(),
|
updateGroup.getName(),
|
||||||
updateGroup.getMembers() == null ? null : recipientHelper.resolveRecipients(updateGroup.getMembers()),
|
updateGroup.getDescription(),
|
||||||
updateGroup.getRemoveMembers() == null
|
updateGroup.getMembers() == null
|
||||||
? null
|
? null
|
||||||
: recipientHelper.resolveRecipients(updateGroup.getRemoveMembers()),
|
: context.getRecipientHelper().resolveRecipients(updateGroup.getMembers()),
|
||||||
updateGroup.getAdmins() == null ? null : recipientHelper.resolveRecipients(updateGroup.getAdmins()),
|
updateGroup.getRemoveMembers() == null
|
||||||
updateGroup.getRemoveAdmins() == null
|
? null
|
||||||
? null
|
: context.getRecipientHelper().resolveRecipients(updateGroup.getRemoveMembers()),
|
||||||
: recipientHelper.resolveRecipients(updateGroup.getRemoveAdmins()),
|
updateGroup.getAdmins() == null
|
||||||
updateGroup.isResetGroupLink(),
|
? null
|
||||||
updateGroup.getGroupLinkState(),
|
: context.getRecipientHelper().resolveRecipients(updateGroup.getAdmins()),
|
||||||
updateGroup.getAddMemberPermission(),
|
updateGroup.getRemoveAdmins() == null
|
||||||
updateGroup.getEditDetailsPermission(),
|
? null
|
||||||
updateGroup.getAvatarFile(),
|
: context.getRecipientHelper().resolveRecipients(updateGroup.getRemoveAdmins()),
|
||||||
updateGroup.getExpirationTimer(),
|
updateGroup.isResetGroupLink(),
|
||||||
updateGroup.getIsAnnouncementGroup());
|
updateGroup.getGroupLinkState(),
|
||||||
|
updateGroup.getAddMemberPermission(),
|
||||||
|
updateGroup.getEditDetailsPermission(),
|
||||||
|
updateGroup.getAvatarFile(),
|
||||||
|
updateGroup.getExpirationTimer(),
|
||||||
|
updateGroup.getIsAnnouncementGroup());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<GroupId, SendGroupMessageResults> joinGroup(
|
public Pair<GroupId, SendGroupMessageResults> joinGroup(
|
||||||
GroupInviteLinkUrl inviteLinkUrl
|
GroupInviteLinkUrl inviteLinkUrl
|
||||||
) throws IOException, InactiveGroupLinkException {
|
) throws IOException, InactiveGroupLinkException {
|
||||||
return groupHelper.joinGroup(inviteLinkUrl);
|
return context.getGroupHelper().joinGroup(inviteLinkUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendMessageResults sendMessage(
|
private SendMessageResults sendMessage(
|
||||||
|
@ -615,8 +523,8 @@ public class ManagerImpl implements Manager {
|
||||||
for (final var recipient : recipients) {
|
for (final var recipient : recipients) {
|
||||||
if (recipient instanceof RecipientIdentifier.Single single) {
|
if (recipient instanceof RecipientIdentifier.Single single) {
|
||||||
try {
|
try {
|
||||||
final var recipientId = recipientHelper.resolveRecipient(single);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(single);
|
||||||
final var result = sendHelper.sendMessage(messageBuilder, recipientId);
|
final var result = context.getSendHelper().sendMessage(messageBuilder, recipientId);
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
List.of(SendMessageResult.from(result,
|
List.of(SendMessageResult.from(result,
|
||||||
account.getRecipientStore(),
|
account.getRecipientStore(),
|
||||||
|
@ -626,13 +534,13 @@ public class ManagerImpl implements Manager {
|
||||||
List.of(SendMessageResult.unregisteredFailure(single.toPartialRecipientAddress())));
|
List.of(SendMessageResult.unregisteredFailure(single.toPartialRecipientAddress())));
|
||||||
}
|
}
|
||||||
} else if (recipient instanceof RecipientIdentifier.NoteToSelf) {
|
} else if (recipient instanceof RecipientIdentifier.NoteToSelf) {
|
||||||
final var result = sendHelper.sendSelfMessage(messageBuilder);
|
final var result = context.getSendHelper().sendSelfMessage(messageBuilder);
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
List.of(SendMessageResult.from(result,
|
List.of(SendMessageResult.from(result,
|
||||||
account.getRecipientStore(),
|
account.getRecipientStore(),
|
||||||
account.getRecipientStore()::resolveRecipientAddress)));
|
account.getRecipientStore()::resolveRecipientAddress)));
|
||||||
} else if (recipient instanceof RecipientIdentifier.Group group) {
|
} else if (recipient instanceof RecipientIdentifier.Group group) {
|
||||||
final var result = sendHelper.sendAsGroupMessage(messageBuilder, group.groupId());
|
final var result = context.getSendHelper().sendAsGroupMessage(messageBuilder, group.groupId());
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
result.stream()
|
result.stream()
|
||||||
.map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
|
.map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
|
||||||
|
@ -653,8 +561,8 @@ public class ManagerImpl implements Manager {
|
||||||
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.absent());
|
||||||
try {
|
try {
|
||||||
final var recipientId = recipientHelper.resolveRecipient(single);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(single);
|
||||||
final var result = sendHelper.sendTypingMessage(message, recipientId);
|
final var result = context.getSendHelper().sendTypingMessage(message, recipientId);
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
List.of(SendMessageResult.from(result,
|
List.of(SendMessageResult.from(result,
|
||||||
account.getRecipientStore(),
|
account.getRecipientStore(),
|
||||||
|
@ -666,7 +574,7 @@ public class ManagerImpl implements Manager {
|
||||||
} else if (recipient instanceof RecipientIdentifier.Group) {
|
} else if (recipient instanceof RecipientIdentifier.Group) {
|
||||||
final var groupId = ((RecipientIdentifier.Group) recipient).groupId();
|
final var groupId = ((RecipientIdentifier.Group) recipient).groupId();
|
||||||
final var message = new SignalServiceTypingMessage(action, timestamp, Optional.of(groupId.serialize()));
|
final var message = new SignalServiceTypingMessage(action, timestamp, Optional.of(groupId.serialize()));
|
||||||
final var result = sendHelper.sendGroupTypingMessage(message, groupId);
|
final var result = context.getSendHelper().sendGroupTypingMessage(message, groupId);
|
||||||
results.put(recipient,
|
results.put(recipient,
|
||||||
result.stream()
|
result.stream()
|
||||||
.map(r -> SendMessageResult.from(r,
|
.map(r -> SendMessageResult.from(r,
|
||||||
|
@ -715,7 +623,8 @@ public class ManagerImpl implements Manager {
|
||||||
final SignalServiceReceiptMessage receiptMessage
|
final SignalServiceReceiptMessage receiptMessage
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
try {
|
try {
|
||||||
final var result = sendHelper.sendReceiptMessage(receiptMessage, recipientHelper.resolveRecipient(sender));
|
final var result = context.getSendHelper()
|
||||||
|
.sendReceiptMessage(receiptMessage, context.getRecipientHelper().resolveRecipient(sender));
|
||||||
return new SendMessageResults(timestamp,
|
return new SendMessageResults(timestamp,
|
||||||
Map.of(sender,
|
Map.of(sender,
|
||||||
List.of(SendMessageResult.from(result,
|
List.of(SendMessageResult.from(result,
|
||||||
|
@ -742,7 +651,7 @@ public class ManagerImpl implements Manager {
|
||||||
messageBuilder.withBody(message.messageText());
|
messageBuilder.withBody(message.messageText());
|
||||||
final var attachments = message.attachments();
|
final var attachments = message.attachments();
|
||||||
if (attachments != null) {
|
if (attachments != null) {
|
||||||
messageBuilder.withAttachments(attachmentHelper.uploadAttachments(attachments));
|
messageBuilder.withAttachments(context.getAttachmentHelper().uploadAttachments(attachments));
|
||||||
}
|
}
|
||||||
if (message.mentions().size() > 0) {
|
if (message.mentions().size() > 0) {
|
||||||
messageBuilder.withMentions(resolveMentions(message.mentions()));
|
messageBuilder.withMentions(resolveMentions(message.mentions()));
|
||||||
|
@ -750,7 +659,8 @@ public class ManagerImpl implements Manager {
|
||||||
if (message.quote().isPresent()) {
|
if (message.quote().isPresent()) {
|
||||||
final var quote = message.quote().get();
|
final var quote = message.quote().get();
|
||||||
messageBuilder.withQuote(new SignalServiceDataMessage.Quote(quote.timestamp(),
|
messageBuilder.withQuote(new SignalServiceDataMessage.Quote(quote.timestamp(),
|
||||||
recipientHelper.resolveSignalServiceAddress(recipientHelper.resolveRecipient(quote.author())),
|
context.getRecipientHelper()
|
||||||
|
.resolveSignalServiceAddress(context.getRecipientHelper().resolveRecipient(quote.author())),
|
||||||
quote.message(),
|
quote.message(),
|
||||||
List.of(),
|
List.of(),
|
||||||
resolveMentions(quote.mentions())));
|
resolveMentions(quote.mentions())));
|
||||||
|
@ -760,8 +670,9 @@ public class ManagerImpl implements Manager {
|
||||||
private ArrayList<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws IOException, UnregisteredRecipientException {
|
private ArrayList<SignalServiceDataMessage.Mention> resolveMentions(final List<Message.Mention> mentionList) throws IOException, UnregisteredRecipientException {
|
||||||
final var mentions = new ArrayList<SignalServiceDataMessage.Mention>();
|
final var mentions = new ArrayList<SignalServiceDataMessage.Mention>();
|
||||||
for (final var m : mentionList) {
|
for (final var m : mentionList) {
|
||||||
final var recipientId = recipientHelper.resolveRecipient(m.recipient());
|
final var recipientId = context.getRecipientHelper().resolveRecipient(m.recipient());
|
||||||
mentions.add(new SignalServiceDataMessage.Mention(recipientHelper.resolveSignalServiceAddress(recipientId)
|
mentions.add(new SignalServiceDataMessage.Mention(context.getRecipientHelper()
|
||||||
|
.resolveSignalServiceAddress(recipientId)
|
||||||
.getAci(), m.start(), m.length()));
|
.getAci(), m.start(), m.length()));
|
||||||
}
|
}
|
||||||
return mentions;
|
return mentions;
|
||||||
|
@ -784,10 +695,10 @@ public class ManagerImpl implements Manager {
|
||||||
long targetSentTimestamp,
|
long targetSentTimestamp,
|
||||||
Set<RecipientIdentifier> recipients
|
Set<RecipientIdentifier> recipients
|
||||||
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException {
|
) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException {
|
||||||
var targetAuthorRecipientId = recipientHelper.resolveRecipient(targetAuthor);
|
var targetAuthorRecipientId = context.getRecipientHelper().resolveRecipient(targetAuthor);
|
||||||
var reaction = new SignalServiceDataMessage.Reaction(emoji,
|
var reaction = new SignalServiceDataMessage.Reaction(emoji,
|
||||||
remove,
|
remove,
|
||||||
recipientHelper.resolveSignalServiceAddress(targetAuthorRecipientId),
|
context.getRecipientHelper().resolveSignalServiceAddress(targetAuthorRecipientId),
|
||||||
targetSentTimestamp);
|
targetSentTimestamp);
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().withReaction(reaction);
|
final var messageBuilder = SignalServiceDataMessage.newBuilder().withReaction(reaction);
|
||||||
return sendMessage(messageBuilder, recipients);
|
return sendMessage(messageBuilder, recipients);
|
||||||
|
@ -806,7 +717,7 @@ public class ManagerImpl implements Manager {
|
||||||
for (var recipient : recipients) {
|
for (var recipient : recipients) {
|
||||||
final RecipientId recipientId;
|
final RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (UnregisteredRecipientException e) {
|
} catch (UnregisteredRecipientException e) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -833,7 +744,7 @@ public class ManagerImpl implements Manager {
|
||||||
if (!account.isMasterDevice()) {
|
if (!account.isMasterDevice()) {
|
||||||
throw new NotMasterDeviceException();
|
throw new NotMasterDeviceException();
|
||||||
}
|
}
|
||||||
contactHelper.setContactName(recipientHelper.resolveRecipient(recipient), name);
|
context.getContactHelper().setContactName(context.getRecipientHelper().resolveRecipient(recipient), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -843,9 +754,9 @@ public class ManagerImpl implements Manager {
|
||||||
if (!account.isMasterDevice()) {
|
if (!account.isMasterDevice()) {
|
||||||
throw new NotMasterDeviceException();
|
throw new NotMasterDeviceException();
|
||||||
}
|
}
|
||||||
contactHelper.setContactBlocked(recipientHelper.resolveRecipient(recipient), blocked);
|
context.getContactHelper().setContactBlocked(context.getRecipientHelper().resolveRecipient(recipient), blocked);
|
||||||
// TODO cycle our profile key, if we're not together in a group with recipient
|
// TODO cycle our profile key, if we're not together in a group with recipient
|
||||||
syncHelper.sendBlockedList();
|
context.getSyncHelper().sendBlockedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -855,9 +766,9 @@ public class ManagerImpl implements Manager {
|
||||||
if (!account.isMasterDevice()) {
|
if (!account.isMasterDevice()) {
|
||||||
throw new NotMasterDeviceException();
|
throw new NotMasterDeviceException();
|
||||||
}
|
}
|
||||||
groupHelper.setGroupBlocked(groupId, blocked);
|
context.getGroupHelper().setGroupBlocked(groupId, blocked);
|
||||||
// TODO cycle our profile key
|
// TODO cycle our profile key
|
||||||
syncHelper.sendBlockedList();
|
context.getSyncHelper().sendBlockedList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -867,8 +778,8 @@ public class ManagerImpl implements Manager {
|
||||||
public void setExpirationTimer(
|
public void setExpirationTimer(
|
||||||
RecipientIdentifier.Single recipient, int messageExpirationTimer
|
RecipientIdentifier.Single recipient, int messageExpirationTimer
|
||||||
) throws IOException, UnregisteredRecipientException {
|
) throws IOException, UnregisteredRecipientException {
|
||||||
var recipientId = recipientHelper.resolveRecipient(recipient);
|
var recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
contactHelper.setExpirationTimer(recipientId, messageExpirationTimer);
|
context.getContactHelper().setExpirationTimer(recipientId, messageExpirationTimer);
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate();
|
final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate();
|
||||||
try {
|
try {
|
||||||
sendMessage(messageBuilder, Set.of(recipient));
|
sendMessage(messageBuilder, Set.of(recipient));
|
||||||
|
@ -911,13 +822,13 @@ public class ManagerImpl implements Manager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestAllSyncData() throws IOException {
|
public void requestAllSyncData() throws IOException {
|
||||||
syncHelper.requestAllSyncData();
|
context.getSyncHelper().requestAllSyncData();
|
||||||
retrieveRemoteStorage();
|
retrieveRemoteStorage();
|
||||||
}
|
}
|
||||||
|
|
||||||
void retrieveRemoteStorage() throws IOException {
|
void retrieveRemoteStorage() throws IOException {
|
||||||
if (account.getStorageKey() != null) {
|
if (account.getStorageKey() != null) {
|
||||||
storageHelper.readDataFromStorage();
|
context.getStorageHelper().readDataFromStorage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,7 +852,8 @@ public class ManagerImpl implements Manager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var result = incomingMessageHandler.handleRetryEnvelope(envelope, ignoreAttachments, handler);
|
final var result = context.getIncomingMessageHandler()
|
||||||
|
.handleRetryEnvelope(envelope, ignoreAttachments, handler);
|
||||||
final var actions = result.first();
|
final var actions = result.first();
|
||||||
final var exception = result.second();
|
final var exception = result.second();
|
||||||
|
|
||||||
|
@ -1171,7 +1083,7 @@ public class ManagerImpl implements Manager {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var result = incomingMessageHandler.handleEnvelope(envelope, ignoreAttachments, handler);
|
final var result = context.getIncomingMessageHandler().handleEnvelope(envelope, ignoreAttachments, handler);
|
||||||
for (final var h : result.first()) {
|
for (final var h : result.first()) {
|
||||||
final var existingAction = queuedActions.get(h);
|
final var existingAction = queuedActions.get(h);
|
||||||
if (existingAction == null) {
|
if (existingAction == null) {
|
||||||
|
@ -1256,16 +1168,16 @@ public class ManagerImpl implements Manager {
|
||||||
public boolean isContactBlocked(final RecipientIdentifier.Single recipient) {
|
public boolean isContactBlocked(final RecipientIdentifier.Single recipient) {
|
||||||
final RecipientId recipientId;
|
final RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException | UnregisteredRecipientException e) {
|
} catch (IOException | UnregisteredRecipientException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return contactHelper.isContactBlocked(recipientId);
|
return context.getContactHelper().isContactBlocked(recipientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void sendContacts() throws IOException {
|
public void sendContacts() throws IOException {
|
||||||
syncHelper.sendContacts();
|
context.getSyncHelper().sendContacts();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1281,7 +1193,7 @@ public class ManagerImpl implements Manager {
|
||||||
public String getContactOrProfileName(RecipientIdentifier.Single recipient) {
|
public String getContactOrProfileName(RecipientIdentifier.Single recipient) {
|
||||||
final RecipientId recipientId;
|
final RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException | UnregisteredRecipientException e) {
|
} catch (IOException | UnregisteredRecipientException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1291,7 +1203,7 @@ public class ManagerImpl implements Manager {
|
||||||
return contact.getName();
|
return contact.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
final var profile = profileHelper.getRecipientProfile(recipientId);
|
final var profile = context.getProfileHelper().getRecipientProfile(recipientId);
|
||||||
if (profile != null) {
|
if (profile != null) {
|
||||||
return profile.getDisplayName();
|
return profile.getDisplayName();
|
||||||
}
|
}
|
||||||
|
@ -1301,11 +1213,7 @@ public class ManagerImpl implements Manager {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Group getGroup(GroupId groupId) {
|
public Group getGroup(GroupId groupId) {
|
||||||
return toGroup(groupHelper.getGroup(groupId));
|
return toGroup(context.getGroupHelper().getGroup(groupId));
|
||||||
}
|
|
||||||
|
|
||||||
private GroupInfo getGroupInfo(GroupId groupId) {
|
|
||||||
return groupHelper.getGroup(groupId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1319,11 +1227,12 @@ public class ManagerImpl implements Manager {
|
||||||
}
|
}
|
||||||
|
|
||||||
final var address = account.getRecipientStore().resolveRecipientAddress(identityInfo.getRecipientId());
|
final var address = account.getRecipientStore().resolveRecipientAddress(identityInfo.getRecipientId());
|
||||||
final var scannableFingerprint = identityHelper.computeSafetyNumberForScanning(identityInfo.getRecipientId(),
|
final var scannableFingerprint = context.getIdentityHelper()
|
||||||
identityInfo.getIdentityKey());
|
.computeSafetyNumberForScanning(identityInfo.getRecipientId(), identityInfo.getIdentityKey());
|
||||||
return new Identity(address,
|
return new Identity(address,
|
||||||
identityInfo.getIdentityKey(),
|
identityInfo.getIdentityKey(),
|
||||||
identityHelper.computeSafetyNumber(identityInfo.getRecipientId(), identityInfo.getIdentityKey()),
|
context.getIdentityHelper()
|
||||||
|
.computeSafetyNumber(identityInfo.getRecipientId(), identityInfo.getIdentityKey()),
|
||||||
scannableFingerprint == null ? null : scannableFingerprint.getSerialized(),
|
scannableFingerprint == null ? null : scannableFingerprint.getSerialized(),
|
||||||
identityInfo.getTrustLevel(),
|
identityInfo.getTrustLevel(),
|
||||||
identityInfo.getDateAdded());
|
identityInfo.getDateAdded());
|
||||||
|
@ -1333,7 +1242,8 @@ public class ManagerImpl implements Manager {
|
||||||
public List<Identity> getIdentities(RecipientIdentifier.Single recipient) {
|
public List<Identity> getIdentities(RecipientIdentifier.Single recipient) {
|
||||||
IdentityInfo identity;
|
IdentityInfo identity;
|
||||||
try {
|
try {
|
||||||
identity = account.getIdentityKeyStore().getIdentity(recipientHelper.resolveRecipient(recipient));
|
identity = account.getIdentityKeyStore()
|
||||||
|
.getIdentity(context.getRecipientHelper().resolveRecipient(recipient));
|
||||||
} catch (IOException | UnregisteredRecipientException e) {
|
} catch (IOException | UnregisteredRecipientException e) {
|
||||||
identity = null;
|
identity = null;
|
||||||
}
|
}
|
||||||
|
@ -1352,11 +1262,11 @@ public class ManagerImpl implements Manager {
|
||||||
) throws UnregisteredRecipientException {
|
) throws UnregisteredRecipientException {
|
||||||
RecipientId recipientId;
|
RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final var updated = identityHelper.trustIdentityVerified(recipientId, fingerprint);
|
final var updated = context.getIdentityHelper().trustIdentityVerified(recipientId, fingerprint);
|
||||||
if (updated && this.isReceiving()) {
|
if (updated && this.isReceiving()) {
|
||||||
needsToRetryFailedMessages = true;
|
needsToRetryFailedMessages = true;
|
||||||
}
|
}
|
||||||
|
@ -1375,11 +1285,11 @@ public class ManagerImpl implements Manager {
|
||||||
) throws UnregisteredRecipientException {
|
) throws UnregisteredRecipientException {
|
||||||
RecipientId recipientId;
|
RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final var updated = identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
|
final var updated = context.getIdentityHelper().trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
|
||||||
if (updated && this.isReceiving()) {
|
if (updated && this.isReceiving()) {
|
||||||
needsToRetryFailedMessages = true;
|
needsToRetryFailedMessages = true;
|
||||||
}
|
}
|
||||||
|
@ -1398,11 +1308,11 @@ public class ManagerImpl implements Manager {
|
||||||
) throws UnregisteredRecipientException {
|
) throws UnregisteredRecipientException {
|
||||||
RecipientId recipientId;
|
RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final var updated = identityHelper.trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
|
final var updated = context.getIdentityHelper().trustIdentityVerifiedSafetyNumber(recipientId, safetyNumber);
|
||||||
if (updated && this.isReceiving()) {
|
if (updated && this.isReceiving()) {
|
||||||
needsToRetryFailedMessages = true;
|
needsToRetryFailedMessages = true;
|
||||||
}
|
}
|
||||||
|
@ -1418,11 +1328,11 @@ public class ManagerImpl implements Manager {
|
||||||
public boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException {
|
public boolean trustIdentityAllKeys(RecipientIdentifier.Single recipient) throws UnregisteredRecipientException {
|
||||||
RecipientId recipientId;
|
RecipientId recipientId;
|
||||||
try {
|
try {
|
||||||
recipientId = recipientHelper.resolveRecipient(recipient);
|
recipientId = context.getRecipientHelper().resolveRecipient(recipient);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final var updated = identityHelper.trustIdentityAllKeys(recipientId);
|
final var updated = context.getIdentityHelper().trustIdentityAllKeys(recipientId);
|
||||||
if (updated && this.isReceiving()) {
|
if (updated && this.isReceiving()) {
|
||||||
needsToRetryFailedMessages = true;
|
needsToRetryFailedMessages = true;
|
||||||
}
|
}
|
||||||
|
@ -1436,13 +1346,6 @@ public class ManagerImpl implements Manager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleIdentityFailure(
|
|
||||||
final RecipientId recipientId,
|
|
||||||
final org.whispersystems.signalservice.api.messages.SendMessageResult.IdentityFailure identityFailure
|
|
||||||
) {
|
|
||||||
this.identityHelper.handleIdentityFailure(recipientId, identityFailure);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
Thread thread;
|
Thread thread;
|
||||||
|
|
|
@ -68,6 +68,10 @@ public class SignalDependencies {
|
||||||
this.sessionLock = sessionLock;
|
this.sessionLock = sessionLock;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ServiceEnvironmentConfig getServiceEnvironmentConfig() {
|
||||||
|
return serviceEnvironmentConfig;
|
||||||
|
}
|
||||||
|
|
||||||
public SignalServiceAccountManager getAccountManager() {
|
public SignalServiceAccountManager getAccountManager() {
|
||||||
return getOrCreate(() -> accountManager,
|
return getOrCreate(() -> accountManager,
|
||||||
() -> accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
|
() -> accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public interface HandleAction {
|
public interface HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class RefreshPreKeysAction implements HandleAction {
|
public class RefreshPreKeysAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
public class RenewSessionAction implements HandleAction {
|
public class RenewSessionAction implements HandleAction {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
public class RetrieveProfileAction implements HandleAction {
|
public class RetrieveProfileAction implements HandleAction {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class RetrieveStorageDataAction implements HandleAction {
|
public class RetrieveStorageDataAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.groups.GroupIdV1;
|
import org.asamk.signal.manager.groups.GroupIdV1;
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
public class SendGroupInfoAction implements HandleAction {
|
public class SendGroupInfoAction implements HandleAction {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.groups.GroupIdV1;
|
import org.asamk.signal.manager.groups.GroupIdV1;
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
public class SendGroupInfoRequestAction implements HandleAction {
|
public class SendGroupInfoRequestAction implements HandleAction {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.groups.GroupId;
|
import org.asamk.signal.manager.groups.GroupId;
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
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;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class SendSyncBlockedListAction implements HandleAction {
|
public class SendSyncBlockedListAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class SendSyncConfigurationAction implements HandleAction {
|
public class SendSyncConfigurationAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class SendSyncContactsAction implements HandleAction {
|
public class SendSyncContactsAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class SendSyncGroupsAction implements HandleAction {
|
public class SendSyncGroupsAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package org.asamk.signal.manager.actions;
|
package org.asamk.signal.manager.actions;
|
||||||
|
|
||||||
import org.asamk.signal.manager.jobs.Context;
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public class SendSyncKeysAction implements HandleAction {
|
public class SendSyncKeysAction implements HandleAction {
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,9 @@ public class AttachmentHelper {
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final AttachmentStore attachmentStore;
|
private final AttachmentStore attachmentStore;
|
||||||
|
|
||||||
public AttachmentHelper(
|
public AttachmentHelper(final Context context) {
|
||||||
final SignalDependencies dependencies, final AttachmentStore attachmentStore
|
this.dependencies = context.getDependencies();
|
||||||
) {
|
this.attachmentStore = context.getAttachmentStore();
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.attachmentStore = attachmentStore;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
public File getAttachmentFile(SignalServiceAttachmentRemoteId attachmentId) {
|
||||||
|
|
155
lib/src/main/java/org/asamk/signal/manager/helper/Context.java
Normal file
155
lib/src/main/java/org/asamk/signal/manager/helper/Context.java
Normal file
|
@ -0,0 +1,155 @@
|
||||||
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.AttachmentStore;
|
||||||
|
import org.asamk.signal.manager.AvatarStore;
|
||||||
|
import org.asamk.signal.manager.JobExecutor;
|
||||||
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
|
import org.asamk.signal.manager.StickerPackStore;
|
||||||
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class Context {
|
||||||
|
|
||||||
|
private final Object LOCK = new Object();
|
||||||
|
|
||||||
|
private final SignalAccount account;
|
||||||
|
private final SignalDependencies dependencies;
|
||||||
|
private final AvatarStore avatarStore;
|
||||||
|
private final StickerPackStore stickerPackStore;
|
||||||
|
private final AttachmentStore attachmentStore;
|
||||||
|
private final JobExecutor jobExecutor;
|
||||||
|
|
||||||
|
private AttachmentHelper attachmentHelper;
|
||||||
|
private ContactHelper contactHelper;
|
||||||
|
private GroupHelper groupHelper;
|
||||||
|
private GroupV2Helper groupV2Helper;
|
||||||
|
private IdentityHelper identityHelper;
|
||||||
|
private IncomingMessageHandler incomingMessageHandler;
|
||||||
|
private PinHelper pinHelper;
|
||||||
|
private PreKeyHelper preKeyHelper;
|
||||||
|
private ProfileHelper profileHelper;
|
||||||
|
private RecipientHelper recipientHelper;
|
||||||
|
private SendHelper sendHelper;
|
||||||
|
private StorageHelper storageHelper;
|
||||||
|
private SyncHelper syncHelper;
|
||||||
|
private UnidentifiedAccessHelper unidentifiedAccessHelper;
|
||||||
|
|
||||||
|
public Context(
|
||||||
|
final SignalAccount account,
|
||||||
|
final SignalDependencies dependencies,
|
||||||
|
final AvatarStore avatarStore,
|
||||||
|
final AttachmentStore attachmentStore,
|
||||||
|
final StickerPackStore stickerPackStore
|
||||||
|
) {
|
||||||
|
this.account = account;
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
this.avatarStore = avatarStore;
|
||||||
|
this.stickerPackStore = stickerPackStore;
|
||||||
|
this.attachmentStore = attachmentStore;
|
||||||
|
this.jobExecutor = new JobExecutor(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SignalAccount getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SignalDependencies getDependencies() {
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AvatarStore getAvatarStore() {
|
||||||
|
return avatarStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public StickerPackStore getStickerPackStore() {
|
||||||
|
return stickerPackStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
AttachmentStore getAttachmentStore() {
|
||||||
|
return attachmentStore;
|
||||||
|
}
|
||||||
|
|
||||||
|
JobExecutor getJobExecutor() {
|
||||||
|
return jobExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AttachmentHelper getAttachmentHelper() {
|
||||||
|
return getOrCreate(() -> attachmentHelper, () -> attachmentHelper = new AttachmentHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ContactHelper getContactHelper() {
|
||||||
|
return getOrCreate(() -> contactHelper, () -> contactHelper = new ContactHelper(account));
|
||||||
|
}
|
||||||
|
|
||||||
|
GroupV2Helper getGroupV2Helper() {
|
||||||
|
return getOrCreate(() -> groupV2Helper, () -> groupV2Helper = new GroupV2Helper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupHelper getGroupHelper() {
|
||||||
|
return getOrCreate(() -> groupHelper, () -> groupHelper = new GroupHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityHelper getIdentityHelper() {
|
||||||
|
return getOrCreate(() -> identityHelper, () -> identityHelper = new IdentityHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public IncomingMessageHandler getIncomingMessageHandler() {
|
||||||
|
return getOrCreate(() -> incomingMessageHandler,
|
||||||
|
() -> this.incomingMessageHandler = new IncomingMessageHandler(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PinHelper getPinHelper() {
|
||||||
|
return getOrCreate(() -> pinHelper, () -> pinHelper = new PinHelper(dependencies.getKeyBackupService()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public PreKeyHelper getPreKeyHelper() {
|
||||||
|
return getOrCreate(() -> preKeyHelper, () -> preKeyHelper = new PreKeyHelper(account, dependencies));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProfileHelper getProfileHelper() {
|
||||||
|
return getOrCreate(() -> profileHelper, () -> profileHelper = new ProfileHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public RecipientHelper getRecipientHelper() {
|
||||||
|
return getOrCreate(() -> recipientHelper, () -> recipientHelper = new RecipientHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SendHelper getSendHelper() {
|
||||||
|
return getOrCreate(() -> sendHelper, () -> sendHelper = new SendHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public StorageHelper getStorageHelper() {
|
||||||
|
return getOrCreate(() -> storageHelper, () -> storageHelper = new StorageHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncHelper getSyncHelper() {
|
||||||
|
return getOrCreate(() -> syncHelper, () -> syncHelper = new SyncHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
UnidentifiedAccessHelper getUnidentifiedAccessHelper() {
|
||||||
|
return getOrCreate(() -> unidentifiedAccessHelper,
|
||||||
|
() -> unidentifiedAccessHelper = new UnidentifiedAccessHelper(this));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> T getOrCreate(Supplier<T> supplier, Callable creator) {
|
||||||
|
var value = supplier.get();
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
synchronized (LOCK) {
|
||||||
|
value = supplier.get();
|
||||||
|
if (value != null) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
creator.call();
|
||||||
|
return supplier.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface Callable {
|
||||||
|
|
||||||
|
void call();
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.AttachmentInvalidException;
|
import org.asamk.signal.manager.AttachmentInvalidException;
|
||||||
import org.asamk.signal.manager.AvatarStore;
|
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
import org.asamk.signal.manager.api.InactiveGroupLinkException;
|
import org.asamk.signal.manager.api.InactiveGroupLinkException;
|
||||||
import org.asamk.signal.manager.api.Pair;
|
import org.asamk.signal.manager.api.Pair;
|
||||||
|
@ -24,7 +23,6 @@ import org.asamk.signal.manager.storage.groups.GroupInfo;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfoV2;
|
import org.asamk.signal.manager.storage.groups.GroupInfoV2;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientResolver;
|
|
||||||
import org.asamk.signal.manager.util.AttachmentUtils;
|
import org.asamk.signal.manager.util.AttachmentUtils;
|
||||||
import org.asamk.signal.manager.util.IOUtils;
|
import org.asamk.signal.manager.util.IOUtils;
|
||||||
import org.signal.storageservice.protos.groups.GroupChange;
|
import org.signal.storageservice.protos.groups.GroupChange;
|
||||||
|
@ -63,31 +61,12 @@ public class GroupHelper {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final AttachmentHelper attachmentHelper;
|
private final Context context;
|
||||||
private final SendHelper sendHelper;
|
|
||||||
private final GroupV2Helper groupV2Helper;
|
|
||||||
private final AvatarStore avatarStore;
|
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
private final RecipientResolver recipientResolver;
|
|
||||||
|
|
||||||
public GroupHelper(
|
public GroupHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final AttachmentHelper attachmentHelper,
|
this.context = context;
|
||||||
final SendHelper sendHelper,
|
|
||||||
final GroupV2Helper groupV2Helper,
|
|
||||||
final AvatarStore avatarStore,
|
|
||||||
final SignalServiceAddressResolver addressResolver,
|
|
||||||
final RecipientResolver recipientResolver
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.attachmentHelper = attachmentHelper;
|
|
||||||
this.sendHelper = sendHelper;
|
|
||||||
this.groupV2Helper = groupV2Helper;
|
|
||||||
this.avatarStore = avatarStore;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
this.recipientResolver = recipientResolver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GroupInfo getGroup(GroupId groupId) {
|
public GroupInfo getGroup(GroupId groupId) {
|
||||||
|
@ -101,15 +80,16 @@ public class GroupHelper {
|
||||||
|
|
||||||
public void downloadGroupAvatar(GroupIdV1 groupId, SignalServiceAttachment avatar) {
|
public void downloadGroupAvatar(GroupIdV1 groupId, SignalServiceAttachment avatar) {
|
||||||
try {
|
try {
|
||||||
avatarStore.storeGroupAvatar(groupId,
|
context.getAvatarStore()
|
||||||
outputStream -> attachmentHelper.retrieveAttachment(avatar, outputStream));
|
.storeGroupAvatar(groupId,
|
||||||
|
outputStream -> context.getAttachmentHelper().retrieveAttachment(avatar, outputStream));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to download avatar for group {}, ignoring: {}", groupId.toBase64(), e.getMessage());
|
logger.warn("Failed to download avatar for group {}, ignoring: {}", groupId.toBase64(), e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<SignalServiceAttachmentStream> createGroupAvatarAttachment(GroupIdV1 groupId) throws IOException {
|
public Optional<SignalServiceAttachmentStream> createGroupAvatarAttachment(GroupIdV1 groupId) throws IOException {
|
||||||
final var streamDetails = avatarStore.retrieveGroupAvatar(groupId);
|
final var streamDetails = context.getAvatarStore().retrieveGroupAvatar(groupId);
|
||||||
if (streamDetails == null) {
|
if (streamDetails == null) {
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
@ -143,13 +123,12 @@ public class GroupHelper {
|
||||||
if (signedGroupChange != null
|
if (signedGroupChange != null
|
||||||
&& groupInfoV2.getGroup() != null
|
&& groupInfoV2.getGroup() != null
|
||||||
&& groupInfoV2.getGroup().getRevision() + 1 == revision) {
|
&& groupInfoV2.getGroup().getRevision() + 1 == revision) {
|
||||||
group = groupV2Helper.getUpdatedDecryptedGroup(groupInfoV2.getGroup(),
|
group = context.getGroupV2Helper()
|
||||||
signedGroupChange,
|
.getUpdatedDecryptedGroup(groupInfoV2.getGroup(), signedGroupChange, groupMasterKey);
|
||||||
groupMasterKey);
|
|
||||||
}
|
}
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
try {
|
try {
|
||||||
group = groupV2Helper.getDecryptedGroup(groupSecretParams);
|
group = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
|
||||||
} catch (NotAGroupMemberException ignored) {
|
} catch (NotAGroupMemberException ignored) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +139,7 @@ public class GroupHelper {
|
||||||
downloadGroupAvatar(groupId, groupSecretParams, avatar);
|
downloadGroupAvatar(groupId, groupSecretParams, avatar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
groupInfoV2.setGroup(group, recipientResolver);
|
groupInfoV2.setGroup(group, account.getRecipientStore());
|
||||||
account.getGroupStore().updateGroup(groupInfoV2);
|
account.getGroupStore().updateGroup(groupInfoV2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,9 +155,8 @@ public class GroupHelper {
|
||||||
members.remove(selfRecipientId);
|
members.remove(selfRecipientId);
|
||||||
}
|
}
|
||||||
|
|
||||||
var gv2Pair = groupV2Helper.createGroup(name == null ? "" : name,
|
var gv2Pair = context.getGroupV2Helper()
|
||||||
members == null ? Set.of() : members,
|
.createGroup(name == null ? "" : name, members == null ? Set.of() : members, avatarFile);
|
||||||
avatarFile);
|
|
||||||
|
|
||||||
if (gv2Pair == null) {
|
if (gv2Pair == null) {
|
||||||
// Failed to create v2 group, creating v1 group instead
|
// Failed to create v2 group, creating v1 group instead
|
||||||
|
@ -191,10 +169,11 @@ public class GroupHelper {
|
||||||
final var gv2 = gv2Pair.first();
|
final var gv2 = gv2Pair.first();
|
||||||
final var decryptedGroup = gv2Pair.second();
|
final var decryptedGroup = gv2Pair.second();
|
||||||
|
|
||||||
gv2.setGroup(decryptedGroup, recipientResolver);
|
gv2.setGroup(decryptedGroup, account.getRecipientStore());
|
||||||
if (avatarFile != null) {
|
if (avatarFile != null) {
|
||||||
avatarStore.storeGroupAvatar(gv2.getGroupId(),
|
context.getAvatarStore()
|
||||||
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
.storeGroupAvatar(gv2.getGroupId(),
|
||||||
|
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
||||||
}
|
}
|
||||||
|
|
||||||
account.getGroupStore().updateGroup(gv2);
|
account.getGroupStore().updateGroup(gv2);
|
||||||
|
@ -274,14 +253,13 @@ public class GroupHelper {
|
||||||
) throws IOException, InactiveGroupLinkException {
|
) throws IOException, InactiveGroupLinkException {
|
||||||
final DecryptedGroupJoinInfo groupJoinInfo;
|
final DecryptedGroupJoinInfo groupJoinInfo;
|
||||||
try {
|
try {
|
||||||
groupJoinInfo = groupV2Helper.getDecryptedGroupJoinInfo(inviteLinkUrl.getGroupMasterKey(),
|
groupJoinInfo = context.getGroupV2Helper()
|
||||||
inviteLinkUrl.getPassword());
|
.getDecryptedGroupJoinInfo(inviteLinkUrl.getGroupMasterKey(), inviteLinkUrl.getPassword());
|
||||||
} catch (GroupLinkNotActiveException e) {
|
} catch (GroupLinkNotActiveException e) {
|
||||||
throw new InactiveGroupLinkException("Group link inactive", e);
|
throw new InactiveGroupLinkException("Group link inactive", e);
|
||||||
}
|
}
|
||||||
final var groupChange = groupV2Helper.joinGroup(inviteLinkUrl.getGroupMasterKey(),
|
final var groupChange = context.getGroupV2Helper()
|
||||||
inviteLinkUrl.getPassword(),
|
.joinGroup(inviteLinkUrl.getGroupMasterKey(), inviteLinkUrl.getPassword(), groupJoinInfo);
|
||||||
groupJoinInfo);
|
|
||||||
final var group = getOrMigrateGroup(inviteLinkUrl.getGroupMasterKey(),
|
final var group = getOrMigrateGroup(inviteLinkUrl.getGroupMasterKey(),
|
||||||
groupJoinInfo.getRevision() + 1,
|
groupJoinInfo.getRevision() + 1,
|
||||||
groupChange.toByteArray());
|
groupChange.toByteArray());
|
||||||
|
@ -315,7 +293,7 @@ public class GroupHelper {
|
||||||
|
|
||||||
public void deleteGroup(GroupId groupId) throws IOException {
|
public void deleteGroup(GroupId groupId) throws IOException {
|
||||||
account.getGroupStore().deleteGroup(groupId);
|
account.getGroupStore().deleteGroup(groupId);
|
||||||
avatarStore.deleteGroupAvatar(groupId);
|
context.getAvatarStore().deleteGroupAvatar(groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGroupBlocked(final GroupId groupId, final boolean blocked) throws GroupNotFoundException {
|
public void setGroupBlocked(final GroupId groupId, final boolean blocked) throws GroupNotFoundException {
|
||||||
|
@ -366,12 +344,12 @@ public class GroupHelper {
|
||||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
DecryptedGroup decryptedGroup;
|
DecryptedGroup decryptedGroup;
|
||||||
try {
|
try {
|
||||||
decryptedGroup = groupV2Helper.getDecryptedGroup(groupSecretParams);
|
decryptedGroup = context.getGroupV2Helper().getDecryptedGroup(groupSecretParams);
|
||||||
} catch (NotAGroupMemberException e) {
|
} catch (NotAGroupMemberException e) {
|
||||||
groupInfoV2.setPermissionDenied(true);
|
groupInfoV2.setPermissionDenied(true);
|
||||||
decryptedGroup = null;
|
decryptedGroup = null;
|
||||||
}
|
}
|
||||||
groupInfoV2.setGroup(decryptedGroup, recipientResolver);
|
groupInfoV2.setGroup(decryptedGroup, account.getRecipientStore());
|
||||||
account.getGroupStore().updateGroup(group);
|
account.getGroupStore().updateGroup(group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -380,8 +358,9 @@ public class GroupHelper {
|
||||||
|
|
||||||
private void downloadGroupAvatar(GroupIdV2 groupId, GroupSecretParams groupSecretParams, String cdnKey) {
|
private void downloadGroupAvatar(GroupIdV2 groupId, GroupSecretParams groupSecretParams, String cdnKey) {
|
||||||
try {
|
try {
|
||||||
avatarStore.storeGroupAvatar(groupId,
|
context.getAvatarStore()
|
||||||
outputStream -> retrieveGroupV2Avatar(groupSecretParams, cdnKey, outputStream));
|
.storeGroupAvatar(groupId,
|
||||||
|
outputStream -> retrieveGroupV2Avatar(groupSecretParams, cdnKey, outputStream));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to download avatar for group {}, ignoring: {}", groupId.toBase64(), e.getMessage());
|
logger.warn("Failed to download avatar for group {}, ignoring: {}", groupId.toBase64(), e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -458,8 +437,9 @@ public class GroupHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avatarFile != null) {
|
if (avatarFile != null) {
|
||||||
avatarStore.storeGroupAvatar(g.getGroupId(),
|
context.getAvatarStore()
|
||||||
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
.storeGroupAvatar(g.getGroupId(),
|
||||||
|
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,7 +456,7 @@ public class GroupHelper {
|
||||||
|
|
||||||
private void sendExpirationTimerUpdate(GroupIdV1 groupId) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
private void sendExpirationTimerUpdate(GroupIdV1 groupId) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException {
|
||||||
final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate();
|
final var messageBuilder = SignalServiceDataMessage.newBuilder().asExpirationUpdate();
|
||||||
sendHelper.sendAsGroupMessage(messageBuilder, groupId);
|
context.getSendHelper().sendAsGroupMessage(messageBuilder, groupId);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendGroupMessageResults updateGroupV2(
|
private SendGroupMessageResults updateGroupV2(
|
||||||
|
@ -496,6 +476,7 @@ public class GroupHelper {
|
||||||
final Boolean isAnnouncementGroup
|
final Boolean isAnnouncementGroup
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
SendGroupMessageResults result = null;
|
SendGroupMessageResults result = null;
|
||||||
|
final var groupV2Helper = context.getGroupV2Helper();
|
||||||
if (group.isPendingMember(account.getSelfRecipientId())) {
|
if (group.isPendingMember(account.getSelfRecipientId())) {
|
||||||
var groupGroupChangePair = groupV2Helper.acceptInvite(group);
|
var groupGroupChangePair = groupV2Helper.acceptInvite(group);
|
||||||
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
|
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
|
||||||
|
@ -587,8 +568,9 @@ public class GroupHelper {
|
||||||
if (name != null || description != null || avatarFile != null) {
|
if (name != null || description != null || avatarFile != null) {
|
||||||
var groupGroupChangePair = groupV2Helper.updateGroup(group, name, description, avatarFile);
|
var groupGroupChangePair = groupV2Helper.updateGroup(group, name, description, avatarFile);
|
||||||
if (avatarFile != null) {
|
if (avatarFile != null) {
|
||||||
avatarStore.storeGroupAvatar(group.getGroupId(),
|
context.getAvatarStore()
|
||||||
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
.storeGroupAvatar(group.getGroupId(),
|
||||||
|
outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
|
||||||
}
|
}
|
||||||
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
|
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
|
||||||
}
|
}
|
||||||
|
@ -622,8 +604,8 @@ public class GroupHelper {
|
||||||
// Last admin can't leave the group, unless she's also the last member
|
// Last admin can't leave the group, unless she's also the last member
|
||||||
throw new LastGroupAdminException(groupInfoV2.getGroupId(), groupInfoV2.getTitle());
|
throw new LastGroupAdminException(groupInfoV2.getGroupId(), groupInfoV2.getTitle());
|
||||||
}
|
}
|
||||||
final var groupGroupChangePair = groupV2Helper.leaveGroup(groupInfoV2, newAdmins);
|
final var groupGroupChangePair = context.getGroupV2Helper().leaveGroup(groupInfoV2, newAdmins);
|
||||||
groupInfoV2.setGroup(groupGroupChangePair.first(), recipientResolver);
|
groupInfoV2.setGroup(groupGroupChangePair.first(), account.getRecipientStore());
|
||||||
account.getGroupStore().updateGroup(groupInfoV2);
|
account.getGroupStore().updateGroup(groupInfoV2);
|
||||||
|
|
||||||
var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().toByteArray());
|
var messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().toByteArray());
|
||||||
|
@ -636,7 +618,10 @@ public class GroupHelper {
|
||||||
var group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.UPDATE)
|
var group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.UPDATE)
|
||||||
.withId(g.getGroupId().serialize())
|
.withId(g.getGroupId().serialize())
|
||||||
.withName(g.name)
|
.withName(g.name)
|
||||||
.withMembers(g.getMembers().stream().map(addressResolver::resolveSignalServiceAddress).toList());
|
.withMembers(g.getMembers()
|
||||||
|
.stream()
|
||||||
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
|
.toList());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final var attachment = createGroupAvatarAttachment(g.getGroupId());
|
final var attachment = createGroupAvatarAttachment(g.getGroupId());
|
||||||
|
@ -666,7 +651,7 @@ public class GroupHelper {
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var selfRecipientId = account.getSelfRecipientId();
|
final var selfRecipientId = account.getSelfRecipientId();
|
||||||
final var members = group.getMembersIncludingPendingWithout(selfRecipientId);
|
final var members = group.getMembersIncludingPendingWithout(selfRecipientId);
|
||||||
group.setGroup(newDecryptedGroup, recipientResolver);
|
group.setGroup(newDecryptedGroup, account.getRecipientStore());
|
||||||
members.addAll(group.getMembersIncludingPendingWithout(selfRecipientId));
|
members.addAll(group.getMembersIncludingPendingWithout(selfRecipientId));
|
||||||
account.getGroupStore().updateGroup(group);
|
account.getGroupStore().updateGroup(group);
|
||||||
|
|
||||||
|
@ -681,11 +666,11 @@ public class GroupHelper {
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var timestamp = System.currentTimeMillis();
|
final var timestamp = System.currentTimeMillis();
|
||||||
messageBuilder.withTimestamp(timestamp);
|
messageBuilder.withTimestamp(timestamp);
|
||||||
final var results = sendHelper.sendGroupMessage(messageBuilder.build(), members, distributionId);
|
final var results = context.getSendHelper().sendGroupMessage(messageBuilder.build(), members, distributionId);
|
||||||
return new SendGroupMessageResults(timestamp,
|
return new SendGroupMessageResults(timestamp,
|
||||||
results.stream()
|
results.stream()
|
||||||
.map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
|
.map(sendMessageResult -> SendMessageResult.from(sendMessageResult,
|
||||||
recipientResolver,
|
account.getRecipientStore(),
|
||||||
account.getRecipientStore()::resolveRecipientAddress))
|
account.getRecipientStore()::resolveRecipientAddress))
|
||||||
.toList());
|
.toList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.groups.GroupId;
|
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
|
||||||
|
|
||||||
public interface GroupProvider {
|
|
||||||
|
|
||||||
GroupInfo getGroup(GroupId groupId);
|
|
||||||
}
|
|
|
@ -2,6 +2,7 @@ package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import com.google.protobuf.InvalidProtocolBufferException;
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
import org.asamk.signal.manager.api.Pair;
|
import org.asamk.signal.manager.api.Pair;
|
||||||
import org.asamk.signal.manager.groups.GroupLinkPassword;
|
import org.asamk.signal.manager.groups.GroupLinkPassword;
|
||||||
import org.asamk.signal.manager.groups.GroupLinkState;
|
import org.asamk.signal.manager.groups.GroupLinkState;
|
||||||
|
@ -32,7 +33,6 @@ 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;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Api;
|
|
||||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
|
import org.whispersystems.signalservice.api.groupsv2.GroupsV2AuthorizationString;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
|
||||||
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
import org.whispersystems.signalservice.api.groupsv2.InvalidGroupStateException;
|
||||||
|
@ -56,32 +56,20 @@ public class GroupV2Helper {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(GroupV2Helper.class);
|
private final static Logger logger = LoggerFactory.getLogger(GroupV2Helper.class);
|
||||||
|
|
||||||
private final ProfileHelper profileHelper;
|
private final SignalDependencies dependencies;
|
||||||
private final SelfRecipientIdProvider selfRecipientIdProvider;
|
private final Context context;
|
||||||
private final GroupsV2Operations groupsV2Operations;
|
|
||||||
private final GroupsV2Api groupsV2Api;
|
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
|
|
||||||
private HashMap<Integer, AuthCredentialResponse> groupApiCredentials;
|
private HashMap<Integer, AuthCredentialResponse> groupApiCredentials;
|
||||||
|
|
||||||
public GroupV2Helper(
|
public GroupV2Helper(final Context context) {
|
||||||
final ProfileHelper profileHelper,
|
this.dependencies = context.getDependencies();
|
||||||
final SelfRecipientIdProvider selfRecipientIdProvider,
|
this.context = context;
|
||||||
final GroupsV2Operations groupsV2Operations,
|
|
||||||
final GroupsV2Api groupsV2Api,
|
|
||||||
final SignalServiceAddressResolver addressResolver
|
|
||||||
) {
|
|
||||||
this.profileHelper = profileHelper;
|
|
||||||
this.selfRecipientIdProvider = selfRecipientIdProvider;
|
|
||||||
this.groupsV2Operations = groupsV2Operations;
|
|
||||||
this.groupsV2Api = groupsV2Api;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public DecryptedGroup getDecryptedGroup(final GroupSecretParams groupSecretParams) throws NotAGroupMemberException {
|
public DecryptedGroup getDecryptedGroup(final GroupSecretParams groupSecretParams) throws NotAGroupMemberException {
|
||||||
try {
|
try {
|
||||||
final var groupsV2AuthorizationString = getGroupAuthForToday(groupSecretParams);
|
final var groupsV2AuthorizationString = getGroupAuthForToday(groupSecretParams);
|
||||||
return groupsV2Api.getGroup(groupSecretParams, groupsV2AuthorizationString);
|
return dependencies.getGroupsV2Api().getGroup(groupSecretParams, groupsV2AuthorizationString);
|
||||||
} catch (NonSuccessfulResponseCodeException e) {
|
} catch (NonSuccessfulResponseCodeException e) {
|
||||||
if (e.getCode() == 403) {
|
if (e.getCode() == 403) {
|
||||||
throw new NotAGroupMemberException(GroupUtils.getGroupIdV2(groupSecretParams), null);
|
throw new NotAGroupMemberException(GroupUtils.getGroupIdV2(groupSecretParams), null);
|
||||||
|
@ -99,9 +87,10 @@ public class GroupV2Helper {
|
||||||
) throws IOException, GroupLinkNotActiveException {
|
) throws IOException, GroupLinkNotActiveException {
|
||||||
var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
||||||
|
|
||||||
return groupsV2Api.getGroupJoinInfo(groupSecretParams,
|
return dependencies.getGroupsV2Api()
|
||||||
Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
|
.getGroupJoinInfo(groupSecretParams,
|
||||||
getGroupAuthForToday(groupSecretParams));
|
Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
|
||||||
|
getGroupAuthForToday(groupSecretParams));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<GroupInfoV2, DecryptedGroup> createGroup(
|
public Pair<GroupInfoV2, DecryptedGroup> createGroup(
|
||||||
|
@ -119,8 +108,8 @@ public class GroupV2Helper {
|
||||||
final DecryptedGroup decryptedGroup;
|
final DecryptedGroup decryptedGroup;
|
||||||
try {
|
try {
|
||||||
groupAuthForToday = getGroupAuthForToday(groupSecretParams);
|
groupAuthForToday = getGroupAuthForToday(groupSecretParams);
|
||||||
groupsV2Api.putNewGroup(newGroup, groupAuthForToday);
|
dependencies.getGroupsV2Api().putNewGroup(newGroup, groupAuthForToday);
|
||||||
decryptedGroup = groupsV2Api.getGroup(groupSecretParams, groupAuthForToday);
|
decryptedGroup = dependencies.getGroupsV2Api().getGroup(groupSecretParams, groupAuthForToday);
|
||||||
} catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
|
} catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
|
||||||
logger.warn("Failed to create V2 group: {}", e.getMessage());
|
logger.warn("Failed to create V2 group: {}", e.getMessage());
|
||||||
return null;
|
return null;
|
||||||
|
@ -148,7 +137,8 @@ public class GroupV2Helper {
|
||||||
private GroupsV2Operations.NewGroup buildNewGroup(
|
private GroupsV2Operations.NewGroup buildNewGroup(
|
||||||
String name, Set<RecipientId> members, byte[] avatar
|
String name, Set<RecipientId> members, byte[] avatar
|
||||||
) {
|
) {
|
||||||
final var profileKeyCredential = profileHelper.getRecipientProfileKeyCredential(selfRecipientIdProvider.getSelfRecipientId());
|
final var profileKeyCredential = context.getProfileHelper()
|
||||||
|
.getRecipientProfileKeyCredential(context.getAccount().getSelfRecipientId());
|
||||||
if (profileKeyCredential == null) {
|
if (profileKeyCredential == null) {
|
||||||
logger.warn("Cannot create a V2 group as self does not have a versioned profile");
|
logger.warn("Cannot create a V2 group as self does not have a versioned profile");
|
||||||
return null;
|
return null;
|
||||||
|
@ -158,26 +148,28 @@ public class GroupV2Helper {
|
||||||
|
|
||||||
final var self = new GroupCandidate(getSelfAci().uuid(), Optional.fromNullable(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 = profileHelper.getRecipientProfileKeyCredential(memberList).stream();
|
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream();
|
||||||
final var uuids = memberList.stream()
|
final var uuids = memberList.stream()
|
||||||
.map(member -> addressResolver.resolveSignalServiceAddress(member).getAci().uuid());
|
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getAci().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.fromNullable(credential)))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
final var groupSecretParams = GroupSecretParams.generate();
|
final var groupSecretParams = GroupSecretParams.generate();
|
||||||
return groupsV2Operations.createNewGroup(groupSecretParams,
|
return dependencies.getGroupsV2Operations()
|
||||||
name,
|
.createNewGroup(groupSecretParams,
|
||||||
Optional.fromNullable(avatar),
|
name,
|
||||||
self,
|
Optional.fromNullable(avatar),
|
||||||
candidates,
|
self,
|
||||||
Member.Role.DEFAULT,
|
candidates,
|
||||||
0);
|
Member.Role.DEFAULT,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean areMembersValid(final Set<RecipientId> members) {
|
private boolean areMembersValid(final Set<RecipientId> members) {
|
||||||
final var noGv2Capability = profileHelper.getRecipientProfile(new ArrayList<>(members))
|
final var noGv2Capability = context.getProfileHelper()
|
||||||
|
.getRecipientProfile(new ArrayList<>(members))
|
||||||
.stream()
|
.stream()
|
||||||
.filter(profile -> profile != null && !profile.getCapabilities().contains(Profile.Capability.gv2))
|
.filter(profile -> profile != null && !profile.getCapabilities().contains(Profile.Capability.gv2))
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -194,7 +186,7 @@ public class GroupV2Helper {
|
||||||
GroupInfoV2 groupInfoV2, String name, String description, File avatarFile
|
GroupInfoV2 groupInfoV2, String name, String description, File avatarFile
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
var groupOperations = groupsV2Operations.forGroup(groupSecretParams);
|
var groupOperations = dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
|
||||||
|
|
||||||
var change = name != null ? groupOperations.createModifyGroupTitle(name) : GroupChange.Actions.newBuilder();
|
var change = name != null ? groupOperations.createModifyGroupTitle(name) : GroupChange.Actions.newBuilder();
|
||||||
|
|
||||||
|
@ -204,9 +196,8 @@ public class GroupV2Helper {
|
||||||
|
|
||||||
if (avatarFile != null) {
|
if (avatarFile != null) {
|
||||||
final var avatarBytes = readAvatarBytes(avatarFile);
|
final var avatarBytes = readAvatarBytes(avatarFile);
|
||||||
var avatarCdnKey = groupsV2Api.uploadAvatar(avatarBytes,
|
var avatarCdnKey = dependencies.getGroupsV2Api()
|
||||||
groupSecretParams,
|
.uploadAvatar(avatarBytes, groupSecretParams, getGroupAuthForToday(groupSecretParams));
|
||||||
getGroupAuthForToday(groupSecretParams));
|
|
||||||
change.setModifyAvatar(GroupChange.Actions.ModifyAvatarAction.newBuilder().setAvatar(avatarCdnKey));
|
change.setModifyAvatar(GroupChange.Actions.ModifyAvatarAction.newBuilder().setAvatar(avatarCdnKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,9 +216,9 @@ public class GroupV2Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final var memberList = new ArrayList<>(newMembers);
|
final var memberList = new ArrayList<>(newMembers);
|
||||||
final var credentials = profileHelper.getRecipientProfileKeyCredential(memberList).stream();
|
final var credentials = context.getProfileHelper().getRecipientProfileKeyCredential(memberList).stream();
|
||||||
final var uuids = memberList.stream()
|
final var uuids = memberList.stream()
|
||||||
.map(member -> addressResolver.resolveSignalServiceAddress(member).getAci().uuid());
|
.map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getAci().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.fromNullable(credential)))
|
||||||
|
@ -253,7 +244,7 @@ public class GroupV2Helper {
|
||||||
}
|
}
|
||||||
|
|
||||||
final var adminUuids = membersToMakeAdmin.stream()
|
final var adminUuids = membersToMakeAdmin.stream()
|
||||||
.map(addressResolver::resolveSignalServiceAddress)
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
.map(SignalServiceAddress::getAci)
|
.map(SignalServiceAddress::getAci)
|
||||||
.map(ACI::uuid)
|
.map(ACI::uuid)
|
||||||
.toList();
|
.toList();
|
||||||
|
@ -266,7 +257,7 @@ public class GroupV2Helper {
|
||||||
GroupInfoV2 groupInfoV2, Set<RecipientId> members
|
GroupInfoV2 groupInfoV2, Set<RecipientId> members
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var memberUuids = members.stream()
|
final var memberUuids = members.stream()
|
||||||
.map(addressResolver::resolveSignalServiceAddress)
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
.map(SignalServiceAddress::getAci)
|
.map(SignalServiceAddress::getAci)
|
||||||
.map(ACI::uuid)
|
.map(ACI::uuid)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
@ -278,7 +269,7 @@ public class GroupV2Helper {
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
|
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
|
||||||
final var memberUuids = members.stream()
|
final var memberUuids = members.stream()
|
||||||
.map(addressResolver::resolveSignalServiceAddress)
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
.map(SignalServiceAddress::getAci)
|
.map(SignalServiceAddress::getAci)
|
||||||
.map(ACI::uuid)
|
.map(ACI::uuid)
|
||||||
.map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid))
|
.map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid))
|
||||||
|
@ -337,10 +328,10 @@ public class GroupV2Helper {
|
||||||
DecryptedGroupJoinInfo decryptedGroupJoinInfo
|
DecryptedGroupJoinInfo decryptedGroupJoinInfo
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
|
||||||
final var groupOperations = groupsV2Operations.forGroup(groupSecretParams);
|
final var groupOperations = dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
|
||||||
|
|
||||||
final var selfRecipientId = this.selfRecipientIdProvider.getSelfRecipientId();
|
final var selfRecipientId = context.getAccount().getSelfRecipientId();
|
||||||
final var profileKeyCredential = profileHelper.getRecipientProfileKeyCredential(selfRecipientId);
|
final var profileKeyCredential = context.getProfileHelper().getRecipientProfileKeyCredential(selfRecipientId);
|
||||||
if (profileKeyCredential == null) {
|
if (profileKeyCredential == null) {
|
||||||
throw new IOException("Cannot join a V2 group as self does not have a versioned profile");
|
throw new IOException("Cannot join a V2 group as self does not have a versioned profile");
|
||||||
}
|
}
|
||||||
|
@ -350,7 +341,10 @@ public class GroupV2Helper {
|
||||||
? groupOperations.createGroupJoinRequest(profileKeyCredential)
|
? groupOperations.createGroupJoinRequest(profileKeyCredential)
|
||||||
: groupOperations.createGroupJoinDirect(profileKeyCredential);
|
: groupOperations.createGroupJoinDirect(profileKeyCredential);
|
||||||
|
|
||||||
change.setSourceUuid(addressResolver.resolveSignalServiceAddress(selfRecipientId).getAci().toByteString());
|
change.setSourceUuid(context.getRecipientHelper()
|
||||||
|
.resolveSignalServiceAddress(selfRecipientId)
|
||||||
|
.getAci()
|
||||||
|
.toByteString());
|
||||||
|
|
||||||
return commitChange(groupSecretParams, decryptedGroupJoinInfo.getRevision(), change, groupLinkPassword);
|
return commitChange(groupSecretParams, decryptedGroupJoinInfo.getRevision(), change, groupLinkPassword);
|
||||||
}
|
}
|
||||||
|
@ -358,15 +352,15 @@ public class GroupV2Helper {
|
||||||
public Pair<DecryptedGroup, GroupChange> acceptInvite(GroupInfoV2 groupInfoV2) throws IOException {
|
public Pair<DecryptedGroup, GroupChange> acceptInvite(GroupInfoV2 groupInfoV2) throws IOException {
|
||||||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||||
|
|
||||||
final var selfRecipientId = this.selfRecipientIdProvider.getSelfRecipientId();
|
final var selfRecipientId = context.getAccount().getSelfRecipientId();
|
||||||
final var profileKeyCredential = profileHelper.getRecipientProfileKeyCredential(selfRecipientId);
|
final var profileKeyCredential = context.getProfileHelper().getRecipientProfileKeyCredential(selfRecipientId);
|
||||||
if (profileKeyCredential == null) {
|
if (profileKeyCredential == null) {
|
||||||
throw new IOException("Cannot join a V2 group as self does not have a versioned profile");
|
throw new IOException("Cannot join a V2 group as self does not have a versioned profile");
|
||||||
}
|
}
|
||||||
|
|
||||||
final var change = groupOperations.createAcceptInviteChange(profileKeyCredential);
|
final var change = groupOperations.createAcceptInviteChange(profileKeyCredential);
|
||||||
|
|
||||||
final var aci = addressResolver.resolveSignalServiceAddress(selfRecipientId).getAci();
|
final var aci = context.getRecipientHelper().resolveSignalServiceAddress(selfRecipientId).getAci();
|
||||||
change.setSourceUuid(aci.toByteString());
|
change.setSourceUuid(aci.toByteString());
|
||||||
|
|
||||||
return commitChange(groupInfoV2, change);
|
return commitChange(groupInfoV2, change);
|
||||||
|
@ -376,7 +370,7 @@ public class GroupV2Helper {
|
||||||
GroupInfoV2 groupInfoV2, RecipientId recipientId, boolean admin
|
GroupInfoV2 groupInfoV2, RecipientId recipientId, boolean admin
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||||
final var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT;
|
final var newRole = admin ? Member.Role.ADMINISTRATOR : Member.Role.DEFAULT;
|
||||||
final var change = groupOperations.createChangeMemberRole(address.getAci().uuid(), newRole);
|
final var change = groupOperations.createChangeMemberRole(address.getAci().uuid(), newRole);
|
||||||
return commitChange(groupInfoV2, change);
|
return commitChange(groupInfoV2, change);
|
||||||
|
@ -415,7 +409,7 @@ public class GroupV2Helper {
|
||||||
|
|
||||||
private GroupsV2Operations.GroupOperations getGroupOperations(final GroupInfoV2 groupInfoV2) {
|
private GroupsV2Operations.GroupOperations getGroupOperations(final GroupInfoV2 groupInfoV2) {
|
||||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
return groupsV2Operations.forGroup(groupSecretParams);
|
return dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Pair<DecryptedGroup, GroupChange> revokeInvites(
|
private Pair<DecryptedGroup, GroupChange> revokeInvites(
|
||||||
|
@ -443,7 +437,7 @@ public class GroupV2Helper {
|
||||||
GroupInfoV2 groupInfoV2, GroupChange.Actions.Builder change
|
GroupInfoV2 groupInfoV2, GroupChange.Actions.Builder change
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
final var groupOperations = groupsV2Operations.forGroup(groupSecretParams);
|
final var groupOperations = dependencies.getGroupsV2Operations().forGroup(groupSecretParams);
|
||||||
final var previousGroupState = groupInfoV2.getGroup();
|
final var previousGroupState = groupInfoV2.getGroup();
|
||||||
final var nextRevision = previousGroupState.getRevision() + 1;
|
final var nextRevision = previousGroupState.getRevision() + 1;
|
||||||
final var changeActions = change.setRevision(nextRevision).build();
|
final var changeActions = change.setRevision(nextRevision).build();
|
||||||
|
@ -457,9 +451,8 @@ public class GroupV2Helper {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
var signedGroupChange = groupsV2Api.patchGroup(changeActions,
|
var signedGroupChange = dependencies.getGroupsV2Api()
|
||||||
getGroupAuthForToday(groupSecretParams),
|
.patchGroup(changeActions, getGroupAuthForToday(groupSecretParams), Optional.absent());
|
||||||
Optional.absent());
|
|
||||||
|
|
||||||
return new Pair<>(decryptedGroupState, signedGroupChange);
|
return new Pair<>(decryptedGroupState, signedGroupChange);
|
||||||
}
|
}
|
||||||
|
@ -473,9 +466,10 @@ public class GroupV2Helper {
|
||||||
final var nextRevision = currentRevision + 1;
|
final var nextRevision = currentRevision + 1;
|
||||||
final var changeActions = change.setRevision(nextRevision).build();
|
final var changeActions = change.setRevision(nextRevision).build();
|
||||||
|
|
||||||
return groupsV2Api.patchGroup(changeActions,
|
return dependencies.getGroupsV2Api()
|
||||||
getGroupAuthForToday(groupSecretParams),
|
.patchGroup(changeActions,
|
||||||
Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
getGroupAuthForToday(groupSecretParams),
|
||||||
|
Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
|
||||||
}
|
}
|
||||||
|
|
||||||
public DecryptedGroup getUpdatedDecryptedGroup(
|
public DecryptedGroup getUpdatedDecryptedGroup(
|
||||||
|
@ -494,7 +488,8 @@ public class GroupV2Helper {
|
||||||
|
|
||||||
private DecryptedGroupChange getDecryptedGroupChange(byte[] signedGroupChange, GroupMasterKey groupMasterKey) {
|
private DecryptedGroupChange getDecryptedGroupChange(byte[] signedGroupChange, GroupMasterKey groupMasterKey) {
|
||||||
if (signedGroupChange != null) {
|
if (signedGroupChange != null) {
|
||||||
var groupOperations = groupsV2Operations.forGroup(GroupSecretParams.deriveFromMasterKey(groupMasterKey));
|
var groupOperations = dependencies.getGroupsV2Operations()
|
||||||
|
.forGroup(GroupSecretParams.deriveFromMasterKey(groupMasterKey));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orNull();
|
return groupOperations.decryptChange(GroupChange.parseFrom(signedGroupChange), true).orNull();
|
||||||
|
@ -516,19 +511,20 @@ public class GroupV2Helper {
|
||||||
final var today = currentTimeDays();
|
final var today = currentTimeDays();
|
||||||
if (groupApiCredentials == null || !groupApiCredentials.containsKey(today)) {
|
if (groupApiCredentials == null || !groupApiCredentials.containsKey(today)) {
|
||||||
// Returns credentials for the next 7 days
|
// Returns credentials for the next 7 days
|
||||||
groupApiCredentials = groupsV2Api.getCredentials(today);
|
groupApiCredentials = dependencies.getGroupsV2Api().getCredentials(today);
|
||||||
// TODO cache credentials on disk until they expire
|
// TODO cache credentials on disk until they expire
|
||||||
}
|
}
|
||||||
var authCredentialResponse = groupApiCredentials.get(today);
|
var authCredentialResponse = groupApiCredentials.get(today);
|
||||||
final var aci = getSelfAci();
|
final var aci = getSelfAci();
|
||||||
try {
|
try {
|
||||||
return groupsV2Api.getGroupsV2AuthorizationString(aci, today, groupSecretParams, authCredentialResponse);
|
return dependencies.getGroupsV2Api()
|
||||||
|
.getGroupsV2AuthorizationString(aci, today, groupSecretParams, authCredentialResponse);
|
||||||
} catch (VerificationFailedException e) {
|
} catch (VerificationFailedException e) {
|
||||||
throw new IOException(e);
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ACI getSelfAci() {
|
private ACI getSelfAci() {
|
||||||
return addressResolver.resolveSignalServiceAddress(this.selfRecipientIdProvider.getSelfRecipientId()).getAci();
|
return context.getAccount().getAci();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
import org.whispersystems.signalservice.api.messages.SendMessageResult;
|
|
||||||
|
|
||||||
public interface IdentityFailureHandler {
|
|
||||||
|
|
||||||
void handleIdentityFailure(RecipientId recipientId, SendMessageResult.IdentityFailure identityFailure);
|
|
||||||
}
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
|
||||||
import org.asamk.signal.manager.TrustLevel;
|
import org.asamk.signal.manager.TrustLevel;
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
||||||
|
@ -27,23 +26,11 @@ public class IdentityHelper {
|
||||||
private final static Logger logger = LoggerFactory.getLogger(IdentityHelper.class);
|
private final static Logger logger = LoggerFactory.getLogger(IdentityHelper.class);
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final Context context;
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
private final SyncHelper syncHelper;
|
|
||||||
private final ProfileHelper profileHelper;
|
|
||||||
|
|
||||||
public IdentityHelper(
|
public IdentityHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.context = context;
|
||||||
final SignalServiceAddressResolver addressResolver,
|
|
||||||
final SyncHelper syncHelper,
|
|
||||||
final ProfileHelper profileHelper
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
this.syncHelper = syncHelper;
|
|
||||||
this.profileHelper = profileHelper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
|
public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
|
||||||
|
@ -74,13 +61,13 @@ public class IdentityHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String computeSafetyNumber(RecipientId recipientId, IdentityKey theirIdentityKey) {
|
public String computeSafetyNumber(RecipientId recipientId, IdentityKey theirIdentityKey) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
|
final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
|
||||||
return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
|
return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScannableFingerprint computeSafetyNumberForScanning(RecipientId recipientId, IdentityKey theirIdentityKey) {
|
public ScannableFingerprint computeSafetyNumberForScanning(RecipientId recipientId, IdentityKey theirIdentityKey) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
|
final Fingerprint fingerprint = computeSafetyNumberFingerprint(address, theirIdentityKey);
|
||||||
return fingerprint == null ? null : fingerprint.getScannableFingerprint();
|
return fingerprint == null ? null : fingerprint.getScannableFingerprint();
|
||||||
}
|
}
|
||||||
|
@ -109,8 +96,8 @@ public class IdentityHelper {
|
||||||
|
|
||||||
account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, identity.getIdentityKey(), trustLevel);
|
account.getIdentityKeyStore().setIdentityTrustLevel(recipientId, identity.getIdentityKey(), trustLevel);
|
||||||
try {
|
try {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
syncHelper.sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
|
context.getSyncHelper().sendVerifiedMessage(address, identity.getIdentityKey(), trustLevel);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to send verification sync message: {}", e.getMessage());
|
logger.warn("Failed to send verification sync message: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -130,7 +117,7 @@ public class IdentityHelper {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Retrieve profile to get the current identity key from the server
|
// Retrieve profile to get the current identity key from the server
|
||||||
profileHelper.refreshRecipientProfile(recipientId);
|
context.getProfileHelper().refreshRecipientProfile(recipientId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.JobExecutor;
|
|
||||||
import org.asamk.signal.manager.Manager;
|
import org.asamk.signal.manager.Manager;
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
import org.asamk.signal.manager.TrustLevel;
|
import org.asamk.signal.manager.TrustLevel;
|
||||||
|
@ -29,7 +28,6 @@ import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
||||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
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.storage.recipients.RecipientResolver;
|
|
||||||
import org.asamk.signal.manager.storage.stickers.Sticker;
|
import org.asamk.signal.manager.storage.stickers.Sticker;
|
||||||
import org.asamk.signal.manager.storage.stickers.StickerPackId;
|
import org.asamk.signal.manager.storage.stickers.StickerPackId;
|
||||||
import org.signal.libsignal.metadata.ProtocolInvalidKeyException;
|
import org.signal.libsignal.metadata.ProtocolInvalidKeyException;
|
||||||
|
@ -61,37 +59,12 @@ public final class IncomingMessageHandler {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final RecipientResolver recipientResolver;
|
private final Context context;
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
private final GroupHelper groupHelper;
|
|
||||||
private final ContactHelper contactHelper;
|
|
||||||
private final AttachmentHelper attachmentHelper;
|
|
||||||
private final SyncHelper syncHelper;
|
|
||||||
private final ProfileProvider profileProvider;
|
|
||||||
private final JobExecutor jobExecutor;
|
|
||||||
|
|
||||||
public IncomingMessageHandler(
|
public IncomingMessageHandler(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final RecipientResolver recipientResolver,
|
this.context = context;
|
||||||
final SignalServiceAddressResolver addressResolver,
|
|
||||||
final GroupHelper groupHelper,
|
|
||||||
final ContactHelper contactHelper,
|
|
||||||
final AttachmentHelper attachmentHelper,
|
|
||||||
final SyncHelper syncHelper,
|
|
||||||
final ProfileProvider profileProvider,
|
|
||||||
final JobExecutor jobExecutor
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.recipientResolver = recipientResolver;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
this.groupHelper = groupHelper;
|
|
||||||
this.contactHelper = contactHelper;
|
|
||||||
this.attachmentHelper = attachmentHelper;
|
|
||||||
this.syncHelper = syncHelper;
|
|
||||||
this.profileProvider = profileProvider;
|
|
||||||
this.jobExecutor = jobExecutor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<List<HandleAction>, Exception> handleRetryEnvelope(
|
public Pair<List<HandleAction>, Exception> handleRetryEnvelope(
|
||||||
|
@ -147,8 +120,8 @@ public final class IncomingMessageHandler {
|
||||||
.resolveRecipientAddress(recipientId), e.getSenderDevice());
|
.resolveRecipientAddress(recipientId), e.getSenderDevice());
|
||||||
} catch (ProtocolInvalidKeyIdException | ProtocolInvalidKeyException | ProtocolNoSessionException | ProtocolInvalidMessageException e) {
|
} catch (ProtocolInvalidKeyIdException | ProtocolInvalidKeyException | ProtocolNoSessionException | ProtocolInvalidMessageException e) {
|
||||||
final var sender = account.getRecipientStore().resolveRecipient(e.getSender());
|
final var sender = account.getRecipientStore().resolveRecipient(e.getSender());
|
||||||
final var senderProfile = profileProvider.getProfile(sender);
|
final var senderProfile = context.getProfileHelper().getRecipientProfile(sender);
|
||||||
final var selfProfile = profileProvider.getProfile(account.getSelfRecipientId());
|
final var selfProfile = context.getProfileHelper().getRecipientProfile(account.getSelfRecipientId());
|
||||||
if (e.getSenderDevice() != account.getDeviceId()
|
if (e.getSenderDevice() != account.getDeviceId()
|
||||||
&& senderProfile != null
|
&& senderProfile != null
|
||||||
&& senderProfile.getCapabilities().contains(Profile.Capability.senderKey)
|
&& senderProfile.getCapabilities().contains(Profile.Capability.senderKey)
|
||||||
|
@ -202,9 +175,9 @@ public final class IncomingMessageHandler {
|
||||||
}
|
}
|
||||||
handler.handleMessage(MessageEnvelope.from(envelope,
|
handler.handleMessage(MessageEnvelope.from(envelope,
|
||||||
content,
|
content,
|
||||||
recipientResolver,
|
account.getRecipientStore(),
|
||||||
account.getRecipientStore()::resolveRecipientAddress,
|
account.getRecipientStore()::resolveRecipientAddress,
|
||||||
attachmentHelper::getAttachmentFile), exception);
|
context.getAttachmentHelper()::getAttachmentFile), exception);
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,16 +189,17 @@ public final class IncomingMessageHandler {
|
||||||
final RecipientId sender;
|
final RecipientId sender;
|
||||||
final int senderDeviceId;
|
final int senderDeviceId;
|
||||||
if (!envelope.isUnidentifiedSender() && envelope.hasSourceUuid()) {
|
if (!envelope.isUnidentifiedSender() && envelope.hasSourceUuid()) {
|
||||||
sender = recipientResolver.resolveRecipient(envelope.getSourceAddress());
|
sender = context.getRecipientHelper().resolveRecipient(envelope.getSourceAddress());
|
||||||
senderDeviceId = envelope.getSourceDevice();
|
senderDeviceId = envelope.getSourceDevice();
|
||||||
} else {
|
} else {
|
||||||
sender = recipientResolver.resolveRecipient(content.getSender());
|
sender = context.getRecipientHelper().resolveRecipient(content.getSender());
|
||||||
senderDeviceId = content.getSenderDevice();
|
senderDeviceId = content.getSenderDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (content.getSenderKeyDistributionMessage().isPresent()) {
|
if (content.getSenderKeyDistributionMessage().isPresent()) {
|
||||||
final var message = content.getSenderKeyDistributionMessage().get();
|
final var message = content.getSenderKeyDistributionMessage().get();
|
||||||
final var protocolAddress = new SignalProtocolAddress(addressResolver.resolveSignalServiceAddress(sender)
|
final var protocolAddress = new SignalProtocolAddress(context.getRecipientHelper()
|
||||||
|
.resolveSignalServiceAddress(sender)
|
||||||
.getIdentifier(), senderDeviceId);
|
.getIdentifier(), senderDeviceId);
|
||||||
logger.debug("Received a sender key distribution message for distributionId {} from {}",
|
logger.debug("Received a sender key distribution message for distributionId {} from {}",
|
||||||
message.getDistributionId(),
|
message.getDistributionId(),
|
||||||
|
@ -281,7 +255,7 @@ public final class IncomingMessageHandler {
|
||||||
actions.addAll(handleSignalServiceDataMessage(message.getMessage(),
|
actions.addAll(handleSignalServiceDataMessage(message.getMessage(),
|
||||||
true,
|
true,
|
||||||
sender,
|
sender,
|
||||||
destination == null ? null : recipientResolver.resolveRecipient(destination),
|
destination == null ? null : context.getRecipientHelper().resolveRecipient(destination),
|
||||||
ignoreAttachments));
|
ignoreAttachments));
|
||||||
}
|
}
|
||||||
if (syncMessage.getRequest().isPresent() && account.isMasterDevice()) {
|
if (syncMessage.getRequest().isPresent() && account.isMasterDevice()) {
|
||||||
|
@ -308,14 +282,15 @@ public final class IncomingMessageHandler {
|
||||||
if (syncMessage.getBlockedList().isPresent()) {
|
if (syncMessage.getBlockedList().isPresent()) {
|
||||||
final var blockedListMessage = syncMessage.getBlockedList().get();
|
final var blockedListMessage = syncMessage.getBlockedList().get();
|
||||||
for (var address : blockedListMessage.getAddresses()) {
|
for (var address : blockedListMessage.getAddresses()) {
|
||||||
contactHelper.setContactBlocked(recipientResolver.resolveRecipient(address), true);
|
context.getContactHelper()
|
||||||
|
.setContactBlocked(context.getRecipientHelper().resolveRecipient(address), true);
|
||||||
}
|
}
|
||||||
for (var groupId : blockedListMessage.getGroupIds()
|
for (var groupId : blockedListMessage.getGroupIds()
|
||||||
.stream()
|
.stream()
|
||||||
.map(GroupId::unknownVersion)
|
.map(GroupId::unknownVersion)
|
||||||
.collect(Collectors.toSet())) {
|
.collect(Collectors.toSet())) {
|
||||||
try {
|
try {
|
||||||
groupHelper.setGroupBlocked(groupId, true);
|
context.getGroupHelper().setGroupBlocked(groupId, true);
|
||||||
} catch (GroupNotFoundException e) {
|
} catch (GroupNotFoundException e) {
|
||||||
logger.warn("BlockedListMessage contained groupID that was not found in GroupStore: {}",
|
logger.warn("BlockedListMessage contained groupID that was not found in GroupStore: {}",
|
||||||
groupId.toBase64());
|
groupId.toBase64());
|
||||||
|
@ -325,8 +300,9 @@ public final class IncomingMessageHandler {
|
||||||
if (syncMessage.getContacts().isPresent()) {
|
if (syncMessage.getContacts().isPresent()) {
|
||||||
try {
|
try {
|
||||||
final var contactsMessage = syncMessage.getContacts().get();
|
final var contactsMessage = syncMessage.getContacts().get();
|
||||||
attachmentHelper.retrieveAttachment(contactsMessage.getContactsStream(),
|
context.getAttachmentHelper()
|
||||||
syncHelper::handleSyncDeviceContacts);
|
.retrieveAttachment(contactsMessage.getContactsStream(),
|
||||||
|
context.getSyncHelper()::handleSyncDeviceContacts);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.warn("Failed to handle received sync contacts, ignoring: {}", e.getMessage());
|
logger.warn("Failed to handle received sync contacts, ignoring: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -355,7 +331,8 @@ public final class IncomingMessageHandler {
|
||||||
sticker = new Sticker(stickerPackId, m.getPackKey().get());
|
sticker = new Sticker(stickerPackId, m.getPackKey().get());
|
||||||
}
|
}
|
||||||
if (installed) {
|
if (installed) {
|
||||||
jobExecutor.enqueueJob(new RetrieveStickerPackJob(stickerPackId, m.getPackKey().get()));
|
context.getJobExecutor()
|
||||||
|
.enqueueJob(new RetrieveStickerPackJob(stickerPackId, m.getPackKey().get()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -410,8 +387,8 @@ public final class IncomingMessageHandler {
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final var recipientId = recipientResolver.resolveRecipient(source);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(source);
|
||||||
if (contactHelper.isContactBlocked(recipientId)) {
|
if (context.getContactHelper().isContactBlocked(recipientId)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +396,7 @@ public final class IncomingMessageHandler {
|
||||||
var message = content.getDataMessage().get();
|
var message = content.getDataMessage().get();
|
||||||
if (message.getGroupContext().isPresent()) {
|
if (message.getGroupContext().isPresent()) {
|
||||||
var groupId = GroupUtils.getGroupId(message.getGroupContext().get());
|
var groupId = GroupUtils.getGroupId(message.getGroupContext().get());
|
||||||
return groupHelper.isGroupBlocked(groupId);
|
return context.getGroupHelper().isGroupBlocked(groupId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,12 +430,12 @@ public final class IncomingMessageHandler {
|
||||||
}
|
}
|
||||||
|
|
||||||
var groupId = GroupUtils.getGroupId(message.getGroupContext().get());
|
var groupId = GroupUtils.getGroupId(message.getGroupContext().get());
|
||||||
var group = groupHelper.getGroup(groupId);
|
var group = context.getGroupHelper().getGroup(groupId);
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var recipientId = recipientResolver.resolveRecipient(source);
|
final var recipientId = context.getRecipientHelper().resolveRecipient(source);
|
||||||
if (!group.isMember(recipientId) && !(group.isPendingMember(recipientId) && message.isGroupV2Update())) {
|
if (!group.isMember(recipientId) && !(group.isPendingMember(recipientId) && message.isGroupV2Update())) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -487,7 +464,7 @@ public final class IncomingMessageHandler {
|
||||||
if (message.getGroupContext().get().getGroupV1().isPresent()) {
|
if (message.getGroupContext().get().getGroupV1().isPresent()) {
|
||||||
var groupInfo = message.getGroupContext().get().getGroupV1().get();
|
var groupInfo = message.getGroupContext().get().getGroupV1().get();
|
||||||
var groupId = GroupId.v1(groupInfo.getGroupId());
|
var groupId = GroupId.v1(groupInfo.getGroupId());
|
||||||
var group = groupHelper.getGroup(groupId);
|
var group = context.getGroupHelper().getGroup(groupId);
|
||||||
if (group == null || group instanceof GroupInfoV1) {
|
if (group == null || group instanceof GroupInfoV1) {
|
||||||
var groupV1 = (GroupInfoV1) group;
|
var groupV1 = (GroupInfoV1) group;
|
||||||
switch (groupInfo.getType()) {
|
switch (groupInfo.getType()) {
|
||||||
|
@ -498,7 +475,7 @@ public final class IncomingMessageHandler {
|
||||||
|
|
||||||
if (groupInfo.getAvatar().isPresent()) {
|
if (groupInfo.getAvatar().isPresent()) {
|
||||||
var avatar = groupInfo.getAvatar().get();
|
var avatar = groupInfo.getAvatar().get();
|
||||||
groupHelper.downloadGroupAvatar(groupV1.getGroupId(), avatar);
|
context.getGroupHelper().downloadGroupAvatar(groupV1.getGroupId(), avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupInfo.getName().isPresent()) {
|
if (groupInfo.getName().isPresent()) {
|
||||||
|
@ -509,7 +486,7 @@ public final class IncomingMessageHandler {
|
||||||
groupV1.addMembers(groupInfo.getMembers()
|
groupV1.addMembers(groupInfo.getMembers()
|
||||||
.get()
|
.get()
|
||||||
.stream()
|
.stream()
|
||||||
.map(recipientResolver::resolveRecipient)
|
.map(context.getRecipientHelper()::resolveRecipient)
|
||||||
.collect(Collectors.toSet()));
|
.collect(Collectors.toSet()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -542,9 +519,10 @@ public final class IncomingMessageHandler {
|
||||||
final var groupContext = message.getGroupContext().get().getGroupV2().get();
|
final var groupContext = message.getGroupContext().get().getGroupV2().get();
|
||||||
final var groupMasterKey = groupContext.getMasterKey();
|
final var groupMasterKey = groupContext.getMasterKey();
|
||||||
|
|
||||||
groupHelper.getOrMigrateGroup(groupMasterKey,
|
context.getGroupHelper()
|
||||||
groupContext.getRevision(),
|
.getOrMigrateGroup(groupMasterKey,
|
||||||
groupContext.hasSignedGroupChange() ? groupContext.getSignedGroupChange() : null);
|
groupContext.getRevision(),
|
||||||
|
groupContext.hasSignedGroupChange() ? groupContext.getSignedGroupChange() : null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -567,19 +545,20 @@ public final class IncomingMessageHandler {
|
||||||
// disappearing message timer already stored in the DecryptedGroup
|
// disappearing message timer already stored in the DecryptedGroup
|
||||||
}
|
}
|
||||||
} else if (conversationPartnerAddress != null) {
|
} else if (conversationPartnerAddress != null) {
|
||||||
contactHelper.setExpirationTimer(conversationPartnerAddress, message.getExpiresInSeconds());
|
context.getContactHelper()
|
||||||
|
.setExpirationTimer(conversationPartnerAddress, message.getExpiresInSeconds());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!ignoreAttachments) {
|
if (!ignoreAttachments) {
|
||||||
if (message.getAttachments().isPresent()) {
|
if (message.getAttachments().isPresent()) {
|
||||||
for (var attachment : message.getAttachments().get()) {
|
for (var attachment : message.getAttachments().get()) {
|
||||||
attachmentHelper.downloadAttachment(attachment);
|
context.getAttachmentHelper().downloadAttachment(attachment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (message.getSharedContacts().isPresent()) {
|
if (message.getSharedContacts().isPresent()) {
|
||||||
for (var contact : message.getSharedContacts().get()) {
|
for (var contact : message.getSharedContacts().get()) {
|
||||||
if (contact.getAvatar().isPresent()) {
|
if (contact.getAvatar().isPresent()) {
|
||||||
attachmentHelper.downloadAttachment(contact.getAvatar().get().getAttachment());
|
context.getAttachmentHelper().downloadAttachment(contact.getAvatar().get().getAttachment());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -587,7 +566,7 @@ public final class IncomingMessageHandler {
|
||||||
final var previews = message.getPreviews().get();
|
final var previews = message.getPreviews().get();
|
||||||
for (var preview : previews) {
|
for (var preview : previews) {
|
||||||
if (preview.getImage().isPresent()) {
|
if (preview.getImage().isPresent()) {
|
||||||
attachmentHelper.downloadAttachment(preview.getImage().get());
|
context.getAttachmentHelper().downloadAttachment(preview.getImage().get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,7 +576,7 @@ public final class IncomingMessageHandler {
|
||||||
for (var quotedAttachment : quote.getAttachments()) {
|
for (var quotedAttachment : quote.getAttachments()) {
|
||||||
final var thumbnail = quotedAttachment.getThumbnail();
|
final var thumbnail = quotedAttachment.getThumbnail();
|
||||||
if (thumbnail != null) {
|
if (thumbnail != null) {
|
||||||
attachmentHelper.downloadAttachment(thumbnail);
|
context.getAttachmentHelper().downloadAttachment(thumbnail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -622,7 +601,7 @@ public final class IncomingMessageHandler {
|
||||||
sticker = new Sticker(stickerPackId, messageSticker.getPackKey());
|
sticker = new Sticker(stickerPackId, messageSticker.getPackKey());
|
||||||
account.getStickerStore().updateSticker(sticker);
|
account.getStickerStore().updateSticker(sticker);
|
||||||
}
|
}
|
||||||
jobExecutor.enqueueJob(new RetrieveStickerPackJob(stickerPackId, messageSticker.getPackKey()));
|
context.getJobExecutor().enqueueJob(new RetrieveStickerPackJob(stickerPackId, messageSticker.getPackKey()));
|
||||||
}
|
}
|
||||||
return actions;
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.AvatarStore;
|
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
import org.asamk.signal.manager.SignalDependencies;
|
||||||
import org.asamk.signal.manager.config.ServiceConfig;
|
import org.asamk.signal.manager.config.ServiceConfig;
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
|
@ -43,22 +42,12 @@ public final class ProfileHelper {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final AvatarStore avatarStore;
|
private final Context context;
|
||||||
private final UnidentifiedAccessProvider unidentifiedAccessProvider;
|
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
|
|
||||||
public ProfileHelper(
|
public ProfileHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final AvatarStore avatarStore,
|
this.context = context;
|
||||||
final UnidentifiedAccessProvider unidentifiedAccessProvider,
|
|
||||||
final SignalServiceAddressResolver addressResolver
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.avatarStore = avatarStore;
|
|
||||||
this.unidentifiedAccessProvider = unidentifiedAccessProvider;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Profile getRecipientProfile(RecipientId recipientId) {
|
public Profile getRecipientProfile(RecipientId recipientId) {
|
||||||
|
@ -139,7 +128,8 @@ public final class ProfileHelper {
|
||||||
|
|
||||||
if (uploadProfile) {
|
if (uploadProfile) {
|
||||||
try (final var streamDetails = avatar == null
|
try (final var streamDetails = avatar == null
|
||||||
? avatarStore.retrieveProfileAvatar(account.getSelfAddress())
|
? context.getAvatarStore()
|
||||||
|
.retrieveProfileAvatar(account.getSelfAddress())
|
||||||
: avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) {
|
: avatar.isPresent() ? Utils.createStreamDetailsFromFile(avatar.get()) : null) {
|
||||||
final var avatarPath = dependencies.getAccountManager()
|
final var avatarPath = dependencies.getAccountManager()
|
||||||
.setVersionedProfile(account.getAci(),
|
.setVersionedProfile(account.getAci(),
|
||||||
|
@ -157,10 +147,11 @@ public final class ProfileHelper {
|
||||||
|
|
||||||
if (avatar != null) {
|
if (avatar != null) {
|
||||||
if (avatar.isPresent()) {
|
if (avatar.isPresent()) {
|
||||||
avatarStore.storeProfileAvatar(account.getSelfAddress(),
|
context.getAvatarStore()
|
||||||
outputStream -> IOUtils.copyFileToStream(avatar.get(), outputStream));
|
.storeProfileAvatar(account.getSelfAddress(),
|
||||||
|
outputStream -> IOUtils.copyFileToStream(avatar.get(), outputStream));
|
||||||
} else {
|
} else {
|
||||||
avatarStore.deleteProfileAvatar(account.getSelfAddress());
|
context.getAvatarStore().deleteProfileAvatar(account.getSelfAddress());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
account.getProfileStore().storeProfile(account.getSelfRecipientId(), newProfile);
|
account.getProfileStore().storeProfile(account.getSelfRecipientId(), newProfile);
|
||||||
|
@ -224,7 +215,9 @@ public final class ProfileHelper {
|
||||||
) {
|
) {
|
||||||
var profile = account.getProfileStore().getProfile(recipientId);
|
var profile = account.getProfileStore().getProfile(recipientId);
|
||||||
if (profile == null || !Objects.equals(avatarPath, profile.getAvatarUrlPath())) {
|
if (profile == null || !Objects.equals(avatarPath, profile.getAvatarUrlPath())) {
|
||||||
downloadProfileAvatar(addressResolver.resolveSignalServiceAddress(recipientId), avatarPath, profileKey);
|
downloadProfileAvatar(context.getRecipientHelper().resolveSignalServiceAddress(recipientId),
|
||||||
|
avatarPath,
|
||||||
|
profileKey);
|
||||||
var builder = profile == null ? Profile.newBuilder() : Profile.newBuilder(profile);
|
var builder = profile == null ? Profile.newBuilder() : Profile.newBuilder(profile);
|
||||||
account.getProfileStore().storeProfile(recipientId, builder.withAvatarUrlPath(avatarPath).build());
|
account.getProfileStore().storeProfile(recipientId, builder.withAvatarUrlPath(avatarPath).build());
|
||||||
}
|
}
|
||||||
|
@ -250,7 +243,7 @@ public final class ProfileHelper {
|
||||||
var unidentifiedAccess = getUnidentifiedAccess(recipientId);
|
var unidentifiedAccess = getUnidentifiedAccess(recipientId);
|
||||||
var profileKey = Optional.fromNullable(account.getProfileStore().getProfileKey(recipientId));
|
var profileKey = Optional.fromNullable(account.getProfileStore().getProfileKey(recipientId));
|
||||||
|
|
||||||
final var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
return retrieveProfile(address, profileKey, unidentifiedAccess, requestType).doOnSuccess(p -> {
|
return retrieveProfile(address, profileKey, unidentifiedAccess, requestType).doOnSuccess(p -> {
|
||||||
final var encryptedProfile = p.getProfile();
|
final var encryptedProfile = p.getProfile();
|
||||||
|
|
||||||
|
@ -289,7 +282,7 @@ public final class ProfileHelper {
|
||||||
}
|
}
|
||||||
} catch (InvalidKeyException ignored) {
|
} catch (InvalidKeyException ignored) {
|
||||||
logger.warn("Got invalid identity key in profile for {}",
|
logger.warn("Got invalid identity key in profile for {}",
|
||||||
addressResolver.resolveSignalServiceAddress(recipientId).getIdentifier());
|
context.getRecipientHelper().resolveSignalServiceAddress(recipientId).getIdentifier());
|
||||||
}
|
}
|
||||||
}).doOnError(e -> {
|
}).doOnError(e -> {
|
||||||
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
||||||
|
@ -333,7 +326,7 @@ public final class ProfileHelper {
|
||||||
) {
|
) {
|
||||||
if (avatarPath == null) {
|
if (avatarPath == null) {
|
||||||
try {
|
try {
|
||||||
avatarStore.deleteProfileAvatar(address);
|
context.getAvatarStore().deleteProfileAvatar(address);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to delete local profile avatar, ignoring: {}", e.getMessage());
|
logger.warn("Failed to delete local profile avatar, ignoring: {}", e.getMessage());
|
||||||
}
|
}
|
||||||
|
@ -341,8 +334,9 @@ public final class ProfileHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
avatarStore.storeProfileAvatar(address,
|
context.getAvatarStore()
|
||||||
outputStream -> retrieveProfileAvatar(avatarPath, profileKey, outputStream));
|
.storeProfileAvatar(address,
|
||||||
|
outputStream -> retrieveProfileAvatar(avatarPath, profileKey, outputStream));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
|
if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
|
@ -374,7 +368,7 @@ public final class ProfileHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<UnidentifiedAccess> getUnidentifiedAccess(RecipientId recipientId) {
|
private Optional<UnidentifiedAccess> getUnidentifiedAccess(RecipientId recipientId) {
|
||||||
var unidentifiedAccess = unidentifiedAccessProvider.getAccessFor(recipientId, true);
|
var unidentifiedAccess = context.getUnidentifiedAccessHelper().getAccessFor(recipientId, true);
|
||||||
|
|
||||||
if (unidentifiedAccess.isPresent()) {
|
if (unidentifiedAccess.isPresent()) {
|
||||||
return unidentifiedAccess.get().getTargetUnidentifiedAccess();
|
return unidentifiedAccess.get().getTargetUnidentifiedAccess();
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
|
||||||
|
|
||||||
public interface ProfileKeyCredentialProvider {
|
|
||||||
|
|
||||||
ProfileKeyCredential getProfileKeyCredential(RecipientId recipientId);
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
|
|
||||||
public interface ProfileProvider {
|
|
||||||
|
|
||||||
Profile getProfile(RecipientId recipientId);
|
|
||||||
}
|
|
|
@ -32,14 +32,10 @@ public class RecipientHelper {
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final ServiceEnvironmentConfig serviceEnvironmentConfig;
|
private final ServiceEnvironmentConfig serviceEnvironmentConfig;
|
||||||
|
|
||||||
public RecipientHelper(
|
public RecipientHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final ServiceEnvironmentConfig serviceEnvironmentConfig
|
this.serviceEnvironmentConfig = dependencies.getServiceEnvironmentConfig();
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.serviceEnvironmentConfig = serviceEnvironmentConfig;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SignalServiceAddress resolveSignalServiceAddress(RecipientId recipientId) {
|
public SignalServiceAddress resolveSignalServiceAddress(RecipientId recipientId) {
|
||||||
|
@ -64,6 +60,10 @@ public class RecipientHelper {
|
||||||
.toSignalServiceAddress();
|
.toSignalServiceAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RecipientId resolveRecipient(final SignalServiceAddress address) {
|
||||||
|
return account.getRecipientStore().resolveRecipient(address);
|
||||||
|
}
|
||||||
|
|
||||||
public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws IOException, UnregisteredRecipientException {
|
public Set<RecipientId> resolveRecipients(Collection<RecipientIdentifier.Single> recipients) throws IOException, UnregisteredRecipientException {
|
||||||
final var recipientIds = new HashSet<RecipientId>(recipients.size());
|
final var recipientIds = new HashSet<RecipientId>(recipients.size());
|
||||||
for (var number : recipients) {
|
for (var number : recipients) {
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.api.UnregisteredRecipientException;
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
public interface RecipientRegistrationRefresher {
|
|
||||||
|
|
||||||
RecipientId refreshRecipientRegistration(RecipientId recipientId) throws IOException, UnregisteredRecipientException;
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.signal.zkgroup.profiles.ProfileKey;
|
|
||||||
|
|
||||||
public interface SelfProfileKeyProvider {
|
|
||||||
|
|
||||||
ProfileKey getProfileKey();
|
|
||||||
}
|
|
|
@ -1,8 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
|
|
||||||
public interface SelfRecipientIdProvider {
|
|
||||||
|
|
||||||
RecipientId getSelfRecipientId();
|
|
||||||
}
|
|
|
@ -11,7 +11,6 @@ import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
import org.asamk.signal.manager.storage.groups.GroupInfo;
|
||||||
import org.asamk.signal.manager.storage.recipients.Profile;
|
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.storage.recipients.RecipientResolver;
|
|
||||||
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;
|
||||||
|
@ -53,34 +52,12 @@ public class SendHelper {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final UnidentifiedAccessHelper unidentifiedAccessHelper;
|
private final Context context;
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
private final RecipientResolver recipientResolver;
|
|
||||||
private final IdentityFailureHandler identityFailureHandler;
|
|
||||||
private final GroupProvider groupProvider;
|
|
||||||
private final ProfileHelper profileHelper;
|
|
||||||
private final RecipientRegistrationRefresher recipientRegistrationRefresher;
|
|
||||||
|
|
||||||
public SendHelper(
|
public SendHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final UnidentifiedAccessHelper unidentifiedAccessHelper,
|
this.context = context;
|
||||||
final SignalServiceAddressResolver addressResolver,
|
|
||||||
final RecipientResolver recipientResolver,
|
|
||||||
final IdentityFailureHandler identityFailureHandler,
|
|
||||||
final GroupProvider groupProvider,
|
|
||||||
final ProfileHelper profileHelper,
|
|
||||||
final RecipientRegistrationRefresher recipientRegistrationRefresher
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.unidentifiedAccessHelper = unidentifiedAccessHelper;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
this.recipientResolver = recipientResolver;
|
|
||||||
this.identityFailureHandler = identityFailureHandler;
|
|
||||||
this.groupProvider = groupProvider;
|
|
||||||
this.profileHelper = profileHelper;
|
|
||||||
this.recipientRegistrationRefresher = recipientRegistrationRefresher;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -223,22 +200,22 @@ public class SendHelper {
|
||||||
public SendMessageResult sendSyncMessage(SignalServiceSyncMessage message) {
|
public SendMessageResult sendSyncMessage(SignalServiceSyncMessage message) {
|
||||||
var messageSender = dependencies.getMessageSender();
|
var messageSender = dependencies.getMessageSender();
|
||||||
try {
|
try {
|
||||||
return messageSender.sendSyncMessage(message, unidentifiedAccessHelper.getAccessForSync());
|
return messageSender.sendSyncMessage(message, context.getUnidentifiedAccessHelper().getAccessForSync());
|
||||||
} catch (UnregisteredUserException e) {
|
} catch (UnregisteredUserException e) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(account.getSelfRecipientId());
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
|
||||||
return SendMessageResult.unregisteredFailure(address);
|
return SendMessageResult.unregisteredFailure(address);
|
||||||
} catch (ProofRequiredException e) {
|
} catch (ProofRequiredException e) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(account.getSelfRecipientId());
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
|
||||||
return SendMessageResult.proofRequiredFailure(address, e);
|
return SendMessageResult.proofRequiredFailure(address, e);
|
||||||
} catch (RateLimitException e) {
|
} catch (RateLimitException e) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(account.getSelfRecipientId());
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
|
||||||
logger.warn("Sending failed due to rate limiting from the signal server: {}", e.getMessage());
|
logger.warn("Sending failed due to rate limiting from the signal server: {}", e.getMessage());
|
||||||
return SendMessageResult.networkFailure(address);
|
return SendMessageResult.networkFailure(address);
|
||||||
} catch (org.whispersystems.signalservice.api.crypto.UntrustedIdentityException e) {
|
} catch (org.whispersystems.signalservice.api.crypto.UntrustedIdentityException e) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(account.getSelfRecipientId());
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
|
||||||
return SendMessageResult.identityFailure(address, e.getIdentityKey());
|
return SendMessageResult.identityFailure(address, e.getIdentityKey());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
var address = addressResolver.resolveSignalServiceAddress(account.getSelfRecipientId());
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(account.getSelfRecipientId());
|
||||||
logger.warn("Failed to send message due to IO exception: {}", e.getMessage());
|
logger.warn("Failed to send message due to IO exception: {}", e.getMessage());
|
||||||
return SendMessageResult.networkFailure(address);
|
return SendMessageResult.networkFailure(address);
|
||||||
}
|
}
|
||||||
|
@ -292,7 +269,7 @@ public class SendHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupInfo getGroupForSending(GroupId groupId) throws GroupNotFoundException, NotAGroupMemberException {
|
private GroupInfo getGroupForSending(GroupId groupId) throws GroupNotFoundException, NotAGroupMemberException {
|
||||||
var g = groupProvider.getGroup(groupId);
|
var g = context.getGroupHelper().getGroup(groupId);
|
||||||
if (g == null) {
|
if (g == null) {
|
||||||
throw new GroupNotFoundException(groupId);
|
throw new GroupNotFoundException(groupId);
|
||||||
}
|
}
|
||||||
|
@ -327,7 +304,7 @@ public class SendHelper {
|
||||||
results.stream().filter(SendMessageResult::isSuccess).forEach(allResults::add);
|
results.stream().filter(SendMessageResult::isSuccess).forEach(allResults::add);
|
||||||
final var failedTargets = results.stream()
|
final var failedTargets = results.stream()
|
||||||
.filter(r -> !r.isSuccess())
|
.filter(r -> !r.isSuccess())
|
||||||
.map(r -> recipientResolver.resolveRecipient(r.getAddress()))
|
.map(r -> context.getRecipientHelper().resolveRecipient(r.getAddress()))
|
||||||
.toList();
|
.toList();
|
||||||
if (failedTargets.size() > 0) {
|
if (failedTargets.size() > 0) {
|
||||||
senderKeyTargets = new HashSet<>(senderKeyTargets);
|
senderKeyTargets = new HashSet<>(senderKeyTargets);
|
||||||
|
@ -357,7 +334,7 @@ public class SendHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<RecipientId> getSenderKeyCapableRecipientIds(final Set<RecipientId> recipientIds) {
|
private Set<RecipientId> getSenderKeyCapableRecipientIds(final Set<RecipientId> recipientIds) {
|
||||||
final var selfProfile = profileHelper.getRecipientProfile(account.getSelfRecipientId());
|
final var selfProfile = context.getProfileHelper().getRecipientProfile(account.getSelfRecipientId());
|
||||||
if (selfProfile == null || !selfProfile.getCapabilities().contains(Profile.Capability.senderKey)) {
|
if (selfProfile == null || !selfProfile.getCapabilities().contains(Profile.Capability.senderKey)) {
|
||||||
logger.debug("Not all of our devices support sender key. Using legacy.");
|
logger.debug("Not all of our devices support sender key. Using legacy.");
|
||||||
return Set.of();
|
return Set.of();
|
||||||
|
@ -365,14 +342,14 @@ public class SendHelper {
|
||||||
|
|
||||||
final var senderKeyTargets = new HashSet<RecipientId>();
|
final var senderKeyTargets = new HashSet<RecipientId>();
|
||||||
final var recipientList = new ArrayList<>(recipientIds);
|
final var recipientList = new ArrayList<>(recipientIds);
|
||||||
final var profiles = profileHelper.getRecipientProfile(recipientList).iterator();
|
final var profiles = context.getProfileHelper().getRecipientProfile(recipientList).iterator();
|
||||||
for (final var recipientId : recipientList) {
|
for (final var recipientId : recipientList) {
|
||||||
final var profile = profiles.next();
|
final var profile = profiles.next();
|
||||||
if (profile == null || !profile.getCapabilities().contains(Profile.Capability.senderKey)) {
|
if (profile == null || !profile.getCapabilities().contains(Profile.Capability.senderKey)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var access = unidentifiedAccessHelper.getAccessFor(recipientId);
|
final var access = context.getUnidentifiedAccessHelper().getAccessFor(recipientId);
|
||||||
if (!access.isPresent() || !access.get().getTargetUnidentifiedAccess().isPresent()) {
|
if (!access.isPresent() || !access.get().getTargetUnidentifiedAccess().isPresent()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -398,8 +375,10 @@ public class SendHelper {
|
||||||
final LegacySenderHandler sender, final Set<RecipientId> recipientIds, final boolean isRecipientUpdate
|
final LegacySenderHandler sender, final Set<RecipientId> recipientIds, final boolean isRecipientUpdate
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final var recipientIdList = new ArrayList<>(recipientIds);
|
final var recipientIdList = new ArrayList<>(recipientIds);
|
||||||
final var addresses = recipientIdList.stream().map(addressResolver::resolveSignalServiceAddress).toList();
|
final var addresses = recipientIdList.stream()
|
||||||
final var unidentifiedAccesses = unidentifiedAccessHelper.getAccessFor(recipientIdList);
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
|
.toList();
|
||||||
|
final var unidentifiedAccesses = context.getUnidentifiedAccessHelper().getAccessFor(recipientIdList);
|
||||||
try {
|
try {
|
||||||
final var results = sender.send(addresses, unidentifiedAccesses, isRecipientUpdate);
|
final var results = sender.send(addresses, unidentifiedAccesses, isRecipientUpdate);
|
||||||
|
|
||||||
|
@ -433,9 +412,10 @@ public class SendHelper {
|
||||||
}
|
}
|
||||||
|
|
||||||
List<SignalServiceAddress> addresses = recipientIdList.stream()
|
List<SignalServiceAddress> addresses = recipientIdList.stream()
|
||||||
.map(addressResolver::resolveSignalServiceAddress)
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
List<UnidentifiedAccess> unidentifiedAccesses = unidentifiedAccessHelper.getAccessFor(recipientIdList)
|
List<UnidentifiedAccess> unidentifiedAccesses = context.getUnidentifiedAccessHelper()
|
||||||
|
.getAccessFor(recipientIdList)
|
||||||
.stream()
|
.stream()
|
||||||
.map(Optional::get)
|
.map(Optional::get)
|
||||||
.map(UnidentifiedAccessPair::getTargetUnidentifiedAccess)
|
.map(UnidentifiedAccessPair::getTargetUnidentifiedAccess)
|
||||||
|
@ -490,19 +470,21 @@ public class SendHelper {
|
||||||
private SendMessageResult handleSendMessage(RecipientId recipientId, SenderHandler s) {
|
private SendMessageResult handleSendMessage(RecipientId recipientId, SenderHandler s) {
|
||||||
var messageSender = dependencies.getMessageSender();
|
var messageSender = dependencies.getMessageSender();
|
||||||
|
|
||||||
var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
return s.send(messageSender, address, unidentifiedAccessHelper.getAccessFor(recipientId));
|
return s.send(messageSender, address, context.getUnidentifiedAccessHelper().getAccessFor(recipientId));
|
||||||
} catch (UnregisteredUserException e) {
|
} catch (UnregisteredUserException e) {
|
||||||
final RecipientId newRecipientId;
|
final RecipientId newRecipientId;
|
||||||
try {
|
try {
|
||||||
newRecipientId = recipientRegistrationRefresher.refreshRecipientRegistration(recipientId);
|
newRecipientId = context.getRecipientHelper().refreshRegisteredUser(recipientId);
|
||||||
} catch (UnregisteredRecipientException ex) {
|
} catch (UnregisteredRecipientException ex) {
|
||||||
return SendMessageResult.unregisteredFailure(address);
|
return SendMessageResult.unregisteredFailure(address);
|
||||||
}
|
}
|
||||||
address = addressResolver.resolveSignalServiceAddress(newRecipientId);
|
address = context.getRecipientHelper().resolveSignalServiceAddress(newRecipientId);
|
||||||
return s.send(messageSender, address, unidentifiedAccessHelper.getAccessFor(newRecipientId));
|
return s.send(messageSender,
|
||||||
|
address,
|
||||||
|
context.getUnidentifiedAccessHelper().getAccessFor(newRecipientId));
|
||||||
}
|
}
|
||||||
} catch (UnregisteredUserException e) {
|
} catch (UnregisteredUserException e) {
|
||||||
return SendMessageResult.unregisteredFailure(address);
|
return SendMessageResult.unregisteredFailure(address);
|
||||||
|
@ -534,7 +516,7 @@ public class SendHelper {
|
||||||
|
|
||||||
private void handleSendMessageResult(final SendMessageResult r) {
|
private void handleSendMessageResult(final SendMessageResult r) {
|
||||||
if (r.isSuccess() && !r.getSuccess().isUnidentified()) {
|
if (r.isSuccess() && !r.getSuccess().isUnidentified()) {
|
||||||
final var recipientId = recipientResolver.resolveRecipient(r.getAddress());
|
final var recipientId = context.getRecipientHelper().resolveRecipient(r.getAddress());
|
||||||
final var profile = account.getRecipientStore().getProfile(recipientId);
|
final var profile = account.getRecipientStore().getProfile(recipientId);
|
||||||
if (profile != null && (
|
if (profile != null && (
|
||||||
profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.ENABLED
|
profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.ENABLED
|
||||||
|
@ -548,7 +530,7 @@ public class SendHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r.isUnregisteredFailure()) {
|
if (r.isUnregisteredFailure()) {
|
||||||
final var recipientId = recipientResolver.resolveRecipient(r.getAddress());
|
final var recipientId = context.getRecipientHelper().resolveRecipient(r.getAddress());
|
||||||
final var profile = account.getRecipientStore().getProfile(recipientId);
|
final var profile = account.getRecipientStore().getProfile(recipientId);
|
||||||
if (profile != null && (
|
if (profile != null && (
|
||||||
profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.ENABLED
|
profile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.ENABLED
|
||||||
|
@ -562,8 +544,8 @@ public class SendHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (r.getIdentityFailure() != null) {
|
if (r.getIdentityFailure() != null) {
|
||||||
final var recipientId = recipientResolver.resolveRecipient(r.getAddress());
|
final var recipientId = context.getRecipientHelper().resolveRecipient(r.getAddress());
|
||||||
identityFailureHandler.handleIdentityFailure(recipientId, r.getIdentityFailure());
|
context.getIdentityHelper().handleIdentityFailure(recipientId, r.getIdentityFailure());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
|
||||||
|
|
||||||
public interface SignalServiceAddressResolver {
|
|
||||||
|
|
||||||
SignalServiceAddress resolveSignalServiceAddress(RecipientId recipientId);
|
|
||||||
}
|
|
|
@ -32,19 +32,12 @@ public class StorageHelper {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final GroupHelper groupHelper;
|
private final Context context;
|
||||||
private final ProfileHelper profileHelper;
|
|
||||||
|
|
||||||
public StorageHelper(
|
public StorageHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final GroupHelper groupHelper,
|
this.context = context;
|
||||||
final ProfileHelper profileHelper
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.groupHelper = groupHelper;
|
|
||||||
this.profileHelper = profileHelper;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void readDataFromStorage() throws IOException {
|
public void readDataFromStorage() throws IOException {
|
||||||
|
@ -139,7 +132,7 @@ public class StorageHelper {
|
||||||
final var group = account.getGroupStore().getGroup(groupIdV1);
|
final var group = account.getGroupStore().getGroup(groupIdV1);
|
||||||
if (group == null) {
|
if (group == null) {
|
||||||
try {
|
try {
|
||||||
groupHelper.sendGroupInfoRequest(groupIdV1, account.getSelfRecipientId());
|
context.getGroupHelper().sendGroupInfoRequest(groupIdV1, account.getSelfRecipientId());
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
logger.warn("Failed to send group request", e);
|
logger.warn("Failed to send group request", e);
|
||||||
}
|
}
|
||||||
|
@ -169,7 +162,7 @@ public class StorageHelper {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final var group = groupHelper.getOrMigrateGroup(groupMasterKey, 0, null);
|
final var group = context.getGroupHelper().getOrMigrateGroup(groupMasterKey, 0, null);
|
||||||
if (group.isBlocked() != groupV2Record.isBlocked()) {
|
if (group.isBlocked() != groupV2Record.isBlocked()) {
|
||||||
group.setBlocked(groupV2Record.isBlocked());
|
group.setBlocked(groupV2Record.isBlocked());
|
||||||
account.getGroupStore().updateGroup(group);
|
account.getGroupStore().updateGroup(group);
|
||||||
|
@ -225,16 +218,17 @@ 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().orNull();
|
||||||
profileHelper.downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, profileKey);
|
context.getProfileHelper().downloadProfileAvatar(account.getSelfRecipientId(), avatarPath, profileKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
profileHelper.setProfile(false,
|
context.getProfileHelper()
|
||||||
accountRecord.getGivenName().orNull(),
|
.setProfile(false,
|
||||||
accountRecord.getFamilyName().orNull(),
|
accountRecord.getGivenName().orNull(),
|
||||||
null,
|
accountRecord.getFamilyName().orNull(),
|
||||||
null,
|
null,
|
||||||
null);
|
null,
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SignalStorageRecord getSignalStorageRecord(final StorageId accountId) throws IOException {
|
private SignalStorageRecord getSignalStorageRecord(final StorageId accountId) throws IOException {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
package org.asamk.signal.manager.helper;
|
package org.asamk.signal.manager.helper;
|
||||||
|
|
||||||
import org.asamk.signal.manager.AvatarStore;
|
|
||||||
import org.asamk.signal.manager.TrustLevel;
|
import org.asamk.signal.manager.TrustLevel;
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
import org.asamk.signal.manager.storage.SignalAccount;
|
||||||
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
import org.asamk.signal.manager.storage.groups.GroupInfoV1;
|
||||||
|
@ -40,30 +39,15 @@ public class SyncHelper {
|
||||||
|
|
||||||
private final static Logger logger = LoggerFactory.getLogger(SyncHelper.class);
|
private final static Logger logger = LoggerFactory.getLogger(SyncHelper.class);
|
||||||
|
|
||||||
|
private final Context context;
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final AttachmentHelper attachmentHelper;
|
|
||||||
private final SendHelper sendHelper;
|
|
||||||
private final GroupHelper groupHelper;
|
|
||||||
private final AvatarStore avatarStore;
|
|
||||||
private final SignalServiceAddressResolver addressResolver;
|
|
||||||
|
|
||||||
public SyncHelper(
|
public SyncHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.context = context;
|
||||||
final AttachmentHelper attachmentHelper,
|
this.account = context.getAccount();
|
||||||
final SendHelper sendHelper,
|
|
||||||
final GroupHelper groupHelper,
|
|
||||||
final AvatarStore avatarStore,
|
|
||||||
final SignalServiceAddressResolver addressResolver
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.attachmentHelper = attachmentHelper;
|
|
||||||
this.sendHelper = sendHelper;
|
|
||||||
this.groupHelper = groupHelper;
|
|
||||||
this.avatarStore = avatarStore;
|
|
||||||
this.addressResolver = addressResolver;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestAllSyncData() throws IOException {
|
public void requestAllSyncData() {
|
||||||
requestSyncGroups();
|
requestSyncGroups();
|
||||||
requestSyncContacts();
|
requestSyncContacts();
|
||||||
requestSyncBlocked();
|
requestSyncBlocked();
|
||||||
|
@ -71,8 +55,9 @@ public class SyncHelper {
|
||||||
requestSyncKeys();
|
requestSyncKeys();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendSyncFetchProfileMessage() throws IOException {
|
public void sendSyncFetchProfileMessage() {
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE));
|
context.getSendHelper()
|
||||||
|
.sendSyncMessage(SignalServiceSyncMessage.forFetchLatest(SignalServiceSyncMessage.FetchType.LOCAL_PROFILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendGroups() throws IOException {
|
public void sendGroups() throws IOException {
|
||||||
|
@ -87,9 +72,9 @@ public class SyncHelper {
|
||||||
Optional.fromNullable(groupInfo.name),
|
Optional.fromNullable(groupInfo.name),
|
||||||
groupInfo.getMembers()
|
groupInfo.getMembers()
|
||||||
.stream()
|
.stream()
|
||||||
.map(addressResolver::resolveSignalServiceAddress)
|
.map(context.getRecipientHelper()::resolveSignalServiceAddress)
|
||||||
.toList(),
|
.toList(),
|
||||||
groupHelper.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.fromNullable(groupInfo.color),
|
||||||
|
@ -108,7 +93,7 @@ public class SyncHelper {
|
||||||
.withLength(groupsFile.length())
|
.withLength(groupsFile.length())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream));
|
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -129,7 +114,7 @@ public class SyncHelper {
|
||||||
for (var contactPair : account.getContactStore().getContacts()) {
|
for (var contactPair : account.getContactStore().getContacts()) {
|
||||||
final var recipientId = contactPair.first();
|
final var recipientId = contactPair.first();
|
||||||
final var contact = contactPair.second();
|
final var contact = contactPair.second();
|
||||||
final var address = addressResolver.resolveSignalServiceAddress(recipientId);
|
final var address = context.getRecipientHelper().resolveSignalServiceAddress(recipientId);
|
||||||
|
|
||||||
var currentIdentity = account.getIdentityKeyStore().getIdentity(recipientId);
|
var currentIdentity = account.getIdentityKeyStore().getIdentity(recipientId);
|
||||||
VerifiedMessage verifiedMessage = null;
|
VerifiedMessage verifiedMessage = null;
|
||||||
|
@ -176,8 +161,9 @@ public class SyncHelper {
|
||||||
.withLength(contactsFile.length())
|
.withLength(contactsFile.length())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream,
|
context.getSendHelper()
|
||||||
true)));
|
.sendSyncMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream,
|
||||||
|
true)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
@ -189,11 +175,11 @@ public class SyncHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendBlockedList() throws IOException {
|
public void sendBlockedList() {
|
||||||
var addresses = new ArrayList<SignalServiceAddress>();
|
var addresses = new ArrayList<SignalServiceAddress>();
|
||||||
for (var record : account.getContactStore().getContacts()) {
|
for (var record : account.getContactStore().getContacts()) {
|
||||||
if (record.second().isBlocked()) {
|
if (record.second().isBlocked()) {
|
||||||
addresses.add(addressResolver.resolveSignalServiceAddress(record.first()));
|
addresses.add(context.getRecipientHelper().resolveSignalServiceAddress(record.first()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var groupIds = new ArrayList<byte[]>();
|
var groupIds = new ArrayList<byte[]>();
|
||||||
|
@ -202,7 +188,8 @@ public class SyncHelper {
|
||||||
groupIds.add(record.getGroupId().serialize());
|
groupIds.add(record.getGroupId().serialize());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(addresses, groupIds)));
|
context.getSendHelper()
|
||||||
|
.sendSyncMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(addresses, groupIds)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendVerifiedMessage(
|
public void sendVerifiedMessage(
|
||||||
|
@ -212,21 +199,21 @@ public class SyncHelper {
|
||||||
identityKey,
|
identityKey,
|
||||||
trustLevel.toVerifiedState(),
|
trustLevel.toVerifiedState(),
|
||||||
System.currentTimeMillis());
|
System.currentTimeMillis());
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forVerified(verifiedMessage));
|
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forVerified(verifiedMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendKeysMessage() throws IOException {
|
public void sendKeysMessage() {
|
||||||
var keysMessage = new KeysMessage(Optional.fromNullable(account.getStorageKey()));
|
var keysMessage = new KeysMessage(Optional.fromNullable(account.getStorageKey()));
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage));
|
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forKeys(keysMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendConfigurationMessage() throws IOException {
|
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.fromNullable(config.getReadReceipts()),
|
||||||
Optional.fromNullable(config.getUnidentifiedDeliveryIndicators()),
|
Optional.fromNullable(config.getUnidentifiedDeliveryIndicators()),
|
||||||
Optional.fromNullable(config.getTypingIndicators()),
|
Optional.fromNullable(config.getTypingIndicators()),
|
||||||
Optional.fromNullable(config.getLinkPreviews()));
|
Optional.fromNullable(config.getLinkPreviews()));
|
||||||
sendHelper.sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage));
|
context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forConfiguration(configurationMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleSyncDeviceContacts(final InputStream input) throws IOException {
|
public void handleSyncDeviceContacts(final InputStream input) throws IOException {
|
||||||
|
@ -282,48 +269,48 @@ public class SyncHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSyncGroups() throws IOException {
|
private void requestSyncGroups() {
|
||||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS)
|
.setType(SignalServiceProtos.SyncMessage.Request.Type.GROUPS)
|
||||||
.build();
|
.build();
|
||||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||||
sendHelper.sendSyncMessage(message);
|
context.getSendHelper().sendSyncMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSyncContacts() throws IOException {
|
private void requestSyncContacts() {
|
||||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONTACTS)
|
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONTACTS)
|
||||||
.build();
|
.build();
|
||||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||||
sendHelper.sendSyncMessage(message);
|
context.getSendHelper().sendSyncMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSyncBlocked() throws IOException {
|
private void requestSyncBlocked() {
|
||||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.BLOCKED)
|
.setType(SignalServiceProtos.SyncMessage.Request.Type.BLOCKED)
|
||||||
.build();
|
.build();
|
||||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||||
sendHelper.sendSyncMessage(message);
|
context.getSendHelper().sendSyncMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSyncConfiguration() throws IOException {
|
private void requestSyncConfiguration() {
|
||||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONFIGURATION)
|
.setType(SignalServiceProtos.SyncMessage.Request.Type.CONFIGURATION)
|
||||||
.build();
|
.build();
|
||||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||||
sendHelper.sendSyncMessage(message);
|
context.getSendHelper().sendSyncMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void requestSyncKeys() throws IOException {
|
private void requestSyncKeys() {
|
||||||
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
var r = SignalServiceProtos.SyncMessage.Request.newBuilder()
|
||||||
.setType(SignalServiceProtos.SyncMessage.Request.Type.KEYS)
|
.setType(SignalServiceProtos.SyncMessage.Request.Type.KEYS)
|
||||||
.build();
|
.build();
|
||||||
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
var message = SignalServiceSyncMessage.forRequest(new RequestMessage(r));
|
||||||
sendHelper.sendSyncMessage(message);
|
context.getSendHelper().sendSyncMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<SignalServiceAttachmentStream> createContactAvatarAttachment(SignalServiceAddress address) throws IOException {
|
private Optional<SignalServiceAttachmentStream> createContactAvatarAttachment(SignalServiceAddress address) throws IOException {
|
||||||
final var streamDetails = avatarStore.retrieveContactAvatar(address);
|
final var streamDetails = context.getAvatarStore().retrieveContactAvatar(address);
|
||||||
if (streamDetails == null) {
|
if (streamDetails == null) {
|
||||||
return Optional.absent();
|
return Optional.absent();
|
||||||
}
|
}
|
||||||
|
@ -333,8 +320,9 @@ public class SyncHelper {
|
||||||
|
|
||||||
private void downloadContactAvatar(SignalServiceAttachment avatar, SignalServiceAddress address) {
|
private void downloadContactAvatar(SignalServiceAttachment avatar, SignalServiceAddress address) {
|
||||||
try {
|
try {
|
||||||
avatarStore.storeContactAvatar(address,
|
context.getAvatarStore()
|
||||||
outputStream -> attachmentHelper.retrieveAttachment(avatar, outputStream));
|
.storeContactAvatar(address,
|
||||||
|
outputStream -> context.getAttachmentHelper().retrieveAttachment(avatar, outputStream));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.warn("Failed to download avatar for contact {}, ignoring: {}", address, e.getMessage());
|
logger.warn("Failed to download avatar for contact {}, ignoring: {}", address, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,22 +26,15 @@ public class UnidentifiedAccessHelper {
|
||||||
|
|
||||||
private final SignalAccount account;
|
private final SignalAccount account;
|
||||||
private final SignalDependencies dependencies;
|
private final SignalDependencies dependencies;
|
||||||
private final SelfProfileKeyProvider selfProfileKeyProvider;
|
private final Context context;
|
||||||
private final ProfileProvider profileProvider;
|
|
||||||
|
|
||||||
private SenderCertificate privacySenderCertificate;
|
private SenderCertificate privacySenderCertificate;
|
||||||
private SenderCertificate senderCertificate;
|
private SenderCertificate senderCertificate;
|
||||||
|
|
||||||
public UnidentifiedAccessHelper(
|
public UnidentifiedAccessHelper(final Context context) {
|
||||||
final SignalAccount account,
|
this.account = context.getAccount();
|
||||||
final SignalDependencies dependencies,
|
this.dependencies = context.getDependencies();
|
||||||
final SelfProfileKeyProvider selfProfileKeyProvider,
|
this.context = context;
|
||||||
final ProfileProvider profileProvider
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.selfProfileKeyProvider = selfProfileKeyProvider;
|
|
||||||
this.profileProvider = profileProvider;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<Optional<UnidentifiedAccessPair>> getAccessFor(List<RecipientId> recipients) {
|
public List<Optional<UnidentifiedAccessPair>> getAccessFor(List<RecipientId> recipients) {
|
||||||
|
@ -145,18 +138,18 @@ public class UnidentifiedAccessHelper {
|
||||||
private byte[] getSelfUnidentifiedAccessKey(boolean noRefresh) {
|
private byte[] getSelfUnidentifiedAccessKey(boolean noRefresh) {
|
||||||
var selfProfile = noRefresh
|
var selfProfile = noRefresh
|
||||||
? account.getProfileStore().getProfile(account.getSelfRecipientId())
|
? account.getProfileStore().getProfile(account.getSelfRecipientId())
|
||||||
: profileProvider.getProfile(account.getSelfRecipientId());
|
: context.getProfileHelper().getRecipientProfile(account.getSelfRecipientId());
|
||||||
if (selfProfile != null
|
if (selfProfile != null
|
||||||
&& selfProfile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED) {
|
&& selfProfile.getUnidentifiedAccessMode() == Profile.UnidentifiedAccessMode.UNRESTRICTED) {
|
||||||
return createUnrestrictedUnidentifiedAccess();
|
return createUnrestrictedUnidentifiedAccess();
|
||||||
}
|
}
|
||||||
return UnidentifiedAccess.deriveAccessKeyFrom(selfProfileKeyProvider.getProfileKey());
|
return UnidentifiedAccess.deriveAccessKeyFrom(account.getProfileKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
private byte[] getTargetUnidentifiedAccessKey(RecipientId recipientId, boolean noRefresh) {
|
private byte[] getTargetUnidentifiedAccessKey(RecipientId recipientId, boolean noRefresh) {
|
||||||
var targetProfile = noRefresh
|
var targetProfile = noRefresh
|
||||||
? account.getProfileStore().getProfile(recipientId)
|
? account.getProfileStore().getProfile(recipientId)
|
||||||
: profileProvider.getProfile(recipientId);
|
: context.getProfileHelper().getRecipientProfile(recipientId);
|
||||||
if (targetProfile == null) {
|
if (targetProfile == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
package org.asamk.signal.manager.helper;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.storage.recipients.RecipientId;
|
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
|
||||||
import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair;
|
|
||||||
|
|
||||||
public interface UnidentifiedAccessProvider {
|
|
||||||
|
|
||||||
Optional<UnidentifiedAccessPair> getAccessFor(RecipientId recipientId, boolean noRefresh);
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
package org.asamk.signal.manager.jobs;
|
|
||||||
|
|
||||||
import org.asamk.signal.manager.SignalDependencies;
|
|
||||||
import org.asamk.signal.manager.StickerPackStore;
|
|
||||||
import org.asamk.signal.manager.helper.GroupHelper;
|
|
||||||
import org.asamk.signal.manager.helper.PreKeyHelper;
|
|
||||||
import org.asamk.signal.manager.helper.ProfileHelper;
|
|
||||||
import org.asamk.signal.manager.helper.SendHelper;
|
|
||||||
import org.asamk.signal.manager.helper.StorageHelper;
|
|
||||||
import org.asamk.signal.manager.helper.SyncHelper;
|
|
||||||
import org.asamk.signal.manager.storage.SignalAccount;
|
|
||||||
|
|
||||||
public class Context {
|
|
||||||
|
|
||||||
private final SignalAccount account;
|
|
||||||
private final SignalDependencies dependencies;
|
|
||||||
private final StickerPackStore stickerPackStore;
|
|
||||||
private final SendHelper sendHelper;
|
|
||||||
private final GroupHelper groupHelper;
|
|
||||||
private final SyncHelper syncHelper;
|
|
||||||
private final ProfileHelper profileHelper;
|
|
||||||
private final StorageHelper storageHelper;
|
|
||||||
private final PreKeyHelper preKeyHelper;
|
|
||||||
|
|
||||||
public Context(
|
|
||||||
final SignalAccount account,
|
|
||||||
final SignalDependencies dependencies,
|
|
||||||
final StickerPackStore stickerPackStore,
|
|
||||||
final SendHelper sendHelper,
|
|
||||||
final GroupHelper groupHelper,
|
|
||||||
final SyncHelper syncHelper,
|
|
||||||
final ProfileHelper profileHelper,
|
|
||||||
final StorageHelper storageHelper,
|
|
||||||
final PreKeyHelper preKeyHelper
|
|
||||||
) {
|
|
||||||
this.account = account;
|
|
||||||
this.dependencies = dependencies;
|
|
||||||
this.stickerPackStore = stickerPackStore;
|
|
||||||
this.sendHelper = sendHelper;
|
|
||||||
this.groupHelper = groupHelper;
|
|
||||||
this.syncHelper = syncHelper;
|
|
||||||
this.profileHelper = profileHelper;
|
|
||||||
this.storageHelper = storageHelper;
|
|
||||||
this.preKeyHelper = preKeyHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignalAccount getAccount() {
|
|
||||||
return account;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SignalDependencies getDependencies() {
|
|
||||||
return dependencies;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StickerPackStore getStickerPackStore() {
|
|
||||||
return stickerPackStore;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SendHelper getSendHelper() {
|
|
||||||
return sendHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public GroupHelper getGroupHelper() {
|
|
||||||
return groupHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SyncHelper getSyncHelper() {
|
|
||||||
return syncHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ProfileHelper getProfileHelper() {
|
|
||||||
return profileHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public StorageHelper getStorageHelper() {
|
|
||||||
return storageHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PreKeyHelper getPreKeyHelper() {
|
|
||||||
return preKeyHelper;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,7 @@
|
||||||
package org.asamk.signal.manager.jobs;
|
package org.asamk.signal.manager.jobs;
|
||||||
|
|
||||||
|
import org.asamk.signal.manager.helper.Context;
|
||||||
|
|
||||||
public interface Job {
|
public interface Job {
|
||||||
|
|
||||||
void run(Context context);
|
void run(Context context);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package org.asamk.signal.manager.jobs;
|
package org.asamk.signal.manager.jobs;
|
||||||
|
|
||||||
import org.asamk.signal.manager.JsonStickerPack;
|
import org.asamk.signal.manager.JsonStickerPack;
|
||||||
|
import org.asamk.signal.manager.helper.Context;
|
||||||
import org.asamk.signal.manager.storage.stickers.StickerPackId;
|
import org.asamk.signal.manager.storage.stickers.StickerPackId;
|
||||||
import org.asamk.signal.manager.util.IOUtils;
|
import org.asamk.signal.manager.util.IOUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue