Merge pull request #114 from loki-project/bug-fix

Fix race condition that occurs on device link authorisation.
This commit is contained in:
gmbnt 2020-02-26 10:00:22 +07:00 committed by GitHub
commit 665f123d97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 22 additions and 2 deletions

View File

@ -194,6 +194,9 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
if (userHexEncodedPublicKey != null) {
if (TextSecurePreferences.getNeedsIsRevokedSlaveDeviceCheck(this)) {
MultiDeviceUtilities.checkIsRevokedSlaveDevice(this);
} else {
// We always update our current device links onto the server in case we failed to do so upon linking
MultiDeviceUtilities.updateDeviceLinksOnServer(this);
}
}
}

View File

@ -138,6 +138,7 @@ 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.crypto.LokiServiceCipher;
import org.whispersystems.signalservice.loki.messaging.LokiMessageFriendRequestStatus;
import org.whispersystems.signalservice.loki.messaging.LokiServiceMessage;
@ -704,6 +705,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
long threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient);
LokiThreadFriendRequestStatus status = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID);
if (status == LokiThreadFriendRequestStatus.NONE || status == LokiThreadFriendRequestStatus.REQUEST_EXPIRED) {
// TODO: We should ensure that our mapping has been uploaded to the server before sending out this message
MessageSender.sendBackgroundFriendRequest(context, hexEncodedPublicKey, "Please accept to enable messages to be synced across devices");
Log.d("Loki", "Sent friend request to " + hexEncodedPublicKey);
} else if (status == LokiThreadFriendRequestStatus.REQUEST_RECEIVED) {
@ -1206,6 +1208,17 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
TextSecurePreferences.setMultiDevice(context, true);
// Send a background message to the master device
MessageSender.sendBackgroundMessage(context, deviceLink.getMasterHexEncodedPublicKey());
/*
Update device link on the file server.
We put this here because after receiving the authorisation message, we will also receive all sync messages.
If these sync messages are contact syncs then we need to send them friend requests so that we can establish multi-device communication.
If our device mapping is not stored on the server before the other party receives our message, they will think that they got a friend request from a non-multi-device user.
*/
try {
PromiseUtil.timeout(LokiFileServerAPI.shared.addDeviceLink(deviceLink), 8000).get();
} catch (Exception e) {
Log.w("Loki", "Failed to upload device links to the file server! " + e);
}
// Update display name if needed
if (content.senderDisplayName.isPresent() && content.senderDisplayName.get().length() > 0) {
TextSecurePreferences.setProfileName(context, content.senderDisplayName.get());
@ -1218,7 +1231,6 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
if (content.getSyncMessage().isPresent() && content.getSyncMessage().get().getContacts().isPresent()) {
handleContactSyncMessage(content.getSyncMessage().get().getContacts().get());
}
// The device link is propagated to the file server in LandingActivity.onDeviceLinkAuthorized because we can handle the error there
}
private void setDisplayName(String hexEncodedPublicKey, String profileName) {

View File

@ -42,6 +42,12 @@ fun checkIsRevokedSlaveDevice(context: Context) {
}
}
fun updateDeviceLinksOnServer(context: Context) {
val hexEncodedPublicKey = TextSecurePreferences.getLocalNumber(context)
val deviceLinks = DatabaseFactory.getLokiAPIDatabase(context).getDeviceLinks(hexEncodedPublicKey)
LokiFileServerAPI.shared.setDeviceLinks(deviceLinks)
}
fun getAllDeviceFriendRequestStatuses(context: Context, hexEncodedPublicKey: String): Promise<Map<String, LokiThreadFriendRequestStatus>, Exception> {
val lokiThreadDatabase = DatabaseFactory.getLokiThreadDatabase(context)
return LokiDeviceLinkUtilities.getAllLinkedDeviceHexEncodedPublicKeys(hexEncodedPublicKey).map { keys ->

View File

@ -114,7 +114,6 @@ class LandingActivity : BaseActionBarActivity(), LinkDeviceSlaveModeDialogDelega
}
override fun onDeviceLinkRequestAuthorized(deviceLink: DeviceLink) {
LokiFileServerAPI.shared.addDeviceLink(deviceLink)
TextSecurePreferences.setMasterHexEncodedPublicKey(this, deviceLink.masterHexEncodedPublicKey)
val intent = Intent(this, HomeActivity::class.java)
show(intent)