From 3bc433844413ac52f2d2279879b4a3061c768680 Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Wed, 9 Dec 2020 18:23:05 +1100 Subject: [PATCH] Pre key bundle removal pt1. Device link functionality removed from app module. --- app/src/main/AndroidManifest.xml | 5 - .../securesms/ApplicationContext.java | 21 +- .../securesms/DatabaseUpgradeActivity.java | 7 +- .../securesms/LinkPreviewsIntroFragment.java | 7 - .../TypingIndicatorIntroFragment.java | 7 - .../securesms/VerifyIdentityActivity.java | 9 +- .../conversation/ConversationActivity.java | 9 - .../securesms/crypto/PreKeyUtil.java | 129 ------- .../storage/SignalProtocolStoreImpl.java | 35 +- .../crypto/storage/TextSecurePreKeyStore.java | 90 ----- .../securesms/database/DatabaseFactory.java | 22 +- .../helpers/PreKeyMigrationHelper.java | 225 ----------- .../database/helpers/SQLCipherOpenHelper.java | 22 +- .../dependencies/AxolotlStorageModule.java | 33 -- .../SignalCommunicationModule.java | 35 +- .../migration/WorkManagerFactoryMappings.java | 24 -- .../securesms/jobs/CleanPreKeysJob.java | 141 ------- .../securesms/jobs/CreateSignedPreKeyJob.java | 88 ----- .../securesms/jobs/JobManagerFactories.java | 15 - .../jobs/MultiDeviceBlockedUpdateJob.java | 108 ------ .../MultiDeviceConfigurationUpdateJob.java | 121 ------ .../jobs/MultiDeviceContactUpdateJob.java | 352 ------------------ .../jobs/MultiDeviceGroupUpdateJob.java | 174 --------- .../jobs/MultiDeviceProfileKeyUpdateJob.java | 112 ------ .../jobs/MultiDeviceReadUpdateJob.java | 144 ------- .../MultiDeviceStickerPackOperationJob.java | 122 ------ .../jobs/MultiDeviceStickerPackSyncJob.java | 94 ----- .../jobs/MultiDeviceVerifiedUpdateJob.java | 147 -------- .../securesms/jobs/PushDecryptJob.java | 104 ++---- .../securesms/jobs/PushSendJob.java | 14 +- .../securesms/jobs/PushTextSendJob.java | 10 +- .../securesms/jobs/RefreshPreKeysJob.java | 102 ----- .../securesms/jobs/RotateSignedPreKeyJob.java | 88 ----- .../securesms/loki/activities/HomeActivity.kt | 6 - .../loki/activities/JoinPublicChatActivity.kt | 9 +- .../loki/database/LokiPreKeyBundleDatabase.kt | 130 ------- .../loki/database/LokiPreKeyRecordDatabase.kt | 51 --- .../ClosedGroupUpdateMessageSendJob.kt | 4 +- .../protocol/SessionManagementProtocol.kt | 31 +- .../protocol/SessionRequestMessageSendJob.kt | 20 +- .../protocol/SessionResetImplementation.kt | 6 +- .../shelved/MultiDeviceOpenGroupUpdateJob.kt | 76 ---- .../protocol/shelved/MultiDeviceProtocol.kt | 204 ---------- .../protocol/shelved/SyncMessagesProtocol.kt | 173 --------- .../notifications/MarkReadReceiver.java | 10 - .../AppProtectionPreferenceFragment.java | 34 -- .../service/RotateSignedPreKeyListener.java | 39 -- .../stickers/StickerManagementRepository.java | 11 - .../service/loki/crypto/LokiServiceCipher.kt | 11 +- 49 files changed, 117 insertions(+), 3314 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/crypto/PreKeyUtil.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/dependencies/AxolotlStorageModule.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceConfigurationUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyBundleDatabase.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyRecordDatabase.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceOpenGroupUpdateJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/SyncMessagesProtocol.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3abe40cb7c..33c4770b0d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -483,11 +483,6 @@ - - - - - diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 656f52aa30..babb511f96 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -43,16 +43,13 @@ import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.dependencies.AxolotlStorageModule; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.dependencies.SignalCommunicationModule; import org.thoughtcrime.securesms.jobmanager.DependencyInjector; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.jobmanager.impl.JsonDataSerializer; -import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.FastJobStorage; import org.thoughtcrime.securesms.jobs.JobManagerFactories; -import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; import org.thoughtcrime.securesms.jobs.PushContentReceiveJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob; @@ -66,7 +63,6 @@ import org.thoughtcrime.securesms.loki.api.BackgroundPollWorker; import org.thoughtcrime.securesms.loki.api.ClosedGroupPoller; import org.thoughtcrime.securesms.loki.api.LokiPushNotificationManager; import org.thoughtcrime.securesms.loki.api.PublicChatManager; -import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob; import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; @@ -89,7 +85,6 @@ import org.thoughtcrime.securesms.service.IncomingMessageObserver; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.service.LocalBackupListener; import org.thoughtcrime.securesms.service.RotateSenderCertificateListener; -import org.thoughtcrime.securesms.service.RotateSignedPreKeyListener; import org.thoughtcrime.securesms.service.UpdateApkRefreshListener; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.Util; @@ -229,7 +224,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc initializeExpiringMessageManager(); initializeTypingStatusRepository(); initializeTypingStatusSender(); - initializeSignedPreKeyCheck(); initializePeriodicTasks(); initializeWebRtc(); initializePendingMessages(); @@ -241,7 +235,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc public void onStart(@NonNull LifecycleOwner owner) { isAppVisible = true; Log.i(TAG, "App is now visible."); - executePendingContactSync(); KeyCachingService.onAppForegrounded(this); // Loki if (poller != null) { poller.setCaughtUp(false); } @@ -365,14 +358,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc private void initializeDependencyInjection() { communicationModule = new SignalCommunicationModule(this, new SignalServiceNetworkAccess(this)); - this.objectGraph = ObjectGraph.create(communicationModule, new AxolotlStorageModule(this)); + this.objectGraph = ObjectGraph.create(communicationModule); } - private void initializeSignedPreKeyCheck() { - if (!TextSecurePreferences.isSignedPreKeyRegistered(this)) { - jobManager.add(new CreateSignedPreKeyJob(this)); - } - } private void initializeExpiringMessageManager() { this.expiringMessageManager = new ExpiringMessageManager(this); @@ -387,7 +375,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } private void initializePeriodicTasks() { - RotateSignedPreKeyListener.schedule(this); LocalBackupListener.schedule(this); RotateSenderCertificateListener.schedule(this); BackgroundPollWorker.schedulePeriodic(this); // Loki @@ -432,12 +419,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } } - private void executePendingContactSync() { - if (TextSecurePreferences.needsFullContactSync(this)) { - ApplicationContext.getInstance(this).getJobManager().add(new MultiDeviceContactUpdateJob(this, true)); - } - } - private void initializePendingMessages() { if (TextSecurePreferences.getNeedsMessagePull(this)) { Log.i(TAG, "Scheduling a message fetch."); diff --git a/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java b/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java index d2d1e5dd30..737d275c69 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/DatabaseUpgradeActivity.java @@ -39,7 +39,6 @@ import org.thoughtcrime.securesms.database.MmsDatabase.Reader; import org.thoughtcrime.securesms.database.PushDatabase; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; -import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.PushDecryptJob; import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; import org.thoughtcrime.securesms.logging.Log; @@ -227,9 +226,9 @@ public class DatabaseUpgradeActivity extends BaseActivity { } if (params[0] < SIGNED_PREKEY_VERSION) { - ApplicationContext.getInstance(getApplicationContext()) - .getJobManager() - .add(new CreateSignedPreKeyJob(context)); +// ApplicationContext.getInstance(getApplicationContext()) +// .getJobManager() +// .add(new CreateSignedPreKeyJob(context)); } if (params[0] < NO_DECRYPT_QUEUE_VERSION) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/LinkPreviewsIntroFragment.java b/app/src/main/java/org/thoughtcrime/securesms/LinkPreviewsIntroFragment.java index 2b813c41e9..6cbf0b90c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/LinkPreviewsIntroFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/LinkPreviewsIntroFragment.java @@ -9,7 +9,6 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; import org.thoughtcrime.securesms.util.TextSecurePreferences; import network.loki.messenger.R; @@ -48,12 +47,6 @@ public class LinkPreviewsIntroFragment extends Fragment { View view = inflater.inflate(R.layout.experience_upgrade_link_previews_fragment, container, false); view.findViewById(R.id.experience_ok_button).setOnClickListener(v -> { - ApplicationContext.getInstance(requireContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), - TextSecurePreferences.isTypingIndicatorsEnabled(requireContext()), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(requireContext()), - TextSecurePreferences.isLinkPreviewsEnabled(requireContext()))); controller.onLinkPreviewsFinished(); }); diff --git a/app/src/main/java/org/thoughtcrime/securesms/TypingIndicatorIntroFragment.java b/app/src/main/java/org/thoughtcrime/securesms/TypingIndicatorIntroFragment.java index 3ce7a99ff4..437a227b03 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/TypingIndicatorIntroFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/TypingIndicatorIntroFragment.java @@ -10,7 +10,6 @@ import android.view.View; import android.view.ViewGroup; import org.thoughtcrime.securesms.components.TypingIndicatorView; -import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; import org.thoughtcrime.securesms.util.TextSecurePreferences; import network.loki.messenger.R; @@ -60,12 +59,6 @@ public class TypingIndicatorIntroFragment extends Fragment { private void onButtonClicked(boolean typingEnabled) { TextSecurePreferences.setTypingIndicatorsEnabled(getContext(), typingEnabled); - ApplicationContext.getInstance(requireContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), - typingEnabled, - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()), - TextSecurePreferences.isLinkPreviewsEnabled(getContext()))); controller.onTypingIndicatorsFinished(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java b/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java index f4a7393473..7ea88eb0ce 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/VerifyIdentityActivity.java @@ -67,7 +67,6 @@ import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; -import org.thoughtcrime.securesms.jobs.MultiDeviceVerifiedUpdateJob; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.permissions.Permissions; import org.thoughtcrime.securesms.qr.QrCode; @@ -188,6 +187,7 @@ public class VerifyIdentityActivity extends PassphraseRequiredActionBarActivity @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + super.onRequestPermissionsResult(requestCode, permissions, grantResults); Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults); } @@ -602,13 +602,6 @@ public class VerifyIdentityActivity extends PassphraseRequiredActionBarActivity VerifiedStatus.DEFAULT); } - ApplicationContext.getInstance(getActivity()) - .getJobManager() - .add(new MultiDeviceVerifiedUpdateJob(recipient.getAddress(), - remoteIdentity, - isChecked ? VerifiedStatus.VERIFIED : - VerifiedStatus.DEFAULT)); - IdentityUtil.markIdentityVerified(getActivity(), recipient, isChecked, false); } return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 5b506c1cdc..42d257feb3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -140,7 +140,6 @@ import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.database.model.StickerRecord; import org.thoughtcrime.securesms.giph.ui.GiphyActivity; -import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob; import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil; @@ -954,10 +953,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity DatabaseFactory.getRecipientDatabase(ConversationActivity.this) .setBlocked(recipient, false); - ApplicationContext.getInstance(ConversationActivity.this) - .getJobManager() - .add(new MultiDeviceBlockedUpdateJob()); - return null; } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -1016,10 +1011,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity DatabaseFactory.getRecipientDatabase(ConversationActivity.this) .setBlocked(recipient, true); - ApplicationContext.getInstance(ConversationActivity.this) - .getJobManager() - .add(new MultiDeviceBlockedUpdateJob()); - Util.runOnMain(() -> finish()); return null; diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/PreKeyUtil.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/PreKeyUtil.java deleted file mode 100644 index 4052baafad..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/PreKeyUtil.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 2013-2018 Open Whisper Systems - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package org.thoughtcrime.securesms.crypto; - -import android.content.Context; - -import org.jetbrains.annotations.Nullable; -import org.thoughtcrime.securesms.crypto.storage.TextSecurePreKeyStore; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.IdentityKeyPair; -import org.session.libsignal.libsignal.InvalidKeyException; -import org.session.libsignal.libsignal.InvalidKeyIdException; -import org.session.libsignal.libsignal.ecc.Curve; -import org.session.libsignal.libsignal.ecc.ECKeyPair; -import org.session.libsignal.libsignal.state.PreKeyRecord; -import org.session.libsignal.libsignal.state.PreKeyStore; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; -import org.session.libsignal.libsignal.state.SignedPreKeyStore; -import org.session.libsignal.libsignal.util.Medium; - -import java.util.LinkedList; -import java.util.List; - -public class PreKeyUtil { - - @SuppressWarnings("unused") - private static final String TAG = PreKeyUtil.class.getSimpleName(); - - private static final int BATCH_SIZE = 100; - - public synchronized static List generatePreKeyRecords(Context context) { - PreKeyStore preKeyStore = new TextSecurePreKeyStore(context); - List records = new LinkedList<>(); - int preKeyIdOffset = TextSecurePreferences.getNextPreKeyId(context); - - for (int i=0;i generatePreKeyRecords(Context context, int amount) { - List records = new LinkedList<>(); - int preKeyIDOffset = TextSecurePreferences.getNextPreKeyId(context); - for (int i = 0; i < amount; i++) { - int preKeyID = (preKeyIDOffset + i) % Medium.MAX_VALUE; - ECKeyPair keyPair = Curve.generateKeyPair(); - PreKeyRecord record = new PreKeyRecord(preKeyID, keyPair); - records.add(record); - } - TextSecurePreferences.setNextPreKeyId(context, (preKeyIDOffset + BATCH_SIZE + 1) % Medium.MAX_VALUE); - return records; - } - - public synchronized static void storePreKeyRecords(Context context, List records) { - PreKeyStore preKeyStore = new TextSecurePreKeyStore(context); - for (PreKeyRecord record : records) { - preKeyStore.storePreKey(record.getId(), record); - } - } - - public synchronized static PreKeyRecord loadPreKey(Context context, int preKeyID) throws InvalidKeyIdException { - PreKeyStore preKeyStore = new TextSecurePreKeyStore(context); - return preKeyStore.loadPreKey(preKeyID); - } - // endregion -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalProtocolStoreImpl.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalProtocolStoreImpl.java index 33b4a9037d..d9c1251053 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalProtocolStoreImpl.java +++ b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/SignalProtocolStoreImpl.java @@ -19,14 +19,14 @@ import java.util.List; public class SignalProtocolStoreImpl implements SignalProtocolStore { - private final PreKeyStore preKeyStore; - private final SignedPreKeyStore signedPreKeyStore; +// private final PreKeyStore preKeyStore; +// private final SignedPreKeyStore signedPreKeyStore; private final IdentityKeyStore identityKeyStore; private final SessionStore sessionStore; public SignalProtocolStoreImpl(Context context) { - this.preKeyStore = new TextSecurePreKeyStore(context); - this.signedPreKeyStore = new TextSecurePreKeyStore(context); +// this.preKeyStore = new TextSecurePreKeyStore(context); +// this.signedPreKeyStore = new TextSecurePreKeyStore(context); this.identityKeyStore = new TextSecureIdentityKeyStore(context); this.sessionStore = new TextSecureSessionStore(context); } @@ -58,22 +58,26 @@ public class SignalProtocolStoreImpl implements SignalProtocolStore { @Override public PreKeyRecord loadPreKey(int preKeyId) throws InvalidKeyIdException { - return preKeyStore.loadPreKey(preKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// return preKeyStore.loadPreKey(preKeyId); } @Override public void storePreKey(int preKeyId, PreKeyRecord record) { - preKeyStore.storePreKey(preKeyId, record); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// preKeyStore.storePreKey(preKeyId, record); } @Override public boolean containsPreKey(int preKeyId) { - return preKeyStore.containsPreKey(preKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// return preKeyStore.containsPreKey(preKeyId); } @Override public void removePreKey(int preKeyId) { - preKeyStore.removePreKey(preKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// preKeyStore.removePreKey(preKeyId); } @Override @@ -108,26 +112,31 @@ public class SignalProtocolStoreImpl implements SignalProtocolStore { @Override public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException { - return signedPreKeyStore.loadSignedPreKey(signedPreKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// return signedPreKeyStore.loadSignedPreKey(signedPreKeyId); } @Override public List loadSignedPreKeys() { - return signedPreKeyStore.loadSignedPreKeys(); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// return signedPreKeyStore.loadSignedPreKeys(); } @Override public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) { - signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// signedPreKeyStore.storeSignedPreKey(signedPreKeyId, record); } @Override public boolean containsSignedPreKey(int signedPreKeyId) { - return signedPreKeyStore.containsSignedPreKey(signedPreKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// return signedPreKeyStore.containsSignedPreKey(signedPreKeyId); } @Override public void removeSignedPreKey(int signedPreKeyId) { - signedPreKeyStore.removeSignedPreKey(signedPreKeyId); + throw new UnsupportedOperationException("This method will be removed with refactor."); +// signedPreKeyStore.removeSignedPreKey(signedPreKeyId); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java b/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java deleted file mode 100644 index f01690ea67..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/crypto/storage/TextSecurePreKeyStore.java +++ /dev/null @@ -1,90 +0,0 @@ -package org.thoughtcrime.securesms.crypto.storage; - -import android.content.Context; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.session.libsignal.libsignal.InvalidKeyIdException; -import org.session.libsignal.libsignal.state.PreKeyRecord; -import org.session.libsignal.libsignal.state.PreKeyStore; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; -import org.session.libsignal.libsignal.state.SignedPreKeyStore; - -import java.util.List; - -public class TextSecurePreKeyStore implements PreKeyStore, SignedPreKeyStore { - - @SuppressWarnings("unused") - private static final String TAG = TextSecurePreKeyStore.class.getSimpleName(); - - private static final Object FILE_LOCK = new Object(); - - @NonNull - private final Context context; - - public TextSecurePreKeyStore(@NonNull Context context) { - this.context = context; - } - - @Override - public PreKeyRecord loadPreKey(int preKeyId) throws InvalidKeyIdException { - synchronized (FILE_LOCK) { - PreKeyRecord preKeyRecord = DatabaseFactory.getPreKeyDatabase(context).getPreKey(preKeyId); - - if (preKeyRecord == null) throw new InvalidKeyIdException("No such key: " + preKeyId); - else return preKeyRecord; - } - } - - @Override - public SignedPreKeyRecord loadSignedPreKey(int signedPreKeyId) throws InvalidKeyIdException { - synchronized (FILE_LOCK) { - SignedPreKeyRecord signedPreKeyRecord = DatabaseFactory.getSignedPreKeyDatabase(context).getSignedPreKey(signedPreKeyId); - - if (signedPreKeyRecord == null) throw new InvalidKeyIdException("No such signed prekey: " + signedPreKeyId); - else return signedPreKeyRecord; - } - } - - @Override - public List loadSignedPreKeys() { - synchronized (FILE_LOCK) { - return DatabaseFactory.getSignedPreKeyDatabase(context).getAllSignedPreKeys(); - } - } - - @Override - public void storePreKey(int preKeyId, PreKeyRecord record) { - synchronized (FILE_LOCK) { - DatabaseFactory.getPreKeyDatabase(context).insertPreKey(preKeyId, record); - } - } - - @Override - public void storeSignedPreKey(int signedPreKeyId, SignedPreKeyRecord record) { - synchronized (FILE_LOCK) { - DatabaseFactory.getSignedPreKeyDatabase(context).insertSignedPreKey(signedPreKeyId, record); - } - } - - @Override - public boolean containsPreKey(int preKeyId) { - return DatabaseFactory.getPreKeyDatabase(context).getPreKey(preKeyId) != null; - } - - @Override - public boolean containsSignedPreKey(int signedPreKeyId) { - return DatabaseFactory.getSignedPreKeyDatabase(context).getSignedPreKey(signedPreKeyId) != null; - } - - @Override - public void removePreKey(int preKeyId) { - DatabaseFactory.getPreKeyDatabase(context).removePreKey(preKeyId); - } - - @Override - public void removeSignedPreKey(int signedPreKeyId) { - DatabaseFactory.getSignedPreKeyDatabase(context).removeSignedPreKey(signedPreKeyId); - } - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java index 8410017e9d..a90b8e286d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/DatabaseFactory.java @@ -33,8 +33,6 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper; import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase; import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase; import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; -import org.thoughtcrime.securesms.loki.database.LokiPreKeyBundleDatabase; -import org.thoughtcrime.securesms.loki.database.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; import org.thoughtcrime.securesms.loki.database.SharedSenderKeysDatabase; @@ -68,8 +66,8 @@ public class DatabaseFactory { // Loki private final LokiAPIDatabase lokiAPIDatabase; - private final LokiPreKeyRecordDatabase lokiContactPreKeyDatabase; - private final LokiPreKeyBundleDatabase lokiPreKeyBundleDatabase; +// private final LokiPreKeyRecordDatabase lokiContactPreKeyDatabase; +// private final LokiPreKeyBundleDatabase lokiPreKeyBundleDatabase; private final LokiMessageDatabase lokiMessageDatabase; private final LokiThreadDatabase lokiThreadDatabase; private final LokiUserDatabase lokiUserDatabase; @@ -166,13 +164,13 @@ public class DatabaseFactory { return getInstance(context).lokiAPIDatabase; } - public static LokiPreKeyRecordDatabase getLokiPreKeyRecordDatabase(Context context) { - return getInstance(context).lokiContactPreKeyDatabase; - } +// public static LokiPreKeyRecordDatabase getLokiPreKeyRecordDatabase(Context context) { +// return getInstance(context).lokiContactPreKeyDatabase; +// } - public static LokiPreKeyBundleDatabase getLokiPreKeyBundleDatabase(Context context) { - return getInstance(context).lokiPreKeyBundleDatabase; - } +// public static LokiPreKeyBundleDatabase getLokiPreKeyBundleDatabase(Context context) { +// return getInstance(context).lokiPreKeyBundleDatabase; +// } public static LokiMessageDatabase getLokiMessageDatabase(Context context) { return getInstance(context).lokiMessageDatabase; @@ -226,8 +224,8 @@ public class DatabaseFactory { this.jobDatabase = new JobDatabase(context, databaseHelper); this.stickerDatabase = new StickerDatabase(context, databaseHelper, attachmentSecret); this.lokiAPIDatabase = new LokiAPIDatabase(context, databaseHelper); - this.lokiContactPreKeyDatabase = new LokiPreKeyRecordDatabase(context, databaseHelper); - this.lokiPreKeyBundleDatabase = new LokiPreKeyBundleDatabase(context, databaseHelper); +// this.lokiContactPreKeyDatabase = new LokiPreKeyRecordDatabase(context, databaseHelper); +// this.lokiPreKeyBundleDatabase = new LokiPreKeyBundleDatabase(context, databaseHelper); this.lokiMessageDatabase = new LokiMessageDatabase(context, databaseHelper); this.lokiThreadDatabase = new LokiThreadDatabase(context, databaseHelper); this.lokiUserDatabase = new LokiUserDatabase(context, databaseHelper); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java deleted file mode 100644 index ca4b0b68ed..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/PreKeyMigrationHelper.java +++ /dev/null @@ -1,225 +0,0 @@ -package org.thoughtcrime.securesms.database.helpers; - - -import android.content.ContentValues; -import android.content.Context; -import androidx.annotation.NonNull; - -import com.fasterxml.jackson.annotation.JsonProperty; - -import net.sqlcipher.database.SQLiteDatabase; - -import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase; -import org.thoughtcrime.securesms.database.SignedPreKeyDatabase; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.Base64; -import org.thoughtcrime.securesms.util.Conversions; -import org.thoughtcrime.securesms.util.JsonUtils; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.InvalidMessageException; -import org.session.libsignal.libsignal.state.PreKeyRecord; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; - -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStreamReader; - -class PreKeyMigrationHelper { - - private static final String PREKEY_DIRECTORY = "prekeys"; - private static final String SIGNED_PREKEY_DIRECTORY = "signed_prekeys"; - - private static final int PLAINTEXT_VERSION = 2; - private static final int CURRENT_VERSION_MARKER = 2; - - private static final String TAG = PreKeyMigrationHelper.class.getSimpleName(); - - static boolean migratePreKeys(Context context, SQLiteDatabase database) { - File[] preKeyFiles = getPreKeyDirectory(context).listFiles(); - boolean clean = true; - - if (preKeyFiles != null) { - for (File preKeyFile : preKeyFiles) { - if (!"index.dat".equals(preKeyFile.getName())) { - try { - PreKeyRecord preKey = new PreKeyRecord(loadSerializedRecord(preKeyFile)); - - ContentValues contentValues = new ContentValues(); - contentValues.put(OneTimePreKeyDatabase.KEY_ID, preKey.getId()); - contentValues.put(OneTimePreKeyDatabase.PUBLIC_KEY, Base64.encodeBytes(preKey.getKeyPair().getPublicKey().serialize())); - contentValues.put(OneTimePreKeyDatabase.PRIVATE_KEY, Base64.encodeBytes(preKey.getKeyPair().getPrivateKey().serialize())); - database.insert(OneTimePreKeyDatabase.TABLE_NAME, null, contentValues); - Log.i(TAG, "Migrated one-time prekey: " + preKey.getId()); - } catch (IOException | InvalidMessageException e) { - Log.w(TAG, e); - clean = false; - } - } - } - } - - File[] signedPreKeyFiles = getSignedPreKeyDirectory(context).listFiles(); - - if (signedPreKeyFiles != null) { - for (File signedPreKeyFile : signedPreKeyFiles) { - if (!"index.dat".equals(signedPreKeyFile.getName())) { - try { - SignedPreKeyRecord signedPreKey = new SignedPreKeyRecord(loadSerializedRecord(signedPreKeyFile)); - - ContentValues contentValues = new ContentValues(); - contentValues.put(SignedPreKeyDatabase.KEY_ID, signedPreKey.getId()); - contentValues.put(SignedPreKeyDatabase.PUBLIC_KEY, Base64.encodeBytes(signedPreKey.getKeyPair().getPublicKey().serialize())); - contentValues.put(SignedPreKeyDatabase.PRIVATE_KEY, Base64.encodeBytes(signedPreKey.getKeyPair().getPrivateKey().serialize())); - contentValues.put(SignedPreKeyDatabase.SIGNATURE, Base64.encodeBytes(signedPreKey.getSignature())); - contentValues.put(SignedPreKeyDatabase.TIMESTAMP, signedPreKey.getTimestamp()); - database.insert(SignedPreKeyDatabase.TABLE_NAME, null, contentValues); - Log.i(TAG, "Migrated signed prekey: " + signedPreKey.getId()); - } catch (IOException | InvalidMessageException e) { - Log.w(TAG, e); - clean = false; - } - } - } - } - - File oneTimePreKeyIndex = new File(getPreKeyDirectory(context), PreKeyIndex.FILE_NAME); - File signedPreKeyIndex = new File(getSignedPreKeyDirectory(context), SignedPreKeyIndex.FILE_NAME); - - if (oneTimePreKeyIndex.exists()) { - try { - InputStreamReader reader = new InputStreamReader(new FileInputStream(oneTimePreKeyIndex)); - PreKeyIndex index = JsonUtils.fromJson(reader, PreKeyIndex.class); - reader.close(); - - Log.i(TAG, "Setting next prekey id: " + index.nextPreKeyId); - TextSecurePreferences.setNextPreKeyId(context, index.nextPreKeyId); - } catch (IOException e) { - Log.w(TAG, e); - } - } - - if (signedPreKeyIndex.exists()) { - try { - InputStreamReader reader = new InputStreamReader(new FileInputStream(signedPreKeyIndex)); - SignedPreKeyIndex index = JsonUtils.fromJson(reader, SignedPreKeyIndex.class); - reader.close(); - - Log.i(TAG, "Setting next signed prekey id: " + index.nextSignedPreKeyId); - Log.i(TAG, "Setting active signed prekey id: " + index.activeSignedPreKeyId); - TextSecurePreferences.setNextSignedPreKeyId(context, index.nextSignedPreKeyId); - TextSecurePreferences.setActiveSignedPreKeyId(context, index.activeSignedPreKeyId); - } catch (IOException e) { - Log.w(TAG, e); - } - } - - return clean; - } - - static void cleanUpPreKeys(@NonNull Context context) { - File preKeyDirectory = getPreKeyDirectory(context); - File[] preKeyFiles = preKeyDirectory.listFiles(); - - if (preKeyFiles != null) { - for (File preKeyFile : preKeyFiles) { - Log.i(TAG, "Deleting: " + preKeyFile.getAbsolutePath()); - preKeyFile.delete(); - } - - Log.i(TAG, "Deleting: " + preKeyDirectory.getAbsolutePath()); - preKeyDirectory.delete(); - } - - File signedPreKeyDirectory = getSignedPreKeyDirectory(context); - File[] signedPreKeyFiles = signedPreKeyDirectory.listFiles(); - - if (signedPreKeyFiles != null) { - for (File signedPreKeyFile : signedPreKeyFiles) { - Log.i(TAG, "Deleting: " + signedPreKeyFile.getAbsolutePath()); - signedPreKeyFile.delete(); - } - - Log.i(TAG, "Deleting: " + signedPreKeyDirectory.getAbsolutePath()); - signedPreKeyDirectory.delete(); - } - } - - private static byte[] loadSerializedRecord(File recordFile) - throws IOException, InvalidMessageException - { - FileInputStream fin = new FileInputStream(recordFile); - int recordVersion = readInteger(fin); - - if (recordVersion > CURRENT_VERSION_MARKER) { - throw new IOException("Invalid version: " + recordVersion); - } - - byte[] serializedRecord = readBlob(fin); - - if (recordVersion < PLAINTEXT_VERSION) { - throw new IOException("Migration didn't happen! " + recordFile.getAbsolutePath() + ", " + recordVersion); - } - - fin.close(); - return serializedRecord; - } - - private static File getPreKeyDirectory(Context context) { - return getRecordsDirectory(context, PREKEY_DIRECTORY); - } - - private static File getSignedPreKeyDirectory(Context context) { - return getRecordsDirectory(context, SIGNED_PREKEY_DIRECTORY); - } - - private static File getRecordsDirectory(Context context, String directoryName) { - File directory = new File(context.getFilesDir(), directoryName); - - if (!directory.exists()) { - if (!directory.mkdirs()) { - Log.w(TAG, "PreKey directory creation failed!"); - } - } - - return directory; - } - - private static byte[] readBlob(FileInputStream in) throws IOException { - int length = readInteger(in); - byte[] blobBytes = new byte[length]; - - in.read(blobBytes, 0, blobBytes.length); - return blobBytes; - } - - private static int readInteger(FileInputStream in) throws IOException { - byte[] integer = new byte[4]; - in.read(integer, 0, integer.length); - return Conversions.byteArrayToInt(integer); - } - - private static class PreKeyIndex { - static final String FILE_NAME = "index.dat"; - - @JsonProperty - private int nextPreKeyId; - - public PreKeyIndex() {} - } - - private static class SignedPreKeyIndex { - static final String FILE_NAME = "index.dat"; - - @JsonProperty - private int nextSignedPreKeyId; - - @JsonProperty - private int activeSignedPreKeyId = -1; - - public SignedPreKeyIndex() {} - - } - - -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java index 0c313e71ab..bf8a31b0b4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/helpers/SQLCipherOpenHelper.java @@ -14,7 +14,7 @@ import net.sqlcipher.database.SQLiteDatabase; import net.sqlcipher.database.SQLiteDatabaseHook; import net.sqlcipher.database.SQLiteOpenHelper; -import org.thoughtcrime.securesms.ApplicationContext; +import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.thoughtcrime.securesms.crypto.DatabaseSecret; import org.thoughtcrime.securesms.crypto.MasterSecret; import org.thoughtcrime.securesms.database.Address; @@ -24,7 +24,6 @@ import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.GroupReceiptDatabase; import org.thoughtcrime.securesms.database.IdentityDatabase; import org.thoughtcrime.securesms.database.JobDatabase; -import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.OneTimePreKeyDatabase; import org.thoughtcrime.securesms.database.PushDatabase; @@ -35,12 +34,10 @@ import org.thoughtcrime.securesms.database.SignedPreKeyDatabase; import org.thoughtcrime.securesms.database.SmsDatabase; import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.ThreadDatabase; -import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase; +import org.thoughtcrime.securesms.loki.database.LokiBackupFilesDatabase; import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; -import org.thoughtcrime.securesms.loki.database.LokiPreKeyBundleDatabase; -import org.thoughtcrime.securesms.loki.database.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; import org.thoughtcrime.securesms.loki.database.SharedSenderKeysDatabase; @@ -48,10 +45,8 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.GroupUtil; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import java.io.File; -import java.util.Arrays; public class SQLCipherOpenHelper extends SQLiteOpenHelper { @@ -161,8 +156,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { db.execSQL(LokiAPIDatabase.getCreateSessionRequestProcessedTimestampTableCommand()); db.execSQL(LokiAPIDatabase.getCreateOpenGroupPublicKeyTableCommand()); db.execSQL(LokiAPIDatabase.getCreateOpenGroupProfilePictureTableCommand()); - db.execSQL(LokiPreKeyBundleDatabase.getCreateTableCommand()); - db.execSQL(LokiPreKeyRecordDatabase.getCreateTableCommand()); db.execSQL(LokiMessageDatabase.getCreateMessageIDTableCommand()); db.execSQL(LokiMessageDatabase.getCreateMessageToThreadMappingTableCommand()); db.execSQL(LokiMessageDatabase.getCreateErrorMessageTableCommand()); @@ -195,12 +188,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { if (masterSecret != null) SQLCipherMigrationHelper.migrateCiphertext(context, masterSecret, legacyDb, db, null); else TextSecurePreferences.setNeedsSqlCipherMigration(context, true); - if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { - ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob()); - } - SessionStoreMigrationHelper.migrateSessions(context, db); - PreKeyMigrationHelper.cleanUpPreKeys(context); } } @@ -229,10 +217,6 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { if (oldVersion < MIGRATE_PREKEYS_VERSION) { db.execSQL("CREATE TABLE signed_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL, signature TEXT NOT NULL, timestamp INTEGER DEFAULT 0)"); db.execSQL("CREATE TABLE one_time_prekeys (_id INTEGER PRIMARY KEY, key_id INTEGER UNIQUE, public_key TEXT NOT NULL, private_key TEXT NOT NULL)"); - - if (!PreKeyMigrationHelper.migratePreKeys(context, db)) { - ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob()); - } } if (oldVersion < MIGRATE_SESSIONS_VERSION) { @@ -671,7 +655,7 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { } if (oldVersion < MIGRATE_PREKEYS_VERSION) { - PreKeyMigrationHelper.cleanUpPreKeys(context); +// PreKeyMigrationHelper.cleanUpPreKeys(context); } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AxolotlStorageModule.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AxolotlStorageModule.java deleted file mode 100644 index 97f0a6ffe7..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AxolotlStorageModule.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.thoughtcrime.securesms.dependencies; - -import android.content.Context; - -import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; -import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; -import org.session.libsignal.libsignal.state.SignedPreKeyStore; - -import dagger.Module; -import dagger.Provides; - -@Module (complete = false, injects = {CleanPreKeysJob.class}) -public class AxolotlStorageModule { - - private final Context context; - - public AxolotlStorageModule(Context context) { - this.context = context; - } - - @Provides SignedPreKeyStoreFactory provideSignedPreKeyStoreFactory() { - return new SignedPreKeyStoreFactory() { - @Override - public SignedPreKeyStore create() { - return new SignalProtocolStoreImpl(context); - } - }; - } - - public static interface SignedPreKeyStoreFactory { - public SignedPreKeyStore create(); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java index 6d9ac6f0dc..bc20a89a76 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java @@ -16,17 +16,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; import org.thoughtcrime.securesms.jobs.AttachmentUploadJob; import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; -import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; -import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackOperationJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackSyncJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceVerifiedUpdateJob; import org.thoughtcrime.securesms.jobs.PushDecryptJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; import org.thoughtcrime.securesms.jobs.PushGroupUpdateJob; @@ -34,14 +23,12 @@ import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob; import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; -import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob; import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; import org.thoughtcrime.securesms.jobs.RotateCertificateJob; import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob; -import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob; import org.thoughtcrime.securesms.jobs.SendReadReceiptJob; import org.thoughtcrime.securesms.jobs.StickerDownloadJob; @@ -50,7 +37,6 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation; -import org.thoughtcrime.securesms.loki.protocol.shelved.MultiDeviceOpenGroupUpdateJob; import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; import org.thoughtcrime.securesms.push.MessageSenderEventListener; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; @@ -64,34 +50,23 @@ import dagger.Module; import dagger.Provides; import network.loki.messenger.BuildConfig; -@Module(complete = false, injects = {CleanPreKeysJob.class, - CreateSignedPreKeyJob.class, - PushGroupSendJob.class, +@Module(complete = false, injects = {PushGroupSendJob.class, PushTextSendJob.class, PushMediaSendJob.class, AttachmentDownloadJob.class, - RefreshPreKeysJob.class, IncomingMessageObserver.class, PushNotificationReceiveJob.class, - MultiDeviceContactUpdateJob.class, - MultiDeviceGroupUpdateJob.class, - MultiDeviceReadUpdateJob.class, - MultiDeviceBlockedUpdateJob.class, RefreshAttributesJob.class, RequestGroupInfoJob.class, PushGroupUpdateJob.class, AvatarDownloadJob.class, - RotateSignedPreKeyJob.class, RetrieveProfileJob.class, - MultiDeviceVerifiedUpdateJob.class, RetrieveProfileAvatarJob.class, - MultiDeviceProfileKeyUpdateJob.class, SendReadReceiptJob.class, AppProtectionPreferenceFragment.class, RotateCertificateJob.class, SendDeliveryReceiptJob.class, RotateProfileKeyJob.class, - MultiDeviceConfigurationUpdateJob.class, RefreshUnidentifiedDeliveryAbilityJob.class, TypingSendJob.class, AttachmentUploadJob.class, @@ -100,10 +75,7 @@ import network.loki.messenger.BuildConfig; StickerPackPreviewRepository.class, StickerRemoteUriLoader.Factory.class, StickerPackDownloadJob.class, - MultiDeviceStickerPackOperationJob.class, - MultiDeviceStickerPackSyncJob.class, - LinkPreviewRepository.class, - MultiDeviceOpenGroupUpdateJob.class}) + LinkPreviewRepository.class}) public class SignalCommunicationModule { @@ -149,7 +121,8 @@ public class SignalCommunicationModule { DatabaseFactory.getSSKDatabase(context), DatabaseFactory.getLokiThreadDatabase(context), DatabaseFactory.getLokiMessageDatabase(context), - DatabaseFactory.getLokiPreKeyBundleDatabase(context), +// DatabaseFactory.getLokiPreKeyBundleDatabase(context), + null, new SessionResetImplementation(context), DatabaseFactory.getLokiUserDatabase(context), DatabaseFactory.getGroupDatabase(context), diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java index df9459cc8d..22d860a1a3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobmanager/migration/WorkManagerFactoryMappings.java @@ -6,19 +6,10 @@ import androidx.annotation.Nullable; import org.thoughtcrime.securesms.jobs.AttachmentDownloadJob; import org.thoughtcrime.securesms.jobs.AttachmentUploadJob; import org.thoughtcrime.securesms.jobs.AvatarDownloadJob; -import org.thoughtcrime.securesms.jobs.CleanPreKeysJob; -import org.thoughtcrime.securesms.jobs.CreateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.LocalBackupJob; import org.thoughtcrime.securesms.jobs.MmsDownloadJob; import org.thoughtcrime.securesms.jobs.MmsReceiveJob; import org.thoughtcrime.securesms.jobs.MmsSendJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceProfileKeyUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; -import org.thoughtcrime.securesms.jobs.MultiDeviceVerifiedUpdateJob; import org.thoughtcrime.securesms.jobs.PushContentReceiveJob; import org.thoughtcrime.securesms.jobs.PushDecryptJob; import org.thoughtcrime.securesms.jobs.PushGroupSendJob; @@ -27,14 +18,12 @@ import org.thoughtcrime.securesms.jobs.PushMediaSendJob; import org.thoughtcrime.securesms.jobs.PushNotificationReceiveJob; import org.thoughtcrime.securesms.jobs.PushTextSendJob; import org.thoughtcrime.securesms.jobs.RefreshAttributesJob; -import org.thoughtcrime.securesms.jobs.RefreshPreKeysJob; import org.thoughtcrime.securesms.jobs.RefreshUnidentifiedDeliveryAbilityJob; import org.thoughtcrime.securesms.jobs.RequestGroupInfoJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob; import org.thoughtcrime.securesms.jobs.RetrieveProfileJob; import org.thoughtcrime.securesms.jobs.RotateCertificateJob; import org.thoughtcrime.securesms.jobs.RotateProfileKeyJob; -import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob; import org.thoughtcrime.securesms.jobs.SendDeliveryReceiptJob; import org.thoughtcrime.securesms.jobs.SendReadReceiptJob; import org.thoughtcrime.securesms.jobs.SmsReceiveJob; @@ -48,7 +37,6 @@ import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJob; import org.thoughtcrime.securesms.loki.protocol.NullMessageSendJob; import org.thoughtcrime.securesms.loki.protocol.SessionRequestMessageSendJob; -import org.thoughtcrime.securesms.loki.protocol.shelved.MultiDeviceOpenGroupUpdateJob; import java.util.HashMap; import java.util.Map; @@ -59,21 +47,11 @@ public class WorkManagerFactoryMappings { put(AttachmentDownloadJob.class.getName(), AttachmentDownloadJob.KEY); put(AttachmentUploadJob.class.getName(), AttachmentUploadJob.KEY); put(AvatarDownloadJob.class.getName(), AvatarDownloadJob.KEY); - put(CleanPreKeysJob.class.getName(), CleanPreKeysJob.KEY); put(ClosedGroupUpdateMessageSendJob.class.getName(), ClosedGroupUpdateMessageSendJob.KEY); - put(CreateSignedPreKeyJob.class.getName(), CreateSignedPreKeyJob.KEY); put(LocalBackupJob.class.getName(), LocalBackupJob.KEY); put(MmsDownloadJob.class.getName(), MmsDownloadJob.KEY); put(MmsReceiveJob.class.getName(), MmsReceiveJob.KEY); put(MmsSendJob.class.getName(), MmsSendJob.KEY); - put(MultiDeviceBlockedUpdateJob.class.getName(), MultiDeviceBlockedUpdateJob.KEY); - put(MultiDeviceConfigurationUpdateJob.class.getName(), MultiDeviceConfigurationUpdateJob.KEY); - put(MultiDeviceContactUpdateJob.class.getName(), MultiDeviceContactUpdateJob.KEY); - put(MultiDeviceGroupUpdateJob.class.getName(), MultiDeviceGroupUpdateJob.KEY); - put(MultiDeviceProfileKeyUpdateJob.class.getName(), MultiDeviceProfileKeyUpdateJob.KEY); - put(MultiDeviceOpenGroupUpdateJob.class.getName(), MultiDeviceOpenGroupUpdateJob.KEY); - put(MultiDeviceReadUpdateJob.class.getName(), MultiDeviceReadUpdateJob.KEY); - put(MultiDeviceVerifiedUpdateJob.class.getName(), MultiDeviceVerifiedUpdateJob.KEY); put(NullMessageSendJob.class.getName(), NullMessageSendJob.KEY); put(PushContentReceiveJob.class.getName(), PushContentReceiveJob.KEY); put(PushDecryptJob.class.getName(), PushDecryptJob.KEY); @@ -83,14 +61,12 @@ public class WorkManagerFactoryMappings { put(PushNotificationReceiveJob.class.getName(), PushNotificationReceiveJob.KEY); put(PushTextSendJob.class.getName(), PushTextSendJob.KEY); put(RefreshAttributesJob.class.getName(), RefreshAttributesJob.KEY); - put(RefreshPreKeysJob.class.getName(), RefreshPreKeysJob.KEY); put(RefreshUnidentifiedDeliveryAbilityJob.class.getName(), RefreshUnidentifiedDeliveryAbilityJob.KEY); put(RequestGroupInfoJob.class.getName(), RequestGroupInfoJob.KEY); put(RetrieveProfileAvatarJob.class.getName(), RetrieveProfileAvatarJob.KEY); put(RetrieveProfileJob.class.getName(), RetrieveProfileJob.KEY); put(RotateCertificateJob.class.getName(), RotateCertificateJob.KEY); put(RotateProfileKeyJob.class.getName(), RotateProfileKeyJob.KEY); - put(RotateSignedPreKeyJob.class.getName(), RotateSignedPreKeyJob.KEY); put(SendDeliveryReceiptJob.class.getName(), SendDeliveryReceiptJob.KEY); put(SendReadReceiptJob.class.getName(), SendReadReceiptJob.KEY); put(SessionRequestMessageSendJob.class.getName(), SessionRequestMessageSendJob.KEY); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java deleted file mode 100644 index eff59668fb..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CleanPreKeysJob.java +++ /dev/null @@ -1,141 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.logging.Log; - -import org.thoughtcrime.securesms.crypto.PreKeyUtil; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.session.libsignal.libsignal.InvalidKeyIdException; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; -import org.session.libsignal.libsignal.state.SignedPreKeyStore; -import org.session.libsignal.service.api.SignalServiceAccountManager; -import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; -import java.util.Collections; -import java.util.Comparator; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -import static org.thoughtcrime.securesms.dependencies.AxolotlStorageModule.SignedPreKeyStoreFactory; - -public class CleanPreKeysJob extends BaseJob implements InjectableType { - - public static final String KEY = "CleanPreKeysJob"; - - private static final String TAG = CleanPreKeysJob.class.getSimpleName(); - - private static final long ARCHIVE_AGE = TimeUnit.DAYS.toMillis(7); - - @Inject SignalServiceAccountManager accountManager; - @Inject SignedPreKeyStoreFactory signedPreKeyStoreFactory; - - public CleanPreKeysJob() { - this(new Job.Parameters.Builder() - .setQueue("CleanPreKeysJob") - .setMaxAttempts(3) - .build()); - } - - private CleanPreKeysJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException { - try { - Log.i(TAG, "Cleaning prekeys..."); - - int activeSignedPreKeyId = PreKeyUtil.getActiveSignedPreKeyId(context); - SignedPreKeyStore signedPreKeyStore = signedPreKeyStoreFactory.create(); - - if (activeSignedPreKeyId < 0) return; - - SignedPreKeyRecord currentRecord = signedPreKeyStore.loadSignedPreKey(activeSignedPreKeyId); - List allRecords = signedPreKeyStore.loadSignedPreKeys(); - LinkedList oldRecords = removeRecordFrom(currentRecord, allRecords); - - Collections.sort(oldRecords, new SignedPreKeySorter()); - - Log.i(TAG, "Active signed prekey: " + activeSignedPreKeyId); - Log.i(TAG, "Old signed prekey record count: " + oldRecords.size()); - - boolean foundAgedRecord = false; - - for (SignedPreKeyRecord oldRecord : oldRecords) { - long archiveDuration = System.currentTimeMillis() - oldRecord.getTimestamp(); - - if (archiveDuration >= ARCHIVE_AGE) { - if (!foundAgedRecord) { - foundAgedRecord = true; - } else { - Log.i(TAG, "Removing signed prekey record: " + oldRecord.getId() + " with timestamp: " + oldRecord.getTimestamp()); - signedPreKeyStore.removeSignedPreKey(oldRecord.getId()); - } - } - } - } catch (InvalidKeyIdException e) { - Log.w(TAG, e); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception throwable) { - if (throwable instanceof NonSuccessfulResponseCodeException) return false; - if (throwable instanceof PushNetworkException) return true; - return false; - } - - @Override - public void onCanceled() { - Log.w(TAG, "Failed to execute clean signed prekeys task."); - } - - private LinkedList removeRecordFrom(SignedPreKeyRecord currentRecord, - List records) - - { - LinkedList others = new LinkedList<>(); - - for (SignedPreKeyRecord record : records) { - if (record.getId() != currentRecord.getId()) { - others.add(record); - } - } - - return others; - } - - private static class SignedPreKeySorter implements Comparator { - @Override - public int compare(SignedPreKeyRecord lhs, SignedPreKeyRecord rhs) { - if (lhs.getTimestamp() > rhs.getTimestamp()) return -1; - else if (lhs.getTimestamp() < rhs.getTimestamp()) return 1; - else return 0; - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull CleanPreKeysJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new CleanPreKeysJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java deleted file mode 100644 index 341e0ddab2..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/CreateSignedPreKeyJob.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.content.Context; -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.crypto.PreKeyUtil; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.IdentityKeyPair; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; -import org.session.libsignal.service.api.SignalServiceAccountManager; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; - -import javax.inject.Inject; - - -public class CreateSignedPreKeyJob extends BaseJob implements InjectableType { - - public static final String KEY = "CreateSignedPreKeyJob"; - - private static final String TAG = CreateSignedPreKeyJob.class.getSimpleName(); - - @Inject SignalServiceAccountManager accountManager; - - public CreateSignedPreKeyJob(Context context) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("CreateSignedPreKeyJob") - .setMaxAttempts(25) - .build()); - } - - private CreateSignedPreKeyJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException { - if (TextSecurePreferences.isSignedPreKeyRegistered(context)) { - Log.w(TAG, "Signed prekey already registered..."); - return; - } - - if (!TextSecurePreferences.isPushRegistered(context)) { - Log.w(TAG, "Not yet registered..."); - return; - } - - IdentityKeyPair identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context); - SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true); - - accountManager.setSignedPreKey(signedPreKeyRecord); - TextSecurePreferences.setSignedPreKeyRegistered(context, true); - } - - @Override - public void onCanceled() {} - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof PushNetworkException) return true; - return false; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull CreateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new CreateSignedPreKeyJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java index 4af3c467b2..17f8dc8e7e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -19,7 +19,6 @@ import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJob; import org.thoughtcrime.securesms.loki.protocol.NullMessageSendJob; import org.thoughtcrime.securesms.loki.protocol.SessionRequestMessageSendJob; -import org.thoughtcrime.securesms.loki.protocol.shelved.MultiDeviceOpenGroupUpdateJob; import java.util.Arrays; import java.util.HashMap; @@ -33,23 +32,11 @@ public final class JobManagerFactories { put(AttachmentDownloadJob.KEY, new AttachmentDownloadJob.Factory()); put(AttachmentUploadJob.KEY, new AttachmentUploadJob.Factory()); put(AvatarDownloadJob.KEY, new AvatarDownloadJob.Factory()); - put(CleanPreKeysJob.KEY, new CleanPreKeysJob.Factory()); put(ClosedGroupUpdateMessageSendJob.KEY, new ClosedGroupUpdateMessageSendJob.Factory()); - put(CreateSignedPreKeyJob.KEY, new CreateSignedPreKeyJob.Factory()); put(LocalBackupJob.KEY, new LocalBackupJob.Factory()); put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory()); put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory()); put(MmsSendJob.KEY, new MmsSendJob.Factory()); - put(MultiDeviceBlockedUpdateJob.KEY, new MultiDeviceBlockedUpdateJob.Factory()); - put(MultiDeviceConfigurationUpdateJob.KEY, new MultiDeviceConfigurationUpdateJob.Factory()); - put(MultiDeviceContactUpdateJob.KEY, new MultiDeviceContactUpdateJob.Factory()); - put(MultiDeviceGroupUpdateJob.KEY, new MultiDeviceGroupUpdateJob.Factory()); - put(MultiDeviceOpenGroupUpdateJob.KEY, new MultiDeviceOpenGroupUpdateJob.Factory()); - put(MultiDeviceProfileKeyUpdateJob.KEY, new MultiDeviceProfileKeyUpdateJob.Factory()); - put(MultiDeviceReadUpdateJob.KEY, new MultiDeviceReadUpdateJob.Factory()); - put(MultiDeviceStickerPackOperationJob.KEY, new MultiDeviceStickerPackOperationJob.Factory()); - put(MultiDeviceStickerPackSyncJob.KEY, new MultiDeviceStickerPackSyncJob.Factory()); - put(MultiDeviceVerifiedUpdateJob.KEY, new MultiDeviceVerifiedUpdateJob.Factory()); put(NullMessageSendJob.KEY, new NullMessageSendJob.Factory()); put(PushContentReceiveJob.KEY, new PushContentReceiveJob.Factory()); put(PushDecryptJob.KEY, new PushDecryptJob.Factory()); @@ -59,14 +46,12 @@ public final class JobManagerFactories { put(PushNotificationReceiveJob.KEY, new PushNotificationReceiveJob.Factory()); put(PushTextSendJob.KEY, new PushTextSendJob.Factory()); put(RefreshAttributesJob.KEY, new RefreshAttributesJob.Factory()); - put(RefreshPreKeysJob.KEY, new RefreshPreKeysJob.Factory()); put(RefreshUnidentifiedDeliveryAbilityJob.KEY, new RefreshUnidentifiedDeliveryAbilityJob.Factory()); put(RequestGroupInfoJob.KEY, new RequestGroupInfoJob.Factory()); put(RetrieveProfileAvatarJob.KEY, new RetrieveProfileAvatarJob.Factory(application)); put(RetrieveProfileJob.KEY, new RetrieveProfileJob.Factory(application)); put(RotateCertificateJob.KEY, new RotateCertificateJob.Factory()); put(RotateProfileKeyJob.KEY, new RotateProfileKeyJob.Factory()); - put(RotateSignedPreKeyJob.KEY, new RotateSignedPreKeyJob.Factory()); put(SendDeliveryReceiptJob.KEY, new SendDeliveryReceiptJob.Factory()); put(SendReadReceiptJob.KEY, new SendReadReceiptJob.Factory()); put(SessionRequestMessageSendJob.KEY, new SessionRequestMessageSendJob.Factory()); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java deleted file mode 100644 index 379dacfa11..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceBlockedUpdateJob.java +++ /dev/null @@ -1,108 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.RecipientDatabase; -import org.thoughtcrime.securesms.database.RecipientDatabase.RecipientReader; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.multidevice.BlockedListMessage; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceBlockedUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceBlockedUpdateJob"; - - @SuppressWarnings("unused") - private static final String TAG = MultiDeviceBlockedUpdateJob.class.getSimpleName(); - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceBlockedUpdateJob() { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("MultiDeviceBlockedUpdateJob") - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build()); - } - - private MultiDeviceBlockedUpdateJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() - throws IOException, UntrustedIdentityException - { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - RecipientDatabase database = DatabaseFactory.getRecipientDatabase(context); - - try (RecipientReader reader = database.readerForBlocked(database.getBlocked())) { - List blockedIndividuals = new LinkedList<>(); - List blockedGroups = new LinkedList<>(); - - Recipient recipient; - - while ((recipient = reader.getNext()) != null) { - if (recipient.isGroupRecipient()) { - blockedGroups.add(GroupUtil.getDecodedId(recipient.getAddress().toGroupString())); - } else { - blockedIndividuals.add(recipient.getAddress().serialize()); - } - } - - messageSender.sendMessage(SignalServiceSyncMessage.forBlocked(new BlockedListMessage(blockedIndividuals, blockedGroups)), - UnidentifiedAccessUtil.getAccessForSync(context)); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof PushNetworkException) return true; - return false; - } - - @Override - public void onCanceled() { - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceBlockedUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceBlockedUpdateJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceConfigurationUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceConfigurationUpdateJob.java deleted file mode 100644 index d979914b78..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceConfigurationUpdateJob.java +++ /dev/null @@ -1,121 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.multidevice.ConfigurationMessage; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; - -import javax.inject.Inject; - -public class MultiDeviceConfigurationUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceConfigurationUpdateJob"; - - private static final String TAG = MultiDeviceConfigurationUpdateJob.class.getSimpleName(); - - private static final String KEY_READ_RECEIPTS_ENABLED = "read_receipts_enabled"; - private static final String KEY_TYPING_INDICATORS_ENABLED = "typing_indicators_enabled"; - private static final String KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED = "unidentified_delivery_indicators_enabled"; - private static final String KEY_LINK_PREVIEWS_ENABLED = "link_previews_enabled"; - - @Inject SignalServiceMessageSender messageSender; - - private boolean readReceiptsEnabled; - private boolean typingIndicatorsEnabled; - private boolean unidentifiedDeliveryIndicatorsEnabled; - private boolean linkPreviewsEnabled; - - public MultiDeviceConfigurationUpdateJob(boolean readReceiptsEnabled, - boolean typingIndicatorsEnabled, - boolean unidentifiedDeliveryIndicatorsEnabled, - boolean linkPreviewsEnabled) - { - this(new Job.Parameters.Builder() - .setQueue("__MULTI_DEVICE_CONFIGURATION_UPDATE_JOB__") - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(10) - .build(), - readReceiptsEnabled, - typingIndicatorsEnabled, - unidentifiedDeliveryIndicatorsEnabled, - linkPreviewsEnabled); - - } - - private MultiDeviceConfigurationUpdateJob(@NonNull Job.Parameters parameters, - boolean readReceiptsEnabled, - boolean typingIndicatorsEnabled, - boolean unidentifiedDeliveryIndicatorsEnabled, - boolean linkPreviewsEnabled) - { - super(parameters); - - this.readReceiptsEnabled = readReceiptsEnabled; - this.typingIndicatorsEnabled = typingIndicatorsEnabled; - this.unidentifiedDeliveryIndicatorsEnabled = unidentifiedDeliveryIndicatorsEnabled; - this.linkPreviewsEnabled = linkPreviewsEnabled; - } - - @Override - public @NonNull Data serialize() { - return new Data.Builder().putBoolean(KEY_READ_RECEIPTS_ENABLED, readReceiptsEnabled) - .putBoolean(KEY_TYPING_INDICATORS_ENABLED, typingIndicatorsEnabled) - .putBoolean(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED, unidentifiedDeliveryIndicatorsEnabled) - .putBoolean(KEY_LINK_PREVIEWS_ENABLED, linkPreviewsEnabled) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException, UntrustedIdentityException { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - messageSender.sendMessage(SignalServiceSyncMessage.forConfiguration(new ConfigurationMessage(Optional.of(readReceiptsEnabled), - Optional.of(unidentifiedDeliveryIndicatorsEnabled), - Optional.of(typingIndicatorsEnabled), - Optional.of(linkPreviewsEnabled))), - UnidentifiedAccessUtil.getAccessForSync(context)); - } - - @Override - public boolean onShouldRetry(@NonNull Exception e) { - return e instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - Log.w(TAG, "**** Failed to synchronize read receipts state!"); - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceConfigurationUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceConfigurationUpdateJob(parameters, - data.getBooleanOrDefault(KEY_READ_RECEIPTS_ENABLED, false), - data.getBooleanOrDefault(KEY_TYPING_INDICATORS_ENABLED, false), - data.getBooleanOrDefault(KEY_UNIDENTIFIED_DELIVERY_INDICATORS_ENABLED, false), - data.getBooleanOrDefault(KEY_LINK_PREVIEWS_ENABLED, false)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java deleted file mode 100644 index 619916f8e0..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceContactUpdateJob.java +++ /dev/null @@ -1,352 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import android.content.Context; -import android.net.Uri; -import android.provider.ContactsContract; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData; -import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.IdentityDatabase; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.loki.protocol.shelved.SyncMessagesProtocol; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.IdentityKey; -import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.SignalServiceAttachment; -import org.session.libsignal.service.api.messages.SignalServiceAttachmentStream; -import org.session.libsignal.service.api.messages.multidevice.ContactsMessage; -import org.session.libsignal.service.api.messages.multidevice.DeviceContact; -import org.session.libsignal.service.api.messages.multidevice.DeviceContactsOutputStream; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; -import org.session.libsignal.service.api.messages.multidevice.VerifiedMessage; -import org.session.libsignal.service.api.util.InvalidNumberException; -import org.session.libsignal.service.loki.utilities.PublicKeyValidation; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceContactUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceContactUpdateJob"; - - private static final String TAG = MultiDeviceContactUpdateJob.class.getSimpleName(); - - private static final long FULL_SYNC_TIME = TimeUnit.HOURS.toMillis(6); - - private static final String KEY_ADDRESS = "address"; - private static final String KEY_FORCE_SYNC = "force_sync"; - - @Inject SignalServiceMessageSender messageSender; - - private @Nullable String address; - - private boolean forceSync; - - /** - * Create a full contact sync job that syncs to all linked devices. - */ - public MultiDeviceContactUpdateJob(@NonNull Context context) { - this(context, false); - } - - public MultiDeviceContactUpdateJob(@NonNull Context context, boolean forceSync) { - this(context, null, forceSync); - } - - /** - * Create a single contact sync job that syncs `address` to all linked devices. - */ - public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address) { - this(context, address, true); - } - - public MultiDeviceContactUpdateJob(@NonNull Context context, @Nullable Address address, boolean forceSync) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("MultiDeviceContactUpdateJob") - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(1) - .build(), - address, - forceSync); - } - - private MultiDeviceContactUpdateJob(@NonNull Job.Parameters parameters, @Nullable Address address, boolean forceSync) { - super(parameters); - - this.forceSync = forceSync; - - if (address != null) this.address = address.serialize(); - else this.address = null; - } - - @Override - public @NonNull Data serialize() { - return new Data.Builder().putString(KEY_ADDRESS, address) - .putBoolean(KEY_FORCE_SYNC, forceSync) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() - throws IOException, UntrustedIdentityException, NetworkException - { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - if (address == null) generateFullContactUpdate(); - else if (SyncMessagesProtocol.shouldSyncContact(context, address)) generateSingleContactUpdate(Address.fromSerialized(address)); - } - - private void generateSingleContactUpdate(@NonNull Address address) - throws IOException, UntrustedIdentityException, NetworkException - { - // Loki - Only sync regular contacts - if (!PublicKeyValidation.isValid(address.serialize())) { return; } - - File contactDataFile = createTempFile("multidevice-contact-update"); - - try { - DeviceContactsOutputStream out = new DeviceContactsOutputStream(new FileOutputStream(contactDataFile)); - Recipient recipient = Recipient.from(context, address, false); - Optional identityRecord = DatabaseFactory.getIdentityDatabase(context).getIdentity(address); - Optional verifiedMessage = getVerifiedMessage(recipient, identityRecord); - - if (SyncMessagesProtocol.shouldSyncContact(context, address.serialize())) { - out.write(new DeviceContact(address.toPhoneString(), - Optional.fromNullable(recipient.getName()), - getAvatar(recipient.getContactUri()), - Optional.fromNullable(recipient.getColor().serialize()), - verifiedMessage, - Optional.fromNullable(recipient.getProfileKey()), - recipient.isBlocked(), - recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent())); - } - - out.close(); - sendUpdate(messageSender, contactDataFile, false); - - } catch(InvalidNumberException e) { - Log.w(TAG, e); - } finally { - if (contactDataFile != null) contactDataFile.delete(); - } - } - - private void generateFullContactUpdate() - throws IOException, UntrustedIdentityException, NetworkException - { - boolean isAppVisible = ApplicationContext.getInstance(context).isAppVisible(); - long timeSinceLastSync = System.currentTimeMillis() - TextSecurePreferences.getLastFullContactSyncTime(context); - - Log.d(TAG, "Requesting a full contact sync. forced = " + forceSync + ", appVisible = " + isAppVisible + ", timeSinceLastSync = " + timeSinceLastSync + " ms"); - - if (!forceSync && !isAppVisible && timeSinceLastSync < FULL_SYNC_TIME) { - Log.i(TAG, "App is backgrounded and the last contact sync was too soon (" + timeSinceLastSync + " ms ago). Marking that we need a sync. Skipping multi-device contact update..."); - TextSecurePreferences.setNeedsFullContactSync(context, true); - return; - } - - TextSecurePreferences.setLastFullContactSyncTime(context, System.currentTimeMillis()); - TextSecurePreferences.setNeedsFullContactSync(context, false); - - File contactDataFile = createTempFile("multidevice-contact-update"); - - try { - DeviceContactsOutputStream out = new DeviceContactsOutputStream(new FileOutputStream(contactDataFile)); - List contacts = SyncMessagesProtocol.getContactsToSync(context); - - for (ContactData contactData : contacts) { - Uri contactUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_URI, String.valueOf(contactData.id)); - Address address = Address.fromExternal(context, contactData.numbers.get(0).number); - Recipient recipient = Recipient.from(context, address, false); - Optional identity = DatabaseFactory.getIdentityDatabase(context).getIdentity(address); - Optional verified = getVerifiedMessage(recipient, identity); - Optional name = Optional.fromNullable(contactData.name); - Optional color = Optional.of(recipient.getColor().serialize()); - Optional profileKey = Optional.fromNullable(recipient.getProfileKey()); - boolean blocked = recipient.isBlocked(); - Optional expireTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); - - out.write(new DeviceContact(address.toPhoneString(), name, getAvatar(contactUri), color, verified, profileKey, blocked, expireTimer)); - } - - if (ProfileKeyUtil.hasProfileKey(context)) { - Recipient self = Recipient.from(context, Address.fromSerialized(TextSecurePreferences.getLocalNumber(context)), false); - out.write(new DeviceContact(TextSecurePreferences.getLocalNumber(context), - Optional.absent(), Optional.absent(), - Optional.of(self.getColor().serialize()), Optional.absent(), - Optional.of(ProfileKeyUtil.getProfileKey(context)), - false, self.getExpireMessages() > 0 ? Optional.of(self.getExpireMessages()) : Optional.absent())); - } - - out.close(); - sendUpdate(messageSender, contactDataFile, true); - } catch(InvalidNumberException e) { - Log.w(TAG, e); - } finally { - if (contactDataFile != null) contactDataFile.delete(); - } - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - // Loki - Disabled since we have our own retrying - return false; - } - - @Override - public void onCanceled() { - - } - - private void sendUpdate(SignalServiceMessageSender messageSender, File contactsFile, boolean complete) - throws IOException, UntrustedIdentityException, NetworkException - { - if (contactsFile.length() > 0) { - FileInputStream contactsFileStream = new FileInputStream(contactsFile); - SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder() - .withStream(contactsFileStream) - .withContentType("application/octet-stream") - .withLength(contactsFile.length()) - .build(); - - Optional unidentifiedAccess = address != null ? UnidentifiedAccessUtil.getAccessFor(context, Recipient.from(context, Address.fromSerialized(address), false)) : Optional.absent(); - - try { - messageSender.sendMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, complete)), unidentifiedAccess); - } catch (IOException ioe) { - throw new NetworkException(ioe); - } - } - } - - private Optional getAvatar(@Nullable Uri uri) throws IOException { - return Optional.absent(); - - /* Loki - Disabled until we support custom profile pictures. This will then need to be reworked. - if (uri == null) { - return Optional.absent(); - } - - Uri displayPhotoUri = Uri.withAppendedPath(uri, ContactsContract.Contacts.Photo.DISPLAY_PHOTO); - - try { - AssetFileDescriptor fd = context.getContentResolver().openAssetFileDescriptor(displayPhotoUri, "r"); - - if (fd == null) { - return Optional.absent(); - } - - return Optional.of(SignalServiceAttachment.newStreamBuilder() - .withStream(fd.createInputStream()) - .withContentType("image/*") - .withLength(fd.getLength()) - .build()); - } catch (IOException e) { - Log.i(TAG, "Could not find avatar for URI: " + displayPhotoUri); - } - - Uri photoUri = Uri.withAppendedPath(uri, ContactsContract.Contacts.Photo.CONTENT_DIRECTORY); - - if (photoUri == null) { - return Optional.absent(); - } - - Cursor cursor = context.getContentResolver().query(photoUri, - new String[] { - ContactsContract.CommonDataKinds.Photo.PHOTO, - ContactsContract.CommonDataKinds.Phone.MIMETYPE - }, null, null, null); - - try { - if (cursor != null && cursor.moveToNext()) { - byte[] data = cursor.getBlob(0); - - if (data != null) { - return Optional.of(SignalServiceAttachment.newStreamBuilder() - .withStream(new ByteArrayInputStream(data)) - .withContentType("image/*") - .withLength(data.length) - .build()); - } - } - - return Optional.absent(); - } finally { - if (cursor != null) { - cursor.close(); - } - } - */ - } - - private Optional getVerifiedMessage(Recipient recipient, Optional identity) throws InvalidNumberException { - if (!identity.isPresent()) return Optional.absent(); - - String destination = recipient.getAddress().toPhoneString(); - IdentityKey identityKey = identity.get().getIdentityKey(); - - VerifiedMessage.VerifiedState state; - - switch (identity.get().getVerifiedStatus()) { - case VERIFIED: state = VerifiedMessage.VerifiedState.VERIFIED; break; - case UNVERIFIED: state = VerifiedMessage.VerifiedState.UNVERIFIED; break; - case DEFAULT: state = VerifiedMessage.VerifiedState.DEFAULT; break; - default: throw new AssertionError("Unknown state: " + identity.get().getVerifiedStatus()); - } - - return Optional.of(new VerifiedMessage(destination, identityKey, state, System.currentTimeMillis())); - } - - private File createTempFile(String prefix) throws IOException { - File file = File.createTempFile(prefix, "tmp", context.getCacheDir()); - file.deleteOnExit(); - - return file; - } - - private static class NetworkException extends Exception { - - public NetworkException(Exception ioe) { - super(ioe); - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceContactUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - String serialized = data.getString(KEY_ADDRESS); - Address address = serialized != null ? Address.fromSerialized(serialized) : null; - - return new MultiDeviceContactUpdateJob(parameters, address, data.getBoolean(KEY_FORCE_SYNC)); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java deleted file mode 100644 index d0ff88d5bb..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceGroupUpdateJob.java +++ /dev/null @@ -1,174 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.DatabaseFactory; -import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.recipients.Recipient; -import org.thoughtcrime.securesms.util.GroupUtil; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.SignalServiceAttachment; -import org.session.libsignal.service.api.messages.SignalServiceAttachmentStream; -import org.session.libsignal.service.api.messages.multidevice.DeviceGroup; -import org.session.libsignal.service.api.messages.multidevice.DeviceGroupsOutputStream; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceGroupUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceGroupUpdateJob"; - - private static final String TAG = MultiDeviceGroupUpdateJob.class.getSimpleName(); - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceGroupUpdateJob() { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("MultiDeviceGroupUpdateJob") - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build()); - } - - private MultiDeviceGroupUpdateJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public void onRun() throws Exception { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - File contactDataFile = createTempFile("multidevice-contact-update"); - GroupDatabase.Reader reader = null; - - GroupDatabase.GroupRecord record; - - try { - DeviceGroupsOutputStream out = new DeviceGroupsOutputStream(new FileOutputStream(contactDataFile)); - - reader = DatabaseFactory.getGroupDatabase(context).getGroups(); - - while ((record = reader.getNext()) != null) { - if (record.isClosedGroup()) { - List members = new LinkedList<>(); - List admins = new LinkedList<>(); - - for (Address member : record.getMembers()) { - members.add(member.serialize()); - } - - for (Address admin : record.getAdmins()) { - admins.add(admin.serialize()); - } - - Recipient recipient = Recipient.from(context, Address.fromSerialized(GroupUtil.getEncodedId(record.getId(), record.isMms())), false); - Optional expirationTimer = recipient.getExpireMessages() > 0 ? Optional.of(recipient.getExpireMessages()) : Optional.absent(); - - out.write(new DeviceGroup(record.getId(), Optional.fromNullable(record.getTitle()), - members, admins, getAvatar(record.getAvatar()), - record.isActive(), expirationTimer, - Optional.of(recipient.getColor().serialize()), - recipient.isBlocked())); - } - } - - out.close(); - - if (contactDataFile.exists() && contactDataFile.length() > 0) { - sendUpdate(messageSender, contactDataFile); - } else { - Log.w(TAG, "No groups present for sync message..."); - } - - } finally { - if (contactDataFile != null) contactDataFile.delete(); - if (reader != null) reader.close(); - } - - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - // Loki - Disabled since we have our own retrying - return false; - } - - @Override - public void onCanceled() { - - } - - private void sendUpdate(SignalServiceMessageSender messageSender, File contactsFile) - throws IOException, UntrustedIdentityException - { - FileInputStream contactsFileStream = new FileInputStream(contactsFile); - SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder() - .withStream(contactsFileStream) - .withContentType("application/octet-stream") - .withLength(contactsFile.length()) - .build(); - - messageSender.sendMessage(SignalServiceSyncMessage.forGroups(attachmentStream), - UnidentifiedAccessUtil.getAccessForSync(context)); - } - - - private Optional getAvatar(@Nullable byte[] avatar) { - if (avatar == null) return Optional.absent(); - - return Optional.of(SignalServiceAttachment.newStreamBuilder() - .withStream(new ByteArrayInputStream(avatar)) - .withContentType("image/*") - .withLength(avatar.length) - .build()); - } - - private File createTempFile(String prefix) throws IOException { - File file = File.createTempFile(prefix, "tmp", context.getCacheDir()); - file.deleteOnExit(); - - return file; - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceGroupUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceGroupUpdateJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java deleted file mode 100644 index a6cee83729..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceProfileKeyUpdateJob.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; - -import org.thoughtcrime.securesms.crypto.ProfileKeyUtil; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.SignalServiceAttachment; -import org.session.libsignal.service.api.messages.SignalServiceAttachmentStream; -import org.session.libsignal.service.api.messages.multidevice.ContactsMessage; -import org.session.libsignal.service.api.messages.multidevice.DeviceContact; -import org.session.libsignal.service.api.messages.multidevice.DeviceContactsOutputStream; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceProfileKeyUpdateJob extends BaseJob implements InjectableType { - - public static String KEY = "MultiDeviceProfileKeyUpdateJob"; - - private static final String TAG = MultiDeviceProfileKeyUpdateJob.class.getSimpleName(); - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceProfileKeyUpdateJob() { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("MultiDeviceProfileKeyUpdateJob") - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build()); - } - - private MultiDeviceProfileKeyUpdateJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException, UntrustedIdentityException { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device..."); - return; - } - - Optional profileKey = Optional.of(ProfileKeyUtil.getProfileKey(context)); - ByteArrayOutputStream baos = new ByteArrayOutputStream(); - DeviceContactsOutputStream out = new DeviceContactsOutputStream(baos); - - out.write(new DeviceContact(TextSecurePreferences.getLocalNumber(context), - Optional.absent(), - Optional.absent(), - Optional.absent(), - Optional.absent(), - profileKey, false, Optional.absent())); - - out.close(); - - SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder() - .withStream(new ByteArrayInputStream(baos.toByteArray())) - .withContentType("application/octet-stream") - .withLength(baos.toByteArray().length) - .build(); - - SignalServiceSyncMessage syncMessage = SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, false)); - - messageSender.sendMessage(syncMessage, UnidentifiedAccessUtil.getAccessForSync(context)); - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof PushNetworkException) return true; - return false; - } - - @Override - public void onCanceled() { - Log.w(TAG, "Profile key sync failed!"); - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceProfileKeyUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceProfileKeyUpdateJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java deleted file mode 100644 index 0353b8c99e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceReadUpdateJob.java +++ /dev/null @@ -1,144 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import com.annimon.stream.Stream; -import com.fasterxml.jackson.annotation.JsonProperty; - -import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; - -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; -import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.util.JsonUtils; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.multidevice.ReadMessage; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; -import java.io.Serializable; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceReadUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceReadUpdateJob"; - - private static final String TAG = MultiDeviceReadUpdateJob.class.getSimpleName(); - - private static final String KEY_MESSAGE_IDS = "message_ids"; - - private List messageIds; - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceReadUpdateJob(List messageIds) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build(), - messageIds); - } - - private MultiDeviceReadUpdateJob(@NonNull Job.Parameters parameters, @NonNull List messageIds) { - super(parameters); - - this.messageIds = new LinkedList<>(); - - for (SyncMessageId messageId : messageIds) { - this.messageIds.add(new SerializableSyncMessageId(messageId.getAddress().toPhoneString(), messageId.getTimetamp())); - } - } - - @Override - public @NonNull Data serialize() { - String[] ids = new String[messageIds.size()]; - - for (int i = 0; i < ids.length; i++) { - try { - ids[i] = JsonUtils.toJson(messageIds.get(i)); - } catch (IOException e) { - throw new AssertionError(e); - } - } - - return new Data.Builder().putStringArray(KEY_MESSAGE_IDS, ids).build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException, UntrustedIdentityException { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device..."); - return; - } - - List readMessages = new LinkedList<>(); - - for (SerializableSyncMessageId messageId : messageIds) { - readMessages.add(new ReadMessage(messageId.sender, messageId.timestamp)); - } - - messageSender.sendMessage(SignalServiceSyncMessage.forRead(readMessages), UnidentifiedAccessUtil.getAccessForSync(context)); - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return exception instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - - } - - private static class SerializableSyncMessageId implements Serializable { - - private static final long serialVersionUID = 1L; - - @JsonProperty - private final String sender; - - @JsonProperty - private final long timestamp; - - private SerializableSyncMessageId(@JsonProperty("sender") String sender, @JsonProperty("timestamp") long timestamp) { - this.sender = sender; - this.timestamp = timestamp; - } - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceReadUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - List ids = Stream.of(data.getStringArray(KEY_MESSAGE_IDS)) - .map(id -> { - try { - return JsonUtils.fromJson(id, SerializableSyncMessageId.class); - } catch (IOException e) { - throw new AssertionError(e); - } - }) - .map(id -> new SyncMessageId(Address.fromSerialized(id.sender), id.timestamp)) - .toList(); - - return new MultiDeviceReadUpdateJob(parameters, ids); - - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java deleted file mode 100644 index db6b92a3f5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackOperationJob.java +++ /dev/null @@ -1,122 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceStickerPackOperationJob extends BaseJob implements InjectableType { - - private static final String TAG = Log.tag(MultiDeviceStickerPackOperationJob.class); - - public static final String KEY = "MultiDeviceStickerPackOperationJob"; - - private static final String KEY_PACK_ID = "pack_id"; - private static final String KEY_PACK_KEY = "pack_key"; - private static final String KEY_TYPE = "type"; - - private final String packId; - private final String packKey; - private final Type type; - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceStickerPackOperationJob(@NonNull String packId, - @NonNull String packKey, - @NonNull Type type) - { - this(new Job.Parameters.Builder() - .setQueue("MultiDeviceStickerPackOperationJob") - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .build(), - packId, - packKey, - type); - } - - public MultiDeviceStickerPackOperationJob(@NonNull Parameters parameters, - @NonNull String packId, - @NonNull String packKey, - @NonNull Type type) - { - super(parameters); - this.packId = packId; - this.packKey = packKey; - this.type = type; - } - - @Override - public @NonNull Data serialize() { - return new Data.Builder().putString(KEY_PACK_ID, packId) - .putString(KEY_PACK_KEY, packKey) - .putString(KEY_TYPE, type.name()) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - protected void onRun() throws Exception { - /* - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - byte[] packIdBytes = Hex.fromStringCondensed(packId); - byte[] packKeyBytes = Hex.fromStringCondensed(packKey); - - StickerPackOperationMessage.Type remoteType; - - switch (type) { - case INSTALL: remoteType = StickerPackOperationMessage.Type.INSTALL; break; - case REMOVE: remoteType = StickerPackOperationMessage.Type.REMOVE; break; - default: throw new AssertionError("No matching type?"); - } - - StickerPackOperationMessage stickerPackOperation = new StickerPackOperationMessage(packIdBytes, packKeyBytes, remoteType); - - messageSender.sendMessage(SignalServiceSyncMessage.forStickerPackOperations(Collections.singletonList(stickerPackOperation)), - UnidentifiedAccessUtil.getAccessForSync(context)); - */ - } - - @Override - protected boolean onShouldRetry(@NonNull Exception e) { - return e instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - Log.w(TAG, "Failed to sync sticker pack operation!"); - } - - // NEVER rename these -- they're persisted by name - public enum Type { - INSTALL, REMOVE - } - - public static class Factory implements Job.Factory { - - @Override - public @NonNull MultiDeviceStickerPackOperationJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceStickerPackOperationJob(parameters, - data.getString(KEY_PACK_ID), - data.getString(KEY_PACK_KEY), - Type.valueOf(data.getString(KEY_TYPE))); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java deleted file mode 100644 index aa5e82cd2e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceStickerPackSyncJob.java +++ /dev/null @@ -1,94 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -/** - * Tells a linked desktop about all installed sticker packs. - */ -public class MultiDeviceStickerPackSyncJob extends BaseJob implements InjectableType { - - private static final String TAG = Log.tag(MultiDeviceStickerPackSyncJob.class); - - public static final String KEY = "MultiDeviceStickerPackSyncJob"; - - @Inject SignalServiceMessageSender messageSender; - - public MultiDeviceStickerPackSyncJob() { - this(new Parameters.Builder() - .setQueue("MultiDeviceStickerPackSyncJob") - .addConstraint(NetworkConstraint.KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .build()); - } - - public MultiDeviceStickerPackSyncJob(@NonNull Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - protected void onRun() throws Exception { - return; - /* - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device, aborting..."); - return; - } - - List operations = new LinkedList<>(); - - try (StickerPackRecordReader reader = new StickerPackRecordReader(DatabaseFactory.getStickerDatabase(context).getInstalledStickerPacks())) { - StickerPackRecord pack; - while ((pack = reader.getNext()) != null) { - byte[] packIdBytes = Hex.fromStringCondensed(pack.getPackId()); - byte[] packKeyBytes = Hex.fromStringCondensed(pack.getPackKey()); - - operations.add(new StickerPackOperationMessage(packIdBytes, packKeyBytes, StickerPackOperationMessage.Type.INSTALL)); - } - } - - messageSender.sendMessage(SignalServiceSyncMessage.forStickerPackOperations(operations), - UnidentifiedAccessUtil.getAccessForSync(context)); - */ - } - - @Override - protected boolean onShouldRetry(@NonNull Exception e) { - return e instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - Log.w(TAG, "Failed to sync sticker pack operation!"); - } - - public static class Factory implements Job.Factory { - - @Override - public @NonNull - MultiDeviceStickerPackSyncJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new MultiDeviceStickerPackSyncJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java deleted file mode 100644 index 290990e492..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/MultiDeviceVerifiedUpdateJob.java +++ /dev/null @@ -1,147 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.database.Address; -import org.thoughtcrime.securesms.database.IdentityDatabase.VerifiedStatus; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.util.Base64; -import org.session.libsignal.libsignal.IdentityKey; -import org.session.libsignal.service.api.SignalServiceMessageSender; -import org.session.libsignal.service.api.crypto.UntrustedIdentityException; -import org.session.libsignal.service.api.messages.multidevice.VerifiedMessage; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; -import java.util.concurrent.TimeUnit; - -import javax.inject.Inject; - -public class MultiDeviceVerifiedUpdateJob extends BaseJob implements InjectableType { - - public static final String KEY = "MultiDeviceVerifiedUpdateJob"; - - private static final String TAG = MultiDeviceVerifiedUpdateJob.class.getSimpleName(); - - private static final String KEY_DESTINATION = "destination"; - private static final String KEY_IDENTITY_KEY = "identity_key"; - private static final String KEY_VERIFIED_STATUS = "verified_status"; - private static final String KEY_TIMESTAMP = "timestamp"; - - @Inject SignalServiceMessageSender messageSender; - - private String destination; - private byte[] identityKey; - private VerifiedStatus verifiedStatus; - private long timestamp; - - public MultiDeviceVerifiedUpdateJob(Address destination, IdentityKey identityKey, VerifiedStatus verifiedStatus) { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue("__MULTI_DEVICE_VERIFIED_UPDATE__") - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build(), - destination, - identityKey.serialize(), - verifiedStatus, - System.currentTimeMillis()); - } - - private MultiDeviceVerifiedUpdateJob(@NonNull Job.Parameters parameters, - @NonNull Address destination, - @NonNull byte[] identityKey, - @NonNull VerifiedStatus verifiedStatus, - long timestamp) - { - super(parameters); - - this.destination = destination.serialize(); - this.identityKey = identityKey; - this.verifiedStatus = verifiedStatus; - this.timestamp = timestamp; - } - - @Override - public @NonNull Data serialize() { - return new Data.Builder().putString(KEY_DESTINATION, destination) - .putString(KEY_IDENTITY_KEY, Base64.encodeBytes(identityKey)) - .putInt(KEY_VERIFIED_STATUS, verifiedStatus.toInt()) - .putLong(KEY_TIMESTAMP, timestamp) - .build(); - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException, UntrustedIdentityException { - /* - try { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.i(TAG, "Not multi device..."); - return; - } - - if (destination == null) { - Log.w(TAG, "No destination..."); - return; - } - - Address canonicalDestination = Address.fromSerialized(destination); - VerifiedMessage.VerifiedState verifiedState = getVerifiedState(verifiedStatus); - VerifiedMessage verifiedMessage = new VerifiedMessage(canonicalDestination.toPhoneString(), new IdentityKey(identityKey, 0), verifiedState, timestamp); - - messageSender.sendMessage(SignalServiceSyncMessage.forVerified(verifiedMessage), - UnidentifiedAccessUtil.getAccessFor(context, Recipient.from(context, Address.fromSerialized(destination), false))); - } catch (InvalidKeyException e) { - throw new IOException(e); - } - */ - } - - private VerifiedMessage.VerifiedState getVerifiedState(VerifiedStatus status) { - VerifiedMessage.VerifiedState verifiedState; - - switch (status) { - case DEFAULT: verifiedState = VerifiedMessage.VerifiedState.DEFAULT; break; - case VERIFIED: verifiedState = VerifiedMessage.VerifiedState.VERIFIED; break; - case UNVERIFIED: verifiedState = VerifiedMessage.VerifiedState.UNVERIFIED; break; - default: throw new AssertionError("Unknown status: " + verifiedStatus); - } - - return verifiedState; - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return exception instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull MultiDeviceVerifiedUpdateJob create(@NonNull Parameters parameters, @NonNull Data data) { - try { - Address destination = Address.fromSerialized(data.getString(KEY_DESTINATION)); - VerifiedStatus verifiedStatus = VerifiedStatus.forState(data.getInt(KEY_VERIFIED_STATUS)); - long timestamp = data.getLong(KEY_TIMESTAMP); - byte[] identityKey = Base64.decode(data.getString(KEY_IDENTITY_KEY)); - - return new MultiDeviceVerifiedUpdateJob(parameters, destination, identityKey, verifiedStatus, timestamp); - } catch (IOException e) { - throw new AssertionError(e); - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 4a45060313..8ea8535205 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -70,8 +70,6 @@ import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol; import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol; import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol; import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation; -import org.thoughtcrime.securesms.loki.protocol.shelved.MultiDeviceProtocol; -import org.thoughtcrime.securesms.loki.protocol.shelved.SyncMessagesProtocol; import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities; import org.thoughtcrime.securesms.loki.utilities.PromiseUtilities; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; @@ -265,13 +263,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType { SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content); if (content.getDeviceLink().isPresent()) { - MultiDeviceProtocol.handleDeviceLinkMessageIfNeeded(context, content.getDeviceLink().get(), content); + throw new UnsupportedOperationException("Device link operations are not supported!"); } else if (content.getDataMessage().isPresent()) { SignalServiceDataMessage message = content.getDataMessage().get(); boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent(); if (message.isDeviceUnlinkingRequest()) { - MultiDeviceProtocol.handleUnlinkingRequestIfNeeded(context, content); + throw new UnsupportedOperationException("Device link operations are not supported!"); } else { if (message.getClosedGroupUpdate().isPresent()) { @@ -303,20 +301,22 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } } else if (content.getSyncMessage().isPresent()) { - TextSecurePreferences.setMultiDevice(context, true); + throw new UnsupportedOperationException("Device link operations are not supported!"); - SignalServiceSyncMessage syncMessage = content.getSyncMessage().get(); - - if (syncMessage.getSent().isPresent()) handleSynchronizeSentMessage(content, syncMessage.getSent().get()); - else if (syncMessage.getRequest().isPresent()) handleSynchronizeRequestMessage(syncMessage.getRequest().get()); - else if (syncMessage.getRead().isPresent()) handleSynchronizeReadMessage(syncMessage.getRead().get(), content.getTimestamp()); - else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get()); - else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get()); - else if (syncMessage.getContacts().isPresent()) SyncMessagesProtocol.handleContactSyncMessage(context, content, syncMessage.getContacts().get()); - else if (syncMessage.getGroups().isPresent()) SyncMessagesProtocol.handleClosedGroupSyncMessage(context, content, syncMessage.getGroups().get()); - else if (syncMessage.getOpenGroups().isPresent()) SyncMessagesProtocol.handleOpenGroupSyncMessage(context, content, syncMessage.getOpenGroups().get()); - else if (syncMessage.getBlockedList().isPresent()) SyncMessagesProtocol.handleBlockedContactsSyncMessage(context, content, syncMessage.getBlockedList().get()); - else Log.w(TAG, "Contains no known sync types..."); +// TextSecurePreferences.setMultiDevice(context, true); +// +// SignalServiceSyncMessage syncMessage = content.getSyncMessage().get(); +// +// if (syncMessage.getSent().isPresent()) handleSynchronizeSentMessage(content, syncMessage.getSent().get()); +// else if (syncMessage.getRequest().isPresent()) handleSynchronizeRequestMessage(syncMessage.getRequest().get()); +// else if (syncMessage.getRead().isPresent()) handleSynchronizeReadMessage(syncMessage.getRead().get(), content.getTimestamp()); +// else if (syncMessage.getVerified().isPresent()) handleSynchronizeVerifiedMessage(syncMessage.getVerified().get()); +// else if (syncMessage.getStickerPackOperations().isPresent()) handleSynchronizeStickerPackOperation(syncMessage.getStickerPackOperations().get()); +// else if (syncMessage.getContacts().isPresent()) SyncMessagesProtocol.handleContactSyncMessage(context, content, syncMessage.getContacts().get()); +// else if (syncMessage.getGroups().isPresent()) SyncMessagesProtocol.handleClosedGroupSyncMessage(context, content, syncMessage.getGroups().get()); +// else if (syncMessage.getOpenGroups().isPresent()) SyncMessagesProtocol.handleOpenGroupSyncMessage(context, content, syncMessage.getOpenGroups().get()); +// else if (syncMessage.getBlockedList().isPresent()) SyncMessagesProtocol.handleBlockedContactsSyncMessage(context, content, syncMessage.getBlockedList().get()); +// else Log.w(TAG, "Contains no known sync types..."); } else if (content.getReceiptMessage().isPresent()) { SignalServiceReceiptMessage message = content.getReceiptMessage().get(); @@ -330,9 +330,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType { resetRecipientToPush(Recipient.from(context, Address.fromSerialized(content.getSender()), false)); - if (envelope.isPreKeySignalMessage()) { - ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob()); - } +// if (envelope.isPreKeySignalMessage()) { +// ApplicationContext.getInstance(context).getJobManager().add(new RefreshPreKeysJob()); +// } } catch (ProtocolInvalidVersionException e) { Log.w(TAG, e); handleInvalidVersionMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId); @@ -560,68 +560,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } - private void handleSynchronizeRequestMessage(@NonNull RequestMessage message) - { - if (message.isContactsRequest()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceContactUpdateJob(context, true)); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new RefreshUnidentifiedDeliveryAbilityJob()); - } - - if (message.isGroupsRequest()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceGroupUpdateJob()); - } - - if (message.isBlockedListRequest()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceBlockedUpdateJob()); - } - - if (message.isConfigurationRequest()) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(context), - TextSecurePreferences.isTypingIndicatorsEnabled(context), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(context), - TextSecurePreferences.isLinkPreviewsEnabled(context))); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceStickerPackSyncJob()); - } - } - - private void handleSynchronizeReadMessage(@NonNull List readMessages, long envelopeTimestamp) - { - for (ReadMessage readMessage : readMessages) { - List> expiringText = DatabaseFactory.getSmsDatabase(context).setTimestampRead(new SyncMessageId(Address.fromSerialized(readMessage.getSender()), readMessage.getTimestamp()), envelopeTimestamp); - List> expiringMedia = DatabaseFactory.getMmsDatabase(context).setTimestampRead(new SyncMessageId(Address.fromSerialized(readMessage.getSender()), readMessage.getTimestamp()), envelopeTimestamp); - - for (Pair expiringMessage : expiringText) { - ApplicationContext.getInstance(context) - .getExpiringMessageManager() - .scheduleDeletion(expiringMessage.first, false, envelopeTimestamp, expiringMessage.second); - } - - for (Pair expiringMessage : expiringMedia) { - ApplicationContext.getInstance(context) - .getExpiringMessageManager() - .scheduleDeletion(expiringMessage.first, true, envelopeTimestamp, expiringMessage.second); - } - } - - messageNotifier.setLastDesktopActivityTimestamp(envelopeTimestamp); - messageNotifier.cancelDelayedNotifications(); - messageNotifier.updateNotification(context); - } - public void handleMediaMessage(@NonNull SignalServiceContent content, @NonNull SignalServiceDataMessage message, @NonNull Optional smsMessageId, @@ -1413,7 +1351,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return sender.isBlocked(); } } else if (content.getSyncMessage().isPresent()) { - return SyncMessagesProtocol.shouldIgnoreSyncMessage(context, sender); + throw new UnsupportedOperationException("Device link operations are not supported!"); } return false; diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java index d24964f526..9c73dc4be4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -71,13 +71,13 @@ public abstract class PushSendJob extends SendJob { @Override protected final void onSend() throws Exception { - if (TextSecurePreferences.getSignedPreKeyFailureCount(context) > 5) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new RotateSignedPreKeyJob()); - - throw new TextSecureExpiredException("Too many signed prekey rotation failures"); - } +// if (TextSecurePreferences.getSignedPreKeyFailureCount(context) > 5) { +// ApplicationContext.getInstance(context) +// .getJobManager() +// .add(new RotateSignedPreKeyJob()); +// +// throw new TextSecureExpiredException("Too many signed prekey rotation failures"); +// } onPushSend(); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index 165aa05fef..533f26813d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -197,17 +197,17 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { log(TAG, "Have access key to use: " + unidentifiedAccess.isPresent()); - PreKeyBundle preKeyBundle = null; - if (message.isEndSession()) { - preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(destination.serialize()); - } +// PreKeyBundle preKeyBundle = null; +// if (message.isEndSession()) { +// preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(destination.serialize()); +// } SignalServiceDataMessage textSecureMessage = SignalServiceDataMessage.newBuilder() .withTimestamp(message.getDateSent()) .withBody(message.getBody()) .withExpiration((int)(message.getExpiresIn() / 1000)) .withProfileKey(profileKey.orNull()) - .withPreKeyBundle(preKeyBundle) +// .withPreKeyBundle(preKeyBundle) .asEndSessionMessage(message.isEndSession()) .build(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java deleted file mode 100644 index c7a95ef4af..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RefreshPreKeysJob.java +++ /dev/null @@ -1,102 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol; -import org.session.libsignal.service.api.SignalServiceAccountManager; -import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import java.io.IOException; - -import javax.inject.Inject; - -public class RefreshPreKeysJob extends BaseJob implements InjectableType { - - public static final String KEY = "RefreshPreKeysJob"; - - private static final String TAG = RefreshPreKeysJob.class.getSimpleName(); - - private static final int PREKEY_MINIMUM = 10; - - @Inject SignalServiceAccountManager accountManager; - - public RefreshPreKeysJob() { - this(new Job.Parameters.Builder() - .setQueue("RefreshPreKeysJob") - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(3) - .build()); - } - - private RefreshPreKeysJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws IOException { - SessionManagementProtocol.refreshSignedPreKey(context); - } - - /* Loki - Original code - @Override - public void onRun() throws IOException { - if (!TextSecurePreferences.isPushRegistered(context)) return; - - int availableKeys = accountManager.getPreKeysCount(); - - if (availableKeys >= PREKEY_MINIMUM && TextSecurePreferences.isSignedPreKeyRegistered(context)) { - Log.i(TAG, "Available keys sufficient: " + availableKeys); - return; - } - - List preKeyRecords = PreKeyUtil.generatePreKeyRecords(context); - IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); - SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false); - - Log.i(TAG, "Registering new prekeys..."); - - accountManager.setPreKeys(identityKey.getPublicKey(), signedPreKeyRecord, preKeyRecords); - - PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId()); - TextSecurePreferences.setSignedPreKeyRegistered(context, true); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new CleanPreKeysJob()); - } - */ - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - if (exception instanceof NonSuccessfulResponseCodeException) return false; - if (exception instanceof PushNetworkException) return true; - - return false; - } - - @Override - public void onCanceled() { - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull RefreshPreKeysJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new RefreshPreKeysJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java deleted file mode 100644 index 040e7eaf49..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RotateSignedPreKeyJob.java +++ /dev/null @@ -1,88 +0,0 @@ -package org.thoughtcrime.securesms.jobs; - - -import androidx.annotation.NonNull; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.crypto.PreKeyUtil; -import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobmanager.Data; -import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; -import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.session.libsignal.libsignal.IdentityKeyPair; -import org.session.libsignal.libsignal.state.SignedPreKeyRecord; -import org.session.libsignal.service.api.SignalServiceAccountManager; -import org.session.libsignal.service.api.push.exceptions.PushNetworkException; - -import javax.inject.Inject; - -public class RotateSignedPreKeyJob extends BaseJob implements InjectableType { - - public static final String KEY = "RotateSignedPreKeyJob"; - - private static final String TAG = RotateSignedPreKeyJob.class.getSimpleName(); - - @Inject SignalServiceAccountManager accountManager; - - public RotateSignedPreKeyJob() { - this(new Job.Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setMaxAttempts(3) - .build()); - } - - private RotateSignedPreKeyJob(@NonNull Job.Parameters parameters) { - super(parameters); - } - - @Override - public @NonNull Data serialize() { - return Data.EMPTY; - } - - @Override - public @NonNull String getFactoryKey() { - return KEY; - } - - @Override - public void onRun() throws Exception { - Log.i(TAG, "Rotating signed prekey..."); - - if (!IdentityKeyUtil.hasIdentityKey(context)) { return; } - - IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context); - SignedPreKeyRecord signedPreKeyRecord = PreKeyUtil.generateSignedPreKey(context, identityKey, false); - - // Loki - Don't upload the new signed pre key - // accountManager.setSignedPreKey(signedPreKeyRecord); - - PreKeyUtil.setActiveSignedPreKeyId(context, signedPreKeyRecord.getId()); - TextSecurePreferences.setSignedPreKeyRegistered(context, true); - TextSecurePreferences.setSignedPreKeyFailureCount(context, 0); - - ApplicationContext.getInstance(context) - .getJobManager() - .add(new CleanPreKeysJob()); - } - - @Override - public boolean onShouldRetry(@NonNull Exception exception) { - return exception instanceof PushNetworkException; - } - - @Override - public void onCanceled() { - TextSecurePreferences.setSignedPreKeyFailureCount(context, TextSecurePreferences.getSignedPreKeyFailureCount(context) + 1); - } - - public static final class Factory implements Job.Factory { - @Override - public @NonNull RotateSignedPreKeyJob create(@NonNull Parameters parameters, @NonNull Data data) { - return new RotateSignedPreKeyJob(parameters); - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt index 9d2af32ee6..4d3fc81959 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt @@ -7,7 +7,6 @@ import android.content.Intent import android.content.IntentFilter import android.database.Cursor import android.net.Uri -import android.os.AsyncTask import android.os.Bundle import android.text.Spannable import android.text.SpannableString @@ -32,10 +31,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.conversation.ConversationActivity import org.thoughtcrime.securesms.database.Address import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.database.ThreadDatabase import org.thoughtcrime.securesms.database.model.ThreadRecord -import org.thoughtcrime.securesms.groups.GroupManager -import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet import org.thoughtcrime.securesms.loki.dialogs.LightThemeFeatureIntroBottomSheet @@ -329,7 +325,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe .setPositiveButton(R.string.RecipientPreferenceActivity_block) { dialog, _ -> Thread { DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, true) - ApplicationContext.getInstance(this).jobManager.add(MultiDeviceBlockedUpdateJob()) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() @@ -346,7 +341,6 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe .setPositiveButton(R.string.RecipientPreferenceActivity_unblock) { dialog, _ -> Thread { DatabaseFactory.getRecipientDatabase(this).setBlocked(thread.recipient, false) - ApplicationContext.getInstance(this).jobManager.add(MultiDeviceBlockedUpdateJob()) Util.runOnMain { recyclerView.adapter!!.notifyDataSetChanged() dialog.dismiss() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/JoinPublicChatActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/JoinPublicChatActivity.kt index 65ea1f3def..c6eb0d25e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/JoinPublicChatActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/JoinPublicChatActivity.kt @@ -3,14 +3,14 @@ package org.thoughtcrime.securesms.loki.activities import android.animation.Animator import android.animation.AnimatorListenerAdapter import android.os.Bundle -import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentPagerAdapter import android.util.Patterns import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.view.inputmethod.InputMethodManager import android.widget.Toast +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentPagerAdapter import androidx.lifecycle.lifecycleScope import kotlinx.android.synthetic.main.activity_join_public_chat.* import kotlinx.android.synthetic.main.fragment_enter_chat_url.* @@ -18,15 +18,11 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import network.loki.messenger.R -import nl.komponents.kovenant.ui.failUi -import nl.komponents.kovenant.ui.successUi import org.thoughtcrime.securesms.BaseActionBarActivity import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragmentDelegate -import org.thoughtcrime.securesms.loki.protocol.shelved.SyncMessagesProtocol import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities -import java.lang.Exception class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCodeWrapperFragmentDelegate { private val adapter = JoinPublicChatActivityAdapter(this) @@ -83,7 +79,6 @@ class JoinPublicChatActivity : PassphraseRequiredActionBarActivity(), ScanQRCode } return@launch } - SyncMessagesProtocol.syncAllOpenGroups(this@JoinPublicChatActivity) withContext(Dispatchers.Main) { finish() } } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyBundleDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyBundleDatabase.kt deleted file mode 100644 index de9faee9f3..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyBundleDatabase.kt +++ /dev/null @@ -1,130 +0,0 @@ -package org.thoughtcrime.securesms.loki.database - -import android.content.ContentValues -import android.content.Context -import net.sqlcipher.Cursor -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.crypto.PreKeyUtil -import org.thoughtcrime.securesms.database.Database -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper -import org.thoughtcrime.securesms.logging.Log -import org.thoughtcrime.securesms.loki.utilities.get -import org.thoughtcrime.securesms.loki.utilities.getBase64EncodedData -import org.thoughtcrime.securesms.loki.utilities.getInt -import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate -import org.thoughtcrime.securesms.util.Base64 -import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.session.libsignal.libsignal.IdentityKey -import org.session.libsignal.libsignal.InvalidKeyException -import org.session.libsignal.libsignal.ecc.Curve -import org.session.libsignal.libsignal.state.PreKeyBundle -import org.session.libsignal.libsignal.util.KeyHelper -import org.session.libsignal.service.api.push.SignalServiceAddress -import org.session.libsignal.service.loki.database.LokiPreKeyBundleDatabaseProtocol - -class LokiPreKeyBundleDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiPreKeyBundleDatabaseProtocol { - - companion object { - private val table = "loki_pre_key_bundle_database" - private val publicKey = "public_key" - private val preKeyID = "pre_key_id" - private val preKeyPublic = "pre_key_public" - private val signedPreKeyID = "signed_pre_key_id" - private val signedPreKeyPublic = "signed_pre_key_public" - private val signedPreKeySignature = "signed_pre_key_signature" - private val identityKey = "identity_key" - private val deviceID = "device_id" - private val registrationID = "registration_id" - @JvmStatic val createTableCommand = "CREATE TABLE $table (" + "$publicKey TEXT PRIMARY KEY," + "$preKeyID INTEGER," + - "$preKeyPublic TEXT NOT NULL," + "$signedPreKeyID INTEGER," + "$signedPreKeyPublic TEXT NOT NULL," + - "$signedPreKeySignature TEXT," + "$identityKey TEXT NOT NULL," + "$deviceID INTEGER," + "$registrationID INTEGER" + ");" - } - - fun generatePreKeyBundle(publicKey: String): PreKeyBundle? { - var failureCount = 0 - while (failureCount < 3) { - try { - val preKey = generatePreKeyBundle(publicKey, failureCount > 0) ?: return null - // Verify the bundle is correct - if (!Curve.verifySignature(preKey.identityKey.publicKey, preKey.signedPreKey.serialize(), preKey.signedPreKeySignature)) { - throw InvalidKeyException() - } - return preKey; - } catch (e: InvalidKeyException) { - failureCount += 1 - } - } - Log.w("Loki", "Failed to generate a valid pre key bundle for: $publicKey.") - return null - } - - private fun generatePreKeyBundle(publicKey: String, forceClean: Boolean): PreKeyBundle? { - if (publicKey.isEmpty()) return null - var registrationID = TextSecurePreferences.getLocalRegistrationId(context) - if (registrationID == 0) { - registrationID = KeyHelper.generateRegistrationId(false) - TextSecurePreferences.setLocalRegistrationId(context, registrationID) - } - val deviceID = SignalServiceAddress.DEFAULT_DEVICE_ID - val preKeyRecord = DatabaseFactory.getLokiPreKeyRecordDatabase(context).getOrCreatePreKeyRecord(publicKey) - val identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context) - if (!forceClean && TextSecurePreferences.isSignedPreKeyRegistered(context)) { - Log.d("Loki", "A signed pre key has already been registered.") - } else { - Log.d("Loki", "Registering a new signed pre key.") - PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true) - TextSecurePreferences.setSignedPreKeyRegistered(context, true) - } - val activeSignedPreKey = PreKeyUtil.getActiveSignedPreKey(context) ?: return null - return PreKeyBundle(registrationID, deviceID, preKeyRecord.id, preKeyRecord.keyPair.publicKey, activeSignedPreKey.id, activeSignedPreKey.keyPair.publicKey, activeSignedPreKey.signature, identityKeyPair.publicKey) - } - - override fun getPreKeyBundle(publicKey: String): PreKeyBundle? { - val database = databaseHelper.readableDatabase - return database.get(table, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor -> - val registrationID = cursor.getInt(registrationID) - val deviceID = cursor.getInt(deviceID) - val preKeyID = cursor.getInt(preKeyID) - val preKey = Curve.decodePoint(cursor.getBase64EncodedData(preKeyPublic), 0) - val signedPreKeyID = cursor.getInt(signedPreKeyID) - val signedPreKey = Curve.decodePoint(cursor.getBase64EncodedData(signedPreKeyPublic), 0) - val signedPreKeySignature = cursor.getBase64EncodedData(signedPreKeySignature) - val identityKey = IdentityKey(cursor.getBase64EncodedData(identityKey), 0) - PreKeyBundle(registrationID, deviceID, preKeyID, preKey, signedPreKeyID, signedPreKey, signedPreKeySignature, identityKey) - } - } - - fun setPreKeyBundle(publicKey: String, preKeyBundle: PreKeyBundle) { - val database = databaseHelper.writableDatabase - val values = ContentValues(9) - values.put(registrationID, preKeyBundle.registrationId) - values.put(deviceID, preKeyBundle.deviceId) - values.put(preKeyID, preKeyBundle.preKeyId) - values.put(preKeyPublic, Base64.encodeBytes(preKeyBundle.preKey.serialize())) - values.put(signedPreKeyID, preKeyBundle.signedPreKeyId) - values.put(signedPreKeyPublic, Base64.encodeBytes(preKeyBundle.signedPreKey.serialize())) - values.put(signedPreKeySignature, Base64.encodeBytes(preKeyBundle.signedPreKeySignature)) - values.put(identityKey, Base64.encodeBytes(preKeyBundle.identityKey.serialize())) - values.put(Companion.publicKey, publicKey) - database.insertOrUpdate(table, values, "${Companion.publicKey} = ?", arrayOf( publicKey )) - } - - override fun removePreKeyBundle(publicKey: String) { - val database = databaseHelper.writableDatabase - database.delete(table, "${Companion.publicKey} = ?", arrayOf( publicKey )) - } - - fun hasPreKeyBundle(publicKey: String): Boolean { - val database = databaseHelper.readableDatabase - var cursor: Cursor? = null - return try { - cursor = database.query(table, null, "${Companion.publicKey} = ?", arrayOf( publicKey ), null, null, null) - cursor != null && cursor.count > 0 - } catch (e: Exception) { - false - } finally { - cursor?.close() - } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyRecordDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyRecordDatabase.kt deleted file mode 100644 index 6a6363902a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiPreKeyRecordDatabase.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.thoughtcrime.securesms.loki.database - -import android.content.ContentValues -import android.content.Context -import org.thoughtcrime.securesms.crypto.PreKeyUtil -import org.thoughtcrime.securesms.database.Database -import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper -import org.thoughtcrime.securesms.loki.utilities.get -import org.thoughtcrime.securesms.loki.utilities.getInt -import org.thoughtcrime.securesms.loki.utilities.insertOrUpdate -import org.session.libsignal.libsignal.state.PreKeyRecord -import org.session.libsignal.service.loki.database.LokiPreKeyRecordDatabaseProtocol - -class LokiPreKeyRecordDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiPreKeyRecordDatabaseProtocol { - - companion object { - private val table = "loki_pre_key_record_database" - private val publicKey = "public_key" - private val preKeyID = "pre_key_id" - @JvmStatic val createTableCommand = "CREATE TABLE $table ($publicKey TEXT PRIMARY KEY, $preKeyID INTEGER);" - } - - fun hasPreKey(publicKey: String): Boolean { - val database = databaseHelper.readableDatabase - return database.get(table, "${Companion.publicKey} = ?", arrayOf( publicKey )) { it.count > 0 } ?: false - } - - override fun getPreKeyRecord(publicKey: String): PreKeyRecord? { - val database = databaseHelper.readableDatabase - return database.get(table, "${Companion.publicKey} = ?", arrayOf( publicKey )) { cursor -> - val preKeyID = cursor.getInt(preKeyID) - PreKeyUtil.loadPreKey(context, preKeyID) - } - } - - fun getOrCreatePreKeyRecord(publicKey: String): PreKeyRecord { - return getPreKeyRecord(publicKey) ?: generateAndStorePreKeyRecord(publicKey) - } - - private fun generateAndStorePreKeyRecord(publicKey: String): PreKeyRecord { - val records = PreKeyUtil.generatePreKeyRecords(context, 1) - PreKeyUtil.storePreKeyRecords(context, records) - val record = records.first() - val database = databaseHelper.writableDatabase - val values = ContentValues(2) - values.put(Companion.publicKey, publicKey) - values.put(preKeyID, record.id) - database.insertOrUpdate(table, values, "${Companion.publicKey} = ?", arrayOf( publicKey )) - return record - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJob.kt index 50f085de8f..04e7714263 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJob.kt @@ -3,7 +3,6 @@ package org.thoughtcrime.securesms.loki.protocol import com.google.protobuf.ByteString import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil -import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl import org.thoughtcrime.securesms.jobmanager.Data import org.thoughtcrime.securesms.jobmanager.Job import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint @@ -124,7 +123,8 @@ class ClosedGroupUpdateMessageSendJob private constructor(parameters: Parameters val recipient = recipient(context, destination) val udAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient) val ttl = TTLUtilities.getTTL(TTLUtilities.MessageType.ClosedGroupUpdate) - val useFallbackEncryption = SignalProtocolStoreImpl(context).containsSession(SignalProtocolAddress(destination, 1)) +// val useFallbackEncryption = SignalProtocolStoreImpl(context).containsSession(SignalProtocolAddress(destination, 1)) + val useFallbackEncryption = true try { // isClosedGroup can always be false as it's only used in the context of legacy closed groups messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt index cf582640f4..b309014208 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt @@ -3,12 +3,9 @@ package org.thoughtcrime.securesms.loki.protocol import android.content.Context import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.crypto.PreKeyUtil import org.thoughtcrime.securesms.crypto.SecurityEvent import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.jobs.CleanPreKeysJob import org.thoughtcrime.securesms.loki.utilities.recipient import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage @@ -41,18 +38,18 @@ object SessionManagementProtocol { lokiThreadDB.removeAllSessionRestoreDevices(threadID) } - @JvmStatic - fun refreshSignedPreKey(context: Context) { - if (TextSecurePreferences.isSignedPreKeyRegistered(context)) { - Log.d("Loki", "Skipping signed pre key refresh; using existing signed pre key.") - } else { - Log.d("Loki", "Signed pre key refreshed successfully.") - val identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context) - PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true) - TextSecurePreferences.setSignedPreKeyRegistered(context, true) - ApplicationContext.getInstance(context).jobManager.add(CleanPreKeysJob()) - } - } +// @JvmStatic +// fun refreshSignedPreKey(context: Context) { +// if (TextSecurePreferences.isSignedPreKeyRegistered(context)) { +// Log.d("Loki", "Skipping signed pre key refresh; using existing signed pre key.") +// } else { +// Log.d("Loki", "Signed pre key refreshed successfully.") +// val identityKeyPair = IdentityKeyUtil.getIdentityKeyPair(context) +// PreKeyUtil.generateSignedPreKey(context, identityKeyPair, true) +// TextSecurePreferences.setSignedPreKeyRegistered(context, true) +// ApplicationContext.getInstance(context).jobManager.add(CleanPreKeysJob()) +// } +// } @JvmStatic fun shouldProcessSessionRequest(context: Context, publicKey: String, timestamp: Long): Boolean { @@ -74,9 +71,9 @@ object SessionManagementProtocol { return } val registrationID = TextSecurePreferences.getLocalRegistrationId(context) - val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) +// val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID) - lokiPreKeyBundleDatabase.setPreKeyBundle(publicKey, preKeyBundle) +// lokiPreKeyBundleDatabase.setPreKeyBundle(publicKey, preKeyBundle) DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestProcessedTimestamp(publicKey, Date().time) val job = NullMessageSendJob(publicKey) ApplicationContext.getInstance(context).jobManager.add(job) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionRequestMessageSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionRequestMessageSendJob.kt index 52dfddd631..b06ece16c3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionRequestMessageSendJob.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionRequestMessageSendJob.kt @@ -44,16 +44,16 @@ class SessionRequestMessageSendJob private constructor(parameters: Parameters, p // Prepare val contentMessage = SignalServiceProtos.Content.newBuilder() // Attach the pre key bundle message - val preKeyBundleMessage = SignalServiceProtos.PreKeyBundleMessage.newBuilder() - val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(publicKey) ?: return - preKeyBundleMessage.identityKey = ByteString.copyFrom(preKeyBundle.identityKey.serialize()) - preKeyBundleMessage.deviceId = preKeyBundle.deviceId - preKeyBundleMessage.preKeyId = preKeyBundle.preKeyId - preKeyBundleMessage.signedKeyId = preKeyBundle.signedPreKeyId - preKeyBundleMessage.preKey = ByteString.copyFrom(preKeyBundle.preKey.serialize()) - preKeyBundleMessage.signedKey = ByteString.copyFrom(preKeyBundle.signedPreKey.serialize()) - preKeyBundleMessage.signature = ByteString.copyFrom(preKeyBundle.signedPreKeySignature) - contentMessage.preKeyBundleMessage = preKeyBundleMessage.build() +// val preKeyBundleMessage = SignalServiceProtos.PreKeyBundleMessage.newBuilder() +// val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(publicKey) ?: return +// preKeyBundleMessage.identityKey = ByteString.copyFrom(preKeyBundle.identityKey.serialize()) +// preKeyBundleMessage.deviceId = preKeyBundle.deviceId +// preKeyBundleMessage.preKeyId = preKeyBundle.preKeyId +// preKeyBundleMessage.signedKeyId = preKeyBundle.signedPreKeyId +// preKeyBundleMessage.preKey = ByteString.copyFrom(preKeyBundle.preKey.serialize()) +// preKeyBundleMessage.signedKey = ByteString.copyFrom(preKeyBundle.signedPreKey.serialize()) +// preKeyBundleMessage.signature = ByteString.copyFrom(preKeyBundle.signedPreKeySignature) +// contentMessage.preKeyBundleMessage = preKeyBundleMessage.build() // Attach the null message val nullMessage = SignalServiceProtos.NullMessage.newBuilder() val sr = SecureRandom() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt index f7de6f26b4..d8675e7279 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt @@ -36,8 +36,8 @@ class SessionResetImplementation(private val context: Context) : SessionResetPro } override fun validatePreKeySignalMessage(publicKey: String, message: PreKeySignalMessage) { - val preKeyRecord = DatabaseFactory.getLokiPreKeyRecordDatabase(context).getPreKeyRecord(publicKey) ?: return - // TODO: Checking that the pre key record isn't null is causing issues when it shouldn't - check(preKeyRecord.id == (message.preKeyId ?: -1)) { "Received a background message from an unknown source." } +// val preKeyRecord = DatabaseFactory.getLokiPreKeyRecordDatabase(context).getPreKeyRecord(publicKey) ?: return +// // TODO: Checking that the pre key record isn't null is causing issues when it shouldn't +// check(preKeyRecord.id == (message.preKeyId ?: -1)) { "Received a background message from an unknown source." } } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceOpenGroupUpdateJob.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceOpenGroupUpdateJob.kt deleted file mode 100644 index a8f49a7a8e..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceOpenGroupUpdateJob.kt +++ /dev/null @@ -1,76 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol.shelved - -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.dependencies.InjectableType -import org.thoughtcrime.securesms.groups.GroupManager -import org.thoughtcrime.securesms.jobmanager.Data -import org.thoughtcrime.securesms.jobmanager.Job -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint -import org.thoughtcrime.securesms.jobs.BaseJob -import org.thoughtcrime.securesms.logging.Log -import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.session.libsignal.service.api.SignalServiceMessageSender -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage -import org.session.libsignal.service.loki.api.opengroups.PublicChat -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -class MultiDeviceOpenGroupUpdateJob private constructor(parameters: Parameters) : BaseJob(parameters), InjectableType { - - companion object { - const val KEY = "MultiDeviceOpenGroupUpdateJob" - } - - @Inject - lateinit var messageSender: SignalServiceMessageSender - - constructor() : this(Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue(KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(Parameters.UNLIMITED) - .build()) - - override fun getFactoryKey(): String { return KEY } - - override fun serialize(): Data { return Data.EMPTY } - - @Throws(Exception::class) - public override fun onRun() { - if (!TextSecurePreferences.isMultiDevice(context)) { - Log.d("Loki", "Not multi device; aborting...") - return - } - // Gather open groups - val openGroups = mutableListOf() - DatabaseFactory.getGroupDatabase(context).groups.use { reader -> - while (true) { - val record = reader.next ?: return@use - if (!record.isOpenGroup) { continue; } - val threadID = GroupManager.getThreadIDFromGroupID(record.encodedId, context) - val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) - if (openGroup != null) { openGroups.add(openGroup) } - } - } - // Send the message - if (openGroups.size > 0) { - messageSender.sendMessage(SignalServiceSyncMessage.forOpenGroups(openGroups), UnidentifiedAccessUtil.getAccessForSync(context)) - } else { - Log.d("Loki", "No open groups to sync.") - } - } - - public override fun onShouldRetry(exception: Exception): Boolean { - return false - } - - override fun onCanceled() { } - - class Factory : Job.Factory { - - override fun create(parameters: Parameters, data: Data): MultiDeviceOpenGroupUpdateJob { - return MultiDeviceOpenGroupUpdateJob(parameters) - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt deleted file mode 100644 index 0c04921135..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/MultiDeviceProtocol.kt +++ /dev/null @@ -1,204 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol.shelved - -import android.content.Context -import org.thoughtcrime.securesms.logging.Log -import nl.komponents.kovenant.Promise -import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.crypto.IdentityKeyUtil -import org.thoughtcrime.securesms.crypto.ProfileKeyUtil -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.jobs.PushMediaSendJob -import org.thoughtcrime.securesms.jobs.PushSendJob -import org.thoughtcrime.securesms.jobs.PushTextSendJob -import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol -import org.thoughtcrime.securesms.loki.utilities.Broadcaster -import org.thoughtcrime.securesms.loki.utilities.recipient -import org.thoughtcrime.securesms.recipients.Recipient -import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.session.libsignal.service.api.messages.SignalServiceContent -import org.session.libsignal.service.api.messages.SignalServiceDataMessage -import org.session.libsignal.service.api.push.SignalServiceAddress -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI -import org.session.libsignal.service.loki.protocol.shelved.multidevice.DeviceLink -import org.session.libsignal.service.loki.protocol.shelved.multidevice.DeviceLinkingSession -import org.session.libsignal.service.loki.protocol.shelved.multidevice.MultiDeviceProtocol -import org.session.libsignal.service.loki.utilities.retryIfNeeded - -object MultiDeviceProtocol { - - enum class MessageType { Text, Media } - - @JvmStatic - fun sendTextPush(context: Context, recipient: Recipient, messageID: Long) { - sendMessagePush(context, recipient, messageID, MessageType.Text) - } - - @JvmStatic - fun sendMediaPush(context: Context, recipient: Recipient, messageID: Long) { - sendMessagePush(context, recipient, messageID, MessageType.Media) - } - - private fun sendMessagePush(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType) { - val jobManager = ApplicationContext.getInstance(context).jobManager - val isMultiDeviceRequired = !recipient.address.isOpenGroup - if (!isMultiDeviceRequired) { - when (messageType) { - MessageType.Text -> jobManager.add(PushTextSendJob(messageID, recipient.address)) - MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, messageID, recipient.address) - } - } - val publicKey = recipient.address.serialize() - FileServerAPI.shared.getDeviceLinks(publicKey).success { - val devices = MultiDeviceProtocol.shared.getAllLinkedDevices(publicKey) - val jobs = devices.map { - when (messageType) { - MessageType.Text -> PushTextSendJob(messageID, messageID, recipient(context, it).address) as PushSendJob - MessageType.Media -> PushMediaSendJob(messageID, messageID, recipient(context, it).address) as PushSendJob - } - } - @Suppress("UNCHECKED_CAST") - when (messageType) { - MessageType.Text -> jobManager.startChain(jobs).enqueue() - MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, jobs as List) - } - }.fail { - // Proceed even if updating the recipient's device links failed, so that message sending - // is independent of whether the file server is online - when (messageType) { - MessageType.Text -> jobManager.add(PushTextSendJob(messageID, recipient.address)) - MessageType.Media -> PushMediaSendJob.enqueue(context, jobManager, messageID, recipient.address) - } - } - } - - fun sendDeviceLinkMessage(context: Context, publicKey: String, deviceLink: DeviceLink): Promise { - val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() - val address = SignalServiceAddress(publicKey) - val message = SignalServiceDataMessage.newBuilder().withDeviceLink(deviceLink) - // A request should include a pre key bundle. An authorization should be a normal message. - if (deviceLink.type == DeviceLink.Type.REQUEST) { - val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number) - message.withPreKeyBundle(preKeyBundle) - } else { - // Include the user's profile key so that the slave device can get the user's profile picture - message.withProfileKey(ProfileKeyUtil.getProfileKey(context)) - } - return try { - Log.d("Loki", "Sending device link message to: $publicKey.") - val udAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient(context, publicKey)) - val result = messageSender.sendMessage(0, address, udAccess, message.build()) - if (result.success == null) { - val exception = when { - result.isNetworkFailure -> "Failed to send device link message due to a network error." - else -> "Failed to send device link message." - } - throw Exception(exception) - } - Promise.ofSuccess(Unit) - } catch (e: Exception) { - Log.d("Loki", "Failed to send device link message to: $publicKey due to error: $e.") - Promise.ofFail(e) - } - } - - fun signAndSendDeviceLinkMessage(context: Context, deviceLink: DeviceLink): Promise { - val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() - val signedDeviceLink = deviceLink.sign(DeviceLink.Type.AUTHORIZATION, userPrivateKey) - if (signedDeviceLink == null || signedDeviceLink.type != DeviceLink.Type.AUTHORIZATION) { - return Promise.ofFail(Exception("Failed to sign device link.")) - } - return retryIfNeeded(8) { - sendDeviceLinkMessage(context, deviceLink.slavePublicKey, signedDeviceLink) - } - } - - @JvmStatic - fun handleDeviceLinkMessageIfNeeded(context: Context, deviceLink: DeviceLink, content: SignalServiceContent) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - if (deviceLink.type == DeviceLink.Type.REQUEST) { - handleDeviceLinkRequestMessage(context, deviceLink, content) - } else if (deviceLink.slavePublicKey == userPublicKey) { - handleDeviceLinkAuthorizedMessage(context, deviceLink, content) - } - } - - private fun isValidDeviceLinkMessage(context: Context, deviceLink: DeviceLink): Boolean { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - val isRequest = (deviceLink.type == DeviceLink.Type.REQUEST) - if (deviceLink.requestSignature == null) { - Log.d("Loki", "Ignoring device link without a request signature.") - return false - } else if (isRequest && TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null) { - Log.d("Loki", "Ignoring unexpected device link message (the device is a slave device).") - return false - } else if (isRequest && deviceLink.masterPublicKey != userPublicKey) { - Log.d("Loki", "Ignoring device linking message addressed to another user.") - return false - } else if (isRequest && deviceLink.slavePublicKey == userPublicKey) { - Log.d("Loki", "Ignoring device linking request message from self.") - return false - } - return deviceLink.verify() - } - - private fun handleDeviceLinkRequestMessage(context: Context, deviceLink: DeviceLink, content: SignalServiceContent) { - val linkingSession = DeviceLinkingSession.shared - if (!linkingSession.isListeningForLinkingRequests) { - return Broadcaster(context).broadcast("unexpectedDeviceLinkRequestReceived") - } - val isValid = isValidDeviceLinkMessage(context, deviceLink) - if (!isValid) { return } - // The line below isn't actually necessary because this is called after PushDecryptJob - // calls handlePreKeyBundleMessageIfNeeded, but it also doesn't hurt. - SessionManagementProtocol.handlePreKeyBundleMessageIfNeeded(context, content) - linkingSession.processLinkingRequest(deviceLink) - } - - private fun handleDeviceLinkAuthorizedMessage(context: Context, deviceLink: DeviceLink, content: SignalServiceContent) { - val linkingSession = DeviceLinkingSession.shared - if (!linkingSession.isListeningForLinkingRequests) { - return - } - val isValid = isValidDeviceLinkMessage(context, deviceLink) - if (!isValid) { return } - linkingSession.processLinkingAuthorization(deviceLink) - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userPublicKey) - DatabaseFactory.getLokiAPIDatabase(context).addDeviceLink(deviceLink) - TextSecurePreferences.setMasterHexEncodedPublicKey(context, deviceLink.masterPublicKey) - TextSecurePreferences.setMultiDevice(context, true) - FileServerAPI.shared.addDeviceLink(deviceLink) - org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol.handleProfileKeyUpdate(context, content) - } - - @JvmStatic - fun handleUnlinkingRequestIfNeeded(context: Context, content: SignalServiceContent) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - // Check that the request was sent by the user's master device - val masterDevicePublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context) ?: return - val wasSentByMasterDevice = (content.sender == masterDevicePublicKey) - if (!wasSentByMasterDevice) { return } - // Ignore the request if we don't know about the device link in question - val masterDeviceLinks = DatabaseFactory.getLokiAPIDatabase(context).getDeviceLinks(masterDevicePublicKey) - if (masterDeviceLinks.none { - it.masterPublicKey == masterDevicePublicKey && it.slavePublicKey == userPublicKey - }) { - return - } - FileServerAPI.shared.getDeviceLinks(userPublicKey, true).success { slaveDeviceLinks -> - // Check that the device link IS present on the file server. - // Note that the device link as seen from the master device's perspective has been deleted at this point, but the - // device link as seen from the slave perspective hasn't. - if (slaveDeviceLinks.any { - it.masterPublicKey == masterDevicePublicKey && it.slavePublicKey == userPublicKey - }) { - for (slaveDeviceLink in slaveDeviceLinks) { // In theory there should only be one - FileServerAPI.shared.removeDeviceLink(slaveDeviceLink) // Attempt to clean up on the file server - } - TextSecurePreferences.setWasUnlinked(context, true) - ApplicationContext.getInstance(context).clearData() - } - } - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/SyncMessagesProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/SyncMessagesProtocol.kt deleted file mode 100644 index 5c687cb76b..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/shelved/SyncMessagesProtocol.kt +++ /dev/null @@ -1,173 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol.shelved - -import android.content.Context -import org.thoughtcrime.securesms.logging.Log -import androidx.annotation.WorkerThread -import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.contacts.ContactAccessor.ContactData -import org.thoughtcrime.securesms.contacts.ContactAccessor.NumberData -import org.thoughtcrime.securesms.database.Address -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.database.RecipientDatabase -import org.thoughtcrime.securesms.groups.GroupManager -import org.thoughtcrime.securesms.groups.GroupMessageProcessor -import org.thoughtcrime.securesms.jobs.MultiDeviceContactUpdateJob -import org.thoughtcrime.securesms.jobs.MultiDeviceGroupUpdateJob -import org.thoughtcrime.securesms.loki.utilities.ContactUtilities -import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities -import org.thoughtcrime.securesms.loki.utilities.recipient -import org.thoughtcrime.securesms.recipients.Recipient -import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.session.libsignal.service.api.messages.SignalServiceAttachment -import org.session.libsignal.service.api.messages.SignalServiceContent -import org.session.libsignal.service.api.messages.SignalServiceDataMessage -import org.session.libsignal.service.api.messages.SignalServiceGroup -import org.session.libsignal.service.api.messages.multidevice.BlockedListMessage -import org.session.libsignal.service.api.messages.multidevice.ContactsMessage -import org.session.libsignal.service.api.messages.multidevice.DeviceContactsInputStream -import org.session.libsignal.service.api.messages.multidevice.DeviceGroupsInputStream -import org.session.libsignal.service.loki.api.opengroups.PublicChat -import org.session.libsignal.service.loki.protocol.shelved.multidevice.MultiDeviceProtocol -import org.session.libsignal.service.loki.utilities.PublicKeyValidation - -object SyncMessagesProtocol { - - @JvmStatic - fun shouldIgnoreSyncMessage(context: Context, sender: Recipient): Boolean { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - return userPublicKey == sender.address.serialize() // return !MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey).contains(sender.address.serialize()) - } - - @JvmStatic - fun syncContact(context: Context, address: Address) { - ApplicationContext.getInstance(context).jobManager.add(MultiDeviceContactUpdateJob(context, address, true)) - } - - @JvmStatic - fun syncAllContacts(context: Context) { - ApplicationContext.getInstance(context).jobManager.add(MultiDeviceContactUpdateJob(context, true)) - } - - @JvmStatic - fun getContactsToSync(context: Context): List { - val contacts = ContactUtilities.getAllContacts(context) - val result = mutableSetOf() - for (contact in contacts) { - val contactPublicKey = contact.recipient.address.serialize() - if (!shouldSyncContact(context, contactPublicKey)) { continue } - val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdIfExistsFor(recipient(context, contactPublicKey)) - if (threadID < 0) { continue } - val displayName = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(contactPublicKey) - val contactData = ContactData(threadID, displayName) - contactData.numbers.add(NumberData("TextSecure", contactPublicKey)) - result.add(contactData) - } - return result.toList() - } - - @JvmStatic - fun shouldSyncContact(context: Context, publicKey: String): Boolean { - if (!PublicKeyValidation.isValid(publicKey)) { return false } - if (publicKey == TextSecurePreferences.getMasterHexEncodedPublicKey(context)) { return false } - if (publicKey == TextSecurePreferences.getLocalNumber(context)) { return false } - if (MultiDeviceProtocol.shared.getSlaveDevices(publicKey).contains(publicKey)) { return false } - return true - } - - @JvmStatic - fun syncAllClosedGroups(context: Context) { - ApplicationContext.getInstance(context).jobManager.add(MultiDeviceGroupUpdateJob()) - } - - @JvmStatic - fun syncAllOpenGroups(context: Context) { - ApplicationContext.getInstance(context).jobManager.add(MultiDeviceOpenGroupUpdateJob()) - } - - @JvmStatic - fun shouldSyncReadReceipt(address: Address): Boolean { - return !address.isGroup - } - - @JvmStatic - fun handleContactSyncMessage(context: Context, content: SignalServiceContent, message: ContactsMessage) { - if (!message.contactsStream.isStream) { return } - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - val allUserDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey) - if (!allUserDevices.contains(content.sender)) { return } - Log.d("Loki", "Received a contact sync message.") - val contactsInputStream = DeviceContactsInputStream(message.contactsStream.asStream().inputStream) - val contacts = contactsInputStream.readAll() - for (contact in contacts) { - val contactPublicKey = contact.number - if (contactPublicKey == userPublicKey || !PublicKeyValidation.isValid(contactPublicKey)) { return } - val applicationContext = context.applicationContext as ApplicationContext - applicationContext.sendSessionRequestIfNeeded(contactPublicKey) - DatabaseFactory.getRecipientDatabase(context).setBlocked(recipient(context, contactPublicKey), contact.isBlocked) - } - } - - @JvmStatic - fun handleClosedGroupSyncMessage(context: Context, content: SignalServiceContent, message: SignalServiceAttachment) { - if (!message.isStream) { return } - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - val allUserDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey) - if (!allUserDevices.contains(content.sender)) { return } - Log.d("Loki", "Received a closed group sync message.") - val closedGroupsInputStream = DeviceGroupsInputStream(message.asStream().inputStream) - val closedGroups = closedGroupsInputStream.readAll() - for (closedGroup in closedGroups) { - val signalServiceGroup = SignalServiceGroup( - SignalServiceGroup.Type.UPDATE, - closedGroup.id, - SignalServiceGroup.GroupType.SIGNAL, - closedGroup.name.orNull(), - closedGroup.members, - closedGroup.avatar.orNull(), - closedGroup.admins - ) - val dataMessage = SignalServiceDataMessage(content.timestamp, signalServiceGroup, null, null) - // This establishes sessions internally - GroupMessageProcessor.process(context, content, dataMessage, false) - } - } - - @JvmStatic - @WorkerThread - fun handleOpenGroupSyncMessage(context: Context, content: SignalServiceContent, openGroups: List) { - val userPublicKey = TextSecurePreferences.getLocalNumber(context) - val allUserDevices = MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey) - if (!allUserDevices.contains(content.sender)) { return } - Log.d("Loki", "Received an open group sync message.") - for (openGroup in openGroups) { - val threadID: Long = GroupManager.getOpenGroupThreadID(openGroup.id, context) - if (threadID > -1) { continue } // Skip existing open groups - val url = openGroup.server - val channel = openGroup.channel - OpenGroupUtilities.addGroup(context, url, channel) - } - } - - @JvmStatic - fun handleBlockedContactsSyncMessage(context: Context, content: SignalServiceContent, blockedContacts: BlockedListMessage) { - val recipientDB = DatabaseFactory.getRecipientDatabase(context) - val cursor = recipientDB.blocked - val blockedPublicKeys = blockedContacts.numbers.toSet() - val publicKeysToUnblock = mutableSetOf() - fun addToUnblockListIfNeeded() { - val publicKey = cursor.getString(cursor.getColumnIndex(RecipientDatabase.ADDRESS)) ?: return - if (blockedPublicKeys.contains(publicKey)) { return } - publicKeysToUnblock.add(publicKey) - } - while (cursor.moveToNext()) { - addToUnblockListIfNeeded() - } - publicKeysToUnblock.forEach { - recipientDB.setBlocked(recipient(context, it), false) - } - blockedPublicKeys.forEach { - recipientDB.setBlocked(recipient(context, it), true) - } - ApplicationContext.getInstance(context).broadcaster.broadcast("blockedContactsChanged") - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java index a9801d3b6d..08592cbef7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/app/src/main/java/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -17,11 +17,9 @@ import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.MessagingDatabase.ExpirationInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.MarkedMessageInfo; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; -import org.thoughtcrime.securesms.jobs.MultiDeviceReadUpdateJob; import org.thoughtcrime.securesms.jobs.SendReadReceiptJob; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.protocol.SessionMetaProtocol; -import org.thoughtcrime.securesms.loki.protocol.shelved.SyncMessagesProtocol; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.session.libsignal.service.loki.protocol.shelved.multidevice.MultiDeviceProtocol; @@ -76,16 +74,8 @@ public class MarkReadReceiver extends BroadcastReceiver { for (MarkedMessageInfo messageInfo : markedReadMessages) { scheduleDeletion(context, messageInfo.getExpirationInfo()); - - if (SyncMessagesProtocol.shouldSyncReadReceipt(messageInfo.getSyncMessageId().getAddress())) { - syncMessageIds.add(messageInfo.getSyncMessageId()); - } } - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceReadUpdateJob(syncMessageIds)); - Map> addressMap = Stream.of(markedReadMessages) .map(MarkedMessageInfo::getSyncMessageId) .collect(Collectors.groupingBy(SyncMessageId::getAddress)); diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java index 4d64ccd295..2ebc0a9ad2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/AppProtectionPreferenceFragment.java @@ -12,20 +12,16 @@ import androidx.appcompat.app.AlertDialog; import androidx.preference.CheckBoxPreference; import androidx.preference.Preference; -import org.session.libsignal.service.api.SignalServiceAccountManager; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.PassphraseChangeActivity; import org.thoughtcrime.securesms.components.SwitchPreferenceCompat; import org.thoughtcrime.securesms.crypto.MasterSecretUtil; import org.thoughtcrime.securesms.dependencies.InjectableType; -import org.thoughtcrime.securesms.jobs.MultiDeviceConfigurationUpdateJob; import org.thoughtcrime.securesms.service.KeyCachingService; import org.thoughtcrime.securesms.util.TextSecurePreferences; import java.util.concurrent.TimeUnit; -import javax.inject.Inject; - import mobi.upod.timedurationpicker.TimeDurationPickerDialog; import network.loki.messenger.R; @@ -33,9 +29,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment private CheckBoxPreference disablePassphrase; - @Inject - SignalServiceAccountManager accountManager; - @Override public void onAttach(Activity activity) { super.onAttach(activity); @@ -147,13 +140,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment @Override public boolean onPreferenceChange(Preference preference, Object newValue) { boolean enabled = (boolean)newValue; - ApplicationContext.getInstance(getContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(enabled, - TextSecurePreferences.isTypingIndicatorsEnabled(requireContext()), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()), - TextSecurePreferences.isLinkPreviewsEnabled(getContext()))); - return true; } } @@ -163,13 +149,6 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment public boolean onPreferenceChange(Preference preference, Object newValue) { boolean enabled = (boolean)newValue; - ApplicationContext.getInstance(getContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), - enabled, - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(getContext()), - TextSecurePreferences.isLinkPreviewsEnabled(getContext()))); - if (!enabled) { ApplicationContext.getInstance(requireContext()).getTypingStatusRepository().clear(); } @@ -191,24 +170,11 @@ public class AppProtectionPreferenceFragment extends CorrectedPreferenceFragment builder.setNegativeButton("Cancel", (dialog, which) -> { TextSecurePreferences.setLinkPreviewsEnabled(requireContext(), false); ((SwitchPreferenceCompat)AppProtectionPreferenceFragment.this.findPreference(TextSecurePreferences.LINK_PREVIEWS)).setChecked(false); - ApplicationContext.getInstance(requireContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), - TextSecurePreferences.isTypingIndicatorsEnabled(requireContext()), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(requireContext()), - false)); dialog.dismiss(); }); builder.create().show(); } - ApplicationContext.getInstance(requireContext()) - .getJobManager() - .add(new MultiDeviceConfigurationUpdateJob(TextSecurePreferences.isReadReceiptsEnabled(requireContext()), - TextSecurePreferences.isTypingIndicatorsEnabled(requireContext()), - TextSecurePreferences.isShowUnidentifiedDeliveryIndicatorsEnabled(requireContext()), - enabled)); - return true; } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java b/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java deleted file mode 100644 index d1a6198892..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/service/RotateSignedPreKeyListener.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.thoughtcrime.securesms.service; - - -import android.content.Context; -import android.content.Intent; - -import org.thoughtcrime.securesms.ApplicationContext; -import org.thoughtcrime.securesms.jobs.RotateSignedPreKeyJob; -import org.thoughtcrime.securesms.util.TextSecurePreferences; - -import java.util.concurrent.TimeUnit; - -public class RotateSignedPreKeyListener extends PersistentAlarmManagerListener { - - private static final long INTERVAL = TimeUnit.DAYS.toMillis(2); - - @Override - protected long getNextScheduledExecutionTime(Context context) { - return TextSecurePreferences.getSignedPreKeyRotationTime(context); - } - - @Override - protected long onAlarm(Context context, long scheduledTime) { - if (scheduledTime != 0 /*&& TextSecurePreferences.isPushRegistered(context)*/) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new RotateSignedPreKeyJob()); - } - - long nextTime = System.currentTimeMillis() + INTERVAL; - TextSecurePreferences.setSignedPreKeyRotationTime(context, nextTime); - - return nextTime; - } - - public static void schedule(Context context) { - new RotateSignedPreKeyListener().onReceive(context, new Intent()); - } -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java index 2dc5abf900..9d805d6a13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/stickers/StickerManagementRepository.java @@ -11,7 +11,6 @@ import org.thoughtcrime.securesms.database.StickerDatabase; import org.thoughtcrime.securesms.database.StickerDatabase.StickerPackRecordReader; import org.thoughtcrime.securesms.database.model.StickerPackRecord; import org.thoughtcrime.securesms.jobmanager.JobManager; -import org.thoughtcrime.securesms.jobs.MultiDeviceStickerPackOperationJob; import org.thoughtcrime.securesms.jobs.StickerPackDownloadJob; import org.thoughtcrime.securesms.util.TextSecurePreferences; import org.thoughtcrime.securesms.util.concurrent.SignalExecutors; @@ -76,12 +75,6 @@ final class StickerManagementRepository { void uninstallStickerPack(@NonNull String packId, @NonNull String packKey) { SignalExecutors.SERIAL.execute(() -> { stickerDatabase.uninstallPack(packId); - - if (TextSecurePreferences.isMultiDevice(context)) { - ApplicationContext.getInstance(context) - .getJobManager() - .add(new MultiDeviceStickerPackOperationJob(packId, packKey, MultiDeviceStickerPackOperationJob.Type.REMOVE)); - } }); } @@ -94,10 +87,6 @@ final class StickerManagementRepository { } jobManager.add(new StickerPackDownloadJob(packId, packKey, false)); - - if (TextSecurePreferences.isMultiDevice(context)) { - jobManager.add(new MultiDeviceStickerPackOperationJob(packId, packKey, MultiDeviceStickerPackOperationJob.Type.INSTALL)); - } }); } diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/LokiServiceCipher.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/LokiServiceCipher.kt index 39cb89abae..4888533a4a 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/LokiServiceCipher.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/crypto/LokiServiceCipher.kt @@ -11,12 +11,19 @@ import org.session.libsignal.service.api.push.SignalServiceAddress import org.session.libsignal.service.internal.push.PushTransportDetails import org.session.libsignal.service.loki.protocol.closedgroups.SharedSenderKeysDatabaseProtocol -class LokiServiceCipher(localAddress: SignalServiceAddress, private val signalProtocolStore: SignalProtocolStore, private val sskDatabase: SharedSenderKeysDatabaseProtocol, sessionResetProtocol: SessionResetProtocol, certificateValidator: CertificateValidator?) : SignalServiceCipher(localAddress, signalProtocolStore, sskDatabase, sessionResetProtocol, certificateValidator) { +class LokiServiceCipher( + localAddress: SignalServiceAddress, + private val signalProtocolStore: SignalProtocolStore, + private val sskDatabase: SharedSenderKeysDatabaseProtocol, + sessionResetProtocol: SessionResetProtocol, + certificateValidator: CertificateValidator?) + : SignalServiceCipher(localAddress, signalProtocolStore, sskDatabase, sessionResetProtocol, certificateValidator) { private val userPrivateKey get() = signalProtocolStore.identityKeyPair.privateKey.serialize() override fun decrypt(envelope: SignalServiceEnvelope, ciphertext: ByteArray): Plaintext { - return if (envelope.isFallbackMessage) decryptFallbackMessage(envelope, ciphertext) else super.decrypt(envelope, ciphertext) +// return if (envelope.isFallbackMessage) decryptFallbackMessage(envelope, ciphertext) else super.decrypt(envelope, ciphertext) + return decryptFallbackMessage(envelope, ciphertext); } private fun decryptFallbackMessage(envelope: SignalServiceEnvelope, ciphertext: ByteArray): Plaintext {