mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-24 23:37:20 +00:00
fix: out of order config messages and avatar downloads, use the hex encoding instead of the mnemonic from seed
This commit is contained in:
parent
6c81580d93
commit
9136f1ac2d
@ -30,6 +30,7 @@ import org.session.libsignal.libsignal.util.KeyHelper
|
|||||||
import org.session.libsignal.service.loki.crypto.MnemonicCodec
|
import org.session.libsignal.service.loki.crypto.MnemonicCodec
|
||||||
import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey
|
import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey
|
||||||
import org.session.libsignal.utilities.Hex
|
import org.session.libsignal.utilities.Hex
|
||||||
|
import org.session.libsignal.utilities.logging.Log
|
||||||
import org.thoughtcrime.securesms.ApplicationContext
|
import org.thoughtcrime.securesms.ApplicationContext
|
||||||
import org.thoughtcrime.securesms.BaseActionBarActivity
|
import org.thoughtcrime.securesms.BaseActionBarActivity
|
||||||
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
|
import org.thoughtcrime.securesms.loki.fragments.ScanQRCodeWrapperFragment
|
||||||
@ -68,7 +69,13 @@ class LinkDeviceActivity : BaseActionBarActivity(), ScanQRCodeWrapperFragmentDel
|
|||||||
|
|
||||||
// region Interaction
|
// region Interaction
|
||||||
override fun handleQRCodeScanned(mnemonic: String) {
|
override fun handleQRCodeScanned(mnemonic: String) {
|
||||||
continueWithMnemonic(mnemonic)
|
try {
|
||||||
|
val seed = Hex.fromStringCondensed(mnemonic)
|
||||||
|
continueWithSeed(seed)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("Loki","Error getting seed from QR code", e)
|
||||||
|
Toast.makeText(this, "An error occurred.", Toast.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun continueWithMnemonic(mnemonic: String) {
|
fun continueWithMnemonic(mnemonic: String) {
|
||||||
|
@ -32,7 +32,7 @@ class PNModeActivity : BaseActionBarActivity() {
|
|||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setUpActionBarSessionLogo()
|
setUpActionBarSessionLogo(true)
|
||||||
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
TextSecurePreferences.setHasSeenWelcomeScreen(this, true)
|
||||||
setContentView(R.layout.activity_pn_mode)
|
setContentView(R.layout.activity_pn_mode)
|
||||||
contentView.disableClipping()
|
contentView.disableClipping()
|
||||||
|
@ -82,78 +82,78 @@ object MultiDeviceProtocol {
|
|||||||
// TODO: remove this after we migrate to new message receiving pipeline
|
// TODO: remove this after we migrate to new message receiving pipeline
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun handleConfigurationMessage(context: Context, content: SignalServiceProtos.Content, senderPublicKey: String, timestamp: Long) {
|
fun handleConfigurationMessage(context: Context, content: SignalServiceProtos.Content, senderPublicKey: String, timestamp: Long) {
|
||||||
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return
|
|
||||||
synchronized(this) {
|
synchronized(this) {
|
||||||
|
val userPublicKey = TextSecurePreferences.getLocalNumber(context) ?: return
|
||||||
if (TextSecurePreferences.getConfigurationMessageSynced(context) && !TextSecurePreferences.shouldUpdateProfile(context, timestamp)) return
|
if (TextSecurePreferences.getConfigurationMessageSynced(context) && !TextSecurePreferences.shouldUpdateProfile(context, timestamp)) return
|
||||||
if (senderPublicKey != userPublicKey) return
|
if (senderPublicKey != userPublicKey) return
|
||||||
TextSecurePreferences.setConfigurationMessageSynced(context, true)
|
TextSecurePreferences.setConfigurationMessageSynced(context, true)
|
||||||
TextSecurePreferences.setLastProfileUpdateTime(context, timestamp)
|
TextSecurePreferences.setLastProfileUpdateTime(context, timestamp)
|
||||||
}
|
|
||||||
|
|
||||||
val configurationMessage = ConfigurationMessage.fromProto(content) ?: return
|
val configurationMessage = ConfigurationMessage.fromProto(content) ?: return
|
||||||
|
|
||||||
val storage = MessagingConfiguration.shared.storage
|
val storage = MessagingConfiguration.shared.storage
|
||||||
val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys()
|
val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys()
|
||||||
|
|
||||||
val threadDatabase = DatabaseFactory.getThreadDatabase(context)
|
val threadDatabase = DatabaseFactory.getThreadDatabase(context)
|
||||||
val recipientDatabase = DatabaseFactory.getRecipientDatabase(context)
|
val recipientDatabase = DatabaseFactory.getRecipientDatabase(context)
|
||||||
|
|
||||||
val ourRecipient = Recipient.from(context, Address.fromSerialized(userPublicKey),false)
|
val ourRecipient = Recipient.from(context, Address.fromSerialized(userPublicKey),false)
|
||||||
|
|
||||||
for (closedGroup in configurationMessage.closedGroups) {
|
for (closedGroup in configurationMessage.closedGroups) {
|
||||||
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
if (allClosedGroupPublicKeys.contains(closedGroup.publicKey)) continue
|
||||||
|
|
||||||
val closedGroupUpdate = DataMessage.ClosedGroupControlMessage.newBuilder()
|
val closedGroupUpdate = DataMessage.ClosedGroupControlMessage.newBuilder()
|
||||||
closedGroupUpdate.type = DataMessage.ClosedGroupControlMessage.Type.NEW
|
closedGroupUpdate.type = DataMessage.ClosedGroupControlMessage.Type.NEW
|
||||||
closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey))
|
closedGroupUpdate.publicKey = ByteString.copyFrom(Hex.fromStringCondensed(closedGroup.publicKey))
|
||||||
closedGroupUpdate.name = closedGroup.name
|
closedGroupUpdate.name = closedGroup.name
|
||||||
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
val encryptionKeyPair = SignalServiceProtos.KeyPair.newBuilder()
|
||||||
encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded())
|
encryptionKeyPair.publicKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.publicKey.serialize().removing05PrefixIfNeeded())
|
||||||
encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.privateKey.serialize())
|
encryptionKeyPair.privateKey = ByteString.copyFrom(closedGroup.encryptionKeyPair.privateKey.serialize())
|
||||||
closedGroupUpdate.encryptionKeyPair = encryptionKeyPair.build()
|
closedGroupUpdate.encryptionKeyPair = encryptionKeyPair.build()
|
||||||
closedGroupUpdate.addAllMembers(closedGroup.members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
closedGroupUpdate.addAllMembers(closedGroup.members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
||||||
closedGroupUpdate.addAllAdmins(closedGroup.admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
closedGroupUpdate.addAllAdmins(closedGroup.admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) })
|
||||||
|
|
||||||
ClosedGroupsProtocolV2.handleNewClosedGroup(context, closedGroupUpdate.build(), userPublicKey, timestamp)
|
ClosedGroupsProtocolV2.handleNewClosedGroup(context, closedGroupUpdate.build(), userPublicKey, timestamp)
|
||||||
}
|
|
||||||
val allOpenGroups = storage.getAllOpenGroups().map { it.value.server }
|
|
||||||
for (openGroup in configurationMessage.openGroups) {
|
|
||||||
if (allOpenGroups.contains(openGroup)) continue
|
|
||||||
OpenGroupUtilities.addGroup(context, openGroup, 1)
|
|
||||||
}
|
|
||||||
if (configurationMessage.displayName.isNotEmpty()) {
|
|
||||||
TextSecurePreferences.setProfileName(context, configurationMessage.displayName)
|
|
||||||
recipientDatabase.setProfileName(ourRecipient, configurationMessage.displayName)
|
|
||||||
}
|
|
||||||
if (configurationMessage.profileKey.isNotEmpty()) {
|
|
||||||
val profileKey = Base64.encodeBytes(configurationMessage.profileKey)
|
|
||||||
ProfileKeyUtil.setEncodedProfileKey(context, profileKey)
|
|
||||||
recipientDatabase.setProfileKey(ourRecipient, configurationMessage.profileKey)
|
|
||||||
if (!configurationMessage.profilePicture.isNullOrEmpty() && TextSecurePreferences.getProfilePictureURL(context) != configurationMessage.profilePicture) {
|
|
||||||
TextSecurePreferences.setProfilePictureURL(context, configurationMessage.profilePicture)
|
|
||||||
TextSecurePreferences.setProfileAvatarId(context, SecureRandom().nextInt())
|
|
||||||
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(ourRecipient, configurationMessage.profilePicture))
|
|
||||||
}
|
}
|
||||||
}
|
val allOpenGroups = storage.getAllOpenGroups().map { it.value.server }
|
||||||
for (contact in configurationMessage.contacts) {
|
for (openGroup in configurationMessage.openGroups) {
|
||||||
val address = Address.fromSerialized(contact.publicKey)
|
if (allOpenGroups.contains(openGroup)) continue
|
||||||
val recipient = Recipient.from(context, address, true)
|
OpenGroupUtilities.addGroup(context, openGroup, 1)
|
||||||
if (!contact.profilePicture.isNullOrEmpty()) {
|
|
||||||
recipientDatabase.setProfileAvatar(recipient, contact.profilePicture)
|
|
||||||
}
|
}
|
||||||
if (contact.profileKey?.isNotEmpty() == true) {
|
if (configurationMessage.displayName.isNotEmpty()) {
|
||||||
recipientDatabase.setProfileKey(recipient, contact.profileKey)
|
TextSecurePreferences.setProfileName(context, configurationMessage.displayName)
|
||||||
|
recipientDatabase.setProfileName(ourRecipient, configurationMessage.displayName)
|
||||||
}
|
}
|
||||||
if (contact.name.isNotEmpty()) {
|
if (configurationMessage.profileKey.isNotEmpty()) {
|
||||||
recipientDatabase.setProfileName(recipient, contact.name)
|
val profileKey = Base64.encodeBytes(configurationMessage.profileKey)
|
||||||
|
ProfileKeyUtil.setEncodedProfileKey(context, profileKey)
|
||||||
|
recipientDatabase.setProfileKey(ourRecipient, configurationMessage.profileKey)
|
||||||
|
if (!configurationMessage.profilePicture.isNullOrEmpty() && TextSecurePreferences.getProfilePictureURL(context) != configurationMessage.profilePicture) {
|
||||||
|
TextSecurePreferences.setProfilePictureURL(context, configurationMessage.profilePicture)
|
||||||
|
TextSecurePreferences.setProfileAvatarId(context, SecureRandom().nextInt())
|
||||||
|
ApplicationContext.getInstance(context).jobManager.add(RetrieveProfileAvatarJob(ourRecipient, configurationMessage.profilePicture))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (contact in configurationMessage.contacts) {
|
||||||
|
val address = Address.fromSerialized(contact.publicKey)
|
||||||
|
val recipient = Recipient.from(context, address, true)
|
||||||
|
if (!contact.profilePicture.isNullOrEmpty()) {
|
||||||
|
recipientDatabase.setProfileAvatar(recipient, contact.profilePicture)
|
||||||
|
}
|
||||||
|
if (contact.profileKey?.isNotEmpty() == true) {
|
||||||
|
recipientDatabase.setProfileKey(recipient, contact.profileKey)
|
||||||
|
}
|
||||||
|
if (contact.name.isNotEmpty()) {
|
||||||
|
recipientDatabase.setProfileName(recipient, contact.name)
|
||||||
|
}
|
||||||
|
recipientDatabase.setProfileSharing(recipient, true)
|
||||||
|
recipientDatabase.setRegistered(recipient, Recipient.RegisteredState.REGISTERED)
|
||||||
|
// create Thread if needed
|
||||||
|
threadDatabase.getOrCreateThreadIdFor(recipient)
|
||||||
|
}
|
||||||
|
if (configurationMessage.contacts.isNotEmpty()) {
|
||||||
|
threadDatabase.notifyUpdatedFromConfig()
|
||||||
}
|
}
|
||||||
recipientDatabase.setProfileSharing(recipient, true)
|
|
||||||
recipientDatabase.setRegistered(recipient, Recipient.RegisteredState.REGISTERED)
|
|
||||||
// create Thread if needed
|
|
||||||
threadDatabase.getOrCreateThreadIdFor(recipient)
|
|
||||||
}
|
|
||||||
if (configurationMessage.contacts.isNotEmpty()) {
|
|
||||||
threadDatabase.notifyUpdatedFromConfig()
|
|
||||||
}
|
}
|
||||||
// TODO: handle new configuration message fields or handle in new pipeline
|
// TODO: handle new configuration message fields or handle in new pipeline
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user