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