fix: compile issues and dependencies resolved to use shared configs throughout apps

This commit is contained in:
0x330a
2023-07-31 17:19:38 +10:00
parent 19083e2ce7
commit bcb2071f44
21 changed files with 302 additions and 217 deletions

View File

@@ -152,7 +152,11 @@ class BatchMessageReceiveJob(
try {
when (message) {
is VisibleMessage -> {
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID, newLastSeen)
MessageReceiver.updateExpiryIfNeeded(
message,
proto,
openGroupID
)
val isUserBlindedSender =
message.sender == serverPublicKey?.let {
SodiumUtilities.blindedKeyPair(

View File

@@ -4,10 +4,10 @@ import network.loki.messenger.libsession_util.util.ExpiryMode
data class ExpirationConfiguration(
val threadId: Long = -1,
val expirationType: ExpiryMode? = null,
val expiryMode: ExpiryMode? = null,
val updatedTimestampMs: Long = 0
) {
val isEnabled = expirationType != null && expirationType.expirySeconds > 0
val isEnabled = expiryMode != null && expiryMode.expirySeconds > 0
companion object {
val isNewConfigEnabled = false /* TODO: System.currentTimeMillis() > 1_676_851_200_000 // 13/02/2023 */

View File

@@ -1,12 +1,14 @@
package org.session.libsession.messaging.messages
import com.google.protobuf.ByteString
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.utilities.GroupUtil
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
abstract class Message {
var id: Long? = null
@@ -60,10 +62,16 @@ abstract class Message {
expirationTimer = 0
return this
}
if (config.isEnabled) {
expirationTimer = config.durationSeconds
if (config.isEnabled && config.expiryMode != null) {
expirationTimer = config.expiryMode.expirySeconds.toInt()
lastDisappearingMessageChangeTimestamp = config.updatedTimestampMs
expirationType = config.expirationType
config.expiryMode.let { expiryMode ->
when (expiryMode) {
is ExpiryMode.AfterSend -> expirationType = ExpirationType.DELETE_AFTER_SEND
is ExpiryMode.AfterRead -> expirationType = ExpirationType.DELETE_AFTER_READ
ExpiryMode.NONE -> { /* do nothing */ }
}
}
}
return this
}

View File

@@ -4,16 +4,15 @@ import com.google.protobuf.ByteString
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
import org.session.libsignal.crypto.ecc.ECKeyPair
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.removingIdPrefixIfNeeded
import org.session.libsignal.utilities.toHexString
import org.session.libsignal.utilities.Hex
class ConfigurationMessage(var closedGroups: List<ClosedGroup>, var openGroups: List<String>, var contacts: List<Contact>,
var displayName: String, var profilePicture: String?, var profileKey: ByteArray) : ControlMessage() {
@@ -130,7 +129,14 @@ class ConfigurationMessage(var closedGroups: List<ClosedGroup>, var openGroups:
val encryptionKeyPair = storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) ?: continue
val threadID = storage.getOrCreateThreadIdFor(Address.fromSerialized(group.encodedId))
val expiryConfig = storage.getExpirationConfiguration(threadID)
val closedGroup = ClosedGroup(groupPublicKey, group.title, encryptionKeyPair, group.members.map { it.serialize() }, group.admins.map { it.serialize() }, expiryConfig?.durationSeconds ?: 0)
val closedGroup = ClosedGroup(
groupPublicKey,
group.title,
encryptionKeyPair,
group.members.map { it.serialize() },
group.admins.map { it.serialize() },
expiryConfig?.expiryMode?.expirySeconds?.toInt() ?: 0
)
closedGroups.add(closedGroup)
}
if (group.isOpenGroup) {

View File

@@ -1,5 +1,6 @@
package org.session.libsession.messaging.sending_receiving
import network.loki.messenger.libsession_util.util.ExpiryMode
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.deferred
import org.session.libsession.messaging.MessagingModuleConfiguration
@@ -33,7 +34,6 @@ import org.session.libsession.utilities.GroupUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsignal.crypto.PushTransportDetails
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.IdPrefix
import org.session.libsignal.utilities.Namespace
@@ -256,8 +256,9 @@ object MessageSender {
storage.getOrCreateThreadIdFor(Address.fromSerialized(address!!))
}
val config = storage.getExpirationConfiguration(threadId) ?: return null
return if (config.isEnabled && (config.expirationType == ExpirationType.DELETE_AFTER_SEND || isSyncMessage)) {
config.durationSeconds * 1000L
val expiryMode = config.expiryMode
return if (config.isEnabled && (expiryMode is ExpiryMode.AfterSend || isSyncMessage)) {
(expiryMode?.expirySeconds ?: 0L) * 1000L
} else null
}

View File

@@ -131,7 +131,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
throw Error.NoThread
}
val threadId = storage.getOrCreateThreadIdFor(fromSerialized(groupID))
val expireTimer = storage.getExpirationConfiguration(threadId)?.durationSeconds ?: 0
val expireTimer = storage.getExpirationConfiguration(threadId)?.expiryMode?.expirySeconds ?: 0
if (membersToAdd.isEmpty()) {
Log.d("Loki", "Invalid closed group update.")
throw Error.InvalidClosedGroupUpdate
@@ -156,7 +156,14 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
send(closedGroupControlMessage, Address.fromSerialized(groupID))
// Send closed group update messages to any new members individually
for (member in membersToAdd) {
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, expireTimer)
val closedGroupNewKind = ClosedGroupControlMessage.Kind.New(
ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)),
name,
encryptionKeyPair,
membersAsData,
adminsAsData,
expireTimer.toInt()
)
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupNewKind, groupID)
// It's important that the sent timestamp of this message is greater than the sent timestamp
// of the `MembersAdded` message above. The reason is that upon receiving this `New` message,

View File

@@ -2,6 +2,7 @@ package org.session.libsession.messaging.sending_receiving
import android.text.TextUtils
import network.loki.messenger.libsession_util.ConfigBase
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.avatars.AvatarHelper
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.jobs.BackgroundGroupAddJob
@@ -39,6 +40,7 @@ import org.session.libsession.utilities.GroupUtil.doubleEncodeGroupID
import org.session.libsession.utilities.ProfileKeyUtil
import org.session.libsession.utilities.SSKEnvironment
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsession.utilities.expiryMode
import org.session.libsession.utilities.recipients.Recipient
import org.session.libsignal.crypto.ecc.DjbECPrivateKey
import org.session.libsignal.crypto.ecc.DjbECPublicKey
@@ -67,7 +69,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content,
// Do nothing if the message was outdated
if (MessageReceiver.messageIsOutdated(message, threadId, openGroupID)) { return }
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID)
MessageReceiver.updateExpiryIfNeeded(message, proto, openGroupID, )
when (message) {
is ReadReceipt -> handleReadReceipt(message)
is TypingIndicator -> handleTypingIndicator(message)
@@ -157,8 +159,8 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
val module = MessagingModuleConfiguration.shared
val recipient = Recipient.from(module.context, Address.fromSerialized(message.sender!!), false)
val type = when {
recipient.isContactRecipient -> ExpirationType.DELETE_AFTER_READ
recipient.isGroupRecipient -> ExpirationType.DELETE_AFTER_SEND
recipient.isContactRecipient -> ExpiryMode.AfterRead(message.duration!!.toLong())
recipient.isGroupRecipient -> ExpiryMode.AfterSend(message.duration!!.toLong())
else -> null
}
try {
@@ -167,12 +169,16 @@ private fun MessageReceiver.handleExpirationTimerUpdate(message: ExpirationTimer
threadId = module.storage.getOrCreateThreadIdFor(fromSerialized(doubleEncodeGroupID(message.groupPublicKey!!)))
}
module.storage.setExpirationConfiguration(
ExpirationConfiguration(threadId, message.duration!!, type?.number ?: -1, System.currentTimeMillis())
ExpirationConfiguration(
threadId,
type,
SnodeAPI.nowWithOffset
)
)
} catch (e: Exception) {
Log.e("Loki", "Failed to update expiration configuration.")
}
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type)
}
private fun MessageReceiver.handleDataExtractionNotification(message: DataExtractionNotification) {
@@ -270,23 +276,30 @@ fun handleMessageRequestResponse(message: MessageRequestResponse) {
}
//endregion
fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceProtos.Content, openGroupID: String?, lastSeen: Long) {
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.getThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID, false)
if (threadID == null) throw MessageReceiver.Error.NoThread
val threadID =
storage.getThreadIdFor(message.sender!!, message.groupPublicKey, openGroupID, false)
?: throw MessageReceiver.Error.NoThread
val recipient = storage.getRecipientForThread(threadID) ?: 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 expiryMode = type?.expiryMode(durationSeconds.toLong())
val remoteConfig = ExpirationConfiguration(
threadID,
durationSeconds,
type?.number ?: -1,
expiryMode,
proto.lastDisappearingMessageChangeTimestamp
)
@@ -312,12 +325,12 @@ fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceP
// handle a delete after send expired fetch
if (type == ExpirationType.DELETE_AFTER_SEND
&& sentTime + configToUse.durationSeconds <= SnodeAPI.nowWithOffset) {
&& sentTime + (configToUse.expiryMode?.expirySeconds ?: 0) <= SnodeAPI.nowWithOffset) {
throw MessageReceiver.Error.ExpiredMessage
}
// handle a delete after read last known config value (test) TODO: actually implement this with shared config library
// handle a delete after read last known config value
if (type == ExpirationType.DELETE_AFTER_READ
&& sentTime + configToUse.durationSeconds <= ExpirationConfiguration.LAST_READ_TEST) {
&& sentTime + (configToUse.expiryMode?.expirySeconds ?: 0) <= storage.getLastSeen(threadID)) {
throw MessageReceiver.Error.ExpiredMessage
}
@@ -326,7 +339,7 @@ fun MessageReceiver.updateExpiryIfNeeded(message: Message, proto: SignalServiceP
}
if (message is ExpirationTimerUpdate) {
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.number ?: -1)
SSKEnvironment.shared.messageExpirationManager.setExpirationTimer(message, type?.expiryMode(durationSeconds.toLong()))
}
}

View File

@@ -1,6 +1,7 @@
package org.session.libsession.messaging.utilities
import android.content.Context
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.R
import org.session.libsession.messaging.MessagingModuleConfiguration
import org.session.libsession.messaging.calls.CallMessageType
@@ -14,7 +15,6 @@ import org.session.libsession.messaging.sending_receiving.data_extraction.DataEx
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.ExpirationUtil
import org.session.libsession.utilities.truncateIdForDisplay
import org.session.libsignal.protos.SignalServiceProtos.Content.ExpirationType
object UpdateMessageBuilder {
val storage = MessagingModuleConfiguration.shared.storage
@@ -99,9 +99,9 @@ object UpdateMessageBuilder {
val time = ExpirationUtil.getExpirationDisplayValue(context, duration.toInt())
val threadId = storage.getThreadId(Address.fromSerialized(senderId!!))
val config = threadId?.let { storage.getExpirationConfiguration(it) }
val state = when (config?.expirationType) {
ExpirationType.DELETE_AFTER_SEND -> context.getString(R.string.MessageRecord_state_sent)
ExpirationType.DELETE_AFTER_READ -> context.getString(R.string.MessageRecord_state_read)
val state = when (config?.expiryMode) {
is ExpiryMode.AfterSend -> context.getString(R.string.MessageRecord_state_sent)
is ExpiryMode.AfterRead -> context.getString(R.string.MessageRecord_state_read)
else -> ""
}
if (isOutgoing) {

View File

@@ -2,10 +2,10 @@ package org.session.libsession.utilities;
import android.content.Context;
import java.util.concurrent.TimeUnit;
import org.session.libsession.R;
import java.util.concurrent.TimeUnit;
public class ExpirationUtil {
public static String getExpirationDisplayValue(Context context, int expirationTime) {
@@ -28,20 +28,20 @@ public class ExpirationUtil {
}
}
public static String getExpirationAbbreviatedDisplayValue(Context context, int expirationTime) {
public static String getExpirationAbbreviatedDisplayValue(Context context, long expirationTime) {
if (expirationTime < TimeUnit.MINUTES.toSeconds(1)) {
return context.getResources().getString(R.string.expiration_seconds_abbreviated, expirationTime);
} else if (expirationTime < TimeUnit.HOURS.toSeconds(1)) {
int minutes = expirationTime / (int)TimeUnit.MINUTES.toSeconds(1);
long minutes = expirationTime / TimeUnit.MINUTES.toSeconds(1);
return context.getResources().getString(R.string.expiration_minutes_abbreviated, minutes);
} else if (expirationTime < TimeUnit.DAYS.toSeconds(1)) {
int hours = expirationTime / (int)TimeUnit.HOURS.toSeconds(1);
long hours = expirationTime / TimeUnit.HOURS.toSeconds(1);
return context.getResources().getString(R.string.expiration_hours_abbreviated, hours);
} else if (expirationTime < TimeUnit.DAYS.toSeconds(7)) {
int days = expirationTime / (int)TimeUnit.DAYS.toSeconds(1);
long days = expirationTime / TimeUnit.DAYS.toSeconds(1);
return context.getResources().getString(R.string.expiration_days_abbreviated, days);
} else {
int weeks = expirationTime / (int)TimeUnit.DAYS.toSeconds(7);
long weeks = expirationTime / TimeUnit.DAYS.toSeconds(7);
return context.getResources().getString(R.string.expiration_weeks_abbreviated, weeks);
}
}

View File

@@ -0,0 +1,29 @@
package org.session.libsession.utilities
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsignal.protos.SignalServiceProtos
import kotlin.reflect.KClass
fun ExpiryMode?.typeRadioIndex(): Int {
return when (this) {
is ExpiryMode.AfterRead -> SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ_VALUE
is ExpiryMode.AfterSend -> SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND_VALUE
else -> -1
}
}
fun SignalServiceProtos.Content.ExpirationType?.expiryMode(durationSeconds: Long): ExpiryMode? = when (this) {
null -> null
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ -> ExpiryMode.AfterRead(durationSeconds)
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND -> ExpiryMode.AfterSend(durationSeconds)
SignalServiceProtos.Content.ExpirationType.UNKNOWN -> null
}
fun Int.expiryType(): KClass<out ExpiryMode>? {
if (this == -1) return null
return when (this) {
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_READ_VALUE -> ExpiryMode.AfterSend::class
SignalServiceProtos.Content.ExpirationType.DELETE_AFTER_SEND_VALUE -> ExpiryMode.AfterRead::class
else -> ExpiryMode.NONE::class
}
}

View File

@@ -1,6 +1,7 @@
package org.session.libsession.utilities
import android.content.Context
import network.loki.messenger.libsession_util.util.ExpiryMode
import org.session.libsession.messaging.contacts.Contact
import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate
import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier
@@ -37,7 +38,7 @@ class SSKEnvironment(
}
interface MessageExpirationManagerProtocol {
fun setExpirationTimer(message: ExpirationTimerUpdate, expiryType: Int)
fun setExpirationTimer(message: ExpirationTimerUpdate, expiryType: ExpiryMode?)
fun startAnyExpiration(timestamp: Long, author: String, expireStartedAt: Long)
}