Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package org.session.libsession.messaging.messages

import com.google.protobuf.ByteString
import network.loki.messenger.libsession_util.protocol.ProProfileFeature
import network.loki.messenger.libsession_util.util.BaseCommunityInfo
import network.loki.messenger.libsession_util.util.BitSet
import network.loki.messenger.libsession_util.util.Conversation
import network.loki.messenger.libsession_util.util.UserPic
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.Address.Companion.toAddress
Expand All @@ -13,6 +16,7 @@ import org.session.libsignal.utilities.Log
import org.thoughtcrime.securesms.database.BlindMappingRepository
import org.thoughtcrime.securesms.database.RecipientRepository
import org.thoughtcrime.securesms.database.RecipientSettingsDatabase
import org.thoughtcrime.securesms.database.model.RecipientSettings
import org.thoughtcrime.securesms.util.DateUtils.Companion.secondsToInstant
import org.thoughtcrime.securesms.util.DateUtils.Companion.toEpochSeconds
import java.time.Instant
Expand Down Expand Up @@ -57,11 +61,14 @@ class ProfileUpdateHandler @Inject constructor(
val standardSender = unblinded ?: (senderAddress as? Address.Standard)
if (standardSender != null && (!updates.name.isNullOrBlank() || updates.pic != null)) {
configFactory.withMutableUserConfigs { configs ->
var shouldUpdate = false
configs.contacts.updateContact(standardSender) {
if (shouldUpdateProfile(
shouldUpdate = shouldUpdateProfile(
lastUpdated = profileUpdatedEpochSeconds.secondsToInstant(),
newUpdateTime = updates.profileUpdateTime
)) {
)

if (shouldUpdate) {
if (updates.name != null) {
name = updates.name
}
Expand All @@ -70,6 +77,10 @@ class ProfileUpdateHandler @Inject constructor(
profilePicture = updates.pic
}

if (updates.proFeatures != null) {
proFeatures = updates.proFeatures
}

if (updates.profileUpdateTime != null) {
profileUpdatedEpochSeconds = updates.profileUpdateTime.toEpochSeconds()
}
Expand All @@ -78,13 +89,20 @@ class ProfileUpdateHandler @Inject constructor(
Log.d(TAG, "Ignoring contact profile update for ${standardSender.debugString}, no changes detected")
}
}

if (shouldUpdate) {
configs.convoInfoVolatile.set(
configs.convoInfoVolatile.getOrConstructOneToOne(standardSender.accountId.hexString)
.copy(proProofInfo = updates.proProof)
)
}
}
}

// If we have a blinded address, we need to look at if we have a blinded contact to update
if (senderAddress is Address.Blinded && (updates.pic != null || !updates.name.isNullOrBlank())) {
configFactory.withMutableUserConfigs { configs ->
configs.contacts.getBlinded(senderAddress.blindedId.hexString)?.let { c ->
val shouldUpdate = configs.contacts.getBlinded(senderAddress.blindedId.hexString)?.let { c ->
if (shouldUpdateProfile(
lastUpdated = c.profileUpdatedEpochSeconds.secondsToInstant(),
newUpdateTime = updates.profileUpdateTime
Expand All @@ -97,12 +115,26 @@ class ProfileUpdateHandler @Inject constructor(
c.name = updates.name
}

if (updates.proFeatures != null) {
c.proFeatures = updates.proFeatures
}

if (updates.profileUpdateTime != null) {
c.profileUpdatedEpochSeconds = updates.profileUpdateTime.toEpochSeconds()
}

configs.contacts.setBlinded(c)
true
} else {
false
}
} == true

if (shouldUpdate) {
configs.convoInfoVolatile.set(
configs.convoInfoVolatile.getOrConstructedBlindedOneToOne(senderAddress.blindedId.hexString)
.copy(proProofInfo = updates.proProof)
)
}
}
}
Expand All @@ -122,7 +154,13 @@ class ProfileUpdateHandler @Inject constructor(
r.copy(
name = updates.name ?: r.name,
profilePic = updates.pic ?: r.profilePic,
blocksCommunityMessagesRequests = updates.blocksCommunityMessageRequests ?: r.blocksCommunityMessagesRequests
blocksCommunityMessagesRequests = updates.blocksCommunityMessageRequests ?: r.blocksCommunityMessagesRequests,
proData = updates.proProof?.let {
RecipientSettings.ProData(
info = it,
features = updates.proFeatures ?: BitSet()
)
},
)
} else if (updates.blocksCommunityMessageRequests != null &&
r.blocksCommunityMessagesRequests != updates.blocksCommunityMessageRequests) {
Expand Down Expand Up @@ -155,6 +193,8 @@ class ProfileUpdateHandler @Inject constructor(
// Name to update, must be non-blank if provided.
val name: String? = null,
val pic: UserPic? = null,
val proProof: Conversation.ProProofInfo? = null,
val proFeatures: BitSet<ProProfileFeature>? = null,
val blocksCommunityMessageRequests: Boolean? = null,
val profileUpdateTime: Instant?,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.session.libsession.messaging.messages.signal

import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage
Expand All @@ -19,7 +20,7 @@ class IncomingMediaMessage(
val body: String?,
val group: Address.GroupLike?,
val attachments: List<Attachment>,
val proFeatures: ProFeatures,
val proFeatures: BitSet<ProMessageFeature>,
val messageContent: MessageContent?,
val quote: QuoteModel?,
val linkPreviews: List<LinkPreview>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.session.libsession.messaging.messages.signal

import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.messaging.calls.CallMessageType
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation
import org.session.libsession.messaging.messages.visible.VisibleMessage
Expand All @@ -20,7 +21,7 @@ data class IncomingTextMessage(
val hasMention: Boolean,
val isOpenGroupInvitation: Boolean,
val isSecureMessage: Boolean,
val proFeatures: ProFeatures,
val proFeatures: BitSet<ProMessageFeature>,
val isGroupMessage: Boolean = false,
val isGroupUpdateMessage: Boolean = false,
) {
Expand Down Expand Up @@ -80,7 +81,7 @@ data class IncomingTextMessage(
hasMention = false,
isOpenGroupInvitation = false,
isSecureMessage = false,
proFeatures = ProFeatures.NONE,
proFeatures = BitSet(),
)

companion object {
Expand Down Expand Up @@ -108,7 +109,7 @@ data class IncomingTextMessage(
hasMention = false,
isOpenGroupInvitation = true,
isSecureMessage = false,
proFeatures = ProFeatures.NONE,
proFeatures = BitSet(),
)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.session.libsession.messaging.messages.signal

import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.sending_receiving.attachments.Attachment
import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview
Expand All @@ -20,7 +21,7 @@ class OutgoingMediaMessage(
val linkPreviews: List<LinkPreview>,
val group: Address.GroupLike?,
val isGroupUpdateMessage: Boolean,
val proFeatures: ProFeatures = ProFeatures.NONE,
val proFeatures: BitSet<ProMessageFeature> = BitSet()
) {
init {
check(!isGroupUpdateMessage || group != null) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.session.libsession.messaging.messages.signal

import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.messaging.messages.visible.OpenGroupInvitation
import org.session.libsession.messaging.messages.visible.VisibleMessage
import org.session.libsession.messaging.utilities.UpdateMessageData
Expand All @@ -13,7 +14,7 @@ data class OutgoingTextMessage(
val expireStartedAtMillis: Long,
val sentTimestampMillis: Long,
val isOpenGroupInvitation: Boolean,
val proFeatures: ProFeatures = ProFeatures.NONE,
val proFeatures: BitSet<ProMessageFeature> = BitSet()
) {
constructor(
message: VisibleMessage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ package org.session.libsession.messaging.messages.visible

import androidx.annotation.Keep
import network.loki.messenger.BuildConfig
import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.ProMessageFeature
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.database.MessageDataProvider
import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.copyExpiration
Expand All @@ -26,12 +27,12 @@ data class VisibleMessage(
var reaction: Reaction? = null,
var hasMention: Boolean = false,
var blocksMessageRequests: Boolean = false,
var proFeatures: ProFeatures = ProFeatures.NONE
var proFeatures: BitSet<ProMessageFeature> = BitSet()
) : Message() {

// This empty constructor is needed for kryo serialization
@Keep
constructor(): this(proFeatures = ProFeatures.NONE)
constructor(): this(proFeatures = BitSet())

override val isSelfSendValid: Boolean = true

Expand Down Expand Up @@ -113,7 +114,7 @@ data class VisibleMessage(
}

// Pro features
if (proFeatures != ProFeatures.NONE) {
if (!proFeatures.isEmpty) {
builder.proMessageBuilder.setFeatures(proFeatures.rawValue)
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.session.libsession.messaging.sending_receiving

import network.loki.messenger.libsession_util.ED25519
import dagger.Lazy
import network.loki.messenger.libsession_util.SessionEncrypt
import network.loki.messenger.libsession_util.pro.ProProof
import network.loki.messenger.libsession_util.protocol.DecodedEnvelope
import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.protocol.DecodedPro
import network.loki.messenger.libsession_util.protocol.SessionProtocol
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.database.StorageProtocol
import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.control.CallMessage
Expand All @@ -21,13 +21,14 @@ import org.session.libsession.messaging.open_groups.OpenGroupApi
import org.session.libsession.snode.SnodeClock
import org.session.libsession.utilities.Address
import org.session.libsession.utilities.ConfigFactoryProtocol
import org.session.libsession.utilities.TextSecurePreferences
import org.session.libsignal.exceptions.NonRetryableException
import org.session.libsignal.protos.SignalServiceProtos
import org.session.libsignal.utilities.AccountId
import org.session.libsignal.utilities.Base64
import org.session.libsignal.utilities.Hex
import org.session.libsignal.utilities.IdPrefix
import java.time.Instant
import org.thoughtcrime.securesms.pro.ProStatusManager
import java.util.concurrent.TimeUnit
import javax.inject.Inject
import javax.inject.Singleton
Expand All @@ -38,6 +39,7 @@ class MessageParser @Inject constructor(
private val configFactory: ConfigFactoryProtocol,
private val storage: StorageProtocol,
private val snodeClock: SnodeClock,
private val prefs: TextSecurePreferences,
) {

//TODO: Obtain proBackendKey from somewhere
Expand Down Expand Up @@ -77,20 +79,10 @@ class MessageParser @Inject constructor(
currentUserBlindedIDs: List<AccountId>,
senderIdPrefix: IdPrefix
): Pair<Message, SignalServiceProtos.Content> {
val proFeatures = if (decodedEnvelope.proProof?.status(
senderED25519PubKey = decodedEnvelope.senderEd25519PubKey.data,
signedMessage = null,
now = decodedEnvelope.timestamp) == ProProof.Status.Valid
) {
decodedEnvelope.proFeatures
} else {
ProFeatures.NONE
}

return parseMessage(
sender = AccountId(senderIdPrefix, decodedEnvelope.senderX25519PubKey.data),
contentPlaintext = decodedEnvelope.contentPlainText.data,
proFeatures = proFeatures,
pro = decodedEnvelope.decodedPro,
messageTimestampMs = decodedEnvelope.timestamp.toEpochMilli(),
relaxSignatureCheck = relaxSignatureCheck,
checkForBlockStatus = checkForBlockStatus,
Expand All @@ -103,7 +95,7 @@ class MessageParser @Inject constructor(
private fun parseMessage(
sender: AccountId,
contentPlaintext: ByteArray,
proFeatures: ProFeatures,
pro: DecodedPro?,
messageTimestampMs: Long,
relaxSignatureCheck: Boolean,
checkForBlockStatus: Boolean,
Expand Down Expand Up @@ -142,7 +134,11 @@ class MessageParser @Inject constructor(
message.sentTimestamp = messageTimestampMs
message.receivedTimestamp = snodeClock.currentTimeMills()
message.isSenderSelf = isSenderSelf
(message as? VisibleMessage)?.proFeatures = proFeatures

// Only process pro features post pro launch
if (prefs.forcePostPro()) {
(message as? VisibleMessage)?.proFeatures = pro?.proMessageFeatures ?: BitSet()
}

// Validate
var isValid = message.isValid()
Expand Down Expand Up @@ -244,19 +240,9 @@ class MessageParser @Inject constructor(

val sender = AccountId(msg.sessionId)

val proFeatures = if (decoded.proProof?.status(
senderED25519PubKey = sender.pubKeyBytes,
signedMessage = null,
now = Instant.ofEpochMilli((msg.posted * 1000.0).toLong())) == ProProof.Status.Valid
) {
decoded.proFeatures
} else {
ProFeatures.NONE
}

return parseMessage(
contentPlaintext = decoded.contentPlainText.data,
proFeatures = proFeatures,
pro = decoded.decodedPro,
relaxSignatureCheck = true,
checkForBlockStatus = false,
isForGroup = false,
Expand Down Expand Up @@ -291,27 +277,10 @@ class MessageParser @Inject constructor(
)

val sender = Address.Standard(AccountId(senderId))
val messageSent = Instant.ofEpochMilli((msg.postedAt * 1000.0).toLong())

val proProof = decoded.proProof
val proFeatures = if (proProof != null) {
val hasValidProof = ED25519.ed25519PubKeysFromCurve25519(sender.accountId.pubKeyBytes)
.any { senderEd25519PubKey ->
proProof.status(senderEd25519PubKey, now = messageSent) == ProProof.Status.Valid
}

if (hasValidProof) {
decoded.proFeatures
} else {
ProFeatures.NONE
}
} else {
ProFeatures.NONE
}

return parseMessage(
contentPlaintext = decoded.contentPlainText.data,
proFeatures = proFeatures,
pro = decoded.decodedPro,
relaxSignatureCheck = true,
checkForBlockStatus = false,
isForGroup = false,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package org.session.libsession.messaging.sending_receiving

import network.loki.messenger.libsession_util.protocol.ProFeatures
import network.loki.messenger.libsession_util.util.BitSet
import org.session.libsession.messaging.messages.Message
import org.session.libsession.messaging.messages.ProfileUpdateHandler
import org.session.libsession.messaging.messages.control.MessageRequestResponse
Expand Down Expand Up @@ -161,7 +161,7 @@ class MessageRequestResponseHandler @Inject constructor(
body = null,
group = null,
attachments = emptyList(),
proFeatures = ProFeatures.NONE,
proFeatures = BitSet(),
messageContent = null,
quote = null,
linkPreviews = emptyList(),
Expand Down
Loading