mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-03 15:05:24 +00:00
Fix various session reset issues
This commit is contained in:
parent
9b329cbd34
commit
a7b94d188f
@ -490,7 +490,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc
|
||||
LokiAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster);
|
||||
lokiPoller = new LokiPoller(userPublicKey, apiDB, protos -> {
|
||||
for (SignalServiceProtos.Envelope proto : protos) {
|
||||
new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto));
|
||||
new PushContentReceiveJob(context).processEnvelope(new SignalServiceEnvelope(proto), false);
|
||||
}
|
||||
return Unit.INSTANCE;
|
||||
});
|
||||
|
@ -207,7 +207,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
SignalServiceEnvelope envelope = database.get(messageId);
|
||||
Optional<Long> optionalSmsMessageId = smsMessageId > 0 ? Optional.of(smsMessageId) : Optional.absent();
|
||||
|
||||
handleMessage(envelope, optionalSmsMessageId);
|
||||
handleMessage(envelope, optionalSmsMessageId, false);
|
||||
database.delete(messageId);
|
||||
}
|
||||
}
|
||||
@ -222,7 +222,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
|
||||
}
|
||||
|
||||
public void processMessage(@NonNull SignalServiceEnvelope envelope) {
|
||||
public void processMessage(@NonNull SignalServiceEnvelope envelope, boolean isPushNotification) {
|
||||
synchronized (PushReceivedJob.RECEIVE_LOCK) {
|
||||
if (needsMigration()) {
|
||||
Log.w(TAG, "Skipping and storing envelope, waiting for migration...");
|
||||
@ -231,7 +231,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
return;
|
||||
}
|
||||
|
||||
handleMessage(envelope, Optional.absent());
|
||||
handleMessage(envelope, Optional.absent(), isPushNotification);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +253,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
|
||||
}
|
||||
|
||||
private void handleMessage(@NonNull SignalServiceEnvelope envelope, @NonNull Optional<Long> smsMessageId) {
|
||||
private void handleMessage(@NonNull SignalServiceEnvelope envelope, @NonNull Optional<Long> smsMessageId, boolean isPushNotification) {
|
||||
try {
|
||||
GroupDatabase groupDatabase = DatabaseFactory.getGroupDatabase(context);
|
||||
SignalProtocolStore axolotlStore = new SignalProtocolStoreImpl(context);
|
||||
@ -378,7 +378,9 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
|
||||
handleInvalidVersionMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId);
|
||||
} catch (ProtocolInvalidMessageException e) {
|
||||
Log.w(TAG, e);
|
||||
if (!isPushNotification) { // This can be triggered if a PN encrypted with an old session comes in after the user performed a session reset
|
||||
handleCorruptMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId);
|
||||
}
|
||||
} catch (ProtocolInvalidKeyIdException | ProtocolInvalidKeyException | ProtocolUntrustedIdentityException e) {
|
||||
Log.w(TAG, e);
|
||||
handleCorruptMessage(e.getSender(), e.getSenderDevice(), envelope.getTimestamp(), smsMessageId);
|
||||
|
@ -57,7 +57,7 @@ public class PushNotificationReceiveJob extends PushReceivedJob implements Injec
|
||||
synchronized (PushReceivedJob.RECEIVE_LOCK) {
|
||||
receiver.retrieveMessages(envelope -> {
|
||||
Log.i(tag, "Retrieved an envelope." + timeSuffix(startTime));
|
||||
processEnvelope(envelope);
|
||||
processEnvelope(envelope, false);
|
||||
Log.i(tag, "Successfully processed an envelope." + timeSuffix(startTime));
|
||||
});
|
||||
TextSecurePreferences.setNeedsMessagePull(context, false);
|
||||
|
@ -22,7 +22,7 @@ public abstract class PushReceivedJob extends BaseJob {
|
||||
super(parameters);
|
||||
}
|
||||
|
||||
public void processEnvelope(@NonNull SignalServiceEnvelope envelope) {
|
||||
public void processEnvelope(@NonNull SignalServiceEnvelope envelope, boolean isPushNotification) {
|
||||
synchronized (RECEIVE_LOCK) {
|
||||
try {
|
||||
if (envelope.hasSource()) {
|
||||
@ -37,7 +37,7 @@ public abstract class PushReceivedJob extends BaseJob {
|
||||
if (envelope.isReceipt()) {
|
||||
handleReceipt(envelope);
|
||||
} else if (envelope.isPreKeySignalMessage() || envelope.isSignalMessage() || envelope.isUnidentifiedSender() || envelope.isFriendRequest()) {
|
||||
handleMessage(envelope);
|
||||
handleMessage(envelope, isPushNotification);
|
||||
} else {
|
||||
Log.w(TAG, "Received envelope of unknown type: " + envelope.getType());
|
||||
}
|
||||
@ -47,8 +47,8 @@ public abstract class PushReceivedJob extends BaseJob {
|
||||
}
|
||||
}
|
||||
|
||||
private void handleMessage(SignalServiceEnvelope envelope) {
|
||||
new PushDecryptJob(context).processMessage(envelope);
|
||||
private void handleMessage(SignalServiceEnvelope envelope, boolean isPushNotification) {
|
||||
new PushDecryptJob(context).processMessage(envelope, isPushNotification);
|
||||
}
|
||||
|
||||
@SuppressLint("DefaultLocale")
|
||||
|
@ -38,7 +38,7 @@ class BackgroundPollWorker : PersistentAlarmManagerListener() {
|
||||
LokiAPI.configureIfNeeded(userHexEncodedPublicKey, lokiAPIDatabase, broadcaster)
|
||||
LokiAPI.shared.getMessages().map { messages ->
|
||||
messages.forEach {
|
||||
PushContentReceiveJob(context).processEnvelope(SignalServiceEnvelope(it))
|
||||
PushContentReceiveJob(context).processEnvelope(SignalServiceEnvelope(it), false)
|
||||
}
|
||||
}
|
||||
} catch (exception: Throwable) {
|
||||
|
@ -24,7 +24,7 @@ class PushNotificationService : FirebaseMessagingService() {
|
||||
if (data != null) {
|
||||
try {
|
||||
val envelope = LokiMessageWrapper.unwrap(data)
|
||||
PushContentReceiveJob(this).processEnvelope(SignalServiceEnvelope(envelope))
|
||||
PushContentReceiveJob(this).processEnvelope(SignalServiceEnvelope(envelope), true)
|
||||
} catch (e: Exception) {
|
||||
Log.d("Loki", "Failed to unwrap data for message.")
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.loki.protocol
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import network.loki.messenger.BuildConfig
|
||||
import nl.komponents.kovenant.Promise
|
||||
import org.thoughtcrime.securesms.ApplicationContext
|
||||
import org.thoughtcrime.securesms.crypto.IdentityKeyUtil
|
||||
@ -34,21 +33,21 @@ object MultiDeviceProtocol {
|
||||
enum class MessageType { Text, Media }
|
||||
|
||||
@JvmStatic
|
||||
fun sendTextPush(context: Context, recipient: Recipient, messageID: Long) {
|
||||
sendMessagePush(context, recipient, messageID, MessageType.Text)
|
||||
fun sendTextPush(context: Context, recipient: Recipient, messageID: Long, isEndSession: Boolean) {
|
||||
sendMessagePush(context, recipient, messageID, MessageType.Text, isEndSession)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun sendMediaPush(context: Context, recipient: Recipient, messageID: Long) {
|
||||
sendMessagePush(context, recipient, messageID, MessageType.Media)
|
||||
sendMessagePush(context, recipient, messageID, MessageType.Media, false)
|
||||
}
|
||||
|
||||
private fun sendMessagePushToDevice(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType): PushSendJob {
|
||||
private fun sendMessagePushToDevice(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType, isEndSession: Boolean): PushSendJob {
|
||||
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
|
||||
val threadFRStatus = DatabaseFactory.getLokiThreadDatabase(context).getFriendRequestStatus(threadID)
|
||||
val isNoteToSelf = SessionMetaProtocol.shared.isNoteToSelf(recipient.address.serialize())
|
||||
val isContactFriend = (threadFRStatus == LokiThreadFriendRequestStatus.FRIENDS || isNoteToSelf) // In the note to self case the device linking request was the FR
|
||||
val isFRMessage = !isContactFriend // Holds true assuming this method isn't invoked for control messages
|
||||
val isFRMessage = !isContactFriend
|
||||
val hasVisibleContent = when (messageType) {
|
||||
MessageType.Text -> DatabaseFactory.getSmsDatabase(context).getMessage(messageID).body.isNotBlank()
|
||||
MessageType.Media -> {
|
||||
@ -56,10 +55,9 @@ object MultiDeviceProtocol {
|
||||
outgoingMediaMessage.body.isNotBlank() || outgoingMediaMessage.attachments.isNotEmpty()
|
||||
}
|
||||
}
|
||||
if (isFRMessage && !hasVisibleContent && BuildConfig.DEBUG) { throw IllegalStateException() } // Verify the above assumption
|
||||
val shouldSendAutoGeneratedFR = !isContactFriend && !isFRMessage
|
||||
&& !isNoteToSelf && !recipient.address.isGroup // Group threads work through session requests
|
||||
&& hasVisibleContent
|
||||
&& hasVisibleContent && !isEndSession
|
||||
if (!shouldSendAutoGeneratedFR) {
|
||||
when (messageType) {
|
||||
MessageType.Text -> return PushTextSendJob(messageID, messageID, recipient.address, isFRMessage, null)
|
||||
@ -74,7 +72,7 @@ object MultiDeviceProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendMessagePush(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType) {
|
||||
private fun sendMessagePush(context: Context, recipient: Recipient, messageID: Long, messageType: MessageType, isEndSession: Boolean) {
|
||||
val jobManager = ApplicationContext.getInstance(context).jobManager
|
||||
val isMultiDeviceRequired = !recipient.address.isOpenGroup
|
||||
if (!isMultiDeviceRequired) {
|
||||
@ -86,7 +84,7 @@ object MultiDeviceProtocol {
|
||||
val publicKey = recipient.address.serialize()
|
||||
LokiFileServerAPI.shared.getDeviceLinks(publicKey).success {
|
||||
val devices = MultiDeviceProtocol.shared.getAllLinkedDevices(publicKey)
|
||||
val jobs = devices.map { sendMessagePushToDevice(context, recipient(context, it), messageID, messageType) }
|
||||
val jobs = devices.map { sendMessagePushToDevice(context, recipient(context, it), messageID, messageType, isEndSession) }
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
when (messageType) {
|
||||
MessageType.Text -> jobManager.startChain(jobs).enqueue()
|
||||
|
@ -89,7 +89,6 @@ object SessionManagementProtocol {
|
||||
@JvmStatic
|
||||
fun handleEndSessionMessageIfNeeded(context: Context, content: SignalServiceContent) {
|
||||
if (!content.dataMessage.isPresent || !content.dataMessage.get().isEndSession) { return }
|
||||
// TODO: Notify the user
|
||||
val sessionStore = TextSecureSessionStore(context)
|
||||
val lokiThreadDB = DatabaseFactory.getLokiThreadDatabase(context)
|
||||
Log.d("Loki", "Received a session reset request from: ${content.sender}; archiving the session.")
|
||||
|
@ -12,15 +12,13 @@ import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.jobmanager.ConstraintObserver;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraintObserver;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationContext;
|
||||
import network.loki.messenger.R;
|
||||
import org.thoughtcrime.securesms.dependencies.InjectableType;
|
||||
import org.thoughtcrime.securesms.jobs.PushContentReceiveJob;
|
||||
import org.thoughtcrime.securesms.logging.Log;
|
||||
import org.thoughtcrime.securesms.notifications.NotificationChannels;
|
||||
import org.thoughtcrime.securesms.push.SignalServiceNetworkAccess;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
@ -33,6 +31,8 @@ import java.util.concurrent.TimeoutException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
public class IncomingMessageObserver implements InjectableType, ConstraintObserver.Notifier {
|
||||
|
||||
private static final String TAG = IncomingMessageObserver.class.getSimpleName();
|
||||
@ -159,7 +159,7 @@ public class IncomingMessageObserver implements InjectableType, ConstraintObserv
|
||||
localPipe.read(REQUEST_TIMEOUT_MINUTES, TimeUnit.MINUTES,
|
||||
envelope -> {
|
||||
Log.i(TAG, "Retrieved envelope! " + String.valueOf(envelope.getSource()));
|
||||
new PushContentReceiveJob(context).processEnvelope(envelope);
|
||||
new PushContentReceiveJob(context).processEnvelope(envelope, false);
|
||||
});
|
||||
} catch (TimeoutException e) {
|
||||
Log.w(TAG, "Application level read timeout...");
|
||||
|
@ -81,7 +81,7 @@ public class MessageSender {
|
||||
FriendRequestProtocol.setFriendRequestStatusToSendingIfNeeded(context, messageId, allocatedThreadId);
|
||||
}
|
||||
|
||||
sendTextMessage(context, recipient, forceSms, keyExchange, messageId);
|
||||
sendTextMessage(context, recipient, forceSms, keyExchange, messageId, message.isEndSession());
|
||||
|
||||
return allocatedThreadId;
|
||||
}
|
||||
@ -135,7 +135,7 @@ public class MessageSender {
|
||||
if (messageRecord.isMms()) {
|
||||
sendMediaMessage(context, recipient, forceSms, messageId, expiresIn);
|
||||
} else {
|
||||
sendTextMessage(context, recipient, forceSms, keyExchange, messageId);
|
||||
sendTextMessage(context, recipient, forceSms, keyExchange, messageId, messageRecord.isEndSession());
|
||||
}
|
||||
}
|
||||
|
||||
@ -152,17 +152,17 @@ public class MessageSender {
|
||||
|
||||
private static void sendTextMessage(Context context, Recipient recipient,
|
||||
boolean forceSms, boolean keyExchange,
|
||||
long messageId)
|
||||
long messageId, boolean isEndSession)
|
||||
{
|
||||
if (isLocalSelfSend(context, recipient, forceSms)) {
|
||||
sendLocalTextSelf(context, messageId);
|
||||
} else {
|
||||
sendTextPush(context, recipient, messageId);
|
||||
sendTextPush(context, recipient, messageId, isEndSession);
|
||||
}
|
||||
}
|
||||
|
||||
private static void sendTextPush(Context context, Recipient recipient, long messageId) {
|
||||
MultiDeviceProtocol.sendTextPush(context, recipient, messageId);
|
||||
private static void sendTextPush(Context context, Recipient recipient, long messageId, boolean isEndSession) {
|
||||
MultiDeviceProtocol.sendTextPush(context, recipient, messageId, isEndSession);
|
||||
}
|
||||
|
||||
private static void sendMediaPush(Context context, Recipient recipient, long messageId) {
|
||||
|
Loading…
Reference in New Issue
Block a user