From 958ec690f10f5e46cf6d0740eb4e6433e97f1532 Mon Sep 17 00:00:00 2001 From: Ryan ZHAO Date: Fri, 19 Feb 2021 11:03:58 +1100 Subject: [PATCH] WIP: clean up signal protocols --- .../securesms/ApplicationContext.java | 14 +- .../conversation/ConversationActivity.java | 11 +- .../securesms/database/PushDatabase.java | 16 +- .../database/helpers/SQLCipherOpenHelper.java | 4 +- .../SignalCommunicationModule.java | 8 +- .../securesms/jobs/JobManagerFactories.java | 2 - .../securesms/jobs/PushDecryptJob.java | 147 +---- .../securesms/jobs/PushMediaSendJob.java | 4 +- .../securesms/jobs/PushReceivedJob.java | 12 +- .../securesms/jobs/PushSendJob.java | 13 - .../securesms/jobs/PushTextSendJob.java | 4 +- .../securesms/jobs/TypingSendJob.java | 4 +- .../loki/activities/BackupRestoreActivity.kt | 2 - .../securesms/loki/activities/HomeActivity.kt | 31 +- .../securesms/loki/api/PublicChatPoller.kt | 83 +-- .../loki/database/LokiThreadDatabase.kt | 29 - .../ClosedGroupUpdateMessageSendJobV2.kt | 3 +- .../loki/protocol/MultiDeviceProtocol.kt | 5 +- .../loki/protocol/NullMessageSendJob.kt | 85 --- .../protocol/SessionManagementProtocol.kt | 102 ---- .../protocol/SessionResetImplementation.kt | 43 -- .../loki/utilities/MentionManagerUtilities.kt | 2 +- .../securesms/loki/views/ConversationView.kt | 2 - .../views/MentionCandidateSelectionView.kt | 2 +- .../loki/views/MentionCandidateView.kt | 2 +- .../loki/views/ProfilePictureView.kt | 2 +- .../service/ExpiringMessageManager.java | 1 - libsignal/protobuf/SignalService.proto | 6 + .../libsignal/loki/LokiSessionCipher.kt | 78 --- .../libsignal/loki/SessionResetProtocol.kt | 11 - .../libsignal/loki/SessionResetStatus.kt | 7 - .../metadata/SealedSessionCipher.java | 12 +- .../api/SignalServiceMessageSender.java | 35 +- .../api/crypto/SignalServiceCipher.java | 28 +- .../api/messages/SignalServiceContent.java | 3 - .../messages/SignalServiceDataMessage.java | 2 +- .../messages/SignalServiceNullMessage.java | 2 +- .../messages/SignalServiceReceiptMessage.java | 2 +- .../messages/SignalServiceTypingMessage.java | 3 +- .../calls/SignalServiceCallMessage.java | 2 +- .../internal/push/SignalServiceProtos.java | 512 +++++++++++++++++- .../libsignal/service/loki/api/LokiMessage.kt | 2 +- .../loki/protocol/meta/SessionMetaProtocol.kt | 24 - .../sessionmanagement/PreKeyBundleMessage.kt | 23 - .../SessionManagementProtocol.kt | 53 -- .../SessionManagementProtocolDelegate.kt | 6 - .../meta => utilities}/TTLUtilities.kt | 2 +- .../mentions/Mention.kt | 2 +- .../mentions/MentionsManager.kt | 2 +- 49 files changed, 568 insertions(+), 882 deletions(-) delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/NullMessageSendJob.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt delete mode 100644 app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/libsignal/loki/LokiSessionCipher.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetProtocol.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetStatus.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/SessionMetaProtocol.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/PreKeyBundleMessage.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocol.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocolDelegate.kt rename libsignal/src/main/java/org/session/libsignal/service/loki/{protocol/meta => utilities}/TTLUtilities.kt (96%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{protocol => utilities}/mentions/Mention.kt (52%) rename libsignal/src/main/java/org/session/libsignal/service/loki/{protocol => utilities}/mentions/MentionsManager.kt (97%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 2a63e99900..1e27dd7822 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -76,7 +76,6 @@ import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol; -import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation; import org.thoughtcrime.securesms.loki.utilities.Broadcaster; import org.thoughtcrime.securesms.loki.utilities.UiModeUtilities; import org.thoughtcrime.securesms.notifications.DefaultMessageNotifier; @@ -84,7 +83,6 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.notifications.OptimizedMessageNotifier; import org.thoughtcrime.securesms.providers.BlobProvider; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; -import org.session.libsession.messaging.threads.recipients.Recipient; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.service.IncomingMessageObserver; import org.thoughtcrime.securesms.service.KeyCachingService; @@ -107,8 +105,7 @@ import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI; import org.session.libsignal.service.loki.api.shelved.p2p.LokiP2PAPI; import org.session.libsignal.service.loki.api.shelved.p2p.LokiP2PAPIDelegate; import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager; -import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol; +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import java.io.File; import java.io.FileInputStream; @@ -136,7 +133,6 @@ import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; public class ApplicationContext extends MultiDexApplication implements DependencyInjector, DefaultLifecycleObserver, LokiP2PAPIDelegate { private static final String TAG = ApplicationContext.class.getSimpleName(); - private final static int OK_HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10 MB private ExpiringMessageManager expiringMessageManager; private TypingStatusRepository typingStatusRepository; @@ -144,7 +140,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc private JobManager jobManager; private ReadReceiptManager readReceiptManager; private ProfileManager profileManager; - private IncomingMessageObserver incomingMessageObserver; private ObjectGraph objectGraph; private PersistentLogger persistentLogger; @@ -182,7 +177,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(this); LokiUserDatabase userDB = DatabaseFactory.getLokiUserDatabase(this); String userPublicKey = TextSecurePreferences.getLocalNumber(this); - SessionResetImplementation sessionResetImpl = new SessionResetImplementation(this); MessagingConfiguration.Companion.configure(this, DatabaseFactory.getStorage(this), DatabaseFactory.getAttachmentProvider(this), @@ -191,7 +185,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc SwarmAPI.Companion.configureIfNeeded(apiDB); SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB); - SessionMetaProtocol.Companion.configureIfNeeded(apiDB, userPublicKey); } setUpP2PAPIIfNeeded(); PushNotificationAPI.Companion.configureIfNeeded(BuildConfig.DEBUG); @@ -206,7 +199,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc UiModeUtilities.setupUiModeToUserSelected(this); // ======== initializeJobManager(); - initializeMessageRetrieval(); initializeExpiringMessageManager(); initializeTypingStatusRepository(); initializeTypingStatusSender(); @@ -347,10 +339,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc .build()); } - public void initializeMessageRetrieval() { - this.incomingMessageObserver = new IncomingMessageObserver(this); - } - private void initializeDependencyInjection() { communicationModule = new SignalCommunicationModule(this, new SignalServiceNetworkAccess(this)); this.objectGraph = ObjectGraph.create(communicationModule); 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 8df2752fbf..5831af49c9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -90,9 +90,8 @@ import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.libsignal.InvalidMessageException; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.loki.api.opengroups.PublicChat; -import org.session.libsignal.service.loki.protocol.mentions.Mention; -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager; -import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol; +import org.session.libsignal.service.loki.utilities.mentions.Mention; +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import org.session.libsignal.service.loki.utilities.HexEncodingKt; import org.session.libsignal.service.loki.utilities.PublicKeyValidation; import org.thoughtcrime.securesms.ApplicationContext; @@ -144,7 +143,6 @@ import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabaseDelegate; import org.thoughtcrime.securesms.loki.database.LokiUserDatabase; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2; -import org.thoughtcrime.securesms.loki.protocol.SessionManagementProtocol; import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt; import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities; import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities; @@ -404,7 +402,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity }); sessionRestoreBannerView.setOnRestore(() -> { - SessionManagementProtocol.startSessionReset(this, recipient.getAddress().serialize()); updateSessionRestoreBanner(); return Unit.INSTANCE; }); @@ -2003,7 +2000,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity Log.w(TAG, ex); } - if (messageStatus == null && !isGroupConversation() && !SessionMetaProtocol.shared.isNoteToSelf(recipient.getAddress().serialize())) { + if (messageStatus == null && !isGroupConversation() && !(TextSecurePreferences.getLocalNumber(this).equals(recipient.getAddress().serialize()))) { messageStatus = "calculatingPoW"; updateSubtitleTextView(); updateMessageStatusProgressBar(); @@ -2680,7 +2677,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } private void handleMessageStatusChanged(String newMessageStatus, long timestamp) { - if (timestamp == 0 || SessionMetaProtocol.shared.isNoteToSelf(recipient.getAddress().serialize()) ) { return; } + if (timestamp == 0 || (TextSecurePreferences.getLocalNumber(this).equals(recipient.getAddress().serialize())) ) { return; } updateForNewMessageStatusIfNeeded(newMessageStatus, timestamp); if (newMessageStatus.equals("messageFailed") || newMessageStatus.equals("messageSent")) { new Handler().postDelayed(() -> clearMessageStatusIfNeeded(timestamp), 1000); diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java index dac1aea8db..73a361ae55 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/PushDatabase.java @@ -49,11 +49,11 @@ public class PushDatabase extends Database { values.put(TYPE, envelope.getType()); values.put(SOURCE, envelope.getSource()); values.put(DEVICE_ID, envelope.getSourceDevice()); - values.put(LEGACY_MSG, envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : ""); + values.put(LEGACY_MSG, ""); values.put(CONTENT, envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : ""); values.put(TIMESTAMP, envelope.getTimestamp()); values.put(SERVER_TIMESTAMP, envelope.getServerTimestamp()); - values.put(SERVER_GUID, envelope.getUuid()); + values.put(SERVER_GUID, ""); return databaseHelper.getWritableDatabase().insert(TABLE_NAME, null, values); } @@ -68,17 +68,14 @@ public class PushDatabase extends Database { null, null, null); if (cursor != null && cursor.moveToNext()) { - String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG)); String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT)); return new SignalServiceEnvelope(cursor.getInt(cursor.getColumnIndexOrThrow(TYPE)), cursor.getString(cursor.getColumnIndexOrThrow(SOURCE)), cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)), - Util.isEmpty(legacyMessage) ? null : Base64.decode(legacyMessage), Util.isEmpty(content) ? null : Base64.decode(content), - cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP)), - cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID))); + cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP))); } } catch (IOException e) { Log.w(TAG, e); @@ -114,7 +111,7 @@ public class PushDatabase extends Database { new String[] {String.valueOf(envelope.getType()), envelope.getSource(), String.valueOf(envelope.getSourceDevice()), - envelope.hasLegacyMessage() ? Base64.encodeBytes(envelope.getLegacyMessage()) : "", + "", envelope.hasContent() ? Base64.encodeBytes(envelope.getContent()) : "", String.valueOf(envelope.getTimestamp())}, null, null, null); @@ -144,16 +141,13 @@ public class PushDatabase extends Database { int type = cursor.getInt(cursor.getColumnIndexOrThrow(TYPE)); String source = cursor.getString(cursor.getColumnIndexOrThrow(SOURCE)); int deviceId = cursor.getInt(cursor.getColumnIndexOrThrow(DEVICE_ID)); - String legacyMessage = cursor.getString(cursor.getColumnIndexOrThrow(LEGACY_MSG)); String content = cursor.getString(cursor.getColumnIndexOrThrow(CONTENT)); long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP)); long serverTimestamp = cursor.getLong(cursor.getColumnIndexOrThrow(SERVER_TIMESTAMP)); - String serverGuid = cursor.getString(cursor.getColumnIndexOrThrow(SERVER_GUID)); return new SignalServiceEnvelope(type, source, deviceId, timestamp, - legacyMessage != null ? Base64.decode(legacyMessage) : null, content != null ? Base64.decode(content) : null, - serverTimestamp, serverGuid); + serverTimestamp); } catch (IOException e) { throw new AssertionError(e); } 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 a69f260991..12346381da 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 @@ -250,7 +250,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper { } if (oldVersion < lokiV21) { - deleteJobRecords(db, "ClosedGroupUpdateMessageSendJob"); + deleteJobRecords(db, + "ClosedGroupUpdateMessageSendJob", + "NullMessageSendJob"); } db.setTransactionSuccessful(); 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 6cec0d16cb..1095d9c3f5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/SignalCommunicationModule.java @@ -32,7 +32,6 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.linkpreview.LinkPreviewRepository; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.loki.api.SessionProtocolImpl; -import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation; import org.thoughtcrime.securesms.preferences.AppProtectionPreferenceFragment; import org.thoughtcrime.securesms.push.MessageSenderEventListener; import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess; @@ -88,20 +87,15 @@ public class SignalCommunicationModule { @Provides public synchronized SignalServiceMessageSender provideSignalMessageSender() { if (this.messageSender == null) { - this.messageSender = new SignalServiceMessageSender(networkAccess.getConfiguration(context), - new DynamicCredentialsProvider(context), + this.messageSender = new SignalServiceMessageSender(new DynamicCredentialsProvider(context), new SignalProtocolStoreImpl(context), - BuildConfig.USER_AGENT, Optional.fromNullable(IncomingMessageObserver.getPipe()), Optional.fromNullable(IncomingMessageObserver.getUnidentifiedPipe()), - Optional.of(new MessageSenderEventListener(context)), TextSecurePreferences.getLocalNumber(context), DatabaseFactory.getLokiAPIDatabase(context), DatabaseFactory.getLokiThreadDatabase(context), DatabaseFactory.getLokiMessageDatabase(context), - null, // DatabaseFactory.getLokiPreKeyBundleDatabase(context) new SessionProtocolImpl(context), - new SessionResetImplementation(context), DatabaseFactory.getLokiUserDatabase(context), DatabaseFactory.getGroupDatabase(context), ((ApplicationContext)context.getApplicationContext()).broadcaster); 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 561d166089..a55637783b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/JobManagerFactories.java @@ -17,7 +17,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.SqlCipherMigrationConstraintOb import org.thoughtcrime.securesms.loki.api.PrepareAttachmentAudioExtrasJob; import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupUpdateMessageSendJobV2; -import org.thoughtcrime.securesms.loki.protocol.NullMessageSendJob; import java.util.ArrayList; import java.util.Arrays; @@ -41,7 +40,6 @@ public final class JobManagerFactories { put(MmsDownloadJob.KEY, new MmsDownloadJob.Factory()); put(MmsReceiveJob.KEY, new MmsReceiveJob.Factory()); put(MmsSendJob.KEY, new MmsSendJob.Factory()); - put(NullMessageSendJob.KEY, new NullMessageSendJob.Factory()); put(PushContentReceiveJob.KEY, new PushContentReceiveJob.Factory()); put(PushDecryptJob.KEY, new PushDecryptJob.Factory()); put(PushGroupSendJob.KEY, new PushGroupSendJob.Factory()); 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 6d5d345572..28d94b796c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -17,19 +17,8 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.jobs.Data; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.metadata.InvalidMetadataMessageException; -import org.session.libsignal.metadata.InvalidMetadataVersionException; -import org.session.libsignal.metadata.ProtocolDuplicateMessageException; -import org.session.libsignal.metadata.ProtocolInvalidKeyException; -import org.session.libsignal.metadata.ProtocolInvalidKeyIdException; import org.session.libsignal.metadata.ProtocolInvalidMessageException; -import org.session.libsignal.metadata.ProtocolInvalidVersionException; -import org.session.libsignal.metadata.ProtocolLegacyMessageException; -import org.session.libsignal.metadata.ProtocolNoSessionException; -import org.session.libsignal.metadata.ProtocolUntrustedIdentityException; -import org.session.libsignal.metadata.SelfSendException; import org.session.libsignal.service.api.crypto.SignalServiceCipher; -import org.session.libsignal.service.loki.api.crypto.SessionProtocol; -import org.session.libsignal.utilities.PromiseUtilities; import org.thoughtcrime.securesms.ApplicationContext; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; @@ -48,13 +37,10 @@ import org.session.libsession.utilities.TextSecurePreferences; import org.thoughtcrime.securesms.contactshare.ContactModelMapper; import org.thoughtcrime.securesms.crypto.IdentityKeyUtil; -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil; import org.thoughtcrime.securesms.crypto.storage.SignalProtocolStoreImpl; import org.thoughtcrime.securesms.database.AttachmentDatabase; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; -import org.thoughtcrime.securesms.database.GroupReceiptDatabase; -import org.thoughtcrime.securesms.database.MessagingDatabase; import org.thoughtcrime.securesms.database.MessagingDatabase.InsertResult; import org.thoughtcrime.securesms.database.MessagingDatabase.SyncMessageId; import org.thoughtcrime.securesms.database.MmsDatabase; @@ -79,26 +65,19 @@ import org.thoughtcrime.securesms.loki.database.LokiMessageDatabase; import org.thoughtcrime.securesms.loki.database.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocolV2; import org.thoughtcrime.securesms.loki.protocol.MultiDeviceProtocol; -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.utilities.MentionManagerUtilities; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; import org.thoughtcrime.securesms.mms.MmsException; -import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; -import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage; -import org.thoughtcrime.securesms.mms.SlideDeck; import org.thoughtcrime.securesms.mms.StickerSlide; import org.thoughtcrime.securesms.notifications.NotificationChannels; import org.thoughtcrime.securesms.sms.IncomingEncryptedMessage; import org.thoughtcrime.securesms.sms.IncomingEndSessionMessage; import org.thoughtcrime.securesms.sms.IncomingTextMessage; -import org.thoughtcrime.securesms.sms.OutgoingEncryptedMessage; import org.thoughtcrime.securesms.sms.OutgoingTextMessage; import org.session.libsignal.utilities.Hex; import org.session.libsignal.libsignal.InvalidMessageException; -import org.session.libsignal.libsignal.loki.SessionResetProtocol; import org.session.libsignal.libsignal.state.SignalProtocolStore; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.SignalServiceMessageSender; @@ -111,16 +90,14 @@ import org.session.libsignal.service.api.messages.SignalServiceReceiptMessage; import org.session.libsignal.service.api.messages.SignalServiceTypingMessage; import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager; +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import org.session.libsignal.service.loki.utilities.PublicKeyValidation; -import java.io.IOException; import java.security.SecureRandom; import java.util.ArrayList; import java.util.Collections; import java.util.LinkedList; import java.util.List; -import java.util.Set; import javax.inject.Inject; @@ -242,10 +219,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType { try { GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context); SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context); - SessionResetProtocol sessionResetProtocol = new SessionResetImplementation(context); SignalServiceAddress localAddress = new SignalServiceAddress(TextSecurePreferences.getLocalNumber(context)); LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(context); - SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, sessionResetProtocol, new SessionProtocolImpl(context), apiDB); + SignalServiceCipher cipher = new SignalServiceCipher(localAddress, axolotlStore, new SessionProtocolImpl(context), apiDB); SignalServiceContent content = cipher.decrypt(envelope); @@ -254,8 +230,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return; } - SessionManagementProtocol.handlePreKeyBundleMessageIfNeeded(context, content); - SessionMetaProtocol.handleProfileUpdateIfNeeded(context, content); if (content.configurationMessageProto.isPresent()) { @@ -341,7 +315,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } if (threadId != null) { - SessionManagementProtocol.handleEndSessionMessageIfNeeded(context, content); messageNotifier.updateNotification(context, threadId); } } @@ -706,82 +679,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { smsDatabase.markAsDecryptFailed(smsMessageId.get()); } } - - if (canRecoverAutomatically(e)) { - Recipient recipient = Recipient.from(context, Address.fromSerialized(sender), false); - LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(context); - long threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient); - threadDB.addSessionRestoreDevice(threadID, sender); - SessionManagementProtocol.startSessionReset(context, sender); - } else { - SessionManagementProtocol.triggerSessionRestorationUI(context, sender, timestamp); - } - } - - private boolean canRecoverAutomatically(Throwable e) { - // Corrupt message exception - if (e.getCause() != null) { - Throwable e2 = e.getCause(); - if (e2.getCause() != null) { - Throwable e3 = e2.getCause(); - if (e3 instanceof InvalidMessageException) { - String message = e3.getMessage(); - return (message != null && message.startsWith("Bad Mac!")); - } - } - } - return false; - } - - private void handleNoSessionMessage(@NonNull String sender, int senderDevice, long timestamp, - @NonNull Optional smsMessageId) - { - SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - if (!SessionMetaProtocol.shouldIgnoreDecryptionException(context, timestamp)) { - if (!smsMessageId.isPresent()) { - Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp); - - if (insertResult.isPresent()) { - smsDatabase.markAsNoSession(insertResult.get().getMessageId()); - messageNotifier.updateNotification(context, insertResult.get().getThreadId()); - } - } else { - smsDatabase.markAsNoSession(smsMessageId.get()); - } - } - } - - private void handleLegacyMessage(@NonNull String sender, int senderDevice, long timestamp, - @NonNull Optional smsMessageId) - { - SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - - if (!smsMessageId.isPresent()) { - Optional insertResult = insertPlaceholder(sender, senderDevice, timestamp); - - if (insertResult.isPresent()) { - smsDatabase.markAsLegacyVersion(insertResult.get().getMessageId()); - messageNotifier.updateNotification(context, insertResult.get().getThreadId()); - } - } else { - smsDatabase.markAsLegacyVersion(smsMessageId.get()); - } - } - - @SuppressWarnings("unused") - private void handleDuplicateMessage(@NonNull String sender, int senderDeviceId, long timestamp, - @NonNull Optional smsMessageId) - { - // Let's start ignoring these now -// SmsDatabase smsDatabase = DatabaseFactory.getEncryptingSmsDatabase(context); -// -// if (smsMessageId <= 0) { -// Pair messageAndThreadId = insertPlaceholder(masterSecret, envelope); -// smsDatabase.markAsDecryptDuplicate(messageAndThreadId.first); -// MessageNotifier.updateNotification(context, masterSecret, messageAndThreadId.second); -// } else { -// smsDatabase.markAsDecryptDuplicate(smsMessageId); -// } } private void handleNeedsDeliveryReceipt(@NonNull SignalServiceContent content, @@ -905,42 +802,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { PointerAttachment.forPointersOfDataMessage(quote.get().getAttachments()))); } - private Optional getStickerAttachment(Optional sticker) { - if (!sticker.isPresent()) { - return Optional.absent(); - } - - if (sticker.get().getPackId() == null || sticker.get().getPackKey() == null || sticker.get().getAttachment() == null) { - Log.w(TAG, "Malformed sticker!"); - return Optional.absent(); - } - - String packId = Hex.toStringCondensed(sticker.get().getPackId()); - String packKey = Hex.toStringCondensed(sticker.get().getPackKey()); - int stickerId = sticker.get().getStickerId(); - StickerLocator stickerLocator = new StickerLocator(packId, packKey, stickerId); - StickerDatabase stickerDatabase = DatabaseFactory.getStickerDatabase(context); - StickerRecord stickerRecord = stickerDatabase.getSticker(stickerLocator.getPackId(), stickerLocator.getStickerId(), false); - - if (stickerRecord != null) { - return Optional.of(new UriAttachment(stickerRecord.getUri(), - stickerRecord.getUri(), - MediaTypes.IMAGE_WEBP, - AttachmentDatabase.TRANSFER_PROGRESS_DONE, - stickerRecord.getSize(), - StickerSlide.WIDTH, - StickerSlide.HEIGHT, - null, - String.valueOf(new SecureRandom().nextLong()), - false, - false, - null, - stickerLocator)); - } else { - return Optional.of(PointerAttachment.forPointer(Optional.of(sticker.get().getAttachment()), stickerLocator).get()); - } - } - private Optional> getContacts(Optional> sharedContacts) { if (!sharedContacts.isPresent()) return Optional.absent(); @@ -1069,10 +930,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType { return false; } - private boolean isGroupChatMessage(SignalServiceContent content) { - return content.getDataMessage().isPresent() && content.getDataMessage().get().isGroupMessage(); - } - private void resetRecipientToPush(@NonNull Recipient recipient) { if (recipient.isForceSmsSelection()) { DatabaseFactory.getRecipientDatabase(context).setForceSmsSelection(recipient, false); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 854f5cb5b0..7ff01e739d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -39,12 +39,10 @@ import org.session.libsignal.service.api.messages.SendMessageResult; import org.session.libsignal.service.api.messages.SignalServiceAttachment; import org.session.libsignal.service.api.messages.SignalServiceDataMessage; import org.session.libsignal.service.api.messages.SignalServiceDataMessage.Preview; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; import org.session.libsignal.service.api.push.exceptions.UnregisteredUserException; import org.session.libsignal.service.loki.api.SnodeAPI; -import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol; import java.io.FileNotFoundException; import java.io.IOException; @@ -285,7 +283,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { .asExpirationUpdate(message.isExpirationUpdate()) .build(); - if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) { + if (userPublicKey == address.getNumber()) { // Loki - Device link messages don't go through here SendMessageResult result = messageSender.sendMessage(messageId, address, unidentifiedAccessPair, mediaMessage); if (result.getLokiAPIError() != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java index 1188c69db0..46ce75b2e7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushReceivedJob.java @@ -33,10 +33,7 @@ public abstract class PushReceivedJob extends BaseJob { } } - if (envelope.isReceipt()) { - handleReceipt(envelope); - } else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() - || envelope.isUnidentifiedSender() || envelope.isFallbackMessage() || envelope.isClosedGroupCiphertext()) { + if (envelope.isUnidentifiedSender() || envelope.isClosedGroupCiphertext()) { handleMessage(envelope, isPushNotification); } else { Log.w(TAG, "Received envelope of unknown type: " + envelope.getType()); @@ -51,13 +48,6 @@ public abstract class PushReceivedJob extends BaseJob { new PushDecryptJob(context).processMessage(envelope, isPushNotification); } - @SuppressLint("DefaultLocale") - private void handleReceipt(SignalServiceEnvelope envelope) { - Log.i(TAG, String.format("Received receipt: (XXXXX, %d)", envelope.getTimestamp())); - DatabaseFactory.getMmsSmsDatabase(context).incrementDeliveryReceiptCount(new SyncMessageId(Address.fromExternal(context, envelope.getSource()), - envelope.getTimestamp()), System.currentTimeMillis()); - } - private boolean isActiveNumber(@NonNull Recipient recipient) { return recipient.resolve().getRegistered() == Recipient.RegisteredState.REGISTERED; } 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 262aac0245..2ba7b7502b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushSendJob.java @@ -12,7 +12,6 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.utilities.Base64; -import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.greenrobot.eventbus.EventBus; @@ -34,13 +33,10 @@ import org.thoughtcrime.securesms.util.BitmapUtil; import org.session.libsignal.utilities.Hex; import org.thoughtcrime.securesms.util.MediaUtil; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair; import org.session.libsignal.service.api.messages.SignalServiceAttachment; import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer; import org.session.libsignal.service.api.messages.SignalServiceDataMessage; import org.session.libsignal.service.api.messages.SignalServiceDataMessage.Preview; -import org.session.libsignal.service.api.messages.multidevice.SentTranscriptMessage; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; @@ -55,7 +51,6 @@ import java.util.concurrent.TimeUnit; public abstract class PushSendJob extends SendJob { private static final String TAG = PushSendJob.class.getSimpleName(); - private static final long CERTIFICATE_EXPIRATION_BUFFER = TimeUnit.DAYS.toMillis(1); protected PushSendJob(Job.Parameters parameters) { super(parameters); @@ -72,14 +67,6 @@ 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"); -// } - 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 62e833774b..aeea404bea 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -30,11 +30,9 @@ import org.session.libsignal.service.api.crypto.UnidentifiedAccessPair; import org.session.libsignal.service.api.crypto.UntrustedIdentityException; import org.session.libsignal.service.api.messages.SendMessageResult; import org.session.libsignal.service.api.messages.SignalServiceDataMessage; -import org.session.libsignal.service.api.messages.multidevice.SignalServiceSyncMessage; import org.session.libsignal.service.api.push.SignalServiceAddress; import org.session.libsignal.service.api.push.exceptions.UnregisteredUserException; import org.session.libsignal.service.loki.api.SnodeAPI; -import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol; import java.io.IOException; @@ -224,7 +222,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { .asEndSessionMessage(message.isEndSession()) .build(); - if (SessionMetaProtocol.shared.isNoteToSelf(address.getNumber())) { + if (userPublicKey.equals(address.getNumber())) { // Loki - Device link messages don't go through here SendMessageResult result = messageSender.sendMessage(messageId, address, unidentifiedAccess, textSecureMessage); if (result.getLokiAPIError() != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java index b7a8e13d57..a3ce38a374 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/TypingSendJob.java @@ -87,16 +87,14 @@ public class TypingSendJob extends BaseJob implements InjectableType { } List recipients = Collections.singletonList(recipient); - Optional groupId = Optional.absent(); if (recipient.isGroupRecipient()) { recipients = DatabaseFactory.getGroupDatabase(context).getGroupMembers(recipient.getAddress().toGroupString(), false); - groupId = Optional.of(GroupUtil.getDecodedGroupIDAsData(recipient.getAddress().toGroupString())); } List addresses = Stream.of(recipients).map(r -> new SignalServiceAddress(r.getAddress().serialize())).toList(); List> unidentifiedAccess = Stream.of(recipients).map(r -> UnidentifiedAccessUtil.getAccessFor(context, r)).toList(); - SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis(), groupId); + SignalServiceTypingMessage typingMessage = new SignalServiceTypingMessage(typing ? Action.STARTED : Action.STOPPED, System.currentTimeMillis()); messageSender.sendTyping(addresses, unidentifiedAccess, typingMessage); } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/BackupRestoreActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/BackupRestoreActivity.kt index a37558a212..cf9bfeb9f7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/BackupRestoreActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/BackupRestoreActivity.kt @@ -193,8 +193,6 @@ class BackupRestoreViewModel(application: Application): AndroidViewModel(applica application.setUpStorageAPIIfNeeded() application.setUpP2PAPIIfNeeded() - HomeActivity.requestResetAllSessionsOnStartup(context) - BackupRestoreResult.SUCCESS } catch (e: DatabaseDowngradeException) { Log.w(TAG, "Failed due to the backup being from a newer version of Signal.", e) 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 ccfc440858..d4fc68b3ea 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 @@ -33,7 +33,6 @@ import org.session.libsession.utilities.GroupUtil import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.ThreadRecord import org.thoughtcrime.securesms.loki.api.ResetThreadSessionJob -import org.thoughtcrime.securesms.loki.protocol.SessionResetImplementation import org.thoughtcrime.securesms.loki.utilities.* import org.thoughtcrime.securesms.loki.views.ConversationView import org.thoughtcrime.securesms.loki.views.NewConversationButtonSetViewDelegate @@ -44,8 +43,7 @@ import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.TextSecurePreferences.getBooleanPreference import org.session.libsession.utilities.TextSecurePreferences.setBooleanPreference import org.session.libsession.utilities.Util -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager -import org.session.libsignal.service.loki.protocol.meta.SessionMetaProtocol +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager import org.session.libsignal.utilities.ThreadUtils import org.session.libsignal.service.loki.utilities.toHexString import org.thoughtcrime.securesms.loki.dialogs.* @@ -54,31 +52,6 @@ import java.io.IOException class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListener, SeedReminderViewDelegate, NewConversationButtonSetViewDelegate { - companion object { - private const val PREF_RESET_ALL_SESSIONS_ON_START_UP = "pref_reset_all_sessions_on_start_up" - - @JvmStatic - fun requestResetAllSessionsOnStartup(context: Context) { - setBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, true) - } - - @JvmStatic - fun scheduleResetAllSessionsIfRequested(context: Context) { - if (!getBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, false)) return - setBooleanPreference(context, PREF_RESET_ALL_SESSIONS_ON_START_UP, false) - - val jobManager = ApplicationContext.getInstance(context).jobManager - - DatabaseFactory.getThreadDatabase(context).conversationListQuick.forEach { tuple -> - val threadId: Long = tuple.first - val recipientAddress: String = tuple.second - jobManager.add(ResetThreadSessionJob( - Address.fromSerialized(recipientAddress), - threadId)) - } - } - } - private lateinit var glide: GlideRequests private var broadcastReceiver: BroadcastReceiver? = null @@ -165,10 +138,8 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe val threadDB = DatabaseFactory.getLokiThreadDatabase(this) val userDB = DatabaseFactory.getLokiUserDatabase(this) val userPublicKey = TextSecurePreferences.getLocalNumber(this) - val sessionResetImpl = SessionResetImplementation(this) if (userPublicKey != null) { MentionsManager.configureIfNeeded(userPublicKey, threadDB, userDB) - SessionMetaProtocol.configureIfNeeded(apiDB, userPublicKey) application.publicChatManager.startPollersIfNeeded() } IP2Country.configureIfNeeded(this) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt index e00aaa4100..989cb2a6fa 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatPoller.kt @@ -153,67 +153,11 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh signalLinkPreviews.add(SignalServiceDataMessage.Preview(linkPreview.linkPreviewURL!!, linkPreview.linkPreviewTitle!!, Optional.of(attachment))) } val body = if (message.body == message.timestamp.toString()) "" else message.body // Workaround for the fact that the back-end doesn't accept messages without a body - return SignalServiceDataMessage(message.timestamp, serviceGroup, attachments, body, 0, false, null, quote, null, signalLinkPreviews) + val syncTarget = if (message.senderPublicKey == userHexEncodedPublicKey) group.id else null + return SignalServiceDataMessage(message.timestamp, serviceGroup, attachments, body, 0, false, null, quote, null, signalLinkPreviews, null, syncTarget) } fun pollForNewMessages(): Promise { - fun processIncomingMessage(message: PublicChatMessage) { - // If the sender of the current message is not a slave device, set the display name in the database - val senderDisplayName = "${message.displayName} (...${message.senderPublicKey.takeLast(8)})" - DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.senderPublicKey, senderDisplayName) - val senderHexEncodedPublicKey = message.senderPublicKey - val serviceDataMessage = getDataMessage(message) - val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.serverTimestamp, false) - if (serviceDataMessage.quote.isPresent || (serviceDataMessage.attachments.isPresent && serviceDataMessage.attachments.get().size > 0) || serviceDataMessage.previews.isPresent) { - PushDecryptJob(context).handleMediaMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) - } else { - PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) - } - // Update profile picture if needed - val senderAsRecipient = Recipient.from(context, Address.fromSerialized(senderHexEncodedPublicKey), false) - if (message.profilePicture != null && message.profilePicture!!.url.isNotEmpty()) { - val profileKey = message.profilePicture!!.profileKey - val url = message.profilePicture!!.url - if (senderAsRecipient.profileKey == null || !MessageDigest.isEqual(senderAsRecipient.profileKey, profileKey)) { - val database = DatabaseFactory.getRecipientDatabase(context) - database.setProfileKey(senderAsRecipient, profileKey) - ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, url)) - } - } - } - fun processOutgoingMessage(message: PublicChatMessage) { - val messageServerID = message.serverID ?: return - val messageID = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) - var isDuplicate = false - if (messageID != null) { - isDuplicate = DatabaseFactory.getMmsDatabase(context).getThreadIdForMessage(messageID) >= 0 - || DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) >= 0 - } - if (isDuplicate) { return } - if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return } - val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - val dataMessage = getDataMessage(message) - SessionMetaProtocol.dropFromTimestampCacheIfNeeded(message.serverTimestamp) - val transcript = SentTranscriptMessage(userHexEncodedPublicKey, message.serverTimestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(userHexEncodedPublicKey, false)) - transcript.messageServerID = messageServerID - if (dataMessage.quote.isPresent || (dataMessage.attachments.isPresent && dataMessage.attachments.get().size > 0) || dataMessage.previews.isPresent) { - PushDecryptJob(context).handleSynchronizeSentMediaMessage(transcript) - } else { - PushDecryptJob(context).handleSynchronizeSentTextMessage(transcript) - } - // If we got a message from our master device then make sure our mapping stays in sync - val recipient = Recipient.from(context, Address.fromSerialized(message.senderPublicKey), false) - if (message.profilePicture != null) { - val profileKey = message.profilePicture!!.profileKey - val url = message.profilePicture!!.url - if (recipient.profileKey == null || !MessageDigest.isEqual(recipient.profileKey, profileKey)) { - val database = DatabaseFactory.getRecipientDatabase(context) - database.setProfileKey(recipient, profileKey) - database.setProfileAvatar(recipient, url) - ApplicationContext.getInstance(context).updateOpenGroupProfilePicturesIfNeeded() - } - } - } if (isPollOngoing) { return Promise.of(Unit) } isPollOngoing = true val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() @@ -226,10 +170,27 @@ class PublicChatPoller(private val context: Context, private val group: PublicCh promise.successBackground { messages -> // Process messages in the background messages.forEach { message -> - if (message.senderPublicKey == userHexEncodedPublicKey) { - processOutgoingMessage(message) + // If the sender of the current message is not a slave device, set the display name in the database + val senderDisplayName = "${message.displayName} (...${message.senderPublicKey.takeLast(8)})" + DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.senderPublicKey, senderDisplayName) + val senderHexEncodedPublicKey = message.senderPublicKey + val serviceDataMessage = getDataMessage(message) + val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.serverTimestamp, false) + if (serviceDataMessage.quote.isPresent || (serviceDataMessage.attachments.isPresent && serviceDataMessage.attachments.get().size > 0) || serviceDataMessage.previews.isPresent) { + PushDecryptJob(context).handleMediaMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) } else { - processIncomingMessage(message) + PushDecryptJob(context).handleTextMessage(serviceContent, serviceDataMessage, Optional.absent(), Optional.of(message.serverID)) + } + // Update profile picture if needed + val senderAsRecipient = Recipient.from(context, Address.fromSerialized(senderHexEncodedPublicKey), false) + if (message.profilePicture != null && message.profilePicture!!.url.isNotEmpty()) { + val profileKey = message.profilePicture!!.profileKey + val url = message.profilePicture!!.url + if (senderAsRecipient.profileKey == null || !MessageDigest.isEqual(senderAsRecipient.profileKey, profileKey)) { + val database = DatabaseFactory.getRecipientDatabase(context) + database.setProfileKey(senderAsRecipient, profileKey) + ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, url)) + } } } isCaughtUp = true diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt index 0b4abf8b7a..70cb854b2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt @@ -14,7 +14,6 @@ import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.service.loki.api.opengroups.PublicChat -import org.session.libsignal.libsignal.loki.SessionResetStatus import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol import org.session.libsignal.service.loki.utilities.PublicKeyValidation @@ -39,34 +38,6 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) } - fun getThreadID(messageID: Long): Long { - return DatabaseFactory.getSmsDatabase(context).getThreadIdForMessage(messageID) - } - - fun getSessionResetStatus(hexEncodedPublicKey: String): SessionResetStatus { - val threadID = getThreadID(hexEncodedPublicKey) - val database = databaseHelper.readableDatabase - val result = database.get(sessionResetTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor -> - cursor.getInt(sessionResetStatus) - } - return if (result != null) { - SessionResetStatus.values().first { it.rawValue == result } - } else { - SessionResetStatus.NONE - } - } - - fun setSessionResetStatus(hexEncodedPublicKey: String, sessionResetStatus: SessionResetStatus) { - val threadID = getThreadID(hexEncodedPublicKey) - val database = databaseHelper.writableDatabase - val contentValues = ContentValues(2) - contentValues.put(Companion.threadID, threadID) - contentValues.put(Companion.sessionResetStatus, sessionResetStatus.rawValue) - database.insertOrUpdate(sessionResetTable, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) - notifyConversationListListeners() - notifyConversationListeners(threadID) - } - fun getAllPublicChats(): Map { val database = databaseHelper.readableDatabase var cursor: Cursor? = null diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJobV2.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJobV2.kt index 9628341e51..4b4673936d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJobV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupUpdateMessageSendJobV2.kt @@ -13,7 +13,7 @@ import org.session.libsignal.libsignal.util.guava.Optional import org.session.libsignal.service.api.push.SignalServiceAddress import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities +import org.session.libsignal.service.loki.utilities.TTLUtilities import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.toHexString import org.thoughtcrime.securesms.ApplicationContext @@ -25,7 +25,6 @@ import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.loki.utilities.recipient import org.session.libsignal.utilities.Hex -import java.util.* import java.util.concurrent.TimeUnit class ClosedGroupUpdateMessageSendJobV2 private constructor(parameters: Parameters, private val destination: String, private val kind: Kind, private val sentTime: Long) : BaseJob(parameters) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt index 9d6195e9cf..b5e1f31e2c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt @@ -8,6 +8,7 @@ import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.libsignal.util.guava.Optional import org.session.libsignal.service.api.push.SignalServiceAddress import org.session.libsignal.service.internal.push.SignalServiceProtos +import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.utilities.Hex import org.session.libsignal.utilities.logging.Log @@ -72,8 +73,8 @@ object MultiDeviceProtocol { for (closedGroup in configurationMessage.closedGroups) { if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue - val closedGroupUpdate = SignalServiceProtos.ClosedGroupUpdateV2.newBuilder() - closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.NEW + val closedGroupUpdate = DataMessage.ClosedGroupControlMessage.newBuilder() + closedGroupUpdate.type = DataMessage.ClosedGroupControlMessage.Type.NEW closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey)) closedGroupUpdate.name = closedGroup.name val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/NullMessageSendJob.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/NullMessageSendJob.kt deleted file mode 100644 index 0ac142e796..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/NullMessageSendJob.kt +++ /dev/null @@ -1,85 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol - -import com.google.protobuf.ByteString -import org.session.libsession.messaging.jobs.Data -import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil -import org.session.libsession.messaging.threads.Address -import org.thoughtcrime.securesms.jobmanager.Job -import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint -import org.thoughtcrime.securesms.jobs.BaseJob -import org.session.libsignal.utilities.logging.Log -import org.session.libsession.messaging.threads.recipients.Recipient -import org.session.libsignal.libsignal.util.guava.Optional -import org.session.libsignal.service.api.push.SignalServiceAddress -import org.session.libsignal.service.internal.push.SignalServiceProtos -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities -import java.io.IOException -import java.security.SecureRandom -import java.util.* -import java.util.concurrent.TimeUnit - -class NullMessageSendJob private constructor(parameters: Parameters, private val publicKey: String) : BaseJob(parameters) { - - companion object { - const val KEY = "NullMessageSendJob" - } - - constructor(publicKey: String) : this(Parameters.Builder() - .addConstraint(NetworkConstraint.KEY) - .setQueue(KEY) - .setLifespan(TimeUnit.DAYS.toMillis(1)) - .setMaxAttempts(1) - .build(), - publicKey) - - override fun serialize(): Data { - return Data.Builder().putString("publicKey", publicKey).build() - } - - override fun getFactoryKey(): String { return KEY } - - public override fun onRun() { - val contentMessage = SignalServiceProtos.Content.newBuilder() - val nullMessage = SignalServiceProtos.NullMessage.newBuilder() - val sr = SecureRandom() - val paddingSize = sr.nextInt(512) - val padding = ByteArray(paddingSize) - sr.nextBytes(padding) - nullMessage.padding = ByteString.copyFrom(padding) - contentMessage.nullMessage = nullMessage.build() - val serializedContentMessage = contentMessage.build().toByteArray() - val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() - val address = SignalServiceAddress(publicKey) - val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) - val udAccess = UnidentifiedAccessUtil.getAccessFor(context, recipient) - val ttl = TTLUtilities.getTTL(TTLUtilities.MessageType.Ephemeral) - try { - messageSender.sendMessage(0, address, udAccess.get().targetUnidentifiedAccess, - Date().time, serializedContentMessage, false, ttl, - false, false, false, Optional.absent()) - } catch (e: Exception) { - Log.d("Loki", "Failed to send null message to: $publicKey due to error: $e.") - throw e - } - } - - public override fun onShouldRetry(e: Exception): Boolean { - // Disable since we have our own retrying - return false - } - - override fun onCanceled() { } - - class Factory : Job.Factory { - - override fun create(parameters: Parameters, data: Data): NullMessageSendJob { - try { - val publicKey = data.getString("publicKey") - return NullMessageSendJob(parameters, publicKey) - } catch (e: IOException) { - throw AssertionError(e) - } - } - } -} 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 deleted file mode 100644 index 9860c7d492..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionManagementProtocol.kt +++ /dev/null @@ -1,102 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol - -import android.content.Context -import org.session.libsignal.utilities.logging.Log -import org.thoughtcrime.securesms.ApplicationContext -import org.thoughtcrime.securesms.crypto.SecurityEvent -import org.thoughtcrime.securesms.crypto.storage.TextSecureSessionStore -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.thoughtcrime.securesms.loki.utilities.recipient -import org.thoughtcrime.securesms.sms.MessageSender -import org.thoughtcrime.securesms.sms.OutgoingEndSessionMessage -import org.thoughtcrime.securesms.sms.OutgoingTextMessage -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.libsignal.loki.SessionResetStatus -import org.session.libsignal.service.api.messages.SignalServiceContent -import java.util.* - -object SessionManagementProtocol { - - @JvmStatic - fun startSessionReset(context: Context, publicKey: String) { - val recipient = recipient(context, publicKey) - if (recipient.isGroupRecipient) { return } - val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context) - val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) - val devices = lokiThreadDB.getSessionRestoreDevices(threadID) - for (device in devices) { - val endSessionMessage = OutgoingEndSessionMessage(OutgoingTextMessage(recipient, "TERMINATE", 0, -1)) - MessageSender.send(context, endSessionMessage, threadID, false, null) - } - val smsDB = DatabaseFactory.getSmsDatabase(context) - val infoMessage = OutgoingTextMessage(recipient, "", 0, 0) - val infoMessageID = smsDB.insertMessageOutbox(threadID, infoMessage, false, System.currentTimeMillis(), null) - if (infoMessageID > -1) { - smsDB.markAsSentLokiSessionRestorationRequest(infoMessageID) - } - 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 shouldProcessSessionRequest(context: Context, publicKey: String, timestamp: Long): Boolean { - val apiDB = DatabaseFactory.getLokiAPIDatabase(context) - val sentTimestamp = apiDB.getSessionRequestSentTimestamp(publicKey) ?: 0 - val processedTimestamp = apiDB.getSessionRequestProcessedTimestamp(publicKey) ?: 0 - val restorationTimestamp = TextSecurePreferences.getRestorationTime(context) - return timestamp > sentTimestamp && timestamp > processedTimestamp && timestamp > restorationTimestamp - } - - @JvmStatic - fun handlePreKeyBundleMessageIfNeeded(context: Context, content: SignalServiceContent) { - val preKeyBundleMessage = content.preKeyBundleMessage.orNull() ?: return - val publicKey = content.sender - if (recipient(context, publicKey).isGroupRecipient) { return } // Should never occur - Log.d("Loki", "Received a pre key bundle from: $publicKey.") - if (!shouldProcessSessionRequest(context, publicKey, content.timestamp)) { - Log.d("Loki", "Ignoring session request from: $publicKey.") - return - } - val registrationID = TextSecurePreferences.getLocalRegistrationId(context) -// val lokiPreKeyBundleDatabase = DatabaseFactory.getLokiPreKeyBundleDatabase(context) - val preKeyBundle = preKeyBundleMessage.getPreKeyBundle(registrationID) -// lokiPreKeyBundleDatabase.setPreKeyBundle(publicKey, preKeyBundle) - DatabaseFactory.getLokiAPIDatabase(context).setSessionRequestProcessedTimestamp(publicKey, Date().time) - val job = NullMessageSendJob(publicKey) - ApplicationContext.getInstance(context).jobManager.add(job) - } - - @JvmStatic - fun handleEndSessionMessageIfNeeded(context: Context, content: SignalServiceContent) { - if (!content.dataMessage.isPresent || !content.dataMessage.get().isEndSession) { return } - val sessionStore = TextSecureSessionStore(context) - val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context) - Log.d("Loki", "Received a session reset request from: ${content.sender}; archiving the session.") - sessionStore.archiveAllSessions(content.sender) - lokiThreadDB.setSessionResetStatus(content.sender, SessionResetStatus.REQUEST_RECEIVED) - Log.d("Loki", "Sending an ephemeral message back to: ${content.sender}.") - val job = NullMessageSendJob(content.sender) - ApplicationContext.getInstance(context).jobManager.add(job) - SecurityEvent.broadcastSecurityUpdateEvent(context) - } - - @JvmStatic - fun triggerSessionRestorationUI(context: Context, publicKey: String, errorTimestamp: Long) { - val recipient = recipient(context, publicKey) - if (recipient.isGroupRecipient) { return } - val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) - DatabaseFactory.getLokiThreadDatabase(context).addSessionRestoreDevice(threadID, publicKey) - } -} \ No newline at end of file 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 deleted file mode 100644 index 2ad11a951a..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/SessionResetImplementation.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.thoughtcrime.securesms.loki.protocol - -import android.content.Context -import org.thoughtcrime.securesms.ApplicationContext -import org.session.libsession.messaging.threads.Address -import org.thoughtcrime.securesms.database.DatabaseFactory -import org.session.libsession.messaging.threads.recipients.Recipient -import org.thoughtcrime.securesms.sms.OutgoingTextMessage -import org.session.libsignal.libsignal.loki.SessionResetProtocol -import org.session.libsignal.libsignal.loki.SessionResetStatus -import org.session.libsignal.libsignal.protocol.PreKeySignalMessage - -class SessionResetImplementation(private val context: Context) : SessionResetProtocol { - - override fun getSessionResetStatus(publicKey: String): SessionResetStatus { - return DatabaseFactory.getLokiThreadDatabase(context).getSessionResetStatus(publicKey) - } - - override fun setSessionResetStatus(publicKey: String, sessionResetStatus: SessionResetStatus) { - return DatabaseFactory.getLokiThreadDatabase(context).setSessionResetStatus(publicKey, sessionResetStatus) - } - - override fun onNewSessionAdopted(publicKey: String, oldSessionResetStatus: SessionResetStatus) { - if (oldSessionResetStatus == SessionResetStatus.IN_PROGRESS) { - val job = NullMessageSendJob(publicKey) - ApplicationContext.getInstance(context).jobManager.add(job) - } - val smsDB = DatabaseFactory.getSmsDatabase(context) - val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) - val threadID = DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) - val infoMessage = OutgoingTextMessage(recipient, "", 0, 0) - val infoMessageID = smsDB.insertMessageOutbox(threadID, infoMessage, false, System.currentTimeMillis(), null) - if (infoMessageID > -1) { - smsDB.markAsLokiSessionRestorationDone(infoMessageID) - } - } - - 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." } - } -} \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt index c565c953ad..f59bc7b71a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt @@ -4,7 +4,7 @@ import android.content.Context import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MessageRecord import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager object MentionManagerUtilities { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt index 321ffed35b..e1a308b645 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ConversationView.kt @@ -15,8 +15,6 @@ import org.thoughtcrime.securesms.loki.utilities.MentionManagerUtilities.populat import org.thoughtcrime.securesms.loki.utilities.MentionUtilities.highlightMentions import org.thoughtcrime.securesms.mms.GlideRequests import org.thoughtcrime.securesms.util.DateUtils -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager import java.util.* class ConversationView : LinearLayout { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt index 53f5f27aa9..ddda015d77 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateSelectionView.kt @@ -10,7 +10,7 @@ import android.widget.ListView import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.loki.utilities.toPx import org.thoughtcrime.securesms.mms.GlideRequests -import org.session.libsignal.service.loki.protocol.mentions.Mention +import org.session.libsignal.service.loki.utilities.mentions.Mention class MentionCandidateSelectionView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : ListView(context, attrs, defStyleAttr) { private var mentionCandidates = listOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt index cf76ece839..d33ff9f34f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt @@ -10,7 +10,7 @@ import kotlinx.android.synthetic.main.view_mention_candidate.view.* import network.loki.messenger.R import org.thoughtcrime.securesms.mms.GlideRequests import org.session.libsignal.service.loki.api.opengroups.PublicChatAPI -import org.session.libsignal.service.loki.protocol.mentions.Mention +import org.session.libsignal.service.loki.utilities.mentions.Mention class MentionCandidateView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : LinearLayout(context, attrs, defStyleAttr) { var mentionCandidate = Mention("", "") diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt index 095fd2d33f..741f62f4ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt @@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.loki.utilities.AvatarPlaceholderGenerator import org.thoughtcrime.securesms.mms.GlideRequests import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.protocol.mentions.MentionsManager +import org.session.libsignal.service.loki.utilities.mentions.MentionsManager // TODO: Look into a better way of handling different sizes. Maybe an enum (with associated values) encapsulating the different modes? diff --git a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java index 1698e56b6a..401a6c7e27 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java +++ b/app/src/main/java/org/thoughtcrime/securesms/service/ExpiringMessageManager.java @@ -83,7 +83,6 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM Optional.absent(), Optional.absent(), Optional.absent(), - Optional.absent(), Optional.absent()); database.insertSecureDecryptedMessageInbox(mediaMessage, -1); diff --git a/libsignal/protobuf/SignalService.proto b/libsignal/protobuf/SignalService.proto index 5d54f5f32b..4e0a646659 100644 --- a/libsignal/protobuf/SignalService.proto +++ b/libsignal/protobuf/SignalService.proto @@ -278,6 +278,12 @@ message GroupContext { repeated string members = 4; optional AttachmentPointer avatar = 5; repeated string admins = 6; + + // Loki - These fields are only used internally for the Android code base. + // This is so that we can differentiate adding/kicking. + // DO NOT USE WHEN SENDING MESSAGES. + repeated string newMembers = 998; + repeated string removedMembers = 999; } message ContactDetails { diff --git a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/LokiSessionCipher.kt b/libsignal/src/main/java/org/session/libsignal/libsignal/loki/LokiSessionCipher.kt deleted file mode 100644 index d567fe97ae..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/LokiSessionCipher.kt +++ /dev/null @@ -1,78 +0,0 @@ -package org.session.libsignal.libsignal.loki - -import org.session.libsignal.libsignal.DecryptionCallback -import org.session.libsignal.libsignal.SessionCipher -import org.session.libsignal.libsignal.SignalProtocolAddress -import org.session.libsignal.libsignal.protocol.PreKeySignalMessage -import org.session.libsignal.libsignal.protocol.SignalMessage -import org.session.libsignal.libsignal.state.SessionState -import org.session.libsignal.libsignal.state.SignalProtocolStore - -/** - * A wrapper class for `SessionCipher`. - * This applies session reset logic on decryption. - */ -class LokiSessionCipher(private val protocolStore: SignalProtocolStore, private var sessionResetProtocol: SessionResetProtocol, val address: SignalProtocolAddress) : SessionCipher(protocolStore, address) { - - override fun decrypt(ciphertext: PreKeySignalMessage?, callback: DecryptionCallback?): ByteArray { - // Record the current session state as it may change during decryption - val activeSession = getCurrentSessionState() - if (activeSession == null && ciphertext != null) { - sessionResetProtocol.validatePreKeySignalMessage(address.name, ciphertext) - } - val plainText = super.decrypt(ciphertext, callback) - handleSessionResetRequestIfNeeded(activeSession) - return plainText - } - - override fun decrypt(ciphertext: SignalMessage?, callback: DecryptionCallback?): ByteArray { - // Record the current session state as it may change during decryption - val activeSession = getCurrentSessionState() - val plainText = super.decrypt(ciphertext, callback) - handleSessionResetRequestIfNeeded(activeSession) - return plainText - } - - private fun getCurrentSessionState(): SessionState? { - val sessionRecord = protocolStore.loadSession(address) - return sessionRecord.sessionState - } - - private fun handleSessionResetRequestIfNeeded(oldSession: SessionState?) { - if (oldSession == null) { return } - val publicKey = address.name - val currentSessionResetStatus = sessionResetProtocol.getSessionResetStatus(publicKey) - if (currentSessionResetStatus == SessionResetStatus.NONE) return - val currentSession = getCurrentSessionState() - if (currentSession == null || currentSession.aliceBaseKey?.contentEquals(oldSession.aliceBaseKey) != true) { - if (currentSessionResetStatus == SessionResetStatus.REQUEST_RECEIVED) { - // The other user used an old session to contact us; wait for them to switch to a new one. - restoreSession(oldSession) - } else { - // Our session reset was successful; we initiated one and got a new session back from the other user. - deleteAllSessionsExcept(currentSession) - sessionResetProtocol.setSessionResetStatus(publicKey, SessionResetStatus.NONE) - sessionResetProtocol.onNewSessionAdopted(publicKey, currentSessionResetStatus) - } - } else if (currentSessionResetStatus == SessionResetStatus.REQUEST_RECEIVED) { - // Our session reset was successful; we received a message with the same session from the other user. - deleteAllSessionsExcept(oldSession) - sessionResetProtocol.setSessionResetStatus(publicKey, SessionResetStatus.NONE) - sessionResetProtocol.onNewSessionAdopted(publicKey, currentSessionResetStatus) - } - } - - private fun restoreSession(state: SessionState) { - val session = protocolStore.loadSession(address) - session.previousSessionStates.removeAll { it.aliceBaseKey?.contentEquals(state.aliceBaseKey) ?: false } - session.promoteState(state) - protocolStore.storeSession(address, session) - } - - private fun deleteAllSessionsExcept(state: SessionState?) { - val sessionRecord = protocolStore.loadSession(address) - sessionRecord.removePreviousSessionStates() - sessionRecord.setState(state ?: SessionState()) - protocolStore.storeSession(address, sessionRecord) - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetProtocol.kt b/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetProtocol.kt deleted file mode 100644 index bfeb54460b..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetProtocol.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.session.libsignal.libsignal.loki - -import org.session.libsignal.libsignal.protocol.PreKeySignalMessage - -interface SessionResetProtocol { - - fun getSessionResetStatus(publicKey: String): SessionResetStatus - fun setSessionResetStatus(publicKey: String, sessionResetStatus: SessionResetStatus) - fun validatePreKeySignalMessage(publicKey: String, message: PreKeySignalMessage) - fun onNewSessionAdopted(publicKey: String, oldSessionResetStatus: SessionResetStatus) -} diff --git a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetStatus.kt b/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetStatus.kt deleted file mode 100644 index b8e557e94e..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/libsignal/loki/SessionResetStatus.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.session.libsignal.libsignal.loki - -enum class SessionResetStatus(val rawValue: Int) { - NONE(0), - IN_PROGRESS(1), - REQUEST_RECEIVED(2) -} diff --git a/libsignal/src/main/java/org/session/libsignal/metadata/SealedSessionCipher.java b/libsignal/src/main/java/org/session/libsignal/metadata/SealedSessionCipher.java index 6a91f2e502..6db3b81019 100644 --- a/libsignal/src/main/java/org/session/libsignal/metadata/SealedSessionCipher.java +++ b/libsignal/src/main/java/org/session/libsignal/metadata/SealedSessionCipher.java @@ -24,8 +24,6 @@ import org.session.libsignal.libsignal.ecc.ECPrivateKey; import org.session.libsignal.libsignal.ecc.ECPublicKey; import org.session.libsignal.libsignal.kdf.HKDFv3; import org.session.libsignal.libsignal.loki.FallbackSessionCipher; -import org.session.libsignal.libsignal.loki.LokiSessionCipher; -import org.session.libsignal.libsignal.loki.SessionResetProtocol; import org.session.libsignal.libsignal.protocol.CiphertextMessage; import org.session.libsignal.libsignal.protocol.PreKeySignalMessage; import org.session.libsignal.libsignal.protocol.SignalMessage; @@ -51,15 +49,11 @@ import javax.crypto.spec.SecretKeySpec; public class SealedSessionCipher { private final SignalProtocolStore signalProtocolStore; - private final SessionResetProtocol sessionResetProtocol; private final SignalProtocolAddress localAddress; - public SealedSessionCipher(SignalProtocolStore signalProtocolStore, - SessionResetProtocol sessionResetProtocol, - SignalProtocolAddress localAddress) + public SealedSessionCipher(SignalProtocolStore signalProtocolStore, SignalProtocolAddress localAddress) { this.signalProtocolStore = signalProtocolStore; - this.sessionResetProtocol = sessionResetProtocol; this.localAddress = localAddress; } @@ -201,8 +195,8 @@ public class SealedSessionCipher { SignalProtocolAddress sender = new SignalProtocolAddress(message.getSenderCertificate().getSender(), message.getSenderCertificate().getSenderDeviceId()); switch (message.getType()) { - case CiphertextMessage.WHISPER_TYPE: return new LokiSessionCipher(signalProtocolStore, sessionResetProtocol, sender).decrypt(new SignalMessage(message.getContent())); - case CiphertextMessage.PREKEY_TYPE: return new LokiSessionCipher(signalProtocolStore, sessionResetProtocol, sender).decrypt(new PreKeySignalMessage(message.getContent())); + case CiphertextMessage.WHISPER_TYPE: return new SessionCipher(signalProtocolStore, sender).decrypt(new SignalMessage(message.getContent())); + case CiphertextMessage.PREKEY_TYPE: return new SessionCipher(signalProtocolStore, sender).decrypt(new PreKeySignalMessage(message.getContent())); case CiphertextMessage.FALLBACK_MESSAGE_TYPE: { try { byte[] privateKey = signalProtocolStore.getIdentityKeyPair().getPrivateKey().serialize(); diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageSender.java b/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageSender.java index e574ca23d9..d1ca970ac9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageSender.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageSender.java @@ -6,12 +6,10 @@ package org.session.libsignal.service.api; import com.google.protobuf.ByteString; -import com.google.protobuf.InvalidProtocolBufferException; import org.jetbrains.annotations.Nullable; import org.session.libsignal.libsignal.ecc.ECKeyPair; import org.session.libsignal.utilities.logging.Log; -import org.session.libsignal.libsignal.loki.SessionResetProtocol; import org.session.libsignal.libsignal.state.SignalProtocolStore; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.crypto.AttachmentCipherOutputStream; @@ -67,24 +65,20 @@ import org.session.libsignal.service.loki.database.LokiOpenGroupDatabaseProtocol import org.session.libsignal.service.loki.database.LokiPreKeyBundleDatabaseProtocol; import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol; import org.session.libsignal.service.loki.database.LokiUserDatabaseProtocol; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; -import org.session.libsignal.service.loki.protocol.sessionmanagement.SessionManagementProtocol; +import org.session.libsignal.service.loki.utilities.TTLUtilities; import org.session.libsignal.service.loki.utilities.Broadcaster; import org.session.libsignal.service.loki.utilities.HexEncodingKt; import org.session.libsignal.service.loki.utilities.PlaintextOutputStreamFactory; import java.io.IOException; import java.io.InputStream; -import java.security.SecureRandom; import java.util.ArrayList; -import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; import kotlin.Unit; @@ -100,10 +94,8 @@ public class SignalServiceMessageSender { private static final String TAG = SignalServiceMessageSender.class.getSimpleName(); - private final PushServiceSocket socket; private final SignalProtocolStore store; private final SignalServiceAddress localAddress; - private final Optional eventListener; private final AtomicReference> pipe; private final AtomicReference> unidentifiedPipe; @@ -113,9 +105,7 @@ public class SignalServiceMessageSender { private final LokiAPIDatabaseProtocol apiDatabase; private final LokiThreadDatabaseProtocol threadDatabase; private final LokiMessageDatabaseProtocol messageDatabase; - private final LokiPreKeyBundleDatabaseProtocol preKeyBundleDatabase; private final SessionProtocol sessionProtocolImpl; - private final SessionResetProtocol sessionResetImpl; private final LokiUserDatabaseProtocol userDatabase; private final LokiOpenGroupDatabaseProtocol openGroupDatabase; private final Broadcaster broadcaster; @@ -123,65 +113,48 @@ public class SignalServiceMessageSender { /** * Construct a SignalServiceMessageSender. * - * @param urls The URL of the Signal Service. * @param user The Signal Service username (eg phone number). * @param password The Signal Service user password. * @param store The SignalProtocolStore. - * @param eventListener An optional event listener, which fires whenever sessions are - * setup or torn down for a recipient. */ - public SignalServiceMessageSender(SignalServiceConfiguration urls, - String user, String password, + public SignalServiceMessageSender(String user, String password, SignalProtocolStore store, - String userAgent, Optional pipe, Optional unidentifiedPipe, - Optional eventListener, String userPublicKey, LokiAPIDatabaseProtocol apiDatabase, LokiThreadDatabaseProtocol threadDatabase, LokiMessageDatabaseProtocol messageDatabase, - LokiPreKeyBundleDatabaseProtocol preKeyBundleDatabase, SessionProtocol sessionProtocolImpl, - SessionResetProtocol sessionResetImpl, LokiUserDatabaseProtocol userDatabase, LokiOpenGroupDatabaseProtocol openGroupDatabase, Broadcaster broadcaster) { - this(urls, new StaticCredentialsProvider(user, password, null), store, userAgent, pipe, unidentifiedPipe, eventListener, userPublicKey, apiDatabase, threadDatabase, messageDatabase, preKeyBundleDatabase, sessionProtocolImpl, sessionResetImpl, userDatabase, openGroupDatabase, broadcaster); + this(new StaticCredentialsProvider(user, password, null), store, pipe, unidentifiedPipe, userPublicKey, apiDatabase, threadDatabase, messageDatabase, sessionProtocolImpl, userDatabase, openGroupDatabase, broadcaster); } - public SignalServiceMessageSender(SignalServiceConfiguration urls, - CredentialsProvider credentialsProvider, + public SignalServiceMessageSender(CredentialsProvider credentialsProvider, SignalProtocolStore store, - String userAgent, Optional pipe, Optional unidentifiedPipe, - Optional eventListener, String userPublicKey, LokiAPIDatabaseProtocol apiDatabase, LokiThreadDatabaseProtocol threadDatabase, LokiMessageDatabaseProtocol messageDatabase, - LokiPreKeyBundleDatabaseProtocol preKeyBundleDatabase, SessionProtocol sessionProtocolImpl, - SessionResetProtocol sessionResetImpl, LokiUserDatabaseProtocol userDatabase, LokiOpenGroupDatabaseProtocol openGroupDatabase, Broadcaster broadcaster) { - this.socket = new PushServiceSocket(urls, credentialsProvider, userAgent); this.store = store; this.localAddress = new SignalServiceAddress(credentialsProvider.getUser()); this.pipe = new AtomicReference<>(pipe); this.unidentifiedPipe = new AtomicReference<>(unidentifiedPipe); - this.eventListener = eventListener; this.userPublicKey = userPublicKey; this.apiDatabase = apiDatabase; this.threadDatabase = threadDatabase; this.messageDatabase = messageDatabase; - this.preKeyBundleDatabase = preKeyBundleDatabase; this.sessionProtocolImpl = sessionProtocolImpl; - this.sessionResetImpl = sessionResetImpl; this.userDatabase = userDatabase; this.openGroupDatabase = openGroupDatabase; this.broadcaster = broadcaster; diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java index c66bc315f5..dec47a68e9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java @@ -10,31 +10,11 @@ import com.google.protobuf.InvalidProtocolBufferException; import org.session.libsignal.libsignal.ecc.ECKeyPair; import org.session.libsignal.metadata.InvalidMetadataMessageException; -import org.session.libsignal.metadata.InvalidMetadataVersionException; -import org.session.libsignal.metadata.ProtocolDuplicateMessageException; -import org.session.libsignal.metadata.ProtocolInvalidKeyException; -import org.session.libsignal.metadata.ProtocolInvalidKeyIdException; import org.session.libsignal.metadata.ProtocolInvalidMessageException; -import org.session.libsignal.metadata.ProtocolInvalidVersionException; -import org.session.libsignal.metadata.ProtocolLegacyMessageException; -import org.session.libsignal.metadata.ProtocolNoSessionException; -import org.session.libsignal.metadata.ProtocolUntrustedIdentityException; import org.session.libsignal.metadata.SealedSessionCipher; -import org.session.libsignal.metadata.SelfSendException; -import org.session.libsignal.libsignal.DuplicateMessageException; -import org.session.libsignal.libsignal.InvalidKeyException; -import org.session.libsignal.libsignal.InvalidKeyIdException; import org.session.libsignal.libsignal.InvalidMessageException; -import org.session.libsignal.libsignal.InvalidVersionException; -import org.session.libsignal.libsignal.LegacyMessageException; -import org.session.libsignal.libsignal.NoSessionException; import org.session.libsignal.libsignal.SessionCipher; import org.session.libsignal.libsignal.SignalProtocolAddress; -import org.session.libsignal.libsignal.UntrustedIdentityException; -import org.session.libsignal.libsignal.loki.LokiSessionCipher; -import org.session.libsignal.libsignal.loki.SessionResetProtocol; -import org.session.libsignal.libsignal.protocol.PreKeySignalMessage; -import org.session.libsignal.libsignal.protocol.SignalMessage; import org.session.libsignal.libsignal.state.SignalProtocolStore; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.SignalServiceAttachment; @@ -60,7 +40,6 @@ import org.session.libsignal.service.loki.api.crypto.SessionProtocol; import org.session.libsignal.service.loki.api.crypto.SessionProtocolUtilities; import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; -import java.io.IOException; import java.util.LinkedList; import java.util.List; @@ -77,19 +56,16 @@ public class SignalServiceCipher { private static final String TAG = SignalServiceCipher.class.getSimpleName(); private final SignalProtocolStore signalProtocolStore; - private final SessionResetProtocol sessionResetProtocol; private final SignalServiceAddress localAddress; private final SessionProtocol sessionProtocolImpl; private final LokiAPIDatabaseProtocol apiDB; public SignalServiceCipher(SignalServiceAddress localAddress, SignalProtocolStore signalProtocolStore, - SessionResetProtocol sessionResetProtocol, SessionProtocol sessionProtocolImpl, LokiAPIDatabaseProtocol apiDB) { this.signalProtocolStore = signalProtocolStore; - this.sessionResetProtocol = sessionResetProtocol; this.localAddress = localAddress; this.sessionProtocolImpl = sessionProtocolImpl; this.apiDB = apiDB; @@ -160,8 +136,8 @@ public class SignalServiceCipher { protected Plaintext decrypt(SignalServiceEnvelope envelope, byte[] ciphertext) throws InvalidMetadataMessageException { SignalProtocolAddress sourceAddress = new SignalProtocolAddress(envelope.getSource(), envelope.getSourceDevice()); - SessionCipher sessionCipher = new LokiSessionCipher(signalProtocolStore, sessionResetProtocol, sourceAddress); - SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(signalProtocolStore, sessionResetProtocol, new SignalProtocolAddress(localAddress.getNumber(), 1)); + SessionCipher sessionCipher = new SessionCipher(signalProtocolStore, sourceAddress); + SealedSessionCipher sealedSessionCipher = new SealedSessionCipher(signalProtocolStore, new SignalProtocolAddress(localAddress.getNumber(), 1)); byte[] paddedMessage; Metadata metadata; diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceContent.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceContent.java index 4ec8cfe9a2..b216332623 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceContent.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceContent.java @@ -7,9 +7,7 @@ package org.session.libsignal.service.api.messages; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.api.messages.calls.SignalServiceCallMessage; import org.session.libsignal.service.internal.push.SignalServiceProtos; -import org.session.libsignal.service.loki.protocol.sessionmanagement.PreKeyBundleMessage; public class SignalServiceContent { private final String sender; @@ -24,7 +22,6 @@ public class SignalServiceContent { // Loki public Optional configurationMessageProto = Optional.absent(); - public Optional preKeyBundleMessage = Optional.absent(); public Optional senderDisplayName = Optional.absent(); public Optional senderProfilePictureURL = Optional.absent(); diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java index 746d18551c..758c49e1a9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java @@ -11,7 +11,7 @@ import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; +import org.session.libsignal.service.loki.utilities.TTLUtilities; import java.util.LinkedList; import java.util.List; diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceNullMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceNullMessage.java index 5baf134e87..234a644315 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceNullMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceNullMessage.java @@ -1,6 +1,6 @@ package org.session.libsignal.service.api.messages; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; +import org.session.libsignal.service.loki.utilities.TTLUtilities; public class SignalServiceNullMessage { diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java index 50836573cd..8e48450011 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java @@ -1,7 +1,7 @@ package org.session.libsignal.service.api.messages; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; +import org.session.libsignal.service.loki.utilities.TTLUtilities; import java.util.List; diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java index 59d3216719..d3fb3a2fc0 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java @@ -1,7 +1,6 @@ package org.session.libsignal.service.api.messages; -import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; +import org.session.libsignal.service.loki.utilities.TTLUtilities; public class SignalServiceTypingMessage { diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/calls/SignalServiceCallMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/calls/SignalServiceCallMessage.java index ddb3216750..ba0790dda0 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/calls/SignalServiceCallMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/calls/SignalServiceCallMessage.java @@ -1,7 +1,7 @@ package org.session.libsignal.service.api.messages.calls; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities; +import org.session.libsignal.service.loki.utilities.TTLUtilities; import java.util.LinkedList; import java.util.List; diff --git a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java index a907e51eb2..5694326b55 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java +++ b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java @@ -24483,6 +24483,70 @@ public final class SignalServiceProtos { */ com.google.protobuf.ByteString getAdminsBytes(int index); + + // repeated string newMembers = 998; + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + java.util.List + getNewMembersList(); + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + int getNewMembersCount(); + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + java.lang.String getNewMembers(int index); + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + com.google.protobuf.ByteString + getNewMembersBytes(int index); + + // repeated string removedMembers = 999; + /** + * repeated string removedMembers = 999; + */ + java.util.List + getRemovedMembersList(); + /** + * repeated string removedMembers = 999; + */ + int getRemovedMembersCount(); + /** + * repeated string removedMembers = 999; + */ + java.lang.String getRemovedMembers(int index); + /** + * repeated string removedMembers = 999; + */ + com.google.protobuf.ByteString + getRemovedMembersBytes(int index); } /** * Protobuf type {@code signalservice.GroupContext} @@ -24585,6 +24649,22 @@ public final class SignalServiceProtos { admins_.add(input.readBytes()); break; } + case 7986: { + if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + newMembers_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000040; + } + newMembers_.add(input.readBytes()); + break; + } + case 7994: { + if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + removedMembers_ = new com.google.protobuf.LazyStringArrayList(); + mutable_bitField0_ |= 0x00000080; + } + removedMembers_.add(input.readBytes()); + break; + } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -24599,6 +24679,12 @@ public final class SignalServiceProtos { if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { admins_ = new com.google.protobuf.UnmodifiableLazyStringList(admins_); } + if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { + newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(newMembers_); + } + if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { + removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(removedMembers_); + } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } @@ -24913,6 +24999,90 @@ public final class SignalServiceProtos { return admins_.getByteString(index); } + // repeated string newMembers = 998; + public static final int NEWMEMBERS_FIELD_NUMBER = 998; + private com.google.protobuf.LazyStringList newMembers_; + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + public java.util.List + getNewMembersList() { + return newMembers_; + } + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + public int getNewMembersCount() { + return newMembers_.size(); + } + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + public java.lang.String getNewMembers(int index) { + return newMembers_.get(index); + } + /** + * repeated string newMembers = 998; + * + *
+     * Loki - These fields are only used internally for the Android code base.
+     * This is so that we can differentiate adding/kicking.
+     * DO NOT USE WHEN SENDING MESSAGES.
+     * 
+ */ + public com.google.protobuf.ByteString + getNewMembersBytes(int index) { + return newMembers_.getByteString(index); + } + + // repeated string removedMembers = 999; + public static final int REMOVEDMEMBERS_FIELD_NUMBER = 999; + private com.google.protobuf.LazyStringList removedMembers_; + /** + * repeated string removedMembers = 999; + */ + public java.util.List + getRemovedMembersList() { + return removedMembers_; + } + /** + * repeated string removedMembers = 999; + */ + public int getRemovedMembersCount() { + return removedMembers_.size(); + } + /** + * repeated string removedMembers = 999; + */ + public java.lang.String getRemovedMembers(int index) { + return removedMembers_.get(index); + } + /** + * repeated string removedMembers = 999; + */ + public com.google.protobuf.ByteString + getRemovedMembersBytes(int index) { + return removedMembers_.getByteString(index); + } + private void initFields() { id_ = com.google.protobuf.ByteString.EMPTY; type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext.Type.UNKNOWN; @@ -24920,6 +25090,8 @@ public final class SignalServiceProtos { members_ = com.google.protobuf.LazyStringArrayList.EMPTY; avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance(); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; + newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { @@ -24951,6 +25123,12 @@ public final class SignalServiceProtos { for (int i = 0; i < admins_.size(); i++) { output.writeBytes(6, admins_.getByteString(i)); } + for (int i = 0; i < newMembers_.size(); i++) { + output.writeBytes(998, newMembers_.getByteString(i)); + } + for (int i = 0; i < removedMembers_.size(); i++) { + output.writeBytes(999, removedMembers_.getByteString(i)); + } getUnknownFields().writeTo(output); } @@ -24994,6 +25172,24 @@ public final class SignalServiceProtos { size += dataSize; size += 1 * getAdminsList().size(); } + { + int dataSize = 0; + for (int i = 0; i < newMembers_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(newMembers_.getByteString(i)); + } + size += dataSize; + size += 2 * getNewMembersList().size(); + } + { + int dataSize = 0; + for (int i = 0; i < removedMembers_.size(); i++) { + dataSize += com.google.protobuf.CodedOutputStream + .computeBytesSizeNoTag(removedMembers_.getByteString(i)); + } + size += dataSize; + size += 2 * getRemovedMembersList().size(); + } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -25127,6 +25323,10 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000010); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); + newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000040); + removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000080); return this; } @@ -25187,6 +25387,18 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000020); } result.admins_ = admins_; + if (((bitField0_ & 0x00000040) == 0x00000040)) { + newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( + newMembers_); + bitField0_ = (bitField0_ & ~0x00000040); + } + result.newMembers_ = newMembers_; + if (((bitField0_ & 0x00000080) == 0x00000080)) { + removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( + removedMembers_); + bitField0_ = (bitField0_ & ~0x00000080); + } + result.removedMembers_ = removedMembers_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -25237,6 +25449,26 @@ public final class SignalServiceProtos { } onChanged(); } + if (!other.newMembers_.isEmpty()) { + if (newMembers_.isEmpty()) { + newMembers_ = other.newMembers_; + bitField0_ = (bitField0_ & ~0x00000040); + } else { + ensureNewMembersIsMutable(); + newMembers_.addAll(other.newMembers_); + } + onChanged(); + } + if (!other.removedMembers_.isEmpty()) { + if (removedMembers_.isEmpty()) { + removedMembers_ = other.removedMembers_; + bitField0_ = (bitField0_ & ~0x00000080); + } else { + ensureRemovedMembersIsMutable(); + removedMembers_.addAll(other.removedMembers_); + } + onChanged(); + } this.mergeUnknownFields(other.getUnknownFields()); return this; } @@ -25745,6 +25977,246 @@ public final class SignalServiceProtos { return this; } + // repeated string newMembers = 998; + private com.google.protobuf.LazyStringList newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureNewMembersIsMutable() { + if (!((bitField0_ & 0x00000040) == 0x00000040)) { + newMembers_ = new com.google.protobuf.LazyStringArrayList(newMembers_); + bitField0_ |= 0x00000040; + } + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public java.util.List + getNewMembersList() { + return java.util.Collections.unmodifiableList(newMembers_); + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public int getNewMembersCount() { + return newMembers_.size(); + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public java.lang.String getNewMembers(int index) { + return newMembers_.get(index); + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public com.google.protobuf.ByteString + getNewMembersBytes(int index) { + return newMembers_.getByteString(index); + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public Builder setNewMembers( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNewMembersIsMutable(); + newMembers_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public Builder addNewMembers( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNewMembersIsMutable(); + newMembers_.add(value); + onChanged(); + return this; + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public Builder addAllNewMembers( + java.lang.Iterable values) { + ensureNewMembersIsMutable(); + super.addAll(values, newMembers_); + onChanged(); + return this; + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public Builder clearNewMembers() { + newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000040); + onChanged(); + return this; + } + /** + * repeated string newMembers = 998; + * + *
+       * Loki - These fields are only used internally for the Android code base.
+       * This is so that we can differentiate adding/kicking.
+       * DO NOT USE WHEN SENDING MESSAGES.
+       * 
+ */ + public Builder addNewMembersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureNewMembersIsMutable(); + newMembers_.add(value); + onChanged(); + return this; + } + + // repeated string removedMembers = 999; + private com.google.protobuf.LazyStringList removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + private void ensureRemovedMembersIsMutable() { + if (!((bitField0_ & 0x00000080) == 0x00000080)) { + removedMembers_ = new com.google.protobuf.LazyStringArrayList(removedMembers_); + bitField0_ |= 0x00000080; + } + } + /** + * repeated string removedMembers = 999; + */ + public java.util.List + getRemovedMembersList() { + return java.util.Collections.unmodifiableList(removedMembers_); + } + /** + * repeated string removedMembers = 999; + */ + public int getRemovedMembersCount() { + return removedMembers_.size(); + } + /** + * repeated string removedMembers = 999; + */ + public java.lang.String getRemovedMembers(int index) { + return removedMembers_.get(index); + } + /** + * repeated string removedMembers = 999; + */ + public com.google.protobuf.ByteString + getRemovedMembersBytes(int index) { + return removedMembers_.getByteString(index); + } + /** + * repeated string removedMembers = 999; + */ + public Builder setRemovedMembers( + int index, java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureRemovedMembersIsMutable(); + removedMembers_.set(index, value); + onChanged(); + return this; + } + /** + * repeated string removedMembers = 999; + */ + public Builder addRemovedMembers( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + ensureRemovedMembersIsMutable(); + removedMembers_.add(value); + onChanged(); + return this; + } + /** + * repeated string removedMembers = 999; + */ + public Builder addAllRemovedMembers( + java.lang.Iterable values) { + ensureRemovedMembersIsMutable(); + super.addAll(values, removedMembers_); + onChanged(); + return this; + } + /** + * repeated string removedMembers = 999; + */ + public Builder clearRemovedMembers() { + removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; + bitField0_ = (bitField0_ & ~0x00000080); + onChanged(); + return this; + } + /** + * repeated string removedMembers = 999; + */ + public Builder addRemovedMembersBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + ensureRemovedMembersIsMutable(); + removedMembers_.add(value); + onChanged(); + return this; + } + // @@protoc_insertion_point(builder_scope:signalservice.GroupContext) } @@ -30486,28 +30958,30 @@ public final class SignalServiceProtos { "thumbnail\030\005 \001(\014\022\016\n\006digest\030\006 \001(\014\022\020\n\010fileN" + "ame\030\007 \001(\t\022\r\n\005flags\030\010 \001(\r\022\r\n\005width\030\t \001(\r\022" + "\016\n\006height\030\n \001(\r\022\017\n\007caption\030\013 \001(\t\022\013\n\003url\030", - "e \001(\t\"\032\n\005Flags\022\021\n\rVOICE_MESSAGE\020\001\"\365\001\n\014Gr" + + "e \001(\t\"\032\n\005Flags\022\021\n\rVOICE_MESSAGE\020\001\"\243\002\n\014Gr" + "oupContext\022\n\n\002id\030\001 \001(\014\022.\n\004type\030\002 \001(\0162 .s" + "ignalservice.GroupContext.Type\022\014\n\004name\030\003" + " \001(\t\022\017\n\007members\030\004 \003(\t\0220\n\006avatar\030\005 \001(\0132 ." + "signalservice.AttachmentPointer\022\016\n\006admin" + - "s\030\006 \003(\t\"H\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001" + - "\022\013\n\007DELIVER\020\002\022\010\n\004QUIT\020\003\022\020\n\014REQUEST_INFO\020" + - "\004\"\356\001\n\016ContactDetails\022\016\n\006number\030\001 \001(\t\022\014\n\004" + - "name\030\002 \001(\t\0224\n\006avatar\030\003 \001(\0132$.signalservi" + - "ce.ContactDetails.Avatar\022\r\n\005color\030\004 \001(\t\022", - "\022\n\nprofileKey\030\006 \001(\014\022\017\n\007blocked\030\007 \001(\010\022\023\n\013" + - "expireTimer\030\010 \001(\r\022\020\n\010nickname\030e \001(\t\032-\n\006A" + - "vatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006length\030\002 \001" + - "(\r\"\367\001\n\014GroupDetails\022\n\n\002id\030\001 \001(\014\022\014\n\004name\030" + - "\002 \001(\t\022\017\n\007members\030\003 \003(\t\0222\n\006avatar\030\004 \001(\0132\"" + - ".signalservice.GroupDetails.Avatar\022\024\n\006ac" + - "tive\030\005 \001(\010:\004true\022\023\n\013expireTimer\030\006 \001(\r\022\r\n" + - "\005color\030\007 \001(\t\022\017\n\007blocked\030\010 \001(\010\022\016\n\006admins\030" + - "\t \003(\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006" + - "length\030\002 \001(\r\"\"\n\016PublicChatInfo\022\020\n\010server", - "ID\030\001 \001(\004BB\n+org.session.libsignal.servic" + - "e.internal.pushB\023SignalServiceProtos" + "s\030\006 \003(\t\022\023\n\nnewMembers\030\346\007 \003(\t\022\027\n\016removedM" + + "embers\030\347\007 \003(\t\"H\n\004Type\022\013\n\007UNKNOWN\020\000\022\n\n\006UP" + + "DATE\020\001\022\013\n\007DELIVER\020\002\022\010\n\004QUIT\020\003\022\020\n\014REQUEST" + + "_INFO\020\004\"\356\001\n\016ContactDetails\022\016\n\006number\030\001 \001" + + "(\t\022\014\n\004name\030\002 \001(\t\0224\n\006avatar\030\003 \001(\0132$.signa", + "lservice.ContactDetails.Avatar\022\r\n\005color\030" + + "\004 \001(\t\022\022\n\nprofileKey\030\006 \001(\014\022\017\n\007blocked\030\007 \001" + + "(\010\022\023\n\013expireTimer\030\010 \001(\r\022\020\n\010nickname\030e \001(" + + "\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t\022\016\n\006leng" + + "th\030\002 \001(\r\"\367\001\n\014GroupDetails\022\n\n\002id\030\001 \001(\014\022\014\n" + + "\004name\030\002 \001(\t\022\017\n\007members\030\003 \003(\t\0222\n\006avatar\030\004" + + " \001(\0132\".signalservice.GroupDetails.Avatar" + + "\022\024\n\006active\030\005 \001(\010:\004true\022\023\n\013expireTimer\030\006 " + + "\001(\r\022\r\n\005color\030\007 \001(\t\022\017\n\007blocked\030\010 \001(\010\022\016\n\006a" + + "dmins\030\t \003(\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001", + "(\t\022\016\n\006length\030\002 \001(\r\"\"\n\016PublicChatInfo\022\020\n\010" + + "serverID\030\001 \001(\004BB\n+org.session.libsignal." + + "service.internal.pushB\023SignalServiceProt" + + "os" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -30651,7 +31125,7 @@ public final class SignalServiceProtos { internal_static_signalservice_GroupContext_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_GroupContext_descriptor, - new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", }); + new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", "NewMembers", "RemovedMembers", }); internal_static_signalservice_ContactDetails_descriptor = getDescriptor().getMessageTypes().get(10); internal_static_signalservice_ContactDetails_fieldAccessorTable = new diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt index b3c82aa7fb..97e1b4ecf4 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt @@ -5,7 +5,7 @@ import nl.komponents.kovenant.deferred import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.service.loki.api.crypto.ProofOfWork -import org.session.libsignal.service.loki.protocol.meta.TTLUtilities +import org.session.libsignal.service.loki.utilities.TTLUtilities import org.session.libsignal.utilities.ThreadUtils import org.session.libsignal.service.loki.utilities.prettifiedDescription diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/SessionMetaProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/SessionMetaProtocol.kt deleted file mode 100644 index 5250964973..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/SessionMetaProtocol.kt +++ /dev/null @@ -1,24 +0,0 @@ -package org.session.libsignal.service.loki.protocol.meta - -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol - -public class SessionMetaProtocol(private val apiDatabase: LokiAPIDatabaseProtocol, private val userPublicKey: String) { - - // region Initialization - companion object { - - public lateinit var shared: SessionMetaProtocol - - public fun configureIfNeeded(apiDatabase: LokiAPIDatabaseProtocol, userPublicKey: String) { - if (::shared.isInitialized) { return; } - shared = SessionMetaProtocol(apiDatabase, userPublicKey) - } - } - // endregion - - // region Utilities - public fun isNoteToSelf(publicKey: String): Boolean { - return userPublicKey == publicKey // return MultiDeviceProtocol.shared.getAllLinkedDevices(userPublicKey).contains(publicKey) - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/PreKeyBundleMessage.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/PreKeyBundleMessage.kt deleted file mode 100644 index e6ea780da7..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/PreKeyBundleMessage.kt +++ /dev/null @@ -1,23 +0,0 @@ -package org.session.libsignal.service.loki.protocol.sessionmanagement - -import org.session.libsignal.libsignal.IdentityKey -import org.session.libsignal.libsignal.ecc.Curve -import org.session.libsignal.libsignal.state.PreKeyBundle - -data class PreKeyBundleMessage( - val identityKey: ByteArray, - val deviceID: Int, - val preKeyID: Int, - val signedPreKeyID: Int, - val preKey: ByteArray, - val signedPreKey: ByteArray, - val signedPreKeySignature: ByteArray -) { - - constructor(preKeyBundle: PreKeyBundle) : this(preKeyBundle.identityKey.serialize(), preKeyBundle.deviceId, preKeyBundle.preKeyId, - preKeyBundle.signedPreKeyId, preKeyBundle.preKey.serialize(), preKeyBundle.signedPreKey.serialize(), preKeyBundle.signedPreKeySignature) - - fun getPreKeyBundle(registrationID: Int): PreKeyBundle { - return PreKeyBundle(registrationID, deviceID, preKeyID, Curve.decodePoint(preKey, 0), signedPreKeyID, Curve.decodePoint(signedPreKey, 0), signedPreKeySignature, IdentityKey(identityKey, 0)) - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocol.kt deleted file mode 100644 index 48a9077f67..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocol.kt +++ /dev/null @@ -1,53 +0,0 @@ -package org.session.libsignal.service.loki.protocol.sessionmanagement - -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.libsignal.loki.SessionResetProtocol -import org.session.libsignal.libsignal.loki.SessionResetStatus -import org.session.libsignal.libsignal.util.guava.Optional -import org.session.libsignal.service.api.SignalServiceMessageSender -import org.session.libsignal.service.api.push.SignalServiceAddress - -public class SessionManagementProtocol(private val sessionResetImpl: SessionResetProtocol, private val delegate: SessionManagementProtocolDelegate) { - - // region Initialization - companion object { - - public lateinit var shared: SessionManagementProtocol - - public fun configureIfNeeded(sessionResetImpl: SessionResetProtocol, delegate: SessionManagementProtocolDelegate) { - if (::shared.isInitialized) { return; } - shared = SessionManagementProtocol(sessionResetImpl, delegate) - } - } - // endregion - - // region Sending - /** - * Called after an end session message is sent. - */ - public fun setSessionResetStatusToInProgressIfNeeded(recipient: SignalServiceAddress, eventListener: Optional) { - val publicKey = recipient.number - val sessionResetStatus = sessionResetImpl.getSessionResetStatus(publicKey) - if (sessionResetStatus == SessionResetStatus.REQUEST_RECEIVED) { return } - Log.d("Loki", "Starting session reset") - sessionResetImpl.setSessionResetStatus(publicKey, SessionResetStatus.IN_PROGRESS) - if (!eventListener.isPresent) { return } - eventListener.get().onSecurityEvent(recipient) - } - - public fun repairSessionIfNeeded(recipient: SignalServiceAddress, isClosedGroup: Boolean) { - val publicKey = recipient.number - if (!isClosedGroup) { return } - delegate.sendSessionRequestIfNeeded(publicKey) - } - - public fun shouldIgnoreMissingPreKeyBundleException(isClosedGroup: Boolean): Boolean { - // When a closed group is created, members try to establish sessions with eachother in the background through - // session requests. Until ALL users those session requests were sent to have come online, stored the pre key - // bundles contained in the session requests and replied with background messages to finalize the session - // creation, a given user won't be able to successfully send a message to all members of a group. This check - // is so that until we can do better on this front the user at least won't see this as an error in the UI. - return isClosedGroup - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocolDelegate.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocolDelegate.kt deleted file mode 100644 index 152f69982e..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/sessionmanagement/SessionManagementProtocolDelegate.kt +++ /dev/null @@ -1,6 +0,0 @@ -package org.session.libsignal.service.loki.protocol.sessionmanagement - -interface SessionManagementProtocolDelegate { - - fun sendSessionRequestIfNeeded(publicKey: String) -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/TTLUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt similarity index 96% rename from libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/TTLUtilities.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt index f786b822e8..c229a97423 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/meta/TTLUtilities.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.protocol.meta +package org.session.libsignal.service.loki.utilities public object TTLUtilities { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/Mention.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt similarity index 52% rename from libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/Mention.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt index dc295fe92c..8d97c45268 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/Mention.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/Mention.kt @@ -1,3 +1,3 @@ -package org.session.libsignal.service.loki.protocol.mentions +package org.session.libsignal.service.loki.utilities.mentions data class Mention(val publicKey: String, val displayName: String) diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/MentionsManager.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt similarity index 97% rename from libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/MentionsManager.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt index d4308cf6a7..2edf6f677c 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/protocol/mentions/MentionsManager.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt @@ -1,4 +1,4 @@ -package org.session.libsignal.service.loki.protocol.mentions +package org.session.libsignal.service.loki.utilities.mentions import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol import org.session.libsignal.service.loki.database.LokiUserDatabaseProtocol