From 24df7812598a47d80f498530163907fd53bd70c9 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 10 Feb 2020 13:40:12 +1100 Subject: [PATCH 01/18] Enable the user to join an open group without entering "https://" --- .../loki/redesign/activities/JoinPublicChatActivity.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt index 2b2b5bef08..37954e7355 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/JoinPublicChatActivity.kt @@ -133,7 +133,10 @@ class EnterChatURLFragment : Fragment() { private fun joinPublicChatIfPossible() { val inputMethodManager = context!!.getSystemService(BaseActionBarActivity.INPUT_METHOD_SERVICE) as InputMethodManager inputMethodManager.hideSoftInputFromWindow(chatURLEditText.windowToken, 0) - val chatURL = chatURLEditText.text.trim().toString().toLowerCase().replace("http://", "https://") + var chatURL = chatURLEditText.text.trim().toString().toLowerCase().replace("http://", "https://") + if (!chatURL.toLowerCase().startsWith("https")) { + chatURL = "https://$chatURL" + } (activity!! as JoinPublicChatActivity).joinPublicChatIfPossible(chatURL) } } From b5792a81aafc5de93d8591cd28466b69a2f0f185 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 11 Feb 2020 09:38:05 +1100 Subject: [PATCH 02/18] Update for core changes --- res/xml/network_security_configuration.xml | 1 + .../securesms/ApplicationContext.java | 6 +++--- .../securesms/CreateProfileActivity.java | 4 ++-- .../securesms/components/TypingStatusSender.java | 6 +++--- .../conversation/ConversationActivity.java | 4 ++-- .../database/loaders/DeviceListLoader.java | 4 ++-- .../securesms/groups/GroupMessageProcessor.java | 6 +++--- .../securesms/jobs/AttachmentUploadJob.java | 2 +- .../securesms/jobs/PushDecryptJob.java | 10 +++++----- .../securesms/jobs/PushGroupSendJob.java | 4 ++-- .../securesms/jobs/PushMediaSendJob.java | 4 ++-- .../securesms/jobs/PushTextSendJob.java | 4 ++-- .../securesms/loki/MultiDeviceUtilities.kt | 16 ++++++++-------- .../redesign/activities/LinkedDevicesActivity.kt | 4 ++-- .../redesign/activities/LinkedDevicesLoader.kt | 4 ++-- .../loki/redesign/activities/SettingsActivity.kt | 4 ++-- .../redesign/messaging/LokiPublicChatPoller.kt | 14 +++++++------- .../loki/redesign/messaging/LokiRSSFeedPoller.kt | 4 ++-- .../notifications/MarkReadReceiver.java | 2 +- .../securesms/sms/MessageSender.java | 6 +++--- 20 files changed, 55 insertions(+), 54 deletions(-) diff --git a/res/xml/network_security_configuration.xml b/res/xml/network_security_configuration.xml index df97928889..c62b3d962e 100644 --- a/res/xml/network_security_configuration.xml +++ b/res/xml/network_security_configuration.xml @@ -6,6 +6,7 @@ storage.seed1.loki.network storage.seed2.loki.network public.loki.foundation:22023 + file-dev.lokinet.org 127.0.0.1 \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 7f099f4617..5bcc0d948c 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -103,7 +103,7 @@ import org.whispersystems.signalservice.loki.api.LokiP2PAPIDelegate; import org.whispersystems.signalservice.loki.api.LokiPublicChat; import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI; import org.whispersystems.signalservice.loki.api.LokiRSSFeed; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.security.Security; import java.util.ArrayList; @@ -188,7 +188,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc LokiDotNetAPI.setCache(new Cache(this.getCacheDir(), OK_HTTP_CACHE_SIZE)); // Loki - Update device mappings if (setUpStorageAPIIfNeeded()) { - LokiStorageAPI.Companion.getShared().updateUserDeviceMappings(); + LokiFileServerAPI.Companion.getShared().updateUserDeviceMappings(); if (TextSecurePreferences.needsRevocationCheck(this)) { checkNeedsRevocation(); } @@ -466,7 +466,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc boolean isDebugMode = BuildConfig.DEBUG; byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize(); LokiAPIDatabaseProtocol database = DatabaseFactory.getLokiAPIDatabase(this); - LokiStorageAPI.Companion.configure(isDebugMode, userHexEncodedPublicKey, userPrivateKey, database); + LokiFileServerAPI.Companion.configure(isDebugMode, userHexEncodedPublicKey, userPrivateKey, database); return true; } return false; diff --git a/src/org/thoughtcrime/securesms/CreateProfileActivity.java b/src/org/thoughtcrime/securesms/CreateProfileActivity.java index b2eb3f32e8..74d7f81b32 100644 --- a/src/org/thoughtcrime/securesms/CreateProfileActivity.java +++ b/src/org/thoughtcrime/securesms/CreateProfileActivity.java @@ -59,7 +59,7 @@ import org.whispersystems.signalservice.api.crypto.ProfileCipher; import org.whispersystems.signalservice.api.util.StreamDetails; import org.whispersystems.signalservice.loki.api.LokiDotNetAPI; import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.io.ByteArrayInputStream; import java.io.File; @@ -407,7 +407,7 @@ public class CreateProfileActivity extends BaseActionBarActivity implements Inje //Loki - Upload the profile photo here if (avatar != null) { Log.d("Loki", "Start uploading profile photo"); - LokiStorageAPI storageAPI = LokiStorageAPI.shared; + LokiFileServerAPI storageAPI = LokiFileServerAPI.shared; LokiDotNetAPI.UploadResult result = storageAPI.uploadProfilePicture(storageAPI.getServer(), profileKey, avatar); Log.d("Loki", "Profile photo uploaded, the url is " + result.getUrl()); TextSecurePreferences.setProfileAvatarUrl(context, result.getUrl()); diff --git a/src/org/thoughtcrime/securesms/components/TypingStatusSender.java b/src/org/thoughtcrime/securesms/components/TypingStatusSender.java index 927b158e42..4b7908cbb6 100644 --- a/src/org/thoughtcrime/securesms/components/TypingStatusSender.java +++ b/src/org/thoughtcrime/securesms/components/TypingStatusSender.java @@ -12,7 +12,7 @@ import org.thoughtcrime.securesms.jobs.TypingSendJob; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.Util; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.util.HashMap; import java.util.Map; @@ -83,7 +83,7 @@ public class TypingStatusSender { } private void sendTyping(long threadId, boolean typingStarted) { - LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); + LokiFileServerAPI storageAPI = LokiFileServerAPI.Companion.getShared(); ThreadDatabase threadDatabase = DatabaseFactory.getThreadDatabase(context); Recipient recipient = threadDatabase.getRecipientForThreadId(threadId); @@ -91,7 +91,7 @@ public class TypingStatusSender { ApplicationContext.getInstance(context).getJobManager().add(new TypingSendJob(threadId, typingStarted)); return; } - LokiStorageAPI.shared.getAllDevicePublicKeys(recipient.getAddress().serialize()).success(devices -> { + LokiFileServerAPI.shared.getAllDevicePublicKeys(recipient.getAddress().serialize()).success(devices -> { for (String device : devices) { Recipient deviceRecipient = Recipient.from(context, Address.fromSerialized(device), false); long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(deviceRecipient); diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index c180b5f054..2d1dabb73b 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -234,7 +234,7 @@ import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.loki.api.LokiAPI; import org.whispersystems.signalservice.loki.api.LokiPublicChat; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.api.PairingAuthorisation; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; @@ -2290,7 +2290,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if (threadID != this.threadId) { Recipient threadRecipient = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadID); if (threadRecipient != null && !threadRecipient.isGroupRecipient()) { - LokiStorageAPI.shared.getAllDevicePublicKeys(threadRecipient.getAddress().serialize()).success(devices -> { + LokiFileServerAPI.shared.getAllDevicePublicKeys(threadRecipient.getAddress().serialize()).success(devices -> { // We should update our input if this thread is a part of the other threads device if (devices.contains(recipient.getAddress().serialize())) { this.updateInputPanel(); diff --git a/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java b/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java index 031eb62a4d..e5abc7d886 100644 --- a/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java +++ b/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java @@ -11,7 +11,7 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities; import org.thoughtcrime.securesms.util.AsyncLoader; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.crypto.MnemonicCodec; import java.io.File; @@ -33,7 +33,7 @@ public class DeviceListLoader extends AsyncLoader> { public List loadInBackground() { try { String ourPublicKey = TextSecurePreferences.getLocalNumber(getContext()); - List secondaryDevicePublicKeys = LokiStorageAPI.shared.getSecondaryDevicePublicKeys(ourPublicKey).get(); + List secondaryDevicePublicKeys = LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(ourPublicKey).get(); List devices = Stream.of(secondaryDevicePublicKeys).map(this::mapToDevice).toList(); Collections.sort(devices, new DeviceComparator()); return devices; diff --git a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java index 9f216e2fad..3ba89fe908 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java +++ b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java @@ -36,7 +36,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceGroup; import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.util.Collections; @@ -318,7 +318,7 @@ public class GroupMessageProcessor { try { String masterHexEncodedPublicKey = hexEncodedPublicKey.equalsIgnoreCase(ourPublicKey) ? TextSecurePreferences.getMasterHexEncodedPublicKey(context) - : PromiseUtil.timeout(LokiStorageAPI.shared.getPrimaryDevicePublicKey(hexEncodedPublicKey), 5000).get(); + : PromiseUtil.timeout(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(hexEncodedPublicKey), 5000).get(); return masterHexEncodedPublicKey != null ? masterHexEncodedPublicKey : hexEncodedPublicKey; } catch (Exception e) { return hexEncodedPublicKey; @@ -329,7 +329,7 @@ public class GroupMessageProcessor { String ourNumber = TextSecurePreferences.getLocalNumber(context); for (String member : members) { // Make sure we have session with all of the members secondary devices - LokiStorageAPI.shared.getAllDevicePublicKeys(member).success(devices -> { + LokiFileServerAPI.shared.getAllDevicePublicKeys(member).success(devices -> { if (devices.contains(ourNumber)) { return Unit.INSTANCE; } for (String device : devices) { SignalProtocolAddress protocolAddress = new SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID); diff --git a/src/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java b/src/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java index dce85f83e6..3bb54e43d9 100644 --- a/src/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java +++ b/src/org/thoughtcrime/securesms/jobs/AttachmentUploadJob.java @@ -27,7 +27,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.io.IOException; import java.io.InputStream; diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 6282120598..0507e8c0f0 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -131,7 +131,7 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.loki.api.DeviceLinkingSession; import org.whispersystems.signalservice.loki.api.LokiAPI; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.api.PairingAuthorisation; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; @@ -1177,7 +1177,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Send a background message to the primary device MessageSender.sendBackgroundMessage(context, authorisation.getPrimaryDevicePublicKey()); // Propagate the updates to the file server - LokiStorageAPI storageAPI = LokiStorageAPI.Companion.getShared(); + LokiFileServerAPI storageAPI = LokiFileServerAPI.Companion.getShared(); storageAPI.updateUserDeviceMappings(); // Update display names if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) { @@ -1245,7 +1245,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { private void handleSessionRequestIfNeeded(@NonNull SignalServiceContent content) { if (content.isFriendRequest() && isSessionRequest(content)) { // Check if the session request from a member in one of our groups or our friend - LokiStorageAPI.shared.getPrimaryDevicePublicKey(content.getSender()).success(primaryDevicePublicKey -> { + LokiFileServerAPI.shared.getPrimaryDevicePublicKey(content.getSender()).success(primaryDevicePublicKey -> { String sender = primaryDevicePublicKey != null ? primaryDevicePublicKey : content.getSender(); long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(sender), false)); LokiThreadFriendRequestStatus threadFriendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID); @@ -1284,7 +1284,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Allow profile sharing with contact DatabaseFactory.getRecipientDatabase(context).setProfileSharing(contactID, true); // Update the last message if needed - LokiStorageAPI.shared.getPrimaryDevicePublicKey(pubKey).success(primaryDevice -> { + LokiFileServerAPI.shared.getPrimaryDevicePublicKey(pubKey).success(primaryDevice -> { Util.runOnMain(() -> { long primaryDeviceThreadID = primaryDevice == null ? threadID : DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(primaryDevice), false)); FriendRequestHandler.updateLastFriendRequestMessage(context, primaryDeviceThreadID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); @@ -1799,7 +1799,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { */ private Recipient getPrimaryDeviceRecipient(String pubKey) { try { - String primaryDevice = PromiseUtil.timeout(LokiStorageAPI.shared.getPrimaryDevicePublicKey(pubKey), 5000).get(); + String primaryDevice = PromiseUtil.timeout(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(pubKey), 5000).get(); String publicKey = (primaryDevice != null) ? primaryDevice : pubKey; // If the public key matches our primary device then we need to forward the message to ourselves (Note to self) String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context); diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 04e672c20a..1c07fd611a 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -51,7 +51,7 @@ import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; import org.whispersystems.signalservice.loki.api.LokiPublicChat; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.io.IOException; @@ -368,7 +368,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType { if (!member.isPhone() || member.serialize().equalsIgnoreCase(localNumber)) { continue; } try { - List secondaryDevices = PromiseUtil.timeout(LokiStorageAPI.shared.getSecondaryDevicePublicKeys(member.serialize()), 5000).get(); + List secondaryDevices = PromiseUtil.timeout(LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(member.serialize()), 5000).get(); memberSet.addAll(Stream.of(secondaryDevices).map(string -> { // Loki - Calling .map(Address::fromSerialized) is causing errors, thus we use the long method :( return Address.fromSerialized(string); diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index ae133a0394..13de89022b 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -43,7 +43,7 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.messaging.LokiSyncMessage; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; @@ -292,7 +292,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { LokiSyncMessage syncMessage = null; if (shouldSendSyncMessage) { // Set the sync message destination the primary device, this way it will show that we sent a message to the primary device and not a secondary device - String primaryDevice = PromiseUtil.get(LokiStorageAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); + String primaryDevice = PromiseUtil.get(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); SignalServiceAddress primaryAddress = primaryDevice == null ? address : new SignalServiceAddress(primaryDevice); // We also need to use the original message id and not -1 syncMessage = new LokiSyncMessage(primaryAddress, templateMessageId); diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index a8a084a447..dfa291436d 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -30,7 +30,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.messaging.LokiSyncMessage; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; @@ -237,7 +237,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { LokiSyncMessage syncMessage = null; if (shouldSendSyncMessage) { // Set the sync message destination to the primary device, this way it will show that we sent a message to the primary device and not a secondary device - String primaryDevice = PromiseUtil.get(LokiStorageAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); + String primaryDevice = PromiseUtil.get(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); SignalServiceAddress primaryAddress = primaryDevice == null ? address : new SignalServiceAddress(primaryDevice); // We also need to use the original message id and not -1 syncMessage = new LokiSyncMessage(primaryAddress, templateMessageId); diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index 125fcdd226..ebdcff428e 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.push.SignalServiceAddress -import org.whispersystems.signalservice.loki.api.LokiStorageAPI +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.utilities.recover @@ -32,12 +32,12 @@ fun checkForRevocation(context: Context) { val primaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) ?: return val ourDevice = TextSecurePreferences.getLocalNumber(context) - LokiStorageAPI.shared.fetchDeviceMappings(primaryDevice).bind { mappings -> + LokiFileServerAPI.shared.fetchDeviceMappings(primaryDevice).bind { mappings -> val ourMapping = mappings.find { it.secondaryDevicePublicKey == ourDevice } if (ourMapping != null) throw Error("Device has not been revoked") // remove pairing authorisations for our device DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(ourDevice) - LokiStorageAPI.shared.updateUserDeviceMappings() + LokiFileServerAPI.shared.updateUserDeviceMappings() }.successUi { TextSecurePreferences.setNeedsRevocationCheck(context, false) ApplicationContext.getInstance(context).clearData() @@ -49,7 +49,7 @@ fun checkForRevocation(context: Context) { fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: String): Promise, Exception> { val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) - return LokiStorageAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> + return LokiFileServerAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> val map = mutableMapOf() for (devicePublicKey in keys) { val device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false) @@ -63,7 +63,7 @@ fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: Str fun getAllDevicePublicKeysWithFriendStatus(context: Context, hexEncodedPublicKey: String): Promise, Unit> { val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - return LokiStorageAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> + return LokiFileServerAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> val devices = keys.toMutableSet() if (hexEncodedPublicKey != userHexEncodedPublicKey) { devices.remove(userHexEncodedPublicKey) @@ -92,7 +92,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Conte return Promise.of(true) } - return LokiStorageAPI.shared.getPrimaryDevicePublicKey(publicKey).bind { primaryDevicePublicKey -> + return LokiFileServerAPI.shared.getPrimaryDevicePublicKey(publicKey).bind { primaryDevicePublicKey -> // If the public key doesn't have any other devices then go through regular friend request logic if (primaryDevicePublicKey == null) { return@bind Promise.of(false) @@ -157,7 +157,7 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio Log.d("Loki", "Failed to send pairing authorization message to ${address.serialize()}.") } - val updatePromise = LokiStorageAPI.shared.updateUserDeviceMappings().fail { + val updatePromise = LokiFileServerAPI.shared.updateUserDeviceMappings().fail { Log.d("Loki", "Failed to update device mapping") } @@ -177,7 +177,7 @@ fun isOneOfOurDevices(context: Context, address: Address): Promise + return LokiFileServerAPI.shared.getAllDevicePublicKeys(ourPublicKey).map { devices -> devices.contains(address.serialize()) } } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index ba659cfa21..5cc7a152ed 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -20,7 +20,7 @@ import org.thoughtcrime.securesms.loki.signAndSendPairingAuthorisationMessage import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.Util -import org.whispersystems.signalservice.loki.api.LokiStorageAPI +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import org.whispersystems.signalservice.loki.api.PairingAuthorisation class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager.LoaderCallbacks>, DeviceClickListener, EditDeviceNameDialogDelegate, LinkDeviceMasterModeDialogDelegate { @@ -119,7 +119,7 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this) val database = DatabaseFactory.getLokiAPIDatabase(this) database.removePairingAuthorisation(userHexEncodedPublicKey, slaveDeviceHexEncodedPublicKey) - LokiStorageAPI.shared.updateUserDeviceMappings().success { + LokiFileServerAPI.shared.updateUserDeviceMappings().success { MessageSender.sendUnpairRequest(this, slaveDeviceHexEncodedPublicKey) } LoaderManager.getInstance(this).restartLoader(0, null, this) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt index 324dd6362f..a2519801d5 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt @@ -6,7 +6,7 @@ import org.thoughtcrime.securesms.devicelist.Device import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities import org.thoughtcrime.securesms.util.AsyncLoader import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.whispersystems.signalservice.loki.api.LokiStorageAPI +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import java.io.File @@ -20,7 +20,7 @@ class LinkedDevicesLoader(context: Context) : AsyncLoader>(context) override fun loadInBackground(): List? { try { val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - val slaveDeviceHexEncodedPublicKeys = LokiStorageAPI.shared.getSecondaryDevicePublicKeys(userHexEncodedPublicKey).get() + val slaveDeviceHexEncodedPublicKeys = LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(userHexEncodedPublicKey).get() return slaveDeviceHexEncodedPublicKeys.map { hexEncodedPublicKey -> val shortID = MnemonicUtilities.getFirst3Words(mnemonicCodec, hexEncodedPublicKey) val name = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(hexEncodedPublicKey) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/SettingsActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/SettingsActivity.kt index e26846e074..79134bb621 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/SettingsActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/SettingsActivity.kt @@ -41,7 +41,7 @@ import org.thoughtcrime.securesms.util.BitmapUtil import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.crypto.ProfileCipher import org.whispersystems.signalservice.api.util.StreamDetails -import org.whispersystems.signalservice.loki.api.LokiStorageAPI +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import java.io.ByteArrayInputStream import java.io.File import java.security.SecureRandom @@ -159,7 +159,7 @@ class SettingsActivity : PassphraseRequiredActionBarActivity() { val encodedProfileKey = ProfileKeyUtil.generateEncodedProfileKey(this) val profileKey = ProfileKeyUtil.getProfileKeyFromEncodedString(encodedProfileKey) if (isUpdatingProfilePicture && profilePicture != null) { - val storageAPI = LokiStorageAPI.shared + val storageAPI = LokiFileServerAPI.shared val deferred = deferred() AsyncTask.execute { val stream = StreamDetails(ByteArrayInputStream(profilePicture), "image/jpeg", profilePicture.size.toLong()) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt index 1a600e4293..fd618562c6 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt @@ -24,7 +24,7 @@ import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.loki.api.LokiPublicChat import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI import org.whispersystems.signalservice.loki.api.LokiPublicChatMessage -import org.whispersystems.signalservice.loki.api.LokiStorageAPI +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.utilities.successBackground import java.security.MessageDigest @@ -156,7 +156,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki fun pollForNewMessages() { fun processIncomingMessage(message: LokiPublicChatMessage) { // If the sender of the current message is not a secondary device, we need to set the display name in the database - val primaryDevice = LokiStorageAPI.shared.getPrimaryDevicePublicKey(message.hexEncodedPublicKey).get() + val primaryDevice = LokiFileServerAPI.shared.getPrimaryDevicePublicKey(message.hexEncodedPublicKey).get() if (primaryDevice == null) { val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})" DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName) @@ -219,17 +219,17 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki var uniqueDevices = setOf() val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() val database = DatabaseFactory.getLokiAPIDatabase(context) - LokiStorageAPI.configure(false, userHexEncodedPublicKey, userPrivateKey, database) - LokiStorageAPI.shared.getAllDevicePublicKeys(userHexEncodedPublicKey).bind { devices -> + LokiFileServerAPI.configure(false, userHexEncodedPublicKey, userPrivateKey, database) + LokiFileServerAPI.shared.getAllDevicePublicKeys(userHexEncodedPublicKey).bind { devices -> userDevices = devices api.getMessages(group.channel, group.server) }.bind { messages -> if (messages.isNotEmpty()) { // We need to fetch device mappings for all the devices we don't have uniqueDevices = messages.map { it.hexEncodedPublicKey }.toSet() - val devicesToUpdate = uniqueDevices.filter { !userDevices.contains(it) && LokiStorageAPI.shared.hasCacheExpired(it) } + val devicesToUpdate = uniqueDevices.filter { !userDevices.contains(it) && LokiFileServerAPI.shared.hasCacheExpired(it) } if (devicesToUpdate.isNotEmpty()) { - return@bind LokiStorageAPI.shared.getDeviceMappings(devicesToUpdate.toSet()).then { messages } + return@bind LokiFileServerAPI.shared.getDeviceMappings(devicesToUpdate.toSet()).then { messages } } } Promise.of(messages) @@ -238,7 +238,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki val newDisplayNameUpdatees = uniqueDevices.mapNotNull { // This will return null if current device is primary // So if it's non-null then we know the device is a secondary device - val primaryDevice = LokiStorageAPI.shared.getPrimaryDevicePublicKey(it).get() + val primaryDevice = LokiFileServerAPI.shared.getPrimaryDevicePublicKey(it).get() primaryDevice }.toSet() // Fetch the display names of the primary devices diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiRSSFeedPoller.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiRSSFeedPoller.kt index d7a6c3398b..b45ce47ade 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiRSSFeedPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiRSSFeedPoller.kt @@ -14,7 +14,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceGroup import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.loki.api.LokiRSSFeed -import org.whispersystems.signalservice.loki.api.LokiRSSProxy +import org.whispersystems.signalservice.loki.api.LokiRSSFeedProxy import org.whispersystems.signalservice.loki.utilities.successBackground import java.text.SimpleDateFormat import java.util.regex.Pattern @@ -48,7 +48,7 @@ class LokiRSSFeedPoller(private val context: Context, private val feed: LokiRSSF } private fun poll() { - LokiRSSProxy.fetch(feed.url).successBackground { xml -> + LokiRSSFeedProxy.fetch(feed.url).successBackground { xml -> val items = XMLParser(xml).call() items.reversed().forEach { item -> val title = item.title ?: return@forEach diff --git a/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java b/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java index f92ff642f0..ed82b436a0 100644 --- a/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java +++ b/src/org/thoughtcrime/securesms/notifications/MarkReadReceiver.java @@ -23,7 +23,7 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.service.ExpiringMessageManager; import org.thoughtcrime.securesms.util.Util; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.util.LinkedList; import java.util.List; diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index df26a6ec03..4dfa91f4c3 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -60,7 +60,7 @@ import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.ContactTokenDetails; -import org.whispersystems.signalservice.loki.api.LokiStorageAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; @@ -99,7 +99,7 @@ public class MessageSender { sendBackgroundMessage(context, contactHexEncodedPublicKey); // Go through the other devices and only send background messages if we're friends or we have received friend request - LokiStorageAPI.shared.getAllDevicePublicKeys(contactHexEncodedPublicKey).success(devices -> { + LokiFileServerAPI.shared.getAllDevicePublicKeys(contactHexEncodedPublicKey).success(devices -> { Util.runOnMain(() -> { for (String device : devices) { // Don't send message to the device we already have sent to @@ -234,7 +234,7 @@ public class MessageSender { final int ttl) { String ourPublicKey = TextSecurePreferences.getLocalNumber(context); JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - LokiStorageAPI.shared.getAllDevicePublicKeys(ourPublicKey).success(devices -> { + LokiFileServerAPI.shared.getAllDevicePublicKeys(ourPublicKey).success(devices -> { Util.runOnMain(() -> { for (String device : devices) { // Don't send to ourselves From cb1553631efcf7374e8894c5fa589276da7b7681 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 11 Feb 2020 11:00:00 +1100 Subject: [PATCH 03/18] Implement file size limit --- .../securesms/mms/PushMediaConstraints.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java index 30a6b1ea18..c976cabea1 100644 --- a/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java +++ b/src/org/thoughtcrime/securesms/mms/PushMediaConstraints.java @@ -3,13 +3,12 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; import org.thoughtcrime.securesms.util.Util; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; public class PushMediaConstraints extends MediaConstraints { private static final int MAX_IMAGE_DIMEN_LOWMEM = 768; private static final int MAX_IMAGE_DIMEN = 4096; - private static final int KB = 1024; - private static final int MB = 1024 * KB; @Override public int getImageMaxWidth(Context context) { @@ -23,26 +22,26 @@ public class PushMediaConstraints extends MediaConstraints { @Override public int getImageMaxSize(Context context) { - return 6 * MB; + return LokiFileServerAPI.Companion.getMaxFileSize(); } @Override public int getGifMaxSize(Context context) { - return 25 * MB; + return LokiFileServerAPI.Companion.getMaxFileSize(); } @Override public int getVideoMaxSize(Context context) { - return 100 * MB; + return LokiFileServerAPI.Companion.getMaxFileSize(); } @Override public int getAudioMaxSize(Context context) { - return 100 * MB; + return LokiFileServerAPI.Companion.getMaxFileSize(); } @Override public int getDocumentMaxSize(Context context) { - return 100 * MB; + return LokiFileServerAPI.Companion.getMaxFileSize(); } } From 18ee21355cda9dfc09e228e0369946d6c45e5aa1 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 11 Feb 2020 11:36:31 +1100 Subject: [PATCH 04/18] Clean --- .../securesms/notifications/NotificationUtilities.kt | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/org/thoughtcrime/securesms/notifications/NotificationUtilities.kt b/src/org/thoughtcrime/securesms/notifications/NotificationUtilities.kt index 8ff7c636cc..f167226223 100644 --- a/src/org/thoughtcrime/securesms/notifications/NotificationUtilities.kt +++ b/src/org/thoughtcrime/securesms/notifications/NotificationUtilities.kt @@ -9,14 +9,10 @@ fun getOpenGroupDisplayName(recipient: Recipient, threadRecipient: Recipient, co val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(threadRecipient) val publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) val hexEncodedPublicKey = recipient.address.toString() - val displayName: String? - displayName = if (publicChat != null) { + val displayName = if (publicChat != null) { DatabaseFactory.getLokiUserDatabase(context).getServerDisplayName(publicChat.id, hexEncodedPublicKey) } else { DatabaseFactory.getLokiUserDatabase(context).getDisplayName(hexEncodedPublicKey) } - if (displayName == null) { - return hexEncodedPublicKey - } - return displayName + return displayName ?: hexEncodedPublicKey } \ No newline at end of file From 2fbe33736c48fbd4efcdf38c68d21120cc8b8b39 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 11 Feb 2020 11:37:06 +1100 Subject: [PATCH 05/18] Reduce background polling interval --- .../securesms/loki/redesign/messaging/BackgroundPollWorker.kt | 2 +- .../loki/redesign/messaging/BackgroundPublicChatPollWorker.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt index 184e11d585..021dba6ac8 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPollWorker.kt @@ -15,7 +15,7 @@ import java.util.concurrent.TimeUnit class BackgroundPollWorker : PersistentAlarmManagerListener() { companion object { - private val pollInterval = TimeUnit.MINUTES.toMillis(2) + private val pollInterval = TimeUnit.MINUTES.toMillis(1) @JvmStatic fun schedule(context: Context) { diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPublicChatPollWorker.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPublicChatPollWorker.kt index 130122c492..6bdbc71252 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPublicChatPollWorker.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/BackgroundPublicChatPollWorker.kt @@ -10,7 +10,7 @@ import java.util.concurrent.TimeUnit class BackgroundPublicChatPollWorker : PersistentAlarmManagerListener() { companion object { - private val pollInterval = TimeUnit.MINUTES.toMillis(4) + private val pollInterval = TimeUnit.MINUTES.toMillis(2) @JvmStatic fun schedule(context: Context) { From b1cbbf294040de00d2bc8e19afcfd27252726533 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 11 Feb 2020 14:02:01 +1100 Subject: [PATCH 06/18] Fix copy --- res/values/strings.xml | 14 +++++++------- .../conversation/ConversationActivity.java | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index d5d65e2d57..348b88b0f5 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1618,13 +1618,13 @@ Accept Decline - %1$s sent you a message request - You\'ve accepted %1$s\'s message request - You\'ve declined %1$s\'s message request - %1$s\'s message request has expired - You\'ve sent %1$s a message request - %1$s accepted your message request - Your message request to %1$s has expired + %1$s sent you a session request + You\'ve accepted %1$s\'s session request + You\'ve declined %1$s\'s session request + %1$s\'s session request has expired + You\'ve sent %1$s a session request + %1$s accepted your session request + Your session request to %1$s has expired Pending Friend Request… New Message diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 2d1dabb73b..5f586e2f96 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -2353,7 +2353,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity private void setInputPanelEnabled(boolean enabled) { Util.runOnMain(() -> { updateToggleButtonState(); - String hint = enabled ? "Message" : "Pending message request"; + String hint = enabled ? "Message" : "Pending session request"; inputPanel.setHint(hint); inputPanel.setEnabled(enabled); if (enabled) { From 705b3dc6259aa78955d1b5858ff9e577334d2f8a Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 12 Feb 2020 12:26:27 +1100 Subject: [PATCH 07/18] Refactor --- .../securesms/ApplicationContext.java | 8 +--- .../securesms/DeviceListFragment.java | 2 +- .../components/TypingStatusSender.java | 5 +- .../conversation/ConversationActivity.java | 14 +++--- .../database/loaders/DeviceListLoader.java | 5 +- .../groups/GroupMessageProcessor.java | 6 +-- .../securesms/jobs/PushDecryptJob.java | 47 ++++++++++--------- .../securesms/jobs/PushGroupSendJob.java | 4 +- .../securesms/jobs/PushMediaSendJob.java | 6 +-- .../securesms/jobs/PushTextSendJob.java | 5 +- .../securesms/loki/MultiDeviceUtilities.kt | 35 +++++++------- .../activities/CreateClosedGroupLoader.kt | 4 +- .../redesign/activities/LandingActivity.kt | 10 ++-- .../activities/LinkedDevicesActivity.kt | 6 +-- .../activities/LinkedDevicesLoader.kt | 4 +- .../dialogs/LinkDeviceMasterModeDialog.kt | 14 +++--- .../dialogs/LinkDeviceSlaveModeDialog.kt | 10 ++-- .../redesign/messaging/LokiAPIDatabase.kt | 22 ++++----- .../messaging/LokiPublicChatPoller.kt | 27 +++++------ .../redesign/utilities/MentionUtilities.kt | 2 +- .../securesms/sms/MessageSender.java | 6 +-- 21 files changed, 117 insertions(+), 125 deletions(-) diff --git a/src/org/thoughtcrime/securesms/ApplicationContext.java b/src/org/thoughtcrime/securesms/ApplicationContext.java index 5bcc0d948c..efb1d1fee6 100644 --- a/src/org/thoughtcrime/securesms/ApplicationContext.java +++ b/src/org/thoughtcrime/securesms/ApplicationContext.java @@ -96,14 +96,13 @@ import org.whispersystems.libsignal.logging.SignalProtocolLoggerProvider; import org.whispersystems.signalservice.api.messages.SignalServiceEnvelope; import org.whispersystems.signalservice.internal.push.SignalServiceProtos; import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol; -import org.whispersystems.signalservice.loki.api.LokiDotNetAPI; +import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.api.LokiLongPoller; import org.whispersystems.signalservice.loki.api.LokiP2PAPI; import org.whispersystems.signalservice.loki.api.LokiP2PAPIDelegate; import org.whispersystems.signalservice.loki.api.LokiPublicChat; import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI; import org.whispersystems.signalservice.loki.api.LokiRSSFeed; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.security.Security; import java.util.ArrayList; @@ -115,7 +114,6 @@ import java.util.concurrent.TimeUnit; import dagger.ObjectGraph; import kotlin.Unit; import network.loki.messenger.BuildConfig; -import okhttp3.Cache; import static nl.komponents.kovenant.android.KovenantAndroid.startKovenant; import static nl.komponents.kovenant.android.KovenantAndroid.stopKovenant; @@ -184,11 +182,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc ProcessLifecycleOwner.get().getLifecycle().addObserver(this); // Loki - Set up P2P API if needed setUpP2PAPI(); - // Loki - Set the cache - LokiDotNetAPI.setCache(new Cache(this.getCacheDir(), OK_HTTP_CACHE_SIZE)); // Loki - Update device mappings if (setUpStorageAPIIfNeeded()) { - LokiFileServerAPI.Companion.getShared().updateUserDeviceMappings(); + LokiFileServerAPI.Companion.getShared().updateUserDeviceLinks(); if (TextSecurePreferences.needsRevocationCheck(this)) { checkNeedsRevocation(); } diff --git a/src/org/thoughtcrime/securesms/DeviceListFragment.java b/src/org/thoughtcrime/securesms/DeviceListFragment.java index 91381c4835..d725522e3d 100644 --- a/src/org/thoughtcrime/securesms/DeviceListFragment.java +++ b/src/org/thoughtcrime/securesms/DeviceListFragment.java @@ -190,7 +190,7 @@ public class DeviceListFragment extends ListFragment private void updateAddDeviceButtonVisibility() { if (addDeviceButton != null) { String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(getContext()); - boolean isDeviceLinkingEnabled = DatabaseFactory.getLokiAPIDatabase(getContext()).getPairingAuthorisations(userHexEncodedPublicKey).isEmpty(); + boolean isDeviceLinkingEnabled = DatabaseFactory.getLokiAPIDatabase(getContext()).getDeviceLinks(userHexEncodedPublicKey).isEmpty(); addDeviceButton.setVisibility(isDeviceLinkingEnabled ? View.VISIBLE : View.INVISIBLE); } } diff --git a/src/org/thoughtcrime/securesms/components/TypingStatusSender.java b/src/org/thoughtcrime/securesms/components/TypingStatusSender.java index 4b7908cbb6..1c851247ea 100644 --- a/src/org/thoughtcrime/securesms/components/TypingStatusSender.java +++ b/src/org/thoughtcrime/securesms/components/TypingStatusSender.java @@ -9,14 +9,13 @@ import org.thoughtcrime.securesms.database.Address; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.ThreadDatabase; import org.thoughtcrime.securesms.jobs.TypingSendJob; -import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.util.Util; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import java.util.HashMap; import java.util.Map; -import java.util.Set; import java.util.concurrent.TimeUnit; import kotlin.Unit; @@ -91,7 +90,7 @@ public class TypingStatusSender { ApplicationContext.getInstance(context).getJobManager().add(new TypingSendJob(threadId, typingStarted)); return; } - LokiFileServerAPI.shared.getAllDevicePublicKeys(recipient.getAddress().serialize()).success(devices -> { + LokiDeviceLinkUtilities.INSTANCE.getAllLinkedDeviceHexEncodedPublicKeys(recipient.getAddress().serialize()).success(devices -> { for (String device : devices) { Recipient deviceRecipient = Recipient.from(context, Address.fromSerialized(device), false); long deviceThreadID = threadDatabase.getThreadIdIfExistsFor(deviceRecipient); diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 5f586e2f96..5e0d427b57 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -232,10 +232,10 @@ import org.thoughtcrime.securesms.util.concurrent.SettableFuture; import org.thoughtcrime.securesms.util.views.Stub; import org.whispersystems.libsignal.InvalidMessageException; import org.whispersystems.libsignal.util.guava.Optional; +import org.whispersystems.signalservice.loki.api.DeviceLink; import org.whispersystems.signalservice.loki.api.LokiAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.api.LokiPublicChat; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; -import org.whispersystems.signalservice.loki.api.PairingAuthorisation; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.Mention; @@ -2290,7 +2290,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity if (threadID != this.threadId) { Recipient threadRecipient = DatabaseFactory.getThreadDatabase(this).getRecipientForThreadId(threadID); if (threadRecipient != null && !threadRecipient.isGroupRecipient()) { - LokiFileServerAPI.shared.getAllDevicePublicKeys(threadRecipient.getAddress().serialize()).success(devices -> { + LokiDeviceLinkUtilities.INSTANCE.getAllLinkedDeviceHexEncodedPublicKeys(threadRecipient.getAddress().serialize()).success(devices -> { // We should update our input if this thread is a part of the other threads device if (devices.contains(recipient.getAddress().serialize())) { this.updateInputPanel(); @@ -3162,11 +3162,11 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity // region Loki private void updateTitleTextView(GlideRequests glide, Recipient recipient) { String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this); - List deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getPairingAuthorisations(userHexEncodedPublicKey); + Set deviceLinks = DatabaseFactory.getLokiAPIDatabase(this).getDeviceLinks(userHexEncodedPublicKey); HashSet userLinkedDeviceHexEncodedPublicKeys = new HashSet<>(); - for (PairingAuthorisation deviceLink : deviceLinks) { - userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getPrimaryDevicePublicKey().toLowerCase()); - userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getSecondaryDevicePublicKey().toLowerCase()); + for (DeviceLink deviceLink : deviceLinks) { + userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getMasterHexEncodedPublicKey().toLowerCase()); + userLinkedDeviceHexEncodedPublicKeys.add(deviceLink.getSlaveHexEncodedPublicKey().toLowerCase()); } userLinkedDeviceHexEncodedPublicKeys.add(userHexEncodedPublicKey.toLowerCase()); if (recipient == null) { diff --git a/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java b/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java index e5abc7d886..7a7a67d535 100644 --- a/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java +++ b/src/org/thoughtcrime/securesms/database/loaders/DeviceListLoader.java @@ -11,13 +11,14 @@ import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities; import org.thoughtcrime.securesms.util.AsyncLoader; import org.thoughtcrime.securesms.util.TextSecurePreferences; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.crypto.MnemonicCodec; import java.io.File; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Set; public class DeviceListLoader extends AsyncLoader> { @@ -33,7 +34,7 @@ public class DeviceListLoader extends AsyncLoader> { public List loadInBackground() { try { String ourPublicKey = TextSecurePreferences.getLocalNumber(getContext()); - List secondaryDevicePublicKeys = LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(ourPublicKey).get(); + Set secondaryDevicePublicKeys = LokiDeviceLinkUtilities.INSTANCE.getSlaveHexEncodedPublicKeys(ourPublicKey).get(); List devices = Stream.of(secondaryDevicePublicKeys).map(this::mapToDevice).toList(); Collections.sort(devices, new DeviceComparator()); return devices; diff --git a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java index 3ba89fe908..d1f37ce390 100644 --- a/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java +++ b/src/org/thoughtcrime/securesms/groups/GroupMessageProcessor.java @@ -36,7 +36,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.SignalServiceGroup; import org.whispersystems.signalservice.api.messages.SignalServiceGroup.Type; import org.whispersystems.signalservice.api.push.SignalServiceAddress; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.util.Collections; @@ -318,7 +318,7 @@ public class GroupMessageProcessor { try { String masterHexEncodedPublicKey = hexEncodedPublicKey.equalsIgnoreCase(ourPublicKey) ? TextSecurePreferences.getMasterHexEncodedPublicKey(context) - : PromiseUtil.timeout(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(hexEncodedPublicKey), 5000).get(); + : PromiseUtil.timeout(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(hexEncodedPublicKey), 5000).get(); return masterHexEncodedPublicKey != null ? masterHexEncodedPublicKey : hexEncodedPublicKey; } catch (Exception e) { return hexEncodedPublicKey; @@ -329,7 +329,7 @@ public class GroupMessageProcessor { String ourNumber = TextSecurePreferences.getLocalNumber(context); for (String member : members) { // Make sure we have session with all of the members secondary devices - LokiFileServerAPI.shared.getAllDevicePublicKeys(member).success(devices -> { + LokiDeviceLinkUtilities.INSTANCE.getAllLinkedDeviceHexEncodedPublicKeys(member).success(devices -> { if (devices.contains(ourNumber)) { return Unit.INSTANCE; } for (String device : devices) { SignalProtocolAddress protocolAddress = new SignalProtocolAddress(device, SignalServiceAddress.DEFAULT_DEVICE_ID); diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 0507e8c0f0..6d0f70316d 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -68,13 +68,13 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreview; import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil; import org.thoughtcrime.securesms.logging.Log; import org.thoughtcrime.securesms.loki.FriendRequestHandler; -import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities; import org.thoughtcrime.securesms.loki.LokiMessageDatabase; -import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase; -import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.loki.LokiThreadDatabase; import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.loki.redesign.activities.HomeActivity; +import org.thoughtcrime.securesms.loki.redesign.messaging.LokiAPIUtilities; +import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyBundleDatabase; +import org.thoughtcrime.securesms.loki.redesign.messaging.LokiPreKeyRecordDatabase; import org.thoughtcrime.securesms.mms.IncomingMediaMessage; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage; @@ -129,10 +129,11 @@ import org.whispersystems.signalservice.api.messages.multidevice.StickerPackOper import org.whispersystems.signalservice.api.messages.multidevice.VerifiedMessage; import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; +import org.whispersystems.signalservice.loki.api.DeviceLink; import org.whispersystems.signalservice.loki.api.DeviceLinkingSession; import org.whispersystems.signalservice.loki.api.LokiAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; -import org.whispersystems.signalservice.loki.api.PairingAuthorisation; import org.whispersystems.signalservice.loki.crypto.LokiServiceCipher; import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus; import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage; @@ -1102,20 +1103,20 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } - private boolean isValidPairingMessage(@NonNull PairingAuthorisation authorisation) { + private boolean isValidPairingMessage(@NonNull DeviceLink authorisation) { boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null; String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); - boolean isRequest = (authorisation.getType() == PairingAuthorisation.Type.REQUEST); + boolean isRequest = (authorisation.getType() == DeviceLink.Type.REQUEST); if (authorisation.getRequestSignature() == null) { Log.d("Loki", "Ignoring pairing request message without a request signature."); return false; } else if (isRequest && isSecondaryDevice) { Log.d("Loki", "Ignoring unexpected pairing request message (the device is already paired as a secondary device)."); return false; - } else if (isRequest && !authorisation.getPrimaryDevicePublicKey().equals(userHexEncodedPublicKey)) { + } else if (isRequest && !authorisation.getMasterHexEncodedPublicKey().equals(userHexEncodedPublicKey)) { Log.d("Loki", "Ignoring pairing request message addressed to another user."); return false; - } else if (isRequest && authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) { + } else if (isRequest && authorisation.getSlaveHexEncodedPublicKey().equals(userHexEncodedPublicKey)) { Log.d("Loki", "Ignoring pairing request message from self."); return false; } @@ -1127,16 +1128,16 @@ public class PushDecryptJob extends BaseJob implements InjectableType { ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(primaryDevice, url)); } - private void handlePairingMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceContent content) { + private void handlePairingMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) { String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); - if (authorisation.getType() == PairingAuthorisation.Type.REQUEST) { + if (authorisation.getType() == DeviceLink.Type.REQUEST) { handlePairingRequestMessage(authorisation, content); - } else if (authorisation.getSecondaryDevicePublicKey().equals(userHexEncodedPublicKey)) { + } else if (authorisation.getSlaveHexEncodedPublicKey().equals(userHexEncodedPublicKey)) { handlePairingAuthorisationMessage(authorisation, content); } } - private void handlePairingRequestMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceContent content) { + private void handlePairingRequestMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) { boolean isValid = isValidPairingMessage(authorisation); DeviceLinkingSession linkingSession = DeviceLinkingSession.Companion.getShared(); if (isValid && linkingSession.isListeningForLinkingRequests()) { @@ -1146,7 +1147,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } - private void handlePairingAuthorisationMessage(@NonNull PairingAuthorisation authorisation, @NonNull SignalServiceContent content) { + private void handlePairingAuthorisationMessage(@NonNull DeviceLink authorisation, @NonNull SignalServiceContent content) { // Prepare boolean isSecondaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) != null; if (isSecondaryDevice) { @@ -1162,23 +1163,23 @@ public class PushDecryptJob extends BaseJob implements InjectableType { Log.d("Loki", "Ignoring pairing authorisation message."); return; } - if (authorisation.getType() != PairingAuthorisation.Type.GRANT) { return; } - Log.d("Loki", "Received pairing authorisation message from: " + authorisation.getPrimaryDevicePublicKey() + "."); + if (authorisation.getType() != DeviceLink.Type.AUTHORIZATION) { return; } + Log.d("Loki", "Received pairing authorisation message from: " + authorisation.getMasterHexEncodedPublicKey() + "."); // Save PreKeyBundle if for whatever reason we got one storePreKeyBundleIfNeeded(content); // Process DeviceLinkingSession.Companion.getShared().processLinkingAuthorization(authorisation); // Store the primary device's public key String userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context); - DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(userHexEncodedPublicKey); - DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(authorisation); - TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getPrimaryDevicePublicKey()); + DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(userHexEncodedPublicKey); + DatabaseFactory.getLokiAPIDatabase(context).addDeviceLink(authorisation); + TextSecurePreferences.setMasterHexEncodedPublicKey(context, authorisation.getMasterHexEncodedPublicKey()); TextSecurePreferences.setMultiDevice(context, true); // Send a background message to the primary device - MessageSender.sendBackgroundMessage(context, authorisation.getPrimaryDevicePublicKey()); + MessageSender.sendBackgroundMessage(context, authorisation.getMasterHexEncodedPublicKey()); // Propagate the updates to the file server LokiFileServerAPI storageAPI = LokiFileServerAPI.Companion.getShared(); - storageAPI.updateUserDeviceMappings(); + storageAPI.updateUserDeviceLinks(); // Update display names if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) { TextSecurePreferences.setProfileName(context, content.senderDisplayName.get()); @@ -1245,7 +1246,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { private void handleSessionRequestIfNeeded(@NonNull SignalServiceContent content) { if (content.isFriendRequest() && isSessionRequest(content)) { // Check if the session request from a member in one of our groups or our friend - LokiFileServerAPI.shared.getPrimaryDevicePublicKey(content.getSender()).success(primaryDevicePublicKey -> { + LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(content.getSender()).success(primaryDevicePublicKey -> { String sender = primaryDevicePublicKey != null ? primaryDevicePublicKey : content.getSender(); long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(sender), false)); LokiThreadFriendRequestStatus threadFriendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID); @@ -1284,7 +1285,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Allow profile sharing with contact DatabaseFactory.getRecipientDatabase(context).setProfileSharing(contactID, true); // Update the last message if needed - LokiFileServerAPI.shared.getPrimaryDevicePublicKey(pubKey).success(primaryDevice -> { + LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(pubKey).success(primaryDevice -> { Util.runOnMain(() -> { long primaryDeviceThreadID = primaryDevice == null ? threadID : DatabaseFactory.getThreadDatabase(context).getThreadIdFor(Recipient.from(context, Address.fromSerialized(primaryDevice), false)); FriendRequestHandler.updateLastFriendRequestMessage(context, primaryDeviceThreadID, LokiMessageFriendRequestStatus.REQUEST_ACCEPTED); @@ -1799,7 +1800,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { */ private Recipient getPrimaryDeviceRecipient(String pubKey) { try { - String primaryDevice = PromiseUtil.timeout(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(pubKey), 5000).get(); + String primaryDevice = PromiseUtil.timeout(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(pubKey), 5000).get(); String publicKey = (primaryDevice != null) ? primaryDevice : pubKey; // If the public key matches our primary device then we need to forward the message to ourselves (Note to self) String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context); diff --git a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java index 1c07fd611a..ef9fa207ac 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushGroupSendJob.java @@ -50,8 +50,8 @@ import org.whispersystems.signalservice.api.messages.SignalServiceGroup; import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.api.LokiPublicChat; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.io.IOException; @@ -368,7 +368,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType { if (!member.isPhone() || member.serialize().equalsIgnoreCase(localNumber)) { continue; } try { - List secondaryDevices = PromiseUtil.timeout(LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(member.serialize()), 5000).get(); + Set secondaryDevices = PromiseUtil.timeout(LokiDeviceLinkUtilities.INSTANCE.getSlaveHexEncodedPublicKeys(member.serialize()), 5000).get(); memberSet.addAll(Stream.of(secondaryDevices).map(string -> { // Loki - Calling .map(Address::fromSerialized) is causing errors, thus we use the long method :( return Address.fromSerialized(string); diff --git a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java index 13de89022b..322642bc7b 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushMediaSendJob.java @@ -22,7 +22,6 @@ import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.JobManager; import org.thoughtcrime.securesms.logging.Log; -import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.mms.MmsException; import org.thoughtcrime.securesms.mms.OutgoingMediaMessage; import org.thoughtcrime.securesms.recipients.Recipient; @@ -43,13 +42,12 @@ import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSy import org.whispersystems.signalservice.api.messages.shared.SharedContact; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.messaging.LokiSyncMessage; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; import java.io.FileNotFoundException; import java.io.IOException; -import java.util.Arrays; import java.util.Collections; import java.util.LinkedList; import java.util.List; @@ -292,7 +290,7 @@ public class PushMediaSendJob extends PushSendJob implements InjectableType { LokiSyncMessage syncMessage = null; if (shouldSendSyncMessage) { // Set the sync message destination the primary device, this way it will show that we sent a message to the primary device and not a secondary device - String primaryDevice = PromiseUtil.get(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); + String primaryDevice = PromiseUtil.get(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(address.getNumber()), null); SignalServiceAddress primaryAddress = primaryDevice == null ? address : new SignalServiceAddress(primaryDevice); // We also need to use the original message id and not -1 syncMessage = new LokiSyncMessage(primaryAddress, templateMessageId); diff --git a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java index dfa291436d..95d6cc8908 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushTextSendJob.java @@ -14,7 +14,6 @@ import org.thoughtcrime.securesms.database.model.SmsMessageRecord; import org.thoughtcrime.securesms.dependencies.InjectableType; import org.thoughtcrime.securesms.jobmanager.Data; import org.thoughtcrime.securesms.jobmanager.Job; -import org.thoughtcrime.securesms.loki.MultiDeviceUtilities; import org.thoughtcrime.securesms.notifications.MessageNotifier; import org.thoughtcrime.securesms.recipients.Recipient; import org.thoughtcrime.securesms.service.ExpiringMessageManager; @@ -30,7 +29,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.push.SignalServiceAddress; import org.whispersystems.signalservice.api.push.exceptions.UnregisteredUserException; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.messaging.LokiSyncMessage; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; @@ -237,7 +236,7 @@ public class PushTextSendJob extends PushSendJob implements InjectableType { LokiSyncMessage syncMessage = null; if (shouldSendSyncMessage) { // Set the sync message destination to the primary device, this way it will show that we sent a message to the primary device and not a secondary device - String primaryDevice = PromiseUtil.get(LokiFileServerAPI.shared.getPrimaryDevicePublicKey(address.getNumber()), null); + String primaryDevice = PromiseUtil.get(LokiDeviceLinkUtilities.INSTANCE.getMasterHexEncodedPublicKey(address.getNumber()), null); SignalServiceAddress primaryAddress = primaryDevice == null ? address : new SignalServiceAddress(primaryDevice); // We also need to use the original message id and not -1 syncMessage = new LokiSyncMessage(primaryAddress, templateMessageId); diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index ebdcff428e..d5c256f52b 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -20,8 +20,9 @@ import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.TextSecurePreferences import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.push.SignalServiceAddress +import org.whispersystems.signalservice.loki.api.DeviceLink +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities import org.whispersystems.signalservice.loki.api.LokiFileServerAPI -import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.utilities.recover import org.whispersystems.signalservice.loki.utilities.retryIfNeeded @@ -32,12 +33,12 @@ fun checkForRevocation(context: Context) { val primaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context) ?: return val ourDevice = TextSecurePreferences.getLocalNumber(context) - LokiFileServerAPI.shared.fetchDeviceMappings(primaryDevice).bind { mappings -> - val ourMapping = mappings.find { it.secondaryDevicePublicKey == ourDevice } + LokiFileServerAPI.shared.getDeviceLinks(primaryDevice, true).bind { mappings -> + val ourMapping = mappings.find { it.slaveHexEncodedPublicKey == ourDevice } if (ourMapping != null) throw Error("Device has not been revoked") // remove pairing authorisations for our device - DatabaseFactory.getLokiAPIDatabase(context).removePairingAuthorisations(ourDevice) - LokiFileServerAPI.shared.updateUserDeviceMappings() + DatabaseFactory.getLokiAPIDatabase(context).clearDeviceLinks(ourDevice) + LokiFileServerAPI.shared.updateUserDeviceLinks() }.successUi { TextSecurePreferences.setNeedsRevocationCheck(context, false) ApplicationContext.getInstance(context).clearData() @@ -49,7 +50,7 @@ fun checkForRevocation(context: Context) { fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: String): Promise, Exception> { val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) - return LokiFileServerAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> + return LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(hexEncodedPublicKey).map { keys -> val map = mutableMapOf() for (devicePublicKey in keys) { val device = Recipient.from(context, Address.fromSerialized(devicePublicKey), false) @@ -63,7 +64,7 @@ fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: Str fun getAllDevicePublicKeysWithFriendStatus(context: Context, hexEncodedPublicKey: String): Promise, Unit> { val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - return LokiFileServerAPI.shared.getAllDevicePublicKeys(hexEncodedPublicKey).map { keys -> + return LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(hexEncodedPublicKey).map { keys -> val devices = keys.toMutableSet() if (hexEncodedPublicKey != userHexEncodedPublicKey) { devices.remove(userHexEncodedPublicKey) @@ -92,7 +93,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Conte return Promise.of(true) } - return LokiFileServerAPI.shared.getPrimaryDevicePublicKey(publicKey).bind { primaryDevicePublicKey -> + return LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(publicKey).bind { primaryDevicePublicKey -> // If the public key doesn't have any other devices then go through regular friend request logic if (primaryDevicePublicKey == null) { return@bind Promise.of(false) @@ -108,12 +109,12 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Conte } } -fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: PairingAuthorisation): Promise { +fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: DeviceLink): Promise { val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() val address = SignalServiceAddress(contactHexEncodedPublicKey) val message = SignalServiceDataMessage.newBuilder().withPairingAuthorisation(authorisation) // A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message. - if (authorisation.type == PairingAuthorisation.Type.REQUEST) { + if (authorisation.type == DeviceLink.Type.REQUEST) { val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number) message.asFriendRequest(true).withPreKeyBundle(preKeyBundle) } else { @@ -139,17 +140,17 @@ fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey } } -fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisation: PairingAuthorisation) { +fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisation: DeviceLink) { val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() - val signedPairingAuthorisation = pairingAuthorisation.sign(PairingAuthorisation.Type.GRANT, userPrivateKey) - if (signedPairingAuthorisation == null || signedPairingAuthorisation.type != PairingAuthorisation.Type.GRANT) { + val signedPairingAuthorisation = pairingAuthorisation.sign(DeviceLink.Type.AUTHORIZATION, userPrivateKey) + if (signedPairingAuthorisation == null || signedPairingAuthorisation.type != DeviceLink.Type.AUTHORIZATION) { Log.d("Loki", "Failed to sign pairing authorization.") return } - DatabaseFactory.getLokiAPIDatabase(context).insertOrUpdatePairingAuthorisation(signedPairingAuthorisation) + DatabaseFactory.getLokiAPIDatabase(context).addDeviceLink(signedPairingAuthorisation) TextSecurePreferences.setMultiDevice(context, true) - val address = Address.fromSerialized(pairingAuthorisation.secondaryDevicePublicKey); + val address = Address.fromSerialized(pairingAuthorisation.slaveHexEncodedPublicKey) val sendPromise = retryIfNeeded(8) { sendPairingAuthorisationMessage(context, address.serialize(), signedPairingAuthorisation) @@ -157,7 +158,7 @@ fun signAndSendPairingAuthorisationMessage(context: Context, pairingAuthorisatio Log.d("Loki", "Failed to send pairing authorization message to ${address.serialize()}.") } - val updatePromise = LokiFileServerAPI.shared.updateUserDeviceMappings().fail { + val updatePromise = LokiFileServerAPI.shared.updateUserDeviceLinks().fail { Log.d("Loki", "Failed to update device mapping") } @@ -177,7 +178,7 @@ fun isOneOfOurDevices(context: Context, address: Address): Promise + return LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(ourPublicKey).map { devices -> devices.contains(address.serialize()) } } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/CreateClosedGroupLoader.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/CreateClosedGroupLoader.kt index 620d47b5c6..2c07fe0772 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/CreateClosedGroupLoader.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/CreateClosedGroupLoader.kt @@ -12,9 +12,9 @@ class CreateClosedGroupLoader(context: Context) : AsyncLoader>(cont val threadDatabase = DatabaseFactory.getThreadDatabase(context) val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context) val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - val deviceLinks = DatabaseFactory.getLokiAPIDatabase(context).getPairingAuthorisations(userHexEncodedPublicKey) + val deviceLinks = DatabaseFactory.getLokiAPIDatabase(context).getDeviceLinks(userHexEncodedPublicKey) val userLinkedDeviceHexEncodedPublicKeys = deviceLinks.flatMap { - listOf( it.primaryDevicePublicKey.toLowerCase(), it.secondaryDevicePublicKey.toLowerCase() ) + listOf( it.masterHexEncodedPublicKey.toLowerCase(), it.slaveHexEncodedPublicKey.toLowerCase() ) }.toMutableSet() userLinkedDeviceHexEncodedPublicKeys.add(userHexEncodedPublicKey.toLowerCase()) val cursor = threadDatabase.conversationList diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt index 2daa93d81d..46477e7159 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LandingActivity.kt @@ -26,7 +26,7 @@ import org.whispersystems.curve25519.Curve25519 import org.whispersystems.libsignal.ecc.Curve import org.whispersystems.libsignal.ecc.ECKeyPair import org.whispersystems.libsignal.util.KeyHelper -import org.whispersystems.signalservice.loki.api.PairingAuthorisation +import org.whispersystems.signalservice.loki.api.DeviceLink import org.whispersystems.signalservice.loki.utilities.hexEncodedPublicKey import org.whispersystems.signalservice.loki.utilities.retryIfNeeded @@ -92,7 +92,7 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega TextSecurePreferences.setLocalNumber(this, userHexEncodedPublicKey) TextSecurePreferences.setHasSeenWelcomeScreen(this, true) TextSecurePreferences.setPromptedPushRegistration(this, true) - val authorisation = PairingAuthorisation(hexEncodedPublicKey, userHexEncodedPublicKey).sign(PairingAuthorisation.Type.REQUEST, keyPair!!.privateKey.serialize()) + val authorisation = DeviceLink(hexEncodedPublicKey, userHexEncodedPublicKey).sign(DeviceLink.Type.REQUEST, keyPair!!.privateKey.serialize()) if (authorisation == null) { Log.d("Loki", "Failed to sign device link request.") reset() @@ -107,13 +107,13 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega linkDeviceDialog.show(supportFragmentManager, "Link Device Dialog") AsyncTask.execute { retryIfNeeded(8) { - sendPairingAuthorisationMessage(this@LandingActivity, authorisation.primaryDevicePublicKey, authorisation) + sendPairingAuthorisationMessage(this@LandingActivity, authorisation.masterHexEncodedPublicKey, authorisation) } } } - override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) { - TextSecurePreferences.setMasterHexEncodedPublicKey(this, authorization.primaryDevicePublicKey) + override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { + TextSecurePreferences.setMasterHexEncodedPublicKey(this, deviceLink.masterHexEncodedPublicKey) val intent = Intent(this, HomeActivity::class.java) show(intent) finish() diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index 5cc7a152ed..42292648f8 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -20,8 +20,8 @@ import org.thoughtcrime.securesms.loki.signAndSendPairingAuthorisationMessage import org.thoughtcrime.securesms.sms.MessageSender import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.Util +import org.whispersystems.signalservice.loki.api.DeviceLink import org.whispersystems.signalservice.loki.api.LokiFileServerAPI -import org.whispersystems.signalservice.loki.api.PairingAuthorisation class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager.LoaderCallbacks>, DeviceClickListener, EditDeviceNameDialogDelegate, LinkDeviceMasterModeDialogDelegate { private var devices = listOf() @@ -119,14 +119,14 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this) val database = DatabaseFactory.getLokiAPIDatabase(this) database.removePairingAuthorisation(userHexEncodedPublicKey, slaveDeviceHexEncodedPublicKey) - LokiFileServerAPI.shared.updateUserDeviceMappings().success { + LokiFileServerAPI.shared.updateUserDeviceLinks().success { MessageSender.sendUnpairRequest(this, slaveDeviceHexEncodedPublicKey) } LoaderManager.getInstance(this).restartLoader(0, null, this) Toast.makeText(this, "Your device was unlinked successfully", Toast.LENGTH_LONG).show() } - override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) { + override fun onDeviceLinkRequestAuthorized(authorization: DeviceLink) { AsyncTask.execute { signAndSendPairingAuthorisationMessage(this, authorization) Util.runOnMain { diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt index a2519801d5..87dcdb528e 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesLoader.kt @@ -6,7 +6,7 @@ import org.thoughtcrime.securesms.devicelist.Device import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities import org.thoughtcrime.securesms.util.AsyncLoader import org.thoughtcrime.securesms.util.TextSecurePreferences -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities import org.whispersystems.signalservice.loki.crypto.MnemonicCodec import java.io.File @@ -20,7 +20,7 @@ class LinkedDevicesLoader(context: Context) : AsyncLoader>(context) override fun loadInBackground(): List? { try { val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) - val slaveDeviceHexEncodedPublicKeys = LokiFileServerAPI.shared.getSecondaryDevicePublicKeys(userHexEncodedPublicKey).get() + val slaveDeviceHexEncodedPublicKeys = LokiDeviceLinkUtilities.getSlaveHexEncodedPublicKeys(userHexEncodedPublicKey).get() return slaveDeviceHexEncodedPublicKeys.map { hexEncodedPublicKey -> val shortID = MnemonicUtilities.getFirst3Words(mnemonicCodec, hexEncodedPublicKey) val name = DatabaseFactory.getLokiUserDatabase(context).getDisplayName(hexEncodedPublicKey) diff --git a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt index 94f6c6de80..10d3468178 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt @@ -17,15 +17,15 @@ import org.thoughtcrime.securesms.loki.redesign.utilities.QRCodeUtilities import org.thoughtcrime.securesms.loki.toPx import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.Util +import org.whispersystems.signalservice.loki.api.DeviceLink import org.whispersystems.signalservice.loki.api.DeviceLinkingSession import org.whispersystems.signalservice.loki.api.DeviceLinkingSessionListener -import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.crypto.MnemonicCodec class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListener { private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) } private lateinit var contentView: View - private var authorization: PairingAuthorisation? = null + private var authorization: DeviceLink? = null var delegate: LinkDeviceMasterModeDialogDelegate? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -45,8 +45,8 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene return result } - override fun requestUserAuthorization(authorization: PairingAuthorisation) { - if (authorization.type != PairingAuthorisation.Type.REQUEST || authorization.primaryDevicePublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } + override fun requestUserAuthorization(authorization: DeviceLink) { + if (authorization.type != DeviceLink.Type.REQUEST || authorization.masterHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } Util.runOnMain { this.authorization = authorization contentView.qrCodeImageView.visibility = View.GONE @@ -56,7 +56,7 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene contentView.titleTextView.text = "Linking Request Received" contentView.explanationTextView.text = "Please check that the words below match those shown on your other device" contentView.mnemonicTextView.visibility = View.VISIBLE - contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), authorization.secondaryDevicePublicKey) + contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), authorization.slaveHexEncodedPublicKey) contentView.authorizeButton.visibility = View.VISIBLE } } @@ -73,7 +73,7 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene DeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.removeListener(this) if (authorization != null) { - DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(authorization!!.secondaryDevicePublicKey) + DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(authorization!!.slaveHexEncodedPublicKey) } dismiss() delegate?.onDeviceLinkCanceled() @@ -82,6 +82,6 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene interface LinkDeviceMasterModeDialogDelegate { - fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) + fun onDeviceLinkRequestAuthorized(authorization: DeviceLink) fun onDeviceLinkCanceled() } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt index 7f80c704a3..d42cabaffe 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt @@ -15,15 +15,15 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.loki.redesign.utilities.MnemonicUtilities import org.thoughtcrime.securesms.util.TextSecurePreferences import org.thoughtcrime.securesms.util.Util +import org.whispersystems.signalservice.loki.api.DeviceLink import org.whispersystems.signalservice.loki.api.DeviceLinkingSession import org.whispersystems.signalservice.loki.api.DeviceLinkingSessionListener -import org.whispersystems.signalservice.loki.api.PairingAuthorisation import org.whispersystems.signalservice.loki.crypto.MnemonicCodec class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener { private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) } private lateinit var contentView: View - private var authorization: PairingAuthorisation? = null + private var authorization: DeviceLink? = null var delegate: LinkDeviceSlaveModeDialogDelegate? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -40,8 +40,8 @@ class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener return result } - override fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) { - if (authorization.type != PairingAuthorisation.Type.GRANT || authorization.secondaryDevicePublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } + override fun onDeviceLinkRequestAuthorized(authorization: DeviceLink) { + if (authorization.type != DeviceLink.Type.AUTHORIZATION || authorization.slaveHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } Util.runOnMain { this.authorization = authorization DeviceLinkingSession.shared.stopListeningForLinkingRequests() @@ -71,6 +71,6 @@ class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener interface LinkDeviceSlaveModeDialogDelegate { - fun onDeviceLinkRequestAuthorized(authorization: PairingAuthorisation) + fun onDeviceLinkRequestAuthorized(authorization: DeviceLink) fun onDeviceLinkCanceled() } \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt index d3aa589aa8..8991e9be32 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt @@ -7,9 +7,9 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.loki.redesign.utilities.* import org.thoughtcrime.securesms.util.Base64 import org.thoughtcrime.securesms.util.TextSecurePreferences +import org.whispersystems.signalservice.loki.api.DeviceLink import org.whispersystems.signalservice.loki.api.LokiAPIDatabaseProtocol import org.whispersystems.signalservice.loki.api.LokiAPITarget -import org.whispersystems.signalservice.loki.api.PairingAuthorisation // TODO: Clean this up a bit @@ -179,28 +179,28 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( database.delete(lastDeletionServerIDCache,"$lastDeletionServerIDCacheIndex = ?", wrap(index)) } - override fun getPairingAuthorisations(hexEncodedPublicKey: String): List { + override fun getDeviceLinks(hexEncodedPublicKey: String): Set { val database = databaseHelper.readableDatabase return database.getAll(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) { cursor -> val primaryDevicePubKey = cursor.getString(primaryDevicePublicKey) val secondaryDevicePubKey = cursor.getString(secondaryDevicePublicKey) val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature) val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature) - PairingAuthorisation(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature) - } + DeviceLink(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature) + }.toSet() } - override fun insertOrUpdatePairingAuthorisation(authorisation: PairingAuthorisation) { + override fun addDeviceLink(deviceLink: DeviceLink) { val database = databaseHelper.writableDatabase val values = ContentValues() - values.put(primaryDevicePublicKey, authorisation.primaryDevicePublicKey) - values.put(secondaryDevicePublicKey, authorisation.secondaryDevicePublicKey) - if (authorisation.requestSignature != null) { values.put(requestSignature, Base64.encodeBytes(authorisation.requestSignature)) } - if (authorisation.grantSignature != null) { values.put(grantSignature, Base64.encodeBytes(authorisation.grantSignature)) } - database.insertOrUpdate(pairingAuthorisationCache, values, "$primaryDevicePublicKey = ? AND $secondaryDevicePublicKey = ?", arrayOf( authorisation.primaryDevicePublicKey, authorisation.secondaryDevicePublicKey )) + values.put(primaryDevicePublicKey, deviceLink.masterHexEncodedPublicKey) + values.put(secondaryDevicePublicKey, deviceLink.slaveHexEncodedPublicKey) + if (deviceLink.requestSignature != null) { values.put(requestSignature, Base64.encodeBytes(deviceLink.requestSignature)) } + if (deviceLink.authorizationSignature != null) { values.put(grantSignature, Base64.encodeBytes(deviceLink.authorizationSignature)) } + database.insertOrUpdate(pairingAuthorisationCache, values, "$primaryDevicePublicKey = ? AND $secondaryDevicePublicKey = ?", arrayOf( deviceLink.masterHexEncodedPublicKey, deviceLink.slaveHexEncodedPublicKey )) } - override fun removePairingAuthorisations(hexEncodedPublicKey: String) { + override fun clearDeviceLinks(hexEncodedPublicKey: String) { val database = databaseHelper.writableDatabase database.delete(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt index fd618562c6..327b382c4a 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt @@ -21,10 +21,7 @@ import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.messages.SignalServiceGroup import org.whispersystems.signalservice.api.messages.multidevice.SentTranscriptMessage import org.whispersystems.signalservice.api.push.SignalServiceAddress -import org.whispersystems.signalservice.loki.api.LokiPublicChat -import org.whispersystems.signalservice.loki.api.LokiPublicChatAPI -import org.whispersystems.signalservice.loki.api.LokiPublicChatMessage -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI +import org.whispersystems.signalservice.loki.api.* import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus import org.whispersystems.signalservice.loki.utilities.successBackground import java.security.MessageDigest @@ -156,7 +153,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki fun pollForNewMessages() { fun processIncomingMessage(message: LokiPublicChatMessage) { // If the sender of the current message is not a secondary device, we need to set the display name in the database - val primaryDevice = LokiFileServerAPI.shared.getPrimaryDevicePublicKey(message.hexEncodedPublicKey).get() + val primaryDevice = LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(message.hexEncodedPublicKey).get() if (primaryDevice == null) { val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})" DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName) @@ -171,9 +168,9 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki } // Update profile avatar if needed val senderRecipient = Recipient.from(context, Address.fromSerialized(senderPublicKey), false) - if (message.avatar != null && message.avatar!!.url.isNotEmpty()) { - val profileKey = message.avatar!!.profileKey - val url = message.avatar!!.url + if (message.profilePicture != null && message.profilePicture!!.url.isNotEmpty()) { + val profileKey = message.profilePicture!!.profileKey + val url = message.profilePicture!!.url if (senderRecipient.profileKey == null || !MessageDigest.isEqual(senderRecipient.profileKey, profileKey)) { val database = DatabaseFactory.getRecipientDatabase(context) database.setProfileKey(senderRecipient, profileKey) @@ -204,9 +201,9 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki } // If we got a message from our master device then make sure our mappings stay in sync val recipient = Recipient.from(context, Address.fromSerialized(message.hexEncodedPublicKey), false) - if (recipient.isOurMasterDevice && message.avatar != null) { - val profileKey = message.avatar!!.profileKey - val url = message.avatar!!.url + if (recipient.isOurMasterDevice && 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) @@ -220,16 +217,16 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki val userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(context).privateKey.serialize() val database = DatabaseFactory.getLokiAPIDatabase(context) LokiFileServerAPI.configure(false, userHexEncodedPublicKey, userPrivateKey, database) - LokiFileServerAPI.shared.getAllDevicePublicKeys(userHexEncodedPublicKey).bind { devices -> + LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(userHexEncodedPublicKey).bind { devices -> userDevices = devices api.getMessages(group.channel, group.server) }.bind { messages -> if (messages.isNotEmpty()) { // We need to fetch device mappings for all the devices we don't have uniqueDevices = messages.map { it.hexEncodedPublicKey }.toSet() - val devicesToUpdate = uniqueDevices.filter { !userDevices.contains(it) && LokiFileServerAPI.shared.hasCacheExpired(it) } + val devicesToUpdate = uniqueDevices.filter { !userDevices.contains(it) && LokiFileServerAPI.shared.hasDeviceLinkCacheExpired(hexEncodedPublicKey = it) } if (devicesToUpdate.isNotEmpty()) { - return@bind LokiFileServerAPI.shared.getDeviceMappings(devicesToUpdate.toSet()).then { messages } + return@bind LokiFileServerAPI.shared.getDeviceLinks(devicesToUpdate.toSet()).then { messages } } } Promise.of(messages) @@ -238,7 +235,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki val newDisplayNameUpdatees = uniqueDevices.mapNotNull { // This will return null if current device is primary // So if it's non-null then we know the device is a secondary device - val primaryDevice = LokiFileServerAPI.shared.getPrimaryDevicePublicKey(it).get() + val primaryDevice = LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(it).get() primaryDevice }.toSet() // Fetch the display names of the primary devices diff --git a/src/org/thoughtcrime/securesms/loki/redesign/utilities/MentionUtilities.kt b/src/org/thoughtcrime/securesms/loki/redesign/utilities/MentionUtilities.kt index 4a29eef131..a425262411 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/utilities/MentionUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/utilities/MentionUtilities.kt @@ -53,7 +53,7 @@ object MentionUtilities { } } val result = SpannableString(text) - val userLinkedDeviceHexEncodedPublicKeys = DatabaseFactory.getLokiAPIDatabase(context).getPairingAuthorisations(userHexEncodedPublicKey).flatMap { listOf( it.primaryDevicePublicKey, it.secondaryDevicePublicKey ) }.toMutableSet() + val userLinkedDeviceHexEncodedPublicKeys = DatabaseFactory.getLokiAPIDatabase(context).getDeviceLinks(userHexEncodedPublicKey).flatMap { listOf( it.masterHexEncodedPublicKey, it.slaveHexEncodedPublicKey ) }.toMutableSet() userLinkedDeviceHexEncodedPublicKeys.add(userHexEncodedPublicKey) for (mention in mentions) { if (!userLinkedDeviceHexEncodedPublicKeys.contains(mention.second)) { continue } diff --git a/src/org/thoughtcrime/securesms/sms/MessageSender.java b/src/org/thoughtcrime/securesms/sms/MessageSender.java index 4dfa91f4c3..d8c8e20fc5 100644 --- a/src/org/thoughtcrime/securesms/sms/MessageSender.java +++ b/src/org/thoughtcrime/securesms/sms/MessageSender.java @@ -60,7 +60,7 @@ import org.thoughtcrime.securesms.util.Util; import org.whispersystems.libsignal.util.guava.Optional; import org.whispersystems.signalservice.api.SignalServiceAccountManager; import org.whispersystems.signalservice.api.push.ContactTokenDetails; -import org.whispersystems.signalservice.loki.api.LokiFileServerAPI; +import org.whispersystems.signalservice.loki.api.LokiDeviceLinkUtilities; import org.whispersystems.signalservice.loki.messaging.LokiThreadFriendRequestStatus; import org.whispersystems.signalservice.loki.utilities.PromiseUtil; @@ -99,7 +99,7 @@ public class MessageSender { sendBackgroundMessage(context, contactHexEncodedPublicKey); // Go through the other devices and only send background messages if we're friends or we have received friend request - LokiFileServerAPI.shared.getAllDevicePublicKeys(contactHexEncodedPublicKey).success(devices -> { + LokiDeviceLinkUtilities.INSTANCE.getAllLinkedDeviceHexEncodedPublicKeys(contactHexEncodedPublicKey).success(devices -> { Util.runOnMain(() -> { for (String device : devices) { // Don't send message to the device we already have sent to @@ -234,7 +234,7 @@ public class MessageSender { final int ttl) { String ourPublicKey = TextSecurePreferences.getLocalNumber(context); JobManager jobManager = ApplicationContext.getInstance(context).getJobManager(); - LokiFileServerAPI.shared.getAllDevicePublicKeys(ourPublicKey).success(devices -> { + LokiDeviceLinkUtilities.INSTANCE.getAllLinkedDeviceHexEncodedPublicKeys(ourPublicKey).success(devices -> { Util.runOnMain(() -> { for (String device : devices) { // Don't send to ourselves From c47ecad0248d3d035afec8dfd0cec8bc306a87c1 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 12 Feb 2020 14:44:23 +1100 Subject: [PATCH 08/18] Handle clock out of sync issue --- .../securesms/conversation/ConversationActivity.java | 9 +++++++++ .../securesms/loki/redesign/utilities/Broadcaster.kt | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 5e0d427b57..41cb2330ce 100644 --- a/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -404,6 +404,15 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity registerMessageStatusObserver("sendingMessage"); registerMessageStatusObserver("messageSent"); registerMessageStatusObserver("messageFailed"); + BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { + + @Override + public void onReceive(Context context, Intent intent) { + Toast.makeText(ConversationActivity.this, "Your clock is out of sync with the service node network.", Toast.LENGTH_LONG).show(); + } + }; + broadcastReceivers.add(broadcastReceiver); + LocalBroadcastManager.getInstance(this).registerReceiver(broadcastReceiver, new IntentFilter("clockOutOfSync")); initializeReceivers(); initializeActionBar(); diff --git a/src/org/thoughtcrime/securesms/loki/redesign/utilities/Broadcaster.kt b/src/org/thoughtcrime/securesms/loki/redesign/utilities/Broadcaster.kt index cf2074b657..7460341bd5 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/utilities/Broadcaster.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/utilities/Broadcaster.kt @@ -6,6 +6,11 @@ import android.support.v4.content.LocalBroadcastManager class Broadcaster(private val context: Context) : org.whispersystems.signalservice.loki.utilities.Broadcaster { + override fun broadcast(event: String) { + val intent = Intent(event) + LocalBroadcastManager.getInstance(context).sendBroadcast(intent) + } + override fun broadcast(event: String, long: Long) { val intent = Intent(event) intent.putExtra("long", long) From 45d78825a037a55257ce078ce934c3160cb492f4 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 12 Feb 2020 16:25:14 +1100 Subject: [PATCH 09/18] Clean --- .../securesms/jobs/PushDecryptJob.java | 14 +++++++------- .../securesms/loki/MultiDeviceUtilities.kt | 2 +- .../securesms/loki/PushBackgroundMessageSendJob.kt | 4 +--- .../securesms/push/MessageSenderEventListener.java | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java index 6d0f70316d..0ef8ce54f8 100644 --- a/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java +++ b/src/org/thoughtcrime/securesms/jobs/PushDecryptJob.java @@ -297,7 +297,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { // Loki - Store pre key bundle // We shouldn't store it if it's a pairing message - if (!content.getPairingAuthorisation().isPresent()) { + if (!content.getDeviceLink().isPresent()) { storePreKeyBundleIfNeeded(content); } @@ -324,13 +324,13 @@ public class PushDecryptJob extends BaseJob implements InjectableType { }); } - if (content.getPairingAuthorisation().isPresent()) { - handlePairingMessage(content.getPairingAuthorisation().get(), content); + if (content.getDeviceLink().isPresent()) { + handlePairingMessage(content.getDeviceLink().get(), content); } else if (content.getDataMessage().isPresent()) { SignalServiceDataMessage message = content.getDataMessage().get(); boolean isMediaMessage = message.getAttachments().isPresent() || message.getQuote().isPresent() || message.getSharedContacts().isPresent() || message.getPreviews().isPresent() || message.getSticker().isPresent(); - if (!content.isFriendRequest() && message.isUnpairingRequest()) { + if (!content.isFriendRequest() && message.isUnlinkingRequest()) { // Make sure we got the request from our primary device String ourPrimaryDevice = TextSecurePreferences.getMasterHexEncodedPublicKey(context); if (ourPrimaryDevice != null && ourPrimaryDevice.equals(content.getSender())) { @@ -339,7 +339,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { } } else { // Loki - Don't process session restore message any further - if (message.isSessionRestore() || message.isSessionRequest()) { return; } + if (message.isSessionRestorationRequest() || message.isSessionRequest()) { return; } if (message.isEndSession()) handleEndSessionMessage(content, smsMessageId); else if (message.isGroupUpdate()) handleGroupMessage(content, message, smsMessageId); @@ -1538,7 +1538,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { if (recipient.getProfileKey() == null || !MessageDigest.isEqual(recipient.getProfileKey(), message.getProfileKey().get())) { database.setProfileKey(recipient, message.getProfileKey().get()); database.setUnidentifiedAccessMode(recipient, RecipientDatabase.UnidentifiedAccessMode.UNKNOWN); - String url = content.senderProfileAvatarUrl.or(""); + String url = content.senderProfilePictureURL.or(""); ApplicationContext.getInstance(context).getJobManager().add(new RetrieveProfileAvatarJob(recipient, url)); // Loki - If the recipient is our master device then we need to go and update our avatar mappings on the public chats @@ -1832,7 +1832,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType { Recipient sender = Recipient.from(context, Address.fromSerialized(content.getSender()), false); - if (content.getPairingAuthorisation().isPresent()) { + if (content.getDeviceLink().isPresent()) { return false; } else if (content.getDataMessage().isPresent()) { SignalServiceDataMessage message = content.getDataMessage().get(); diff --git a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt index d5c256f52b..bfb7da57bf 100644 --- a/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt +++ b/src/org/thoughtcrime/securesms/loki/MultiDeviceUtilities.kt @@ -112,7 +112,7 @@ fun shouldAutomaticallyBecomeFriendsWithDevice(publicKey: String, context: Conte fun sendPairingAuthorisationMessage(context: Context, contactHexEncodedPublicKey: String, authorisation: DeviceLink): Promise { val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender() val address = SignalServiceAddress(contactHexEncodedPublicKey) - val message = SignalServiceDataMessage.newBuilder().withPairingAuthorisation(authorisation) + val message = SignalServiceDataMessage.newBuilder().withDeviceLink(authorisation) // A REQUEST should always act as a friend request. A GRANT should always be replying back as a normal message. if (authorisation.type == DeviceLink.Type.REQUEST) { val preKeyBundle = DatabaseFactory.getLokiPreKeyBundleDatabase(context).generatePreKeyBundle(address.number) diff --git a/src/org/thoughtcrime/securesms/loki/PushBackgroundMessageSendJob.kt b/src/org/thoughtcrime/securesms/loki/PushBackgroundMessageSendJob.kt index 8aa084eb54..0a3f00e7e7 100644 --- a/src/org/thoughtcrime/securesms/loki/PushBackgroundMessageSendJob.kt +++ b/src/org/thoughtcrime/securesms/loki/PushBackgroundMessageSendJob.kt @@ -10,8 +10,6 @@ import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint import org.thoughtcrime.securesms.jobs.BaseJob import org.thoughtcrime.securesms.logging.Log import org.thoughtcrime.securesms.recipients.Recipient -import org.whispersystems.libsignal.util.guava.Optional -import org.whispersystems.signalservice.api.crypto.UnidentifiedAccessPair import org.whispersystems.signalservice.api.messages.SignalServiceDataMessage import org.whispersystems.signalservice.api.push.SignalServiceAddress import org.whispersystems.signalservice.internal.util.JsonUtil @@ -99,7 +97,7 @@ class PushBackgroundMessageSendJob private constructor( } if (message.get("sessionRestore", false)) { - dataMessage.asSessionRestore(true) + dataMessage.asSessionRestorationRequest(true) } if (message.get("sessionRequest", false)) { diff --git a/src/org/thoughtcrime/securesms/push/MessageSenderEventListener.java b/src/org/thoughtcrime/securesms/push/MessageSenderEventListener.java index 5cc2d886c1..86850399d3 100644 --- a/src/org/thoughtcrime/securesms/push/MessageSenderEventListener.java +++ b/src/org/thoughtcrime/securesms/push/MessageSenderEventListener.java @@ -38,7 +38,7 @@ public class MessageSenderEventListener implements SignalServiceMessageSender.Ev FriendRequestHandler.updateFriendRequestState(context, FriendRequestHandler.ActionType.Sent, messageID, threadID); } - @Override public void onFriendRequestSendingFail(long messageID, long threadID) { + @Override public void onFriendRequestSendingFailed(long messageID, long threadID) { FriendRequestHandler.updateFriendRequestState(context, FriendRequestHandler.ActionType.Failed, messageID, threadID); } } From 31350adcf7eff8d565df10a83ae6301928fd8a44 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Wed, 12 Feb 2020 16:42:33 +1100 Subject: [PATCH 10/18] Clean --- .../fragment_enter_public_key.xml | 2 +- res/layout/activity_settings.xml | 2 +- res/layout/fragment_enter_public_key.xml | 2 +- .../database/helpers/SQLCipherOpenHelper.java | 4 +- .../activities/CreateClosedGroupActivity.kt | 20 +++----- .../activities/LinkedDevicesActivity.kt | 2 +- .../dialogs/LinkDeviceMasterModeDialog.kt | 16 +++---- .../dialogs/LinkDeviceSlaveModeDialog.kt | 10 ++-- .../redesign/messaging/LokiAPIDatabase.kt | 38 +++++++-------- .../messaging/LokiPublicChatPoller.kt | 47 +++++++++---------- ...paratorView.kt => LabeledSeparatorView.kt} | 2 +- 11 files changed, 68 insertions(+), 77 deletions(-) rename src/org/thoughtcrime/securesms/loki/redesign/views/{SeparatorView.kt => LabeledSeparatorView.kt} (98%) diff --git a/res/layout-sw400dp/fragment_enter_public_key.xml b/res/layout-sw400dp/fragment_enter_public_key.xml index a2e53ce92d..bb85cef9c5 100644 --- a/res/layout-sw400dp/fragment_enter_public_key.xml +++ b/res/layout-sw400dp/fragment_enter_public_key.xml @@ -30,7 +30,7 @@ android:textAlignment="center" android:text="Users can share their Session ID by going into their account settings and tapping "Share Session ID", or by sharing their QR code." /> - - - , - private val avatar: Bitmap?, + private val profilePicture: Bitmap?, private val name: String?, private val members: Set, private val admins: Set @@ -130,24 +130,18 @@ class CreateClosedGroupActivity : PassphraseRequiredActionBarActivity(), MemberC override fun doInBackground(vararg params: Void?): Optional { val activity = activity.get() ?: return Optional.absent() - return Optional.of(GroupManager.createGroup(activity, members, avatar, name, false, admins)) + return Optional.of(GroupManager.createGroup(activity, members, profilePicture, name, false, admins)) } override fun onPostExecute(result: Optional) { - val activity = activity.get() - if (activity == null) { - super.onPostExecute(result) - return - } - + val activity = activity.get() ?: return super.onPostExecute(result) if (result.isPresent && result.get().threadId > -1) { if (!activity.isFinishing) { activity.handleOpenConversation(result.get().threadId, result.get().groupRecipient) } } else { super.onPostExecute(result) - Toast.makeText(activity.applicationContext, - R.string.GroupCreateActivity_contacts_invalid_number, Toast.LENGTH_LONG).show() + Toast.makeText(activity.applicationContext, "One of the members of your group has an invalid Session ID.", Toast.LENGTH_LONG).show() } } } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt index 42292648f8..7e77b76507 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/activities/LinkedDevicesActivity.kt @@ -118,7 +118,7 @@ class LinkedDevicesActivity : PassphraseRequiredActionBarActivity, LoaderManager private fun unlinkDevice(slaveDeviceHexEncodedPublicKey: String) { val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(this) val database = DatabaseFactory.getLokiAPIDatabase(this) - database.removePairingAuthorisation(userHexEncodedPublicKey, slaveDeviceHexEncodedPublicKey) + database.removeDeviceLink(userHexEncodedPublicKey, slaveDeviceHexEncodedPublicKey) LokiFileServerAPI.shared.updateUserDeviceLinks().success { MessageSender.sendUnpairRequest(this, slaveDeviceHexEncodedPublicKey) } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt index 10d3468178..44fc08bddf 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceMasterModeDialog.kt @@ -25,7 +25,7 @@ import org.whispersystems.signalservice.loki.crypto.MnemonicCodec class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListener { private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) } private lateinit var contentView: View - private var authorization: DeviceLink? = null + private var deviceLink: DeviceLink? = null var delegate: LinkDeviceMasterModeDialogDelegate? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -45,10 +45,10 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene return result } - override fun requestUserAuthorization(authorization: DeviceLink) { - if (authorization.type != DeviceLink.Type.REQUEST || authorization.masterHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } + override fun requestUserAuthorization(deviceLink: DeviceLink) { + if (deviceLink.type != DeviceLink.Type.REQUEST || deviceLink.masterHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.deviceLink != null) { return } Util.runOnMain { - this.authorization = authorization + this.deviceLink = deviceLink contentView.qrCodeImageView.visibility = View.GONE val titleTextViewLayoutParams = contentView.titleTextView.layoutParams as LinearLayout.LayoutParams titleTextViewLayoutParams.topMargin = toPx(8, resources) @@ -56,13 +56,13 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene contentView.titleTextView.text = "Linking Request Received" contentView.explanationTextView.text = "Please check that the words below match those shown on your other device" contentView.mnemonicTextView.visibility = View.VISIBLE - contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), authorization.slaveHexEncodedPublicKey) + contentView.mnemonicTextView.text = MnemonicUtilities.getFirst3Words(MnemonicCodec(languageFileDirectory), deviceLink.slaveHexEncodedPublicKey) contentView.authorizeButton.visibility = View.VISIBLE } } private fun authorizeDeviceLink() { - val authorization = this.authorization ?: return + val authorization = this.deviceLink ?: return delegate?.onDeviceLinkRequestAuthorized(authorization) DeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.removeListener(this) @@ -72,8 +72,8 @@ class LinkDeviceMasterModeDialog : DialogFragment(), DeviceLinkingSessionListene private fun onDeviceLinkCanceled() { DeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.removeListener(this) - if (authorization != null) { - DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(authorization!!.slaveHexEncodedPublicKey) + if (deviceLink != null) { + DatabaseFactory.getLokiPreKeyBundleDatabase(context).removePreKeyBundle(deviceLink!!.slaveHexEncodedPublicKey) } dismiss() delegate?.onDeviceLinkCanceled() diff --git a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt index d42cabaffe..8a7d0acf85 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/dialogs/LinkDeviceSlaveModeDialog.kt @@ -23,7 +23,7 @@ import org.whispersystems.signalservice.loki.crypto.MnemonicCodec class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener { private val languageFileDirectory by lazy { MnemonicUtilities.getLanguageFileDirectory(context!!) } private lateinit var contentView: View - private var authorization: DeviceLink? = null + private var deviceLink: DeviceLink? = null var delegate: LinkDeviceSlaveModeDialogDelegate? = null override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { @@ -40,10 +40,10 @@ class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener return result } - override fun onDeviceLinkRequestAuthorized(authorization: DeviceLink) { - if (authorization.type != DeviceLink.Type.AUTHORIZATION || authorization.slaveHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.authorization != null) { return } + override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) { + if (deviceLink.type != DeviceLink.Type.AUTHORIZATION || deviceLink.slaveHexEncodedPublicKey != TextSecurePreferences.getLocalNumber(context!!) || this.deviceLink != null) { return } Util.runOnMain { - this.authorization = authorization + this.deviceLink = deviceLink DeviceLinkingSession.shared.stopListeningForLinkingRequests() DeviceLinkingSession.shared.removeListener(this) contentView.spinner.visibility = View.GONE @@ -56,7 +56,7 @@ class LinkDeviceSlaveModeDialog : DialogFragment(), DeviceLinkingSessionListener contentView.cancelButton.visibility = View.GONE Handler().postDelayed({ dismiss() - delegate?.onDeviceLinkRequestAuthorized(authorization) + delegate?.onDeviceLinkRequestAuthorized(deviceLink) }, 4000) } } diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt index 8991e9be32..ef26b02c16 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiAPIDatabase.kt @@ -48,14 +48,14 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( private val lastDeletionServerIDCacheIndex = "loki_api_last_deletion_server_id_cache_index" private val lastDeletionServerID = "last_deletion_server_id" @JvmStatic val createLastDeletionServerIDTableCommand = "CREATE TABLE $lastDeletionServerIDCache ($lastDeletionServerIDCacheIndex STRING PRIMARY KEY, $lastDeletionServerID INTEGER DEFAULT 0);" - // Pairing authorisation cache - private val pairingAuthorisationCache = "loki_pairing_authorisation_cache" - private val primaryDevicePublicKey = "primary_device" - private val secondaryDevicePublicKey = "secondary_device" + // Device link cache + private val deviceLinkCache = "loki_pairing_authorisation_cache" + private val masterHexEncodedPublicKey = "primary_device" + private val slaveHexEncodedPublicKey = "secondary_device" private val requestSignature = "request_signature" - private val grantSignature = "grant_signature" - @JvmStatic val createPairingAuthorisationTableCommand = "CREATE TABLE $pairingAuthorisationCache ($primaryDevicePublicKey TEXT, $secondaryDevicePublicKey TEXT, " + - "$requestSignature TEXT NULLABLE DEFAULT NULL, $grantSignature TEXT NULLABLE DEFAULT NULL, PRIMARY KEY ($primaryDevicePublicKey, $secondaryDevicePublicKey));" + private val authorizationSignature = "grant_signature" + @JvmStatic val createDeviceLinkTableCommand = "CREATE TABLE $deviceLinkCache ($masterHexEncodedPublicKey TEXT, $slaveHexEncodedPublicKey TEXT, " + + "$requestSignature TEXT NULLABLE DEFAULT NULL, $authorizationSignature TEXT NULLABLE DEFAULT NULL, PRIMARY KEY ($masterHexEncodedPublicKey, $slaveHexEncodedPublicKey));" // User count cache private val userCountCache = "loki_user_count_cache" private val publicChatID = "public_chat_id" @@ -181,33 +181,33 @@ class LokiAPIDatabase(context: Context, helper: SQLCipherOpenHelper) : Database( override fun getDeviceLinks(hexEncodedPublicKey: String): Set { val database = databaseHelper.readableDatabase - return database.getAll(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) { cursor -> - val primaryDevicePubKey = cursor.getString(primaryDevicePublicKey) - val secondaryDevicePubKey = cursor.getString(secondaryDevicePublicKey) + return database.getAll(deviceLinkCache, "$masterHexEncodedPublicKey = ? OR $slaveHexEncodedPublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) { cursor -> + val masterHexEncodedPublicKey = cursor.getString(masterHexEncodedPublicKey) + val slaveHexEncodedPublicKey = cursor.getString(slaveHexEncodedPublicKey) val requestSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(requestSignature))) null else cursor.getBase64EncodedData(requestSignature) - val grantSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(grantSignature))) null else cursor.getBase64EncodedData(grantSignature) - DeviceLink(primaryDevicePubKey, secondaryDevicePubKey, requestSignature, grantSignature) + val authorizationSignature: ByteArray? = if (cursor.isNull(cursor.getColumnIndexOrThrow(authorizationSignature))) null else cursor.getBase64EncodedData(authorizationSignature) + DeviceLink(masterHexEncodedPublicKey, slaveHexEncodedPublicKey, requestSignature, authorizationSignature) }.toSet() } override fun addDeviceLink(deviceLink: DeviceLink) { val database = databaseHelper.writableDatabase val values = ContentValues() - values.put(primaryDevicePublicKey, deviceLink.masterHexEncodedPublicKey) - values.put(secondaryDevicePublicKey, deviceLink.slaveHexEncodedPublicKey) + values.put(masterHexEncodedPublicKey, deviceLink.masterHexEncodedPublicKey) + values.put(slaveHexEncodedPublicKey, deviceLink.slaveHexEncodedPublicKey) if (deviceLink.requestSignature != null) { values.put(requestSignature, Base64.encodeBytes(deviceLink.requestSignature)) } - if (deviceLink.authorizationSignature != null) { values.put(grantSignature, Base64.encodeBytes(deviceLink.authorizationSignature)) } - database.insertOrUpdate(pairingAuthorisationCache, values, "$primaryDevicePublicKey = ? AND $secondaryDevicePublicKey = ?", arrayOf( deviceLink.masterHexEncodedPublicKey, deviceLink.slaveHexEncodedPublicKey )) + if (deviceLink.authorizationSignature != null) { values.put(authorizationSignature, Base64.encodeBytes(deviceLink.authorizationSignature)) } + database.insertOrUpdate(deviceLinkCache, values, "$masterHexEncodedPublicKey = ? AND $slaveHexEncodedPublicKey = ?", arrayOf( deviceLink.masterHexEncodedPublicKey, deviceLink.slaveHexEncodedPublicKey )) } override fun clearDeviceLinks(hexEncodedPublicKey: String) { val database = databaseHelper.writableDatabase - database.delete(pairingAuthorisationCache, "$primaryDevicePublicKey = ? OR $secondaryDevicePublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) + database.delete(deviceLinkCache, "$masterHexEncodedPublicKey = ? OR $slaveHexEncodedPublicKey = ?", arrayOf( hexEncodedPublicKey, hexEncodedPublicKey )) } - fun removePairingAuthorisation(primaryDevicePublicKey: String, secondaryDevicePublicKey: String) { + fun removeDeviceLink(masterHexEncodedPublicKey: String, slaveHexEncodedPublicKey: String) { val database = databaseHelper.writableDatabase - database.delete(pairingAuthorisationCache, "${Companion.primaryDevicePublicKey} = ? OR ${Companion.secondaryDevicePublicKey} = ?", arrayOf( primaryDevicePublicKey, secondaryDevicePublicKey )) + database.delete(deviceLinkCache, "${Companion.masterHexEncodedPublicKey} = ? OR ${Companion.slaveHexEncodedPublicKey} = ?", arrayOf( masterHexEncodedPublicKey, slaveHexEncodedPublicKey )) } fun getUserCount(group: Long, server: String): Int? { diff --git a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt index 327b382c4a..744cf414c6 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/messaging/LokiPublicChatPoller.kt @@ -152,36 +152,36 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki fun pollForNewMessages() { fun processIncomingMessage(message: LokiPublicChatMessage) { - // If the sender of the current message is not a secondary device, we need to set the display name in the database - val primaryDevice = LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(message.hexEncodedPublicKey).get() - if (primaryDevice == null) { + // If the sender of the current message is not a slave device, set the display name in the database + val masterHexEncodedPublicKey = LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(message.hexEncodedPublicKey).get() + if (masterHexEncodedPublicKey == null) { val senderDisplayName = "${message.displayName} (...${message.hexEncodedPublicKey.takeLast(8)})" DatabaseFactory.getLokiUserDatabase(context).setServerDisplayName(group.id, message.hexEncodedPublicKey, senderDisplayName) } - val senderPublicKey = primaryDevice ?: message.hexEncodedPublicKey + val senderHexEncodedPublicKey = masterHexEncodedPublicKey ?: message.hexEncodedPublicKey val serviceDataMessage = getDataMessage(message) - val serviceContent = SignalServiceContent(serviceDataMessage, senderPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, false) + val serviceContent = SignalServiceContent(serviceDataMessage, senderHexEncodedPublicKey, SignalServiceAddress.DEFAULT_DEVICE_ID, message.timestamp, false, 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 avatar if needed - val senderRecipient = Recipient.from(context, Address.fromSerialized(senderPublicKey), false) + // 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 (senderRecipient.profileKey == null || !MessageDigest.isEqual(senderRecipient.profileKey, profileKey)) { + if (senderAsRecipient.profileKey == null || !MessageDigest.isEqual(senderAsRecipient.profileKey, profileKey)) { val database = DatabaseFactory.getRecipientDatabase(context) - database.setProfileKey(senderRecipient, profileKey) - ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderRecipient, url)) + database.setProfileKey(senderAsRecipient, profileKey) + ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, url)) } - } else if (senderRecipient.profileAvatar.orEmpty().isNotEmpty()) { - // Unset the avatar if we had an avatar before and we're not friends with the person - val threadId = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(senderRecipient) - val friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadId) + } else if (senderAsRecipient.profileAvatar.orEmpty().isNotEmpty()) { + // Clear the profile picture if we had a profile picture before and we're not friends with the person + val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(senderAsRecipient) + val friendRequestStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID) if (friendRequestStatus != LokiThreadFriendRequestStatus.FRIENDS) { - ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderRecipient, "")) + ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(senderAsRecipient, "")) } } } @@ -190,16 +190,16 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki val isDuplicate = DatabaseFactory.getLokiMessageDatabase(context).getMessageID(messageServerID) != null if (isDuplicate) { return } if (message.body.isEmpty() && message.attachments.isEmpty() && message.quote == null) { return } - val localNumber = TextSecurePreferences.getLocalNumber(context) + val userHexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context) val dataMessage = getDataMessage(message) - val transcript = SentTranscriptMessage(localNumber, dataMessage.timestamp, dataMessage, dataMessage.expiresInSeconds.toLong(), Collections.singletonMap(localNumber, false)) + val transcript = SentTranscriptMessage(userHexEncodedPublicKey, dataMessage.timestamp, 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 mappings stay in sync + // 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.hexEncodedPublicKey), false) if (recipient.isOurMasterDevice && message.profilePicture != null) { val profileKey = message.profilePicture!!.profileKey @@ -222,7 +222,7 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki api.getMessages(group.channel, group.server) }.bind { messages -> if (messages.isNotEmpty()) { - // We need to fetch device mappings for all the devices we don't have + // We need to fetch the device mapping for any devices we don't have uniqueDevices = messages.map { it.hexEncodedPublicKey }.toSet() val devicesToUpdate = uniqueDevices.filter { !userDevices.contains(it) && LokiFileServerAPI.shared.hasDeviceLinkCacheExpired(hexEncodedPublicKey = it) } if (devicesToUpdate.isNotEmpty()) { @@ -231,14 +231,11 @@ class LokiPublicChatPoller(private val context: Context, private val group: Loki } Promise.of(messages) }.successBackground { - // Get the set of primary device pubKeys FROM the secondary devices in uniqueDevices val newDisplayNameUpdatees = uniqueDevices.mapNotNull { - // This will return null if current device is primary - // So if it's non-null then we know the device is a secondary device - val primaryDevice = LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(it).get() - primaryDevice + // This will return null if the current device is a master device + LokiDeviceLinkUtilities.getMasterHexEncodedPublicKey(it).get() }.toSet() - // Fetch the display names of the primary devices + // Fetch the display names of the master devices displayNameUpdatees = displayNameUpdatees.union(newDisplayNameUpdatees) }.successBackground { messages -> // Process messages in the background diff --git a/src/org/thoughtcrime/securesms/loki/redesign/views/SeparatorView.kt b/src/org/thoughtcrime/securesms/loki/redesign/views/LabeledSeparatorView.kt similarity index 98% rename from src/org/thoughtcrime/securesms/loki/redesign/views/SeparatorView.kt rename to src/org/thoughtcrime/securesms/loki/redesign/views/LabeledSeparatorView.kt index 3a9e68ffa0..7fdab43795 100644 --- a/src/org/thoughtcrime/securesms/loki/redesign/views/SeparatorView.kt +++ b/src/org/thoughtcrime/securesms/loki/redesign/views/LabeledSeparatorView.kt @@ -12,7 +12,7 @@ import network.loki.messenger.R import org.thoughtcrime.securesms.loki.getColorWithID import org.thoughtcrime.securesms.loki.toPx -class SeparatorView : RelativeLayout { +class LabeledSeparatorView : RelativeLayout { private val path = Path() From 27fdfe4ee8224a98457e6bb99311fb03e3f4125c Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 13 Feb 2020 09:28:00 +1100 Subject: [PATCH 11/18] Trim unused files --- res/drawable/{icon_crown.xml => ic_crown.xml} | 0 .../scroll_to_bottom_button_background.xml | 5 +- ..._name_v2.xml => activity_display_name.xml} | 0 ...activity_seed_v2.xml => activity_seed.xml} | 0 res/layout/activity_display_name.xml | 95 ++++---- res/layout/activity_display_name_v2.xml | 59 ----- res/layout/activity_seed.xml | 209 ++++++------------ res/layout/activity_seed_v2.xml | 77 ------- res/layout/conversation_item_received.xml | 2 +- res/layout/view_mention_candidate.xml | 2 +- .../securesms/ApplicationContext.java | 7 +- .../securesms/CreateProfileActivity.java | 2 +- .../conversation/ConversationActivity.java | 107 +++++---- .../securesms/jobs/PushDecryptJob.java | 2 +- .../activities/DisplayNameActivity.kt | 4 +- .../loki/redesign/activities/SeedActivity.kt | 4 +- .../redesign/activities/SettingsActivity.kt | 2 +- .../messaging/LokiPublicChatPoller.kt | 2 +- 18 files changed, 181 insertions(+), 398 deletions(-) rename res/drawable/{icon_crown.xml => ic_crown.xml} (100%) rename res/layout-sw400dp/{activity_display_name_v2.xml => activity_display_name.xml} (100%) rename res/layout-sw400dp/{activity_seed_v2.xml => activity_seed.xml} (100%) delete mode 100644 res/layout/activity_display_name_v2.xml delete mode 100644 res/layout/activity_seed_v2.xml diff --git a/res/drawable/icon_crown.xml b/res/drawable/ic_crown.xml similarity index 100% rename from res/drawable/icon_crown.xml rename to res/drawable/ic_crown.xml diff --git a/res/drawable/scroll_to_bottom_button_background.xml b/res/drawable/scroll_to_bottom_button_background.xml index 68e512346c..387c75be90 100644 --- a/res/drawable/scroll_to_bottom_button_background.xml +++ b/res/drawable/scroll_to_bottom_button_background.xml @@ -1,5 +1,8 @@ - + + \ No newline at end of file diff --git a/res/layout-sw400dp/activity_display_name_v2.xml b/res/layout-sw400dp/activity_display_name.xml similarity index 100% rename from res/layout-sw400dp/activity_display_name_v2.xml rename to res/layout-sw400dp/activity_display_name.xml diff --git a/res/layout-sw400dp/activity_seed_v2.xml b/res/layout-sw400dp/activity_seed.xml similarity index 100% rename from res/layout-sw400dp/activity_seed_v2.xml rename to res/layout-sw400dp/activity_seed.xml diff --git a/res/layout/activity_display_name.xml b/res/layout/activity_display_name.xml index fc934a4df0..443f6c23e0 100644 --- a/res/layout/activity_display_name.xml +++ b/res/layout/activity_display_name.xml @@ -1,58 +1,59 @@ - + android:layout_height="match_parent" + android:background="@drawable/default_session_background" + android:orientation="vertical"> - + + + android:layout_marginLeft="@dimen/very_large_spacing" + android:layout_marginRight="@dimen/very_large_spacing" + android:textSize="@dimen/large_font_size" + android:textStyle="bold" + android:textColor="@color/text" + android:text="Pick your display name" /> - + - + - + - +