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 {
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;
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;
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
}
}
try {
- preKeyHelper.refreshPreKeysIfNecessary();
+ context.getPreKeyHelper().refreshPreKeysIfNecessary();
if (account.getAci() == null) {
account.setAci(ACI.parseOrNull(dependencies.getAccountManager().getWhoAmI().getAci()));
}
.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);
if (configuration.linkPreviews().isPresent()) {
configurationStore.setLinkPreviews(configuration.linkPreviews().get());
}
- syncHelper.sendConfigurationMessage();
+ context.getSyncHelper().sendConfigurationMessage();
}
/**
public void setProfile(
String givenName, final String familyName, String about, String aboutEmoji, java.util.Optional<File> avatar
) throws IOException {
- profileHelper.setProfile(givenName,
- familyName,
- about,
- aboutEmoji,
- avatar == null ? null : Optional.fromNullable(avatar.orElse(null)));
- syncHelper.sendSyncFetchProfileMessage();
+ context.getProfileHelper()
+ .setProfile(givenName,
+ familyName,
+ about,
+ aboutEmoji,
+ avatar == null ? null : Optional.fromNullable(avatar.orElse(null)));
+ context.getSyncHelper().sendSyncFetchProfileMessage();
}
@Override
@Override
public void deleteAccount() throws IOException {
try {
- pinHelper.removeRegistrationLockPin();
+ context.getPinHelper().removeRegistrationLockPin();
} catch (IOException e) {
logger.warn("Failed to remove registration lock pin");
}
? 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
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),
- avatarFile);
+ return context.getGroupHelper()
+ .createGroup(name,
+ members == null ? null : context.getRecipientHelper().resolveRecipients(members),
+ avatarFile);
}
@Override
public SendGroupMessageResults updateGroup(
final GroupId groupId, final UpdateGroup updateGroup
) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException, UnregisteredRecipientException {
- return groupHelper.updateGroup(groupId,
- updateGroup.getName(),
- updateGroup.getDescription(),
- updateGroup.getMembers() == null ? null : recipientHelper.resolveRecipients(updateGroup.getMembers()),
- updateGroup.getRemoveMembers() == null
- ? null
- : recipientHelper.resolveRecipients(updateGroup.getRemoveMembers()),
- updateGroup.getAdmins() == null ? null : recipientHelper.resolveRecipients(updateGroup.getAdmins()),
- updateGroup.getRemoveAdmins() == null
- ? null
- : recipientHelper.resolveRecipients(updateGroup.getRemoveAdmins()),
- updateGroup.isResetGroupLink(),
- updateGroup.getGroupLinkState(),
- updateGroup.getAddMemberPermission(),
- updateGroup.getEditDetailsPermission(),
- updateGroup.getAvatarFile(),
- updateGroup.getExpirationTimer(),
- updateGroup.getIsAnnouncementGroup());
+ return context.getGroupHelper()
+ .updateGroup(groupId,
+ updateGroup.getName(),
+ updateGroup.getDescription(),
+ updateGroup.getMembers() == null
+ ? null
+ : context.getRecipientHelper().resolveRecipients(updateGroup.getMembers()),
+ updateGroup.getRemoveMembers() == null
+ ? null
+ : context.getRecipientHelper().resolveRecipients(updateGroup.getRemoveMembers()),
+ updateGroup.getAdmins() == null
+ ? null
+ : context.getRecipientHelper().resolveRecipients(updateGroup.getAdmins()),
+ updateGroup.getRemoveAdmins() == null
+ ? null
+ : context.getRecipientHelper().resolveRecipients(updateGroup.getRemoveAdmins()),
+ updateGroup.isResetGroupLink(),
+ updateGroup.getGroupLinkState(),
+ updateGroup.getAddMemberPermission(),
+ updateGroup.getEditDetailsPermission(),
+ updateGroup.getAvatarFile(),
+ updateGroup.getExpirationTimer(),
+ updateGroup.getIsAnnouncementGroup());
}
@Override
public Pair<GroupId, SendGroupMessageResults> joinGroup(
GroupInviteLinkUrl inviteLinkUrl
) throws IOException, InactiveGroupLinkException {
- return groupHelper.joinGroup(inviteLinkUrl);
+ return context.getGroupHelper().joinGroup(inviteLinkUrl);
}
private SendMessageResults sendMessage(
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(),
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,
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(),
} 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,
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,
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()));
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())));
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;
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);
for (var recipient : recipients) {
final RecipientId recipientId;
try {
- recipientId = recipientHelper.resolveRecipient(recipient);
+ recipientId = context.getRecipientHelper().resolveRecipient(recipient);
} catch (UnregisteredRecipientException e) {
continue;
}
if (!account.isMasterDevice()) {
throw new NotMasterDeviceException();
}
- contactHelper.setContactName(recipientHelper.resolveRecipient(recipient), name);
+ context.getContactHelper().setContactName(context.getRecipientHelper().resolveRecipient(recipient), name);
}
@Override
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
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();
}
/**
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));
@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();
}
}
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();
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) {
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
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;
}
return contact.getName();
}
- final var profile = profileHelper.getRecipientProfile(recipientId);
+ final var profile = context.getProfileHelper().getRecipientProfile(recipientId);
if (profile != null) {
return profile.getDisplayName();
}
@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
}
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());
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;
}
) 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;
}
) 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;
}
) 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;
}
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;
}
}
}
- 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;
this.sessionLock = sessionLock;
}
+ public ServiceEnvironmentConfig getServiceEnvironmentConfig() {
+ return serviceEnvironmentConfig;
+ }
+
public SignalServiceAccountManager getAccountManager() {
return getOrCreate(() -> accountManager,
() -> accountManager = new SignalServiceAccountManager(serviceEnvironmentConfig.getSignalServiceConfiguration(),
package org.asamk.signal.manager.actions;
-import org.asamk.signal.manager.jobs.Context;
+import org.asamk.signal.manager.helper.Context;
public interface HandleAction {
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 {
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 {
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 {
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 {
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 {
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 {
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;
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;
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 {
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 {
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 {
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 {
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 {
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) {
--- /dev/null
+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();
+ }
+}
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;
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;
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;
-
- 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;
+ private final Context context;
+
+ public GroupHelper(final Context context) {
+ this.account = context.getAccount();
+ this.dependencies = context.getDependencies();
+ this.context = context;
}
public GroupInfo getGroup(GroupId groupId) {
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();
}
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) {
}
}
downloadGroupAvatar(groupId, groupSecretParams, avatar);
}
}
- groupInfoV2.setGroup(group, recipientResolver);
+ groupInfoV2.setGroup(group, account.getRecipientStore());
account.getGroupStore().updateGroup(groupInfoV2);
}
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
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(),
- outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
+ context.getAvatarStore()
+ .storeGroupAvatar(gv2.getGroupId(),
+ outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
}
account.getGroupStore().updateGroup(gv2);
) 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());
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 {
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);
}
}
private void downloadGroupAvatar(GroupIdV2 groupId, GroupSecretParams groupSecretParams, String cdnKey) {
try {
- avatarStore.storeGroupAvatar(groupId,
- outputStream -> retrieveGroupV2Avatar(groupSecretParams, cdnKey, outputStream));
+ 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());
}
}
if (avatarFile != null) {
- avatarStore.storeGroupAvatar(g.getGroupId(),
- outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
+ context.getAvatarStore()
+ .storeGroupAvatar(g.getGroupId(),
+ outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
}
}
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(
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());
if (name != null || description != null || avatarFile != null) {
var groupGroupChangePair = groupV2Helper.updateGroup(group, name, description, avatarFile);
if (avatarFile != null) {
- avatarStore.storeGroupAvatar(group.getGroupId(),
- outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
+ context.getAvatarStore()
+ .storeGroupAvatar(group.getGroupId(),
+ outputStream -> IOUtils.copyFileToStream(avatarFile, outputStream));
}
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
}
// 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());
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());
) 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);
) 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());
}
+++ /dev/null
-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);
-}
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;
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;
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);
) throws IOException, GroupLinkNotActiveException {
var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupMasterKey);
- return groupsV2Api.getGroupJoinInfo(groupSecretParams,
- Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
- getGroupAuthForToday(groupSecretParams));
+ return dependencies.getGroupsV2Api()
+ .getGroupJoinInfo(groupSecretParams,
+ Optional.fromNullable(password).transform(GroupLinkPassword::serialize),
+ getGroupAuthForToday(groupSecretParams));
}
public Pair<GroupInfoV2, DecryptedGroup> createGroup(
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;
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;
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,
- name,
- Optional.fromNullable(avatar),
- self,
- candidates,
- Member.Role.DEFAULT,
- 0);
+ return dependencies.getGroupsV2Operations()
+ .createNewGroup(groupSecretParams,
+ name,
+ Optional.fromNullable(avatar),
+ self,
+ candidates,
+ Member.Role.DEFAULT,
+ 0);
}
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());
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();
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));
}
}
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)))
}
final var adminUuids = membersToMakeAdmin.stream()
- .map(addressResolver::resolveSignalServiceAddress)
+ .map(context.getRecipientHelper()::resolveSignalServiceAddress)
.map(SignalServiceAddress::getAci)
.map(ACI::uuid)
.toList();
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());
) 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))
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");
}
? 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);
}
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);
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);
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(
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();
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);
}
final var nextRevision = currentRevision + 1;
final var changeActions = change.setRevision(nextRevision).build();
- return groupsV2Api.patchGroup(changeActions,
- getGroupAuthForToday(groupSecretParams),
- Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
+ return dependencies.getGroupsV2Api()
+ .patchGroup(changeActions,
+ getGroupAuthForToday(groupSecretParams),
+ Optional.fromNullable(password).transform(GroupLinkPassword::serialize));
}
public DecryptedGroup getUpdatedDecryptedGroup(
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();
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();
}
}
+++ /dev/null
-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);
-}
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;
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;
-
- 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;
+ private final Context context;
+
+ public IdentityHelper(final Context context) {
+ this.account = context.getAccount();
+ this.context = context;
}
public boolean trustIdentityVerified(RecipientId recipientId, byte[] fingerprint) {
}
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();
}
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());
}
}
} else {
// Retrieve profile to get the current identity key from the server
- profileHelper.refreshRecipientProfile(recipientId);
+ context.getProfileHelper().refreshRecipientProfile(recipientId);
}
}
}
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;
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;
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;
-
- 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;
+ private final Context context;
+
+ public IncomingMessageHandler(final Context context) {
+ this.account = context.getAccount();
+ this.dependencies = context.getDependencies();
+ this.context = context;
}
public Pair<List<HandleAction>, Exception> handleRetryEnvelope(
.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)
}
handler.handleMessage(MessageEnvelope.from(envelope,
content,
- recipientResolver,
+ account.getRecipientStore(),
account.getRecipientStore()::resolveRecipientAddress,
- attachmentHelper::getAttachmentFile), exception);
+ context.getAttachmentHelper()::getAttachmentFile), exception);
return actions;
}
}
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(),
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()) {
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());
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());
}
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()));
}
}
} 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;
}
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);
}
}
}
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;
}
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()) {
if (groupInfo.getAvatar().isPresent()) {
var avatar = groupInfo.getAvatar().get();
- groupHelper.downloadGroupAvatar(groupV1.getGroupId(), avatar);
+ context.getGroupHelper().downloadGroupAvatar(groupV1.getGroupId(), avatar);
}
if (groupInfo.getName().isPresent()) {
groupV1.addMembers(groupInfo.getMembers()
.get()
.stream()
- .map(recipientResolver::resolveRecipient)
+ .map(context.getRecipientHelper()::resolveRecipient)
.collect(Collectors.toSet()));
}
final var groupContext = message.getGroupContext().get().getGroupV2().get();
final var groupMasterKey = groupContext.getMasterKey();
- groupHelper.getOrMigrateGroup(groupMasterKey,
- groupContext.getRevision(),
- groupContext.hasSignedGroupChange() ? groupContext.getSignedGroupChange() : null);
+ context.getGroupHelper()
+ .getOrMigrateGroup(groupMasterKey,
+ groupContext.getRevision(),
+ groupContext.hasSignedGroupChange() ? groupContext.getSignedGroupChange() : null);
}
}
// 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());
}
}
}
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());
}
}
}
for (var quotedAttachment : quote.getAttachments()) {
final var thumbnail = quotedAttachment.getThumbnail();
if (thumbnail != null) {
- attachmentHelper.downloadAttachment(thumbnail);
+ context.getAttachmentHelper().downloadAttachment(thumbnail);
}
}
}
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;
}
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;
private final SignalAccount account;
private final SignalDependencies dependencies;
- private final AvatarStore avatarStore;
- private final UnidentifiedAccessProvider unidentifiedAccessProvider;
- private final SignalServiceAddressResolver addressResolver;
-
- 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;
+ private final Context context;
+
+ public ProfileHelper(final Context context) {
+ this.account = context.getAccount();
+ this.dependencies = context.getDependencies();
+ this.context = context;
}
public Profile getRecipientProfile(RecipientId recipientId) {
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(),
if (avatar != null) {
if (avatar.isPresent()) {
- avatarStore.storeProfileAvatar(account.getSelfAddress(),
- outputStream -> IOUtils.copyFileToStream(avatar.get(), outputStream));
+ 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);
) {
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());
}
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();
}
} 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());
) {
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());
}
}
try {
- avatarStore.storeProfileAvatar(address,
- outputStream -> retrieveProfileAvatar(avatarPath, profileKey, outputStream));
+ context.getAvatarStore()
+ .storeProfileAvatar(address,
+ outputStream -> retrieveProfileAvatar(avatarPath, profileKey, outputStream));
} catch (Throwable e) {
if (e instanceof AssertionError && e.getCause() instanceof InterruptedException) {
Thread.currentThread().interrupt();
}
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();
+++ /dev/null
-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);
-}
+++ /dev/null
-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);
-}
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) {
.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) {
+++ /dev/null
-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;
-}
+++ /dev/null
-package org.asamk.signal.manager.helper;
-
-import org.signal.zkgroup.profiles.ProfileKey;
-
-public interface SelfProfileKeyProvider {
-
- ProfileKey getProfileKey();
-}
+++ /dev/null
-package org.asamk.signal.manager.helper;
-
-import org.asamk.signal.manager.storage.recipients.RecipientId;
-
-public interface SelfRecipientIdProvider {
-
- RecipientId getSelfRecipientId();
-}
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;
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;
-
- 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;
+ private final Context context;
+
+ public SendHelper(final Context context) {
+ this.account = context.getAccount();
+ this.dependencies = context.getDependencies();
+ this.context = context;
}
/**
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);
}
}
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);
}
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);
}
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();
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;
}
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);
}
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)
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);
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
}
}
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
}
}
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());
}
}
+++ /dev/null
-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);
-}
private final SignalAccount account;
private final SignalDependencies dependencies;
- private final GroupHelper groupHelper;
- private final ProfileHelper profileHelper;
-
- 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;
+ private final Context context;
+
+ public StorageHelper(final Context context) {
+ this.account = context.getAccount();
+ this.dependencies = context.getDependencies();
+ this.context = context;
}
public void readDataFromStorage() throws IOException {
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);
}
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);
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,
- accountRecord.getGivenName().orNull(),
- accountRecord.getFamilyName().orNull(),
- null,
- null,
- null);
+ context.getProfileHelper()
+ .setProfile(false,
+ accountRecord.getGivenName().orNull(),
+ accountRecord.getFamilyName().orNull(),
+ null,
+ null,
+ null);
}
private SignalStorageRecord getSignalStorageRecord(final StorageId accountId) throws IOException {
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;
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();
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 {
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),
.withLength(groupsFile.length())
.build();
- sendHelper.sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream));
+ context.getSendHelper().sendSyncMessage(SignalServiceSyncMessage.forGroups(attachmentStream));
}
}
} finally {
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;
.withLength(contactsFile.length())
.build();
- sendHelper.sendSyncMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream,
- true)));
+ context.getSendHelper()
+ .sendSyncMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream,
+ true)));
}
}
} finally {
}
}
- 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[]>();
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(
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 {
}
}
- 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();
}
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());
}
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) {
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;
}
+++ /dev/null
-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);
-}
+++ /dev/null
-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;
- }
-}
package org.asamk.signal.manager.jobs;
+import org.asamk.signal.manager.helper.Context;
+
public interface Job {
void run(Context context);
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;