|
|
@ -1,12 +1,18 @@
|
|
|
|
package org.thoughtcrime.securesms.loki.protocol
|
|
|
|
package org.thoughtcrime.securesms.loki.protocol
|
|
|
|
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import android.content.Context
|
|
|
|
|
|
|
|
import com.google.protobuf.ByteString
|
|
|
|
|
|
|
|
import org.session.libsession.messaging.MessagingConfiguration
|
|
|
|
import org.session.libsession.messaging.messages.control.ConfigurationMessage
|
|
|
|
import org.session.libsession.messaging.messages.control.ConfigurationMessage
|
|
|
|
import org.session.libsession.utilities.TextSecurePreferences
|
|
|
|
import org.session.libsession.utilities.TextSecurePreferences
|
|
|
|
import org.session.libsignal.service.api.push.SignalServiceAddress
|
|
|
|
import org.session.libsignal.service.api.push.SignalServiceAddress
|
|
|
|
|
|
|
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
|
|
|
|
|
|
|
import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded
|
|
|
|
|
|
|
|
import org.session.libsignal.utilities.Hex
|
|
|
|
import org.session.libsignal.utilities.logging.Log
|
|
|
|
import org.session.libsignal.utilities.logging.Log
|
|
|
|
import org.thoughtcrime.securesms.ApplicationContext
|
|
|
|
import org.thoughtcrime.securesms.ApplicationContext
|
|
|
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
|
|
|
|
import org.thoughtcrime.securesms.crypto.UnidentifiedAccessUtil
|
|
|
|
|
|
|
|
import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities
|
|
|
|
import org.thoughtcrime.securesms.loki.utilities.recipient
|
|
|
|
import org.thoughtcrime.securesms.loki.utilities.recipient
|
|
|
|
import java.util.*
|
|
|
|
import java.util.*
|
|
|
|
|
|
|
|
|
|
|
@ -14,7 +20,7 @@ object MultiDeviceProtocol {
|
|
|
|
|
|
|
|
|
|
|
|
@JvmStatic
|
|
|
|
@JvmStatic
|
|
|
|
fun syncConfigurationIfNeeded(context: Context) {
|
|
|
|
fun syncConfigurationIfNeeded(context: Context) {
|
|
|
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
|
|
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return
|
|
|
|
val lastSyncTime = TextSecurePreferences.getLastConfigurationSyncTime(context)
|
|
|
|
val lastSyncTime = TextSecurePreferences.getLastConfigurationSyncTime(context)
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
val now = System.currentTimeMillis()
|
|
|
|
if (now - lastSyncTime < 2 * 24 * 60 * 60 * 1000) return
|
|
|
|
if (now - lastSyncTime < 2 * 24 * 60 * 60 * 1000) return
|
|
|
@ -35,7 +41,7 @@ object MultiDeviceProtocol {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
fun forceSyncConfigurationNowIfNeeded(context: Context) {
|
|
|
|
fun forceSyncConfigurationNowIfNeeded(context: Context) {
|
|
|
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context)!!
|
|
|
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return
|
|
|
|
val configurationMessage = ConfigurationMessage.getCurrent()
|
|
|
|
val configurationMessage = ConfigurationMessage.getCurrent()
|
|
|
|
val serializedMessage = configurationMessage.toProto()!!.toByteArray()
|
|
|
|
val serializedMessage = configurationMessage.toProto()!!.toByteArray()
|
|
|
|
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
|
|
|
val messageSender = ApplicationContext.getInstance(context).communicationModule.provideSignalMessageSender()
|
|
|
@ -50,4 +56,34 @@ object MultiDeviceProtocol {
|
|
|
|
Log.d("Loki", "Failed to send configuration message due to error: $e.")
|
|
|
|
Log.d("Loki", "Failed to send configuration message due to error: $e.")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@JvmStatic
|
|
|
|
|
|
|
|
fun handleConfigurationMessage(context: Context, content: SignalServiceProtos.Content, senderPublicKey: String) {
|
|
|
|
|
|
|
|
val configurationMessage = ConfigurationMessage.fromProto(content) ?: return
|
|
|
|
|
|
|
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return
|
|
|
|
|
|
|
|
if (senderPublicKey != userPublicKey) return
|
|
|
|
|
|
|
|
val storage = MessagingConfiguration.shared.storage
|
|
|
|
|
|
|
|
val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys()
|
|
|
|
|
|
|
|
for (closedGroup in configurationMessage.closedGroups) {
|
|
|
|
|
|
|
|
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
val closedGroupUpdate = SignalServiceProtos.ClosedGroupUpdateV2.newBuilder()
|
|
|
|
|
|
|
|
closedGroupUpdate.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.NEW
|
|
|
|
|
|
|
|
closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey))
|
|
|
|
|
|
|
|
closedGroupUpdate.name = closedGroup.name
|
|
|
|
|
|
|
|
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
|
|
|
|
|
|
|
encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded())
|
|
|
|
|
|
|
|
encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.privateKey.serialize())
|
|
|
|
|
|
|
|
closedGroupUpdate.encryptionKeyPair = encryptionKeyPair.build()
|
|
|
|
|
|
|
|
closedGroupUpdate.addAllMembers(closedGroup.members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
|
|
|
|
|
|
|
closedGroupUpdate.addAllAdmins(closedGroup.admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClosedGroupsProtocolV2.handleNewClosedGroup(context, closedGroupUpdate.build(), userPublicKey)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
val allOpenGroups = storage.getAllOpenGroups().map { it.value.server }
|
|
|
|
|
|
|
|
for (openGroup in configurationMessage.openGroups) {
|
|
|
|
|
|
|
|
if (allOpenGroups.contains(openGroup)) continue
|
|
|
|
|
|
|
|
OpenGroupUtilities.addGroup(context, openGroup, 1)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|