mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-19 20:48:27 +00:00
fix: look at early expiring incoming messages for delete after read
This commit is contained in:
parent
2048e08c86
commit
f0aba3a973
@ -572,7 +572,7 @@ class ConversationActivityV2 : PassphraseRequiredActionBarActivity(), InputBarDe
|
||||
|
||||
private fun setUpOutdatedClientBanner() {
|
||||
val recipient = viewModel.recipient ?: return
|
||||
if (!ExpirationConfiguration.isNewConfigEnabled && recipient.isContactRecipient &&
|
||||
if (ExpirationConfiguration.isNewConfigEnabled && recipient.isContactRecipient &&
|
||||
recipient.disappearingState == DisappearingState.LEGACY &&
|
||||
viewModel.expirationConfiguration?.isEnabled == true
|
||||
) {
|
||||
|
@ -84,9 +84,6 @@ public class ExpiringMessageManager implements SSKEnvironment.MessageExpirationM
|
||||
if (expiryType == ExpirationType.DELETE_AFTER_SEND_VALUE && message.getSentTimestamp() != null && senderPublicKey != null) {
|
||||
startAnyExpiration(message.getSentTimestamp(), senderPublicKey, expireStartedAt);
|
||||
}
|
||||
if (message.getId() != null) {
|
||||
DatabaseComponent.get(context).smsDatabase().deleteMessage(message.getId());
|
||||
}
|
||||
}
|
||||
|
||||
private void insertIncomingExpirationTimerMessage(ExpirationTimerUpdate message, long expireStartedAt) {
|
||||
|
@ -18,7 +18,7 @@ import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
||||
import org.session.libsession.messaging.sending_receiving.handle
|
||||
import org.session.libsession.messaging.sending_receiving.handleOpenGroupReactions
|
||||
import org.session.libsession.messaging.sending_receiving.handleVisibleMessage
|
||||
import org.session.libsession.messaging.sending_receiving.updateExpirationConfigurationIfNeeded
|
||||
import org.session.libsession.messaging.sending_receiving.updateExpiryIfNeeded
|
||||
import org.session.libsession.messaging.utilities.Data
|
||||
import org.session.libsession.messaging.utilities.SessionId
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||
@ -113,7 +113,7 @@ class BatchMessageReceiveJob(
|
||||
messages.forEach { (parameters, message, proto) ->
|
||||
try {
|
||||
if (message is VisibleMessage) {
|
||||
MessageReceiver.updateExpirationConfigurationIfNeeded(message, proto, openGroupID)
|
||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID)
|
||||
val messageId = MessageReceiver.handleVisibleMessage(message, proto, openGroupID,
|
||||
runIncrement = false,
|
||||
runThreadUpdate = false,
|
||||
|
@ -13,5 +13,6 @@ class ExpirationConfiguration(
|
||||
|
||||
companion object {
|
||||
val isNewConfigEnabled = false /* TODO: System.currentTimeMillis() > 1_676_851_200_000 // 13/02/2023 */
|
||||
const val LAST_READ_TEST = 1673587663000L
|
||||
}
|
||||
}
|
@ -35,11 +35,12 @@ object MessageReceiver {
|
||||
object InvalidGroupPublicKey: Error("Invalid group public key.")
|
||||
object NoGroupKeyPair: Error("Missing group key pair.")
|
||||
object NoUserED25519KeyPair : Error("Couldn't find user ED25519 key pair.")
|
||||
object ExpiredMessage: Error("Message has already expired, prevent adding")
|
||||
|
||||
internal val isRetryable: Boolean = when (this) {
|
||||
is DuplicateMessage, is InvalidMessage, is UnknownMessage,
|
||||
is UnknownEnvelopeType, is InvalidSignature, is NoData,
|
||||
is SenderBlocked, is SelfSend -> false
|
||||
is SenderBlocked, is SelfSend, is ExpiredMessage -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
@ -49,7 +50,7 @@ object MessageReceiver {
|
||||
openGroupServerID: Long?,
|
||||
isOutgoing: Boolean? = null,
|
||||
otherBlindedPublicKey: String? = null,
|
||||
openGroupPublicKey: String? = null,
|
||||
openGroupPublicKey: String? = null
|
||||
): Pair<Message, SignalServiceProtos.Content> {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val userPublicKey = storage.getUserPublicKey()
|
||||
@ -179,4 +180,5 @@ object MessageReceiver {
|
||||
// Return
|
||||
return Pair(message, proto)
|
||||
}
|
||||
|
||||
}
|
@ -39,7 +39,6 @@ import org.session.libsession.utilities.ProfileKeyUtil
|
||||
import org.session.libsession.utilities.SSKEnvironment
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsession.utilities.recipients.Recipient
|
||||
import org.session.libsession.utilities.recipients.Recipient.DisappearingState
|
||||
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
|
||||
import org.session.libsignal.crypto.ecc.DjbECPublicKey
|
||||
import org.session.libsignal.crypto.ecc.ECKeyPair
|
||||
@ -63,7 +62,7 @@ internal fun MessageReceiver.isBlocked(publicKey: String): Boolean {
|
||||
}
|
||||
|
||||
fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
||||
updateExpirationConfigurationIfNeeded(message, proto, openGroupID)
|
||||
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID)
|
||||
when (message) {
|
||||
is ReadReceipt -> handleReadReceipt(message)
|
||||
is TypingIndicator -> handleTypingIndicator(message)
|
||||
@ -82,29 +81,6 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
|
||||
}
|
||||
}
|
||||
|
||||
fun MessageReceiver.updateExpirationConfigurationIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val disappearingState = if (proto.hasExpirationTimer()) DisappearingState.UPDATED else DisappearingState.LEGACY
|
||||
if (!proto.hasLastDisappearingMessageChangeTimestamp() || !ExpirationConfiguration.isNewConfigEnabled) return
|
||||
val threadID = storage.getOrCreateThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID)
|
||||
if (threadID <= 0) return
|
||||
storage.updateDisappearingState(threadID, disappearingState)
|
||||
val localConfig = storage.getExpirationConfiguration(threadID)
|
||||
if (localConfig != null && localConfig.updatedTimestampMs > proto.lastDisappearingMessageChangeTimestamp) return
|
||||
val durationSeconds = if (proto.hasExpirationTimer()) proto.expirationTimer else 0
|
||||
val type = if (proto.hasExpirationType()) proto.expirationType else null
|
||||
val remoteConfig = ExpirationConfiguration(
|
||||
threadID,
|
||||
durationSeconds,
|
||||
type?.number ?: -1,
|
||||
proto.lastDisappearingMessageChangeTimestamp
|
||||
)
|
||||
storage.setExpirationConfiguration(remoteConfig)
|
||||
if (message is ExpirationTimerUpdate) {
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
|
||||
}
|
||||
}
|
||||
|
||||
// region Control Messages
|
||||
private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) {
|
||||
val context = MessagingModuleConfiguration.shared.context
|
||||
@ -256,6 +232,63 @@ fun handleMessageRequestResponse(message: MessageRequestResponse) {
|
||||
}
|
||||
//endregion
|
||||
|
||||
fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?) {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val sentTime = message.sentTimestamp ?: throw MessageReceiver.Error.InvalidMessage
|
||||
if (!proto.hasLastDisappearingMessageChangeTimestamp()) return
|
||||
val threadID = storage.getOrCreateThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID)
|
||||
if (threadID <= 0) throw MessageReceiver.Error.NoThread
|
||||
|
||||
val localConfig = storage.getExpirationConfiguration(threadID)
|
||||
|
||||
val durationSeconds = if (proto.hasExpirationTimer()) proto.expirationTimer else 0
|
||||
val type = if (proto.hasExpirationType()) proto.expirationType else null
|
||||
val remoteConfig = ExpirationConfiguration(
|
||||
threadID,
|
||||
durationSeconds,
|
||||
type?.number ?: -1,
|
||||
proto.lastDisappearingMessageChangeTimestamp
|
||||
)
|
||||
|
||||
val (shouldUpdateConfig, configToUse) =
|
||||
if (localConfig != null && localConfig.updatedTimestampMs > proto.lastDisappearingMessageChangeTimestamp) {
|
||||
false to localConfig
|
||||
} else {
|
||||
true to remoteConfig
|
||||
}
|
||||
|
||||
val recipient = storage.getRecipientForThread(threadID) ?: throw MessageReceiver.Error.NoThread
|
||||
|
||||
// don't update any values for open groups
|
||||
if (recipient.isOpenGroupRecipient && type != null) throw MessageReceiver.Error.InvalidMessage
|
||||
if ((recipient.isGroupRecipient || recipient.isLocalNumber)
|
||||
&& type == ExpirationType.DELETE_AFTER_READ) {
|
||||
// don't allow deleteAfterRead if we are sending to note to self or a group, treat the entire message as invalid
|
||||
throw MessageReceiver.Error.InvalidMessage
|
||||
}
|
||||
|
||||
// handle a delete after send expired fetch
|
||||
if (type == ExpirationType.DELETE_AFTER_SEND
|
||||
&& sentTime + configToUse.durationSeconds <= SnodeAPI.nowWithClockOffset) {
|
||||
throw MessageReceiver.Error.ExpiredMessage
|
||||
}
|
||||
// handle a delete after read last known config value (test) TODO: actually implement this with shared config library
|
||||
if (type == ExpirationType.DELETE_AFTER_READ
|
||||
&& sentTime + configToUse.durationSeconds <= ExpirationConfiguration.LAST_READ_TEST) {
|
||||
throw MessageReceiver.Error.ExpiredMessage
|
||||
}
|
||||
|
||||
if (shouldUpdateConfig) {
|
||||
val disappearingState = if (proto.hasExpirationType()) Recipient.DisappearingState.UPDATED else Recipient.DisappearingState.LEGACY
|
||||
storage.updateDisappearingState(threadID, disappearingState)
|
||||
storage.setExpirationConfiguration(configToUse)
|
||||
}
|
||||
|
||||
if (message is ExpirationTimerUpdate) {
|
||||
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
|
||||
}
|
||||
}
|
||||
|
||||
fun MessageReceiver.handleVisibleMessage(message: VisibleMessage,
|
||||
proto: SignalServiceProtos.Content,
|
||||
openGroupID: String?,
|
||||
|
@ -25,7 +25,6 @@ import org.session.libsignal.utilities.Snode
|
||||
import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsignal.utilities.recover
|
||||
import org.session.libsignal.utilities.toHexString
|
||||
import java.util.Date
|
||||
import kotlin.collections.set
|
||||
|
||||
private typealias Path = List<Snode>
|
||||
@ -594,7 +593,7 @@ object OnionRequestAPI {
|
||||
}
|
||||
if (body["t"] != null) {
|
||||
val timestamp = body["t"] as Long
|
||||
val offset = timestamp - Date().time
|
||||
val offset = timestamp - System.currentTimeMillis()
|
||||
SnodeAPI.clockOffset = offset
|
||||
}
|
||||
if (body.containsKey("hf")) {
|
||||
|
@ -56,6 +56,10 @@ object SnodeAPI {
|
||||
* user's clock is incorrect.
|
||||
*/
|
||||
var clockOffset = 0L
|
||||
|
||||
val nowWithClockOffset
|
||||
get() = System.currentTimeMillis() + clockOffset
|
||||
|
||||
internal var forkInfo by observable(database.getForkInfo()) { _, oldValue, newValue ->
|
||||
if (newValue > oldValue) {
|
||||
Log.d("Loki", "Setting new fork info new: $newValue, old: $oldValue")
|
||||
|
Loading…
x
Reference in New Issue
Block a user