From 21ca5492c9ab226275987841e1caddbb7c9c6ede Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Sat, 23 Oct 2021 12:44:43 +0300 Subject: [PATCH 01/38] Added PublicKeyEntity. Refactored code. WIP.| #1188 --- .../email/api/email/model/AttachmentInfo.kt | 1 - .../email/database/FlowCryptRoomDatabase.kt | 9 +- .../email/database/dao/ContactsDao.kt | 17 ++- .../email/database/dao/PubKeysDao.kt | 32 ++++++ .../email/database/entity/ContactEntity.kt | 105 +++--------------- .../email/database/entity/PublicKeyEntity.kt | 97 ++++++++++++++++ .../entity/relation/RecipientWithPubKeys.kt | 49 ++++++++ .../email/extensions/javax/mail/PartExt.kt | 1 - .../email/extensions/kotlin/StringExt.kt | 4 - .../jetpack/viewmodel/ContactsViewModel.kt | 22 ++-- .../jetpack/viewmodel/MsgDetailsViewModel.kt | 2 +- .../workmanager/sync/LoadContactsWorker.kt | 15 ++- .../com/flowcrypt/email/model/PgpContact.kt | 12 +- .../flowcrypt/email/model/PublicKeyInfo.kt | 6 +- .../flowcrypt/email/security/SecurityUtils.kt | 4 +- .../email/security/pgp/PgpDecrypt.kt | 1 - .../flowcrypt/email/security/pgp/PgpMsg.kt | 1 - .../service/EmailAndNameUpdaterService.kt | 6 +- ...PrepareOutgoingMessagesJobIntentService.kt | 4 +- .../ui/activity/SelectContactsActivity.kt | 12 +- .../activity/fragment/ContactsListFragment.kt | 24 ++-- .../PreviewImportPgpContactFragment.kt | 10 +- .../fragment/PublicKeyDetailsFragment.kt | 4 +- .../fragment/base/CreateMessageFragment.kt | 2 +- .../FixNeedPassphraseIssueDialogFragment.kt | 1 - .../ui/adapter/ContactsRecyclerViewAdapter.kt | 30 ++--- 26 files changed, 290 insertions(+), 181 deletions(-) create mode 100644 FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt create mode 100644 FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt create mode 100644 FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/model/AttachmentInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/model/AttachmentInfo.kt index a8269cb036..937f976c61 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/model/AttachmentInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/model/AttachmentInfo.kt @@ -9,7 +9,6 @@ import android.net.Uri import android.os.Parcel import android.os.Parcelable import com.flowcrypt.email.Constants -import com.flowcrypt.email.extensions.kotlin.lowercase import com.flowcrypt.email.security.SecurityUtils /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt index 3c8d24351a..aefbaf0325 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt @@ -26,6 +26,7 @@ import com.flowcrypt.email.database.dao.ContactsDao import com.flowcrypt.email.database.dao.KeysDao import com.flowcrypt.email.database.dao.LabelDao import com.flowcrypt.email.database.dao.MessageDao +import com.flowcrypt.email.database.dao.PubKeysDao import com.flowcrypt.email.database.entity.AccountAliasesEntity import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.ActionQueueEntity @@ -34,6 +35,7 @@ import com.flowcrypt.email.database.entity.ContactEntity import com.flowcrypt.email.database.entity.KeyEntity import com.flowcrypt.email.database.entity.LabelEntity import com.flowcrypt.email.database.entity.MessageEntity +import com.flowcrypt.email.database.entity.PublicKeyEntity import com.flowcrypt.email.security.pgp.PgpKey import org.pgpainless.key.OpenPgpV4Fingerprint @@ -56,7 +58,8 @@ import org.pgpainless.key.OpenPgpV4Fingerprint ContactEntity::class, KeyEntity::class, LabelEntity::class, - MessageEntity::class + MessageEntity::class, + PublicKeyEntity::class ], version = FlowCryptRoomDatabase.DB_VERSION ) @@ -78,6 +81,8 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { abstract fun contactsDao(): ContactsDao + abstract fun pubKeysDao(): PubKeysDao + @WorkerThread fun forceDatabaseCreationIfNeeded() { super.getOpenHelper().readableDatabase @@ -85,7 +90,7 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { companion object { const val DB_NAME = "flowcrypt.db" - const val DB_VERSION = 26 + const val DB_VERSION = 27 private val MIGRATION_1_3 = object : FlowCryptMigration(1, 3) { override fun doMigration(database: SupportSQLiteDatabase) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt index 40f1992115..be0d4a5255 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt @@ -9,7 +9,9 @@ import android.database.Cursor import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Query +import androidx.room.Transaction import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys /** * This object describes a logic of work with [ContactEntity]. @@ -21,19 +23,28 @@ import com.flowcrypt.email.database.entity.ContactEntity */ @Dao interface ContactsDao : BaseDao { + //fixed @Query("SELECT * FROM contacts") suspend fun getAllContacts(): List + //fixed @Query("SELECT * FROM contacts") fun getAllContactsLD(): LiveData> - @Query("SELECT * FROM contacts WHERE has_pgp = 1") + @Transaction + @Query("SELECT * FROM contacts WHERE email IN (SELECT recipient FROM public_keys GROUP BY recipient)") + fun getAllContactsWithPgpLD1(): LiveData> + + @Query("SELECT * FROM contacts") + //@Query("SELECT * FROM contacts WHERE has_pgp = 1") fun getAllContactsWithPgpLD(): LiveData> - @Query("SELECT * FROM contacts WHERE has_pgp = 1") + @Query("SELECT * FROM contacts") + //@Query("SELECT * FROM contacts WHERE has_pgp = 1") suspend fun getAllContactsWithPgp(): List - @Query("SELECT * FROM contacts WHERE has_pgp = 1 AND (email LIKE :searchPattern OR name LIKE :searchPattern)") + @Query("SELECT * FROM contacts WHERE (email LIKE :searchPattern OR name LIKE :searchPattern)") + //@Query("SELECT * FROM contacts WHERE has_pgp = 1 AND (email LIKE :searchPattern OR name LIKE :searchPattern)") suspend fun getAllContactsWithPgpWhichMatched(searchPattern: String): List @Query("SELECT * FROM contacts WHERE email = :email") diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt new file mode 100644 index 0000000000..fde7f7d864 --- /dev/null +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt @@ -0,0 +1,32 @@ +/* + * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com + * Contributors: DenBond7 + */ + +package com.flowcrypt.email.database.dao + +import androidx.lifecycle.LiveData +import androidx.room.Dao +import androidx.room.Query +import com.flowcrypt.email.database.entity.PublicKeyEntity + +/** + * @author Denis Bondarenko + * Date: 10/20/21 + * Time: 4:58 PM + * E-mail: DenBond7@gmail.com + */ +@Dao +interface PubKeysDao : BaseDao { + @Query("SELECT * FROM public_keys") + suspend fun getAllPublicKeys(): List + + @Query("SELECT * FROM public_keys") + fun getAllPublicKeysLD(): LiveData> + + @Query("SELECT * FROM public_keys WHERE recipient = :recipient") + suspend fun getPublicKeysByRecipient(recipient: String): List + + @Query("SELECT * FROM public_keys WHERE fingerprint = :fingerprint") + suspend fun getPublicKeysByFingerprint(fingerprint: String): List +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt index 6ae065efe0..9dcc19a2fe 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt @@ -25,9 +25,7 @@ import com.flowcrypt.email.security.model.PgpKeyDetails @Entity( tableName = "contacts", indices = [ - Index(name = "has_pgp_in_contacts", value = ["has_pgp"]), Index(name = "name_in_contacts", value = ["name"]), - Index(name = "long_id_in_contacts", value = ["long_id"]), Index(name = "last_use_in_contacts", value = ["last_use"]), Index(name = "email_in_contacts", value = ["email"], unique = true) ] @@ -36,16 +34,6 @@ data class ContactEntity( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = BaseColumns._ID) val id: Long? = null, val email: String, @ColumnInfo(defaultValue = "NULL") val name: String? = null, - @ColumnInfo(name = "public_key", defaultValue = "NULL") val publicKey: ByteArray? = null, - @ColumnInfo(name = "has_pgp") val hasPgp: Boolean, - @ColumnInfo(defaultValue = "NULL") val client: String? = null, - @ColumnInfo(defaultValue = "NULL") val attested: Boolean? = null, - @ColumnInfo(defaultValue = "NULL") val fingerprint: String? = null, - @Deprecated("Unused") @ColumnInfo( - name = "long_id", - defaultValue = "NULL" - ) val longId: String? = null, - @Deprecated("Unused") @ColumnInfo(defaultValue = "NULL") val keywords: String? = null, @ColumnInfo(name = "last_use", defaultValue = "0") val lastUse: Long = 0 ) : Parcelable { @@ -54,100 +42,41 @@ data class ContactEntity( constructor(parcel: Parcel) : this( parcel.readValue(Long::class.java.classLoader) as? Long, - parcel.readString() ?: throw IllegalArgumentException("Email can't be empty"), - parcel.readString(), - parcel.createByteArray(), - parcel.readByte() != 0.toByte(), - parcel.readString(), - parcel.readValue(Boolean::class.java.classLoader) as? Boolean, - parcel.readString(), - parcel.readString(), + requireNotNull(parcel.readString()), parcel.readString(), parcel.readLong() - ) - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as ContactEntity - - if (id != other.id) return false - if (email != other.email) return false - if (name != other.name) return false - if (publicKey != null) { - if (other.publicKey == null) return false - if (!publicKey.contentEquals(other.publicKey)) return false - } else if (other.publicKey != null) return false - if (hasPgp != other.hasPgp) return false - if (client != other.client) return false - if (attested != other.attested) return false - if (fingerprint != other.fingerprint) return false - if (longId != other.longId) return false - if (lastUse != other.lastUse) return false + ) { + pgpKeyDetails = parcel.readParcelable(PgpKeyDetails::class.java.classLoader) + } - return true + fun toPgpContact(): PgpContact { + return PgpContact( + email = email, + name = name, + lastUse = lastUse, + pgpKeyDetails = pgpKeyDetails + ) } - override fun hashCode(): Int { - var result = id.hashCode() - result = 31 * result + email.hashCode() - result = 31 * result + (name?.hashCode() ?: 0) - result = 31 * result + (publicKey?.contentHashCode() ?: 0) - result = 31 * result + hasPgp.hashCode() - result = 31 * result + (client?.hashCode() ?: 0) - result = 31 * result + (attested?.hashCode() ?: 0) - result = 31 * result + (fingerprint?.hashCode() ?: 0) - result = 31 * result + (longId?.hashCode() ?: 0) - result = 31 * result + lastUse.hashCode() - return result + //todo-denbond7 need to think about this class. + enum class Type { + TO, CC, BCC } override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeValue(id) parcel.writeString(email) parcel.writeString(name) - parcel.writeByteArray(publicKey) - parcel.writeByte(if (hasPgp) 1 else 0) - parcel.writeString(client) - parcel.writeValue(attested) - parcel.writeString(fingerprint) - parcel.writeString(longId) - parcel.writeString(null) parcel.writeLong(lastUse) + parcel.writeParcelable(pgpKeyDetails, flags) } override fun describeContents(): Int { return 0 } - fun toPgpContact(): PgpContact { - return PgpContact( - email = email, - name = name, - pubkey = String(publicKey ?: byteArrayOf()), - hasPgp = hasPgp, - client = client, - fingerprint = fingerprint, - lastUse = lastUse, - pgpKeyDetails = pgpKeyDetails - ) - } - companion object CREATOR : Parcelable.Creator { - const val CLIENT_FLOWCRYPT = "flowcrypt" - const val CLIENT_PGP = "pgp" - - override fun createFromParcel(parcel: Parcel): ContactEntity { - return ContactEntity(parcel) - } - - override fun newArray(size: Int): Array { - return arrayOfNulls(size) - } - } - - enum class Type { - TO, CC, BCC + override fun createFromParcel(parcel: Parcel): ContactEntity = ContactEntity(parcel) + override fun newArray(size: Int): Array = arrayOfNulls(size) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt new file mode 100644 index 0000000000..7fc421a9ff --- /dev/null +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt @@ -0,0 +1,97 @@ +/* + * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com + * Contributors: DenBond7 + */ + +package com.flowcrypt.email.database.entity + +import android.os.Parcel +import android.os.Parcelable +import android.provider.BaseColumns +import androidx.room.ColumnInfo +import androidx.room.Entity +import androidx.room.ForeignKey +import androidx.room.Index +import androidx.room.PrimaryKey + +/** + * @author Denis Bondarenko + * Date: 10/20/21 + * Time: 11:00 AM + * E-mail: DenBond7@gmail.com + */ +@Entity( + tableName = "public_keys", + indices = [ + Index( + name = "recipient_fingerprint_in_public_keys", + value = ["recipient", "fingerprint"], + unique = true + ), + Index( + name = "fingerprint_in_public_keys", + value = ["fingerprint"], + unique = false + ) + ], + foreignKeys = [ + ForeignKey( + entity = ContactEntity::class, + parentColumns = ["email"], + childColumns = ["recipient"], + onDelete = ForeignKey.CASCADE + ) + ] +) +class PublicKeyEntity( + @PrimaryKey(autoGenerate = true) @ColumnInfo(name = BaseColumns._ID) val id: Long? = null, + @ColumnInfo(name = "recipient") val recipient: String, + @ColumnInfo(name = "fingerprint") val fingerprint: String, + @ColumnInfo(name = "public_key") val publicKey: ByteArray +) : Parcelable { + constructor(parcel: Parcel) : this( + parcel.readValue(Long::class.java.classLoader) as? Long, + requireNotNull(parcel.readString()), + requireNotNull(parcel.readString()), + requireNotNull(parcel.createByteArray()) + ) + + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeValue(id) + parcel.writeString(recipient) + parcel.writeString(fingerprint) + parcel.writeByteArray(publicKey) + } + + override fun describeContents(): Int { + return 0 + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as PublicKeyEntity + + if (id != other.id) return false + if (recipient != other.recipient) return false + if (fingerprint != other.fingerprint) return false + if (!publicKey.contentEquals(other.publicKey)) return false + + return true + } + + override fun hashCode(): Int { + var result = id?.hashCode() ?: 0 + result = 31 * result + recipient.hashCode() + result = 31 * result + fingerprint.hashCode() + result = 31 * result + publicKey.contentHashCode() + return result + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): PublicKeyEntity = PublicKeyEntity(parcel) + override fun newArray(size: Int): Array = arrayOfNulls(size) + } +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt new file mode 100644 index 0000000000..b0ecf5a914 --- /dev/null +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt @@ -0,0 +1,49 @@ +/* + * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com + * Contributors: DenBond7 + */ + +package com.flowcrypt.email.database.entity.relation + +import android.os.Parcel +import android.os.Parcelable +import androidx.room.Embedded +import androidx.room.Relation +import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.PublicKeyEntity + +/** + * @author Denis Bondarenko + * Date: 10/21/21 + * Time: 11:29 AM + * E-mail: DenBond7@gmail.com + */ +data class RecipientWithPubKeys( + @Embedded val contact: ContactEntity, + @Relation( + parentColumn = "email", + entityColumn = "recipient", + entity = PublicKeyEntity::class, + projection = ["fingerprint", "public_key"] + ) + val publicKeys: List +) : Parcelable { + constructor(parcel: Parcel) : this( + requireNotNull(parcel.readParcelable(ContactEntity::class.java.classLoader)), + requireNotNull(parcel.createTypedArrayList(PublicKeyEntity)) + ) + + override fun writeToParcel(parcel: Parcel, flags: Int) { + parcel.writeParcelable(contact, flags) + parcel.writeTypedList(publicKeys) + } + + override fun describeContents(): Int { + return 0 + } + + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel) = RecipientWithPubKeys(parcel) + override fun newArray(size: Int): Array = arrayOfNulls(size) + } +} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/javax/mail/PartExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/javax/mail/PartExt.kt index 14a4e1c986..95f5c56d24 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/javax/mail/PartExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/javax/mail/PartExt.kt @@ -6,7 +6,6 @@ package com.flowcrypt.email.extensions.javax.mail -import com.flowcrypt.email.extensions.kotlin.lowercase import javax.mail.Part fun Part.isInline(): Boolean { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/kotlin/StringExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/kotlin/StringExt.kt index 13935c6fec..e4967f145e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/kotlin/StringExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/kotlin/StringExt.kt @@ -15,7 +15,6 @@ import java.net.URLEncoder import java.nio.charset.Charset import java.nio.charset.StandardCharsets import java.util.Base64 -import java.util.Locale fun String.normalizeDashes(): String { return this.replace(DASHES_REGEX, "-----") @@ -167,6 +166,3 @@ fun String.isValidEmail(): Boolean { fun String.isValidLocalhostEmail(): Boolean { return BetterInternetAddress.isValidLocalhostEmail(this) } - -fun String.lowercase(): String = toLowerCase(Locale.ROOT) -fun String.uppercase(): String = toUpperCase(Locale.ROOT) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index f4f77fe9e0..82aeaaf76f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -93,9 +93,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application ?: return@launch roomDatabase.contactsDao().updateSuspend( originalContactEntity.copy( - publicKey = contactEntity.publicKey, + /*publicKey = contactEntity.publicKey, fingerprint = contactEntity.fingerprint, - hasPgp = true + hasPgp = true*/ ) ) } @@ -136,7 +136,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application try { for (email in emails) { if (GeneralUtil.isEmailValid(email)) { - val emailLowerCase = email.toLowerCase(Locale.getDefault()) + val emailLowerCase = email.lowercase(Locale.getDefault()) var cachedContactEntity = roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) @@ -147,10 +147,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) } else { try { - cachedContactEntity.publicKey?.let { + /*cachedContactEntity.publicKey?.let { val result = PgpKey.parseKeys(it).pgpKeyDetailsList cachedContactEntity?.pgpKeyDetails = result.firstOrNull() - } + }*/ } catch (e: Exception) { e.printStackTrace() pgpContacts.add(cachedContactEntity.toPgpContact().copy(hasNotUsablePubKey = true)) @@ -159,7 +159,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } try { - if (cachedContactEntity?.hasPgp == false) { + if (true) { getPgpContactInfoFromServer(email = emailLowerCase)?.let { cachedContactEntity = updateCachedInfoWithAttesterInfo(cachedContactEntity, it, emailLowerCase) @@ -223,10 +223,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application roomDatabase.contactsDao().updateSuspend(updateCandidate) val lastVersion = roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) - lastVersion?.publicKey?.let { + /*lastVersion?.publicKey?.let { val result = PgpKey.parseKeys(it).pgpKeyDetailsList lastVersion.pgpKeyDetails = result.firstOrNull() - } + }*/ return lastVersion } @@ -263,8 +263,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application roomDatabase.contactsDao().updateSuspend( contactEntityFromPrimaryPgpContact.copy( id = contactEntity.id, - email = contactEntity.email.toLowerCase(Locale.US), - client = ContactEntity.CLIENT_PGP, + email = contactEntity.email.lowercase(Locale.US), ) ) } @@ -337,12 +336,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application when (response.status) { Result.Status.SUCCESS -> { val pubKeyString = response.data?.pubkey - val client = ContactEntity.CLIENT_PGP - if (pubKeyString?.isNotEmpty() == true) { PgpKey.parseKeys(pubKeyString).pgpKeyDetailsList.firstOrNull()?.let { val pgpContact = it.primaryPgpContact - pgpContact.client = client pgpContact.pgpKeyDetails = it return@withContext pgpContact } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 792950b0cb..0cf9574770 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -415,7 +415,7 @@ class MsgDetailsViewModel( val keyDetails = block.keyDetails ?: continue val pgpContact = keyDetails.primaryPgpContact val contactEntity = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) - block.existingPgpContact = contactEntity?.toPgpContact() + //block.existingPgpContact = contactEntity?.toPgpContact() } if (block is DecryptErrorMsgBlock) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index a1e1977c9a..db3e3e80ab 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -65,9 +65,9 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : if (msgs.isNotEmpty()) { val fetchProfile = FetchProfile() - fetchProfile.add(Message.RecipientType.TO.toString().toUpperCase(Locale.getDefault())) - fetchProfile.add(Message.RecipientType.CC.toString().toUpperCase(Locale.getDefault())) - fetchProfile.add(Message.RecipientType.BCC.toString().toUpperCase(Locale.getDefault())) + fetchProfile.add(Message.RecipientType.TO.toString().uppercase(Locale.getDefault())) + fetchProfile.add(Message.RecipientType.CC.toString().uppercase(Locale.getDefault())) + fetchProfile.add(Message.RecipientType.BCC.toString().uppercase(Locale.getDefault())) imapFolder.fetch(msgs, fetchProfile) return@fetchContactsInternal msgs @@ -171,8 +171,8 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : val updateCandidates = mutableListOf() for (contact in availableContacts) { - contactsInDatabase.add(contact.email.toLowerCase(Locale.getDefault())) - contactsByEmailMap[contact.email.toLowerCase(Locale.getDefault())] = contact + contactsInDatabase.add(contact.email.lowercase()) + contactsByEmailMap[contact.email.lowercase()] = contact } for (emailAndNamePair in emailAndNamePairs) { @@ -193,8 +193,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : newCandidates.add( ContactEntity( email = it, - name = emailAndNamePair.name, - hasPgp = false + name = emailAndNamePair.name ) ) } @@ -228,7 +227,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : for (address in addresses) { emailAndNamePairs.add( EmailAndNamePair( - address.address.toLowerCase(Locale.getDefault()), address.personal + address.address.lowercase(Locale.getDefault()), address.personal ) ) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt index b1b63aafa3..da20a2fc9e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt @@ -10,7 +10,6 @@ import android.os.Parcelable import com.flowcrypt.email.database.entity.ContactEntity import com.flowcrypt.email.security.model.PgpKeyDetails import java.util.ArrayList -import java.util.Locale import javax.mail.internet.AddressException import javax.mail.internet.InternetAddress @@ -61,14 +60,9 @@ data class PgpContact constructor( fun toContactEntity(): ContactEntity { return ContactEntity( - email = email.toLowerCase(Locale.getDefault()), + email = email.lowercase(), name = name, - publicKey = pubkey?.toByteArray(), - hasPgp = hasPgp, - client = client, - fingerprint = fingerprint, - lastUse = lastUse, - attested = false + lastUse = lastUse ) } @@ -86,7 +80,7 @@ data class PgpContact constructor( val internetAddresses = InternetAddress.parse(user) for (internetAddress in internetAddresses) { - val email = internetAddress.address.toLowerCase(Locale.US) + val email = internetAddress.address.lowercase() val name = internetAddress.personal pgpContacts.add(PgpContact(email, name)) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt index 11c9db73c0..ec6733a415 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt @@ -8,7 +8,6 @@ package com.flowcrypt.email.model import android.os.Parcel import android.os.Parcelable import com.flowcrypt.email.database.entity.ContactEntity -import java.util.Locale /** * This class describes information about some public key. @@ -49,10 +48,7 @@ data class PublicKeyInfo constructor( fun toContactEntity(): ContactEntity { return ContactEntity( - email = keyOwner.toLowerCase(Locale.getDefault()), - publicKey = publicKey.toByteArray(), - hasPgp = true, - fingerprint = fingerprint + email = keyOwner.lowercase() ) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt index f06893bf1b..75026e8012 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt @@ -120,9 +120,9 @@ class SecurityUtils { .getContactsByEmails(emails) for (contact in contacts) { - if (contact.publicKey?.isNotEmpty() == true) { + /*if (contact.publicKey?.isNotEmpty() == true) { contact.publicKey.let { publicKeys.add(String(it)) } - } + }*/ } return publicKeys diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpDecrypt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpDecrypt.kt index d89b21f5f7..7976310822 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpDecrypt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpDecrypt.kt @@ -7,7 +7,6 @@ package com.flowcrypt.email.security.pgp import android.os.Parcel import android.os.Parcelable -import com.flowcrypt.email.extensions.kotlin.uppercase import com.flowcrypt.email.util.exception.DecryptionException import org.bouncycastle.openpgp.PGPDataValidationException import org.bouncycastle.openpgp.PGPException diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt index d4ca634f3d..310f9e470e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/pgp/PgpMsg.kt @@ -25,7 +25,6 @@ import com.flowcrypt.email.extensions.javax.mail.internet.hasFileName import com.flowcrypt.email.extensions.javax.mail.isInline import com.flowcrypt.email.extensions.kotlin.decodeFcHtmlAttr import com.flowcrypt.email.extensions.kotlin.escapeHtmlAttr -import com.flowcrypt.email.extensions.kotlin.lowercase import com.flowcrypt.email.extensions.kotlin.stripHtmlRootTags import com.flowcrypt.email.extensions.kotlin.toEscapedHtml import com.flowcrypt.email.extensions.kotlin.toInputStream diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 69e18e0649..0dfc438104 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -47,12 +47,12 @@ class EmailAndNameUpdaterService : JobIntentService() { ?: return for (pair in pairs) { - val email = pair.email?.toLowerCase(Locale.getDefault()) ?: continue + val email = pair.email?.lowercase(Locale.getDefault()) ?: continue val contactEntity = contactsDao.getContactByEmail(email) if (contactEntity != null) { - if (contactEntity.name.isNullOrEmpty()) { + /*if (contactEntity.name.isNullOrEmpty()) { contactsDao.update(contactEntity.copy(name = pair.name)) - } + }*/ } else { contactsDao.insert(PgpContact(email, pair.name).toContactEntity()) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index 094ad64a2c..95e489d34d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -79,7 +79,7 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { intent.getParcelableExtra(EXTRA_KEY_OUTGOING_MESSAGE_INFO) ?: return val accountEntity = - roomDatabase.accountDao().getAccount(outgoingMsgInfo.account.toLowerCase(Locale.US)) + roomDatabase.accountDao().getAccount(outgoingMsgInfo.account.lowercase(Locale.US)) ?: return val uid = outgoingMsgInfo.uid @@ -385,7 +385,7 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { if (contactEntity == null) { contactsDao.insert(PgpContact(email, null).toContactEntity()) } else { - contactsDao.update(contactEntity.copy(lastUse = System.currentTimeMillis())) + //contactsDao.update(contactEntity.copy(lastUse = System.currentTimeMillis())) } } } catch (e: Exception) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index 095b5647fb..761021b377 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -5,7 +5,6 @@ package com.flowcrypt.email.ui.activity -import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle @@ -23,6 +22,7 @@ import androidx.test.espresso.idling.CountingIdlingResource import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel @@ -108,12 +108,12 @@ class SelectContactsActivity : BaseBackStackActivity(), return super.onPrepareOptionsMenu(menu) } - override fun onContactClick(contactEntity: ContactEntity) { + /*override fun onContactClick(contactEntity: ContactEntity) { val intent = Intent() intent.putExtra(KEY_EXTRA_PGP_CONTACT, contactEntity) setResult(Activity.RESULT_OK, intent) finish() - } + }*/ override fun onQueryTextSubmit(query: String): Boolean { searchPattern = query @@ -144,7 +144,7 @@ class SelectContactsActivity : BaseBackStackActivity(), if (it.data.isNullOrEmpty()) { UIUtil.exchangeViewVisibility(true, emptyView, recyclerViewContacts) } else { - contactsRecyclerViewAdapter.swap(it.data) + //contactsRecyclerViewAdapter.swap(it.data) UIUtil.exchangeViewVisibility(false, emptyView, recyclerViewContacts) } countingIdlingResourceForFilter.decrementSafely() @@ -180,4 +180,8 @@ class SelectContactsActivity : BaseBackStackActivity(), return intent } } + + override fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) { + TODO("Not yet implemented") + } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt index 111c95da4a..fe21baad1f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt @@ -12,14 +12,12 @@ import android.view.View import android.widget.Toast import androidx.core.content.res.ResourcesCompat import androidx.fragment.app.viewModels -import androidx.lifecycle.Observer import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result -import com.flowcrypt.email.database.entity.ContactEntity -import com.flowcrypt.email.extensions.navController +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.ui.activity.ImportPgpContactActivity import com.flowcrypt.email.ui.activity.fragment.base.BaseFragment @@ -73,20 +71,20 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet } } - override fun onContactClick(contactEntity: ContactEntity) { + /*override fun onContactClick(contactEntity: ContactEntity) { navController?.navigate( ContactsListFragmentDirections .actionContactsListFragmentToPublicKeyDetailsFragment(contactEntity) ) - } + }*/ - override fun onDeleteContact(contactEntity: ContactEntity) { + /*override fun onDeleteContact(contactEntity: ContactEntity) { contactsViewModel.deleteContact(contactEntity) Toast.makeText( context, getString(R.string.the_contact_was_deleted, contactEntity.email), Toast.LENGTH_SHORT ).show() - } + }*/ private fun initViews(root: View) { this.progressBar = root.findViewById(R.id.progressBar) @@ -113,7 +111,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet } private fun setupContactsViewModel() { - contactsViewModel.contactsWithPgpLiveData.observe(viewLifecycleOwner, Observer { + contactsViewModel.contactsWithPgpLiveData.observe(viewLifecycleOwner, { when (it.status) { Result.Status.LOADING -> { UIUtil.exchangeViewVisibility(true, progressBar, recyclerViewContacts) @@ -124,7 +122,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet if (it.data.isNullOrEmpty()) { UIUtil.exchangeViewVisibility(true, emptyView, recyclerViewContacts) } else { - contactsRecyclerViewAdapter.swap(it.data) + //contactsRecyclerViewAdapter.swap(it.data) UIUtil.exchangeViewVisibility(false, emptyView, recyclerViewContacts) } } @@ -138,4 +136,12 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet companion object { private const val REQUEST_CODE_START_IMPORT_PUB_KEY_ACTIVITY = 0 } + + override fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) { + TODO("Not yet implemented") + } + + override fun onDeleteContact(contactWithPubKeys: RecipientWithPubKeys) { + TODO("Not yet implemented") + } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index f2aede05d7..d23b782c35 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -296,7 +296,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, var keyOwner: String? = pgpKeyDetails.primaryPgpContact.email if (keyOwner != null) { - keyOwner = keyOwner.toLowerCase(Locale.getDefault()) + keyOwner = keyOwner.lowercase(Locale.getDefault()) if (emails.contains(keyOwner)) { return null @@ -304,11 +304,11 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, emails.add(keyOwner) - if (weakRef.get() != null) { + /*if (weakRef.get() != null) { val contact = FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) .contactsDao().getContactByEmail(keyOwner)?.toPgpContact() return PublicKeyInfo(fingerprint, keyOwner, contact, pgpKeyDetails.publicKey) - } + }*/ } return null } @@ -386,9 +386,9 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) .contactsDao().getContactByEmail(pgpContact.email) foundContactEntity?.let { entity -> - contacts.add( + /*contacts.add( pgpContact.toContactEntity().copy(id = entity.id) - ) + )*/ } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt index 413572608e..314ad7ea98 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt @@ -135,8 +135,8 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { private fun setupContactsViewModel() { contactEntity?.let { contactsViewModel.contactChangesLiveData(it).observe(viewLifecycleOwner, { contactEntity -> - this.contactEntity = contactEntity - parseKeysViewModel.fetchKeys(it.publicKey) + /*this.contactEntity = contactEntity + parseKeysViewModel.fetchKeys(it.publicKey)*/ }) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index 04a21a759b..71ece35998 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -432,7 +432,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, val contactEntity = data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) contactEntity?.let { - pgpContactWithNoPublicKey?.pubkey = String(contactEntity.publicKey ?: byteArrayOf()) + //pgpContactWithNoPublicKey?.pubkey = String(contactEntity.publicKey ?: byteArrayOf()) pgpContactWithNoPublicKey?.email?.let { email -> contactsViewModel.updateContactPgpInfo( email, diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/dialog/FixNeedPassphraseIssueDialogFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/dialog/FixNeedPassphraseIssueDialogFragment.kt index 58ae871d4b..f27aa2c0ed 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/dialog/FixNeedPassphraseIssueDialogFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/dialog/FixNeedPassphraseIssueDialogFragment.kt @@ -24,7 +24,6 @@ import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.gone import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.extensions.invisible -import com.flowcrypt.email.extensions.kotlin.uppercase import com.flowcrypt.email.extensions.navController import com.flowcrypt.email.extensions.toast import com.flowcrypt.email.extensions.visible diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt index 28d8f5724c..9adbff7f46 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt @@ -13,7 +13,7 @@ import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys /** * This adapter describes logic to prepare show contacts from the database. @@ -26,7 +26,7 @@ import com.flowcrypt.email.database.entity.ContactEntity class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boolean = true) : RecyclerView.Adapter() { - private val list: MutableList = mutableListOf() + private val list: MutableList = mutableListOf() var onDeleteContactListener: OnDeleteContactListener? = null var onContactClickListener: OnContactClickListener? = null @@ -41,14 +41,14 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } override fun onBindViewHolder(viewHolder: ContactsRecyclerViewAdapter.ViewHolder, position: Int) { - val contactEntity = list[position] + val contactWithPubKeys = list[position] - if (contactEntity.name.isNullOrEmpty()) { + if (contactWithPubKeys.contact.name.isNullOrEmpty()) { viewHolder.textViewName.visibility = View.GONE viewHolder.textViewEmail.visibility = View.GONE viewHolder.textViewOnlyEmail.visibility = View.VISIBLE - viewHolder.textViewOnlyEmail.text = contactEntity.email + viewHolder.textViewOnlyEmail.text = contactWithPubKeys.contact.email viewHolder.textViewEmail.text = null viewHolder.textViewName.text = null } else { @@ -56,22 +56,22 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole viewHolder.textViewEmail.visibility = View.VISIBLE viewHolder.textViewOnlyEmail.visibility = View.GONE - viewHolder.textViewEmail.text = contactEntity.email - viewHolder.textViewName.text = contactEntity.name + viewHolder.textViewEmail.text = contactWithPubKeys.contact.email + viewHolder.textViewName.text = contactWithPubKeys.contact.name viewHolder.textViewOnlyEmail.text = null } if (isDeleteEnabled) { viewHolder.imageButtonDeleteContact.visibility = View.VISIBLE viewHolder.imageButtonDeleteContact.setOnClickListener { - onDeleteContactListener?.onDeleteContact(contactEntity) + onDeleteContactListener?.onDeleteContact(contactWithPubKeys) } } else { viewHolder.imageButtonDeleteContact.visibility = View.GONE } viewHolder.itemView.setOnClickListener { - onContactClickListener?.onContactClick(contactEntity) + onContactClickListener?.onContactClick(contactWithPubKeys) } } @@ -79,7 +79,7 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole return list.size } - fun swap(newList: List) { + fun swap(newList: List) { val diffUtilCallback = DiffUtilCallback(this.list, newList) val productDiffResult = DiffUtil.calculateDiff(diffUtilCallback) @@ -89,11 +89,11 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } interface OnDeleteContactListener { - fun onDeleteContact(contactEntity: ContactEntity) + fun onDeleteContact(contactWithPubKeys: RecipientWithPubKeys) } interface OnContactClickListener { - fun onContactClick(contactEntity: ContactEntity) + fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) } /** @@ -107,13 +107,13 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } inner class DiffUtilCallback( - private val oldList: List, - private val newList: List + private val oldList: List, + private val newList: List ) : DiffUtil.Callback() { override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldList[oldItemPosition] val newItem = newList[newItemPosition] - return oldItem.fingerprint == newItem.fingerprint + return oldItem.publicKeys == newItem.publicKeys } override fun getOldListSize(): Int = oldList.size From ae23630c0f53b77bbfa482b737a95561c5719099 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 25 Oct 2021 12:45:55 +0300 Subject: [PATCH 02/38] Fixed using ContactsDao.getAllContactsWithPgpLD().| #1188 --- .../27.json | 997 ++++++++++++++++++ .../email/database/dao/ContactsDao.kt | 10 +- .../email/database/entity/PublicKeyEntity.kt | 1 - .../jetpack/viewmodel/ContactsViewModel.kt | 14 +- .../com/flowcrypt/email/model/PgpContact.kt | 9 + .../ui/activity/SelectContactsActivity.kt | 16 +- .../activity/fragment/ContactsListFragment.kt | 27 +- .../PreviewImportPgpContactFragment.kt | 9 +- .../ui/adapter/ContactsRecyclerViewAdapter.kt | 39 +- FlowCrypt/src/main/res/values/strings.xml | 1 + 10 files changed, 1060 insertions(+), 63 deletions(-) create mode 100644 FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json diff --git a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json new file mode 100644 index 0000000000..e506c24d8a --- /dev/null +++ b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json @@ -0,0 +1,997 @@ +{ + "formatVersion": 1, + "database": { + "version": 27, + "identityHash": "eaedc306ac21cf0fe3b68066c95d72e8", + "entities": [ + { + "tableName": "accounts_aliases", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `account_type` TEXT NOT NULL, `send_as_email` TEXT NOT NULL, `display_name` TEXT DEFAULT NULL, `is_default` INTEGER DEFAULT 0, `verification_status` TEXT NOT NULL, FOREIGN KEY(`email`, `account_type`) REFERENCES `accounts`(`email`, `account_type`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "sendAsEmail", + "columnName": "send_as_email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "display_name", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "isDefault", + "columnName": "is_default", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "verificationStatus", + "columnName": "verification_status", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "email_account_type_send_as_email_in_accounts_aliases", + "unique": true, + "columnNames": [ + "email", + "account_type", + "send_as_email" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_account_type_send_as_email_in_accounts_aliases` ON `${TABLE_NAME}` (`email`, `account_type`, `send_as_email`)" + } + ], + "foreignKeys": [ + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "email", + "account_type" + ], + "referencedColumns": [ + "email", + "account_type" + ] + } + ] + }, + { + "tableName": "accounts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `account_type` TEXT DEFAULT NULL, `display_name` TEXT DEFAULT NULL, `given_name` TEXT DEFAULT NULL, `family_name` TEXT DEFAULT NULL, `photo_url` TEXT DEFAULT NULL, `is_enabled` INTEGER DEFAULT 1, `is_active` INTEGER DEFAULT 0, `username` TEXT NOT NULL, `password` TEXT NOT NULL, `imap_server` TEXT NOT NULL, `imap_port` INTEGER DEFAULT 143, `imap_use_ssl_tls` INTEGER DEFAULT 0, `imap_use_starttls` INTEGER DEFAULT 0, `imap_auth_mechanisms` TEXT, `smtp_server` TEXT NOT NULL, `smtp_port` INTEGER DEFAULT 25, `smtp_use_ssl_tls` INTEGER DEFAULT 0, `smtp_use_starttls` INTEGER DEFAULT 0, `smtp_auth_mechanisms` TEXT, `smtp_use_custom_sign` INTEGER DEFAULT 0, `smtp_username` TEXT DEFAULT NULL, `smtp_password` TEXT DEFAULT NULL, `contacts_loaded` INTEGER DEFAULT 0, `show_only_encrypted` INTEGER DEFAULT 0, `uuid` TEXT DEFAULT NULL, `client_configuration` TEXT DEFAULT NULL, `use_api` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "displayName", + "columnName": "display_name", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "givenName", + "columnName": "given_name", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "familyName", + "columnName": "family_name", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "photoUrl", + "columnName": "photo_url", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "isEnabled", + "columnName": "is_enabled", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "1" + }, + { + "fieldPath": "isActive", + "columnName": "is_active", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imapServer", + "columnName": "imap_server", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "imapPort", + "columnName": "imap_port", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "143" + }, + { + "fieldPath": "imapUseSslTls", + "columnName": "imap_use_ssl_tls", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "imapUseStarttls", + "columnName": "imap_use_starttls", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "imapAuthMechanisms", + "columnName": "imap_auth_mechanisms", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "smtpServer", + "columnName": "smtp_server", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "smtpPort", + "columnName": "smtp_port", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "25" + }, + { + "fieldPath": "smtpUseSslTls", + "columnName": "smtp_use_ssl_tls", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "smtpUseStarttls", + "columnName": "smtp_use_starttls", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "smtpAuthMechanisms", + "columnName": "smtp_auth_mechanisms", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "smtpUseCustomSign", + "columnName": "smtp_use_custom_sign", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "smtpUsername", + "columnName": "smtp_username", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "smtpPassword", + "columnName": "smtp_password", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "contactsLoaded", + "columnName": "contacts_loaded", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "showOnlyEncrypted", + "columnName": "show_only_encrypted", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "uuid", + "columnName": "uuid", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "clientConfiguration", + "columnName": "client_configuration", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "useAPI", + "columnName": "use_api", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "email_account_type_in_accounts", + "unique": true, + "columnNames": [ + "email", + "account_type" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_account_type_in_accounts` ON `${TABLE_NAME}` (`email`, `account_type`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "action_queue", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `action_type` TEXT NOT NULL, `action_json` TEXT NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actionType", + "columnName": "action_type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actionJson", + "columnName": "action_json", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [], + "foreignKeys": [] + }, + { + "tableName": "attachment", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `folder` TEXT NOT NULL, `uid` INTEGER NOT NULL, `name` TEXT NOT NULL, `encodedSize` INTEGER DEFAULT 0, `type` TEXT NOT NULL, `attachment_id` TEXT, `file_uri` TEXT, `forwarded_folder` TEXT, `forwarded_uid` INTEGER DEFAULT -1, `path` TEXT NOT NULL, FOREIGN KEY(`email`, `folder`, `uid`) REFERENCES `messages`(`email`, `folder`, `uid`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "folder", + "columnName": "folder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "encodedSize", + "columnName": "encodedSize", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "attachmentId", + "columnName": "attachment_id", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "fileUri", + "columnName": "file_uri", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "forwardedFolder", + "columnName": "forwarded_folder", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "forwardedUid", + "columnName": "forwarded_uid", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "-1" + }, + { + "fieldPath": "path", + "columnName": "path", + "affinity": "TEXT", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "email_uid_folder_path_in_attachment", + "unique": true, + "columnNames": [ + "email", + "uid", + "folder", + "path" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_uid_folder_path_in_attachment` ON `${TABLE_NAME}` (`email`, `uid`, `folder`, `path`)" + }, + { + "name": "email_folder_uid_in_attachment", + "unique": false, + "columnNames": [ + "email", + "folder", + "uid" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `email_folder_uid_in_attachment` ON `${TABLE_NAME}` (`email`, `folder`, `uid`)" + } + ], + "foreignKeys": [ + { + "table": "messages", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "email", + "folder", + "uid" + ], + "referencedColumns": [ + "email", + "folder", + "uid" + ] + } + ] + }, + { + "tableName": "contacts", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `name` TEXT DEFAULT NULL, `last_use` INTEGER NOT NULL DEFAULT 0)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "lastUse", + "columnName": "last_use", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "name_in_contacts", + "unique": false, + "columnNames": [ + "name" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `name_in_contacts` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "last_use_in_contacts", + "unique": false, + "columnNames": [ + "last_use" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `last_use_in_contacts` ON `${TABLE_NAME}` (`last_use`)" + }, + { + "name": "email_in_contacts", + "unique": true, + "columnNames": [ + "email" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_in_contacts` ON `${TABLE_NAME}` (`email`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "keys", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `fingerprint` TEXT NOT NULL, `account` TEXT NOT NULL, `account_type` TEXT DEFAULT NULL, `source` TEXT NOT NULL, `public_key` BLOB NOT NULL, `private_key` BLOB NOT NULL, `passphrase` TEXT DEFAULT NULL, `passphrase_type` INTEGER NOT NULL DEFAULT 0, FOREIGN KEY(`account`, `account_type`) REFERENCES `accounts`(`email`, `account_type`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "fingerprint", + "columnName": "fingerprint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "account", + "columnName": "account", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "source", + "columnName": "source", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "publicKey", + "columnName": "public_key", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "privateKey", + "columnName": "private_key", + "affinity": "BLOB", + "notNull": true + }, + { + "fieldPath": "storedPassphrase", + "columnName": "passphrase", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "passphraseType", + "columnName": "passphrase_type", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "fingerprint_account_account_type_in_keys", + "unique": true, + "columnNames": [ + "fingerprint", + "account", + "account_type" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `fingerprint_account_account_type_in_keys` ON `${TABLE_NAME}` (`fingerprint`, `account`, `account_type`)" + } + ], + "foreignKeys": [ + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "account", + "account_type" + ], + "referencedColumns": [ + "email", + "account_type" + ] + } + ] + }, + { + "tableName": "labels", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `account_type` TEXT DEFAULT NULL, `name` TEXT NOT NULL, `alias` TEXT DEFAULT NULL, `is_custom` INTEGER NOT NULL DEFAULT 0, `messages_total` INTEGER NOT NULL DEFAULT 0, `message_unread` INTEGER NOT NULL DEFAULT 0, `attributes` TEXT DEFAULT NULL, `next_page_token` TEXT DEFAULT NULL, `history_id` TEXT DEFAULT NULL, FOREIGN KEY(`email`, `account_type`) REFERENCES `accounts`(`email`, `account_type`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountType", + "columnName": "account_type", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "alias", + "columnName": "alias", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "isCustom", + "columnName": "is_custom", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "messagesTotal", + "columnName": "messages_total", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "messagesUnread", + "columnName": "message_unread", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "fieldPath": "attributes", + "columnName": "attributes", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "nextPageToken", + "columnName": "next_page_token", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "historyId", + "columnName": "history_id", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "email_account_type_name_in_labels", + "unique": true, + "columnNames": [ + "email", + "account_type", + "name" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_account_type_name_in_labels` ON `${TABLE_NAME}` (`email`, `account_type`, `name`)" + } + ], + "foreignKeys": [ + { + "table": "accounts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "email", + "account_type" + ], + "referencedColumns": [ + "email", + "account_type" + ] + } + ] + }, + { + "tableName": "messages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `folder` TEXT NOT NULL, `uid` INTEGER NOT NULL, `received_date` INTEGER DEFAULT NULL, `sent_date` INTEGER DEFAULT NULL, `from_address` TEXT DEFAULT NULL, `to_address` TEXT DEFAULT NULL, `cc_address` TEXT DEFAULT NULL, `subject` TEXT DEFAULT NULL, `flags` TEXT DEFAULT NULL, `raw_message_without_attachments` TEXT DEFAULT NULL, `is_message_has_attachments` INTEGER DEFAULT 0, `is_encrypted` INTEGER DEFAULT -1, `is_new` INTEGER DEFAULT -1, `state` INTEGER DEFAULT -1, `attachments_directory` TEXT, `error_msg` TEXT DEFAULT NULL, `reply_to` TEXT DEFAULT NULL, `thread_id` TEXT DEFAULT NULL, `history_id` TEXT DEFAULT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "email", + "columnName": "email", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "folder", + "columnName": "folder", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "uid", + "columnName": "uid", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "receivedDate", + "columnName": "received_date", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "sentDate", + "columnName": "sent_date", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "fromAddress", + "columnName": "from_address", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "toAddress", + "columnName": "to_address", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "ccAddress", + "columnName": "cc_address", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "subject", + "columnName": "subject", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "flags", + "columnName": "flags", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "rawMessageWithoutAttachments", + "columnName": "raw_message_without_attachments", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "hasAttachments", + "columnName": "is_message_has_attachments", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "0" + }, + { + "fieldPath": "isEncrypted", + "columnName": "is_encrypted", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "-1" + }, + { + "fieldPath": "isNew", + "columnName": "is_new", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "-1" + }, + { + "fieldPath": "state", + "columnName": "state", + "affinity": "INTEGER", + "notNull": false, + "defaultValue": "-1" + }, + { + "fieldPath": "attachmentsDirectory", + "columnName": "attachments_directory", + "affinity": "TEXT", + "notNull": false + }, + { + "fieldPath": "errorMsg", + "columnName": "error_msg", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "replyTo", + "columnName": "reply_to", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "threadId", + "columnName": "thread_id", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + }, + { + "fieldPath": "historyId", + "columnName": "history_id", + "affinity": "TEXT", + "notNull": false, + "defaultValue": "NULL" + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "email_in_messages", + "unique": false, + "columnNames": [ + "email" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `email_in_messages` ON `${TABLE_NAME}` (`email`)" + }, + { + "name": "email_uid_folder_in_messages", + "unique": true, + "columnNames": [ + "email", + "uid", + "folder" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_uid_folder_in_messages` ON `${TABLE_NAME}` (`email`, `uid`, `folder`)" + } + ], + "foreignKeys": [] + }, + { + "tableName": "public_keys", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `recipient` TEXT NOT NULL, `fingerprint` TEXT NOT NULL, `public_key` BLOB NOT NULL, FOREIGN KEY(`recipient`) REFERENCES `contacts`(`email`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "_id", + "affinity": "INTEGER", + "notNull": false + }, + { + "fieldPath": "recipient", + "columnName": "recipient", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "fingerprint", + "columnName": "fingerprint", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "publicKey", + "columnName": "public_key", + "affinity": "BLOB", + "notNull": true + } + ], + "primaryKey": { + "columnNames": [ + "_id" + ], + "autoGenerate": true + }, + "indices": [ + { + "name": "recipient_fingerprint_in_public_keys", + "unique": true, + "columnNames": [ + "recipient", + "fingerprint" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `recipient_fingerprint_in_public_keys` ON `${TABLE_NAME}` (`recipient`, `fingerprint`)" + }, + { + "name": "fingerprint_in_public_keys", + "unique": false, + "columnNames": [ + "fingerprint" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `fingerprint_in_public_keys` ON `${TABLE_NAME}` (`fingerprint`)" + } + ], + "foreignKeys": [ + { + "table": "contacts", + "onDelete": "CASCADE", + "onUpdate": "NO ACTION", + "columns": [ + "recipient" + ], + "referencedColumns": [ + "email" + ] + } + ] + } + ], + "views": [], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'eaedc306ac21cf0fe3b68066c95d72e8')" + ] + } +} \ No newline at end of file diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt index be0d4a5255..5792f3e775 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt @@ -9,9 +9,7 @@ import android.database.Cursor import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Query -import androidx.room.Transaction import com.flowcrypt.email.database.entity.ContactEntity -import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys /** * This object describes a logic of work with [ContactEntity]. @@ -31,12 +29,8 @@ interface ContactsDao : BaseDao { @Query("SELECT * FROM contacts") fun getAllContactsLD(): LiveData> - @Transaction - @Query("SELECT * FROM contacts WHERE email IN (SELECT recipient FROM public_keys GROUP BY recipient)") - fun getAllContactsWithPgpLD1(): LiveData> - - @Query("SELECT * FROM contacts") - //@Query("SELECT * FROM contacts WHERE has_pgp = 1") + //fixed + @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") fun getAllContactsWithPgpLD(): LiveData> @Query("SELECT * FROM contacts") diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt index 7fc421a9ff..ede6790155 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt @@ -56,7 +56,6 @@ class PublicKeyEntity( requireNotNull(parcel.createByteArray()) ) - override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeValue(id) parcel.writeString(recipient) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index 82aeaaf76f..99bdd11525 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -6,11 +6,14 @@ package com.flowcrypt.email.jetpack.viewmodel import android.app.Application +import android.content.Context +import android.widget.Toast import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import androidx.lifecycle.Transformations import androidx.lifecycle.liveData import androidx.lifecycle.viewModelScope +import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.ApiRepository import com.flowcrypt.email.api.retrofit.FlowcryptApiRepository import com.flowcrypt.email.api.retrofit.response.attester.PubResponse @@ -241,7 +244,16 @@ class ContactsViewModel(application: Application) : AccountViewModel(application viewModelScope.launch { val contact = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) if (contact == null) { - roomDatabase.contactsDao().insertSuspend(pgpContact.toContactEntity()) + val isInserted = roomDatabase.contactsDao().insertSuspend(pgpContact.toContactEntity()) > 0 + if (isInserted) { + roomDatabase.pubKeysDao().insertSuspend(pgpContact.toPubKey()) + } else { + val context: Context = getApplication() + Toast.makeText( + context, + context.getString(R.string.could_not_save_new_recipient), Toast.LENGTH_LONG + ).show() + } } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt index da20a2fc9e..7117eb9c50 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt @@ -8,6 +8,7 @@ package com.flowcrypt.email.model import android.os.Parcel import android.os.Parcelable import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.PublicKeyEntity import com.flowcrypt.email.security.model.PgpKeyDetails import java.util.ArrayList import javax.mail.internet.AddressException @@ -66,6 +67,14 @@ data class PgpContact constructor( ) } + fun toPubKey(): PublicKeyEntity { + return PublicKeyEntity( + recipient = email, + fingerprint = fingerprint!!, + publicKey = pubkey!!.toByteArray() + ) + } + companion object { @JvmField val CREATOR: Parcelable.Creator = object : Parcelable.Creator { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index 761021b377..4523aba626 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -5,6 +5,7 @@ package com.flowcrypt.email.ui.activity +import android.app.Activity import android.content.Context import android.content.Intent import android.os.Bundle @@ -22,7 +23,6 @@ import androidx.test.espresso.idling.CountingIdlingResource import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.ContactEntity -import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel @@ -41,7 +41,7 @@ import com.flowcrypt.email.util.UIUtil * E-mail: DenBond7@gmail.com */ class SelectContactsActivity : BaseBackStackActivity(), - ContactsRecyclerViewAdapter.OnContactClickListener, SearchView.OnQueryTextListener { + ContactsRecyclerViewAdapter.OnContactActionsListener, SearchView.OnQueryTextListener { private var progressBar: View? = null private var recyclerViewContacts: RecyclerView? = null @@ -65,7 +65,7 @@ class SelectContactsActivity : BaseBackStackActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - contactsRecyclerViewAdapter.onContactClickListener = this + contactsRecyclerViewAdapter.onContactActionsListener = this //todo-denbond7 need to fix this in the future. Not urgent //val isMultiply = intent.getBooleanExtra(KEY_EXTRA_IS_MULTIPLY, false) @@ -108,12 +108,14 @@ class SelectContactsActivity : BaseBackStackActivity(), return super.onPrepareOptionsMenu(menu) } - /*override fun onContactClick(contactEntity: ContactEntity) { + override fun onContactClick(contactEntity: ContactEntity) { val intent = Intent() intent.putExtra(KEY_EXTRA_PGP_CONTACT, contactEntity) setResult(Activity.RESULT_OK, intent) finish() - }*/ + } + + override fun onDeleteContact(contactEntity: ContactEntity) {} override fun onQueryTextSubmit(query: String): Boolean { searchPattern = query @@ -180,8 +182,4 @@ class SelectContactsActivity : BaseBackStackActivity(), return intent } } - - override fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) { - TODO("Not yet implemented") - } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt index fe21baad1f..a40889a5f5 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt @@ -17,7 +17,8 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result -import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys +import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.extensions.navController import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.ui.activity.ImportPgpContactActivity import com.flowcrypt.email.ui.activity.fragment.base.BaseFragment @@ -32,8 +33,7 @@ import com.flowcrypt.email.util.UIUtil * Time: 6:11 PM * E-mail: DenBond7@gmail.com */ -class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDeleteContactListener, - ContactsRecyclerViewAdapter.OnContactClickListener { +class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnContactActionsListener { private var progressBar: View? = null private var recyclerViewContacts: RecyclerView? = null @@ -46,8 +46,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - contactsRecyclerViewAdapter.onDeleteContactListener = this - contactsRecyclerViewAdapter.onContactClickListener = this + contactsRecyclerViewAdapter.onContactActionsListener = this } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -71,20 +70,20 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet } } - /*override fun onContactClick(contactEntity: ContactEntity) { + override fun onContactClick(contactEntity: ContactEntity) { navController?.navigate( ContactsListFragmentDirections .actionContactsListFragmentToPublicKeyDetailsFragment(contactEntity) ) - }*/ + } - /*override fun onDeleteContact(contactEntity: ContactEntity) { + override fun onDeleteContact(contactEntity: ContactEntity) { contactsViewModel.deleteContact(contactEntity) Toast.makeText( context, getString(R.string.the_contact_was_deleted, contactEntity.email), Toast.LENGTH_SHORT ).show() - }*/ + } private fun initViews(root: View) { this.progressBar = root.findViewById(R.id.progressBar) @@ -122,7 +121,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet if (it.data.isNullOrEmpty()) { UIUtil.exchangeViewVisibility(true, emptyView, recyclerViewContacts) } else { - //contactsRecyclerViewAdapter.swap(it.data) + contactsRecyclerViewAdapter.swap(it.data) UIUtil.exchangeViewVisibility(false, emptyView, recyclerViewContacts) } } @@ -136,12 +135,4 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnDelet companion object { private const val REQUEST_CODE_START_IMPORT_PUB_KEY_ACTIVITY = 0 } - - override fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) { - TODO("Not yet implemented") - } - - override fun onDeleteContact(contactWithPubKeys: RecipientWithPubKeys) { - TODO("Not yet implemented") - } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index d23b782c35..7d382ca051 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -304,11 +304,12 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, emails.add(keyOwner) - /*if (weakRef.get() != null) { - val contact = FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .contactsDao().getContactByEmail(keyOwner)?.toPgpContact() + if (weakRef.get() != null) { + //todo-denbond7 fix me + val contact = null/*FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) + .contactsDao().getContactByEmail(keyOwner)?.toPgpContact()*/ return PublicKeyInfo(fingerprint, keyOwner, contact, pgpKeyDetails.publicKey) - }*/ + } } return null } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt index 9adbff7f46..9241947235 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt @@ -13,7 +13,7 @@ import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R -import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys +import com.flowcrypt.email.database.entity.ContactEntity /** * This adapter describes logic to prepare show contacts from the database. @@ -26,10 +26,8 @@ import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boolean = true) : RecyclerView.Adapter() { - private val list: MutableList = mutableListOf() - var onDeleteContactListener: OnDeleteContactListener? = null - var onContactClickListener: OnContactClickListener? = null - + private val list: MutableList = mutableListOf() + var onContactActionsListener: OnContactActionsListener? = null override fun onCreateViewHolder( parent: ViewGroup, @@ -41,14 +39,14 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } override fun onBindViewHolder(viewHolder: ContactsRecyclerViewAdapter.ViewHolder, position: Int) { - val contactWithPubKeys = list[position] + val contactEntity = list[position] - if (contactWithPubKeys.contact.name.isNullOrEmpty()) { + if (contactEntity.name.isNullOrEmpty()) { viewHolder.textViewName.visibility = View.GONE viewHolder.textViewEmail.visibility = View.GONE viewHolder.textViewOnlyEmail.visibility = View.VISIBLE - viewHolder.textViewOnlyEmail.text = contactWithPubKeys.contact.email + viewHolder.textViewOnlyEmail.text = contactEntity.email viewHolder.textViewEmail.text = null viewHolder.textViewName.text = null } else { @@ -56,22 +54,22 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole viewHolder.textViewEmail.visibility = View.VISIBLE viewHolder.textViewOnlyEmail.visibility = View.GONE - viewHolder.textViewEmail.text = contactWithPubKeys.contact.email - viewHolder.textViewName.text = contactWithPubKeys.contact.name + viewHolder.textViewEmail.text = contactEntity.email + viewHolder.textViewName.text = contactEntity.name viewHolder.textViewOnlyEmail.text = null } if (isDeleteEnabled) { viewHolder.imageButtonDeleteContact.visibility = View.VISIBLE viewHolder.imageButtonDeleteContact.setOnClickListener { - onDeleteContactListener?.onDeleteContact(contactWithPubKeys) + onContactActionsListener?.onDeleteContact(contactEntity) } } else { viewHolder.imageButtonDeleteContact.visibility = View.GONE } viewHolder.itemView.setOnClickListener { - onContactClickListener?.onContactClick(contactWithPubKeys) + onContactActionsListener?.onContactClick(contactEntity) } } @@ -79,7 +77,7 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole return list.size } - fun swap(newList: List) { + fun swap(newList: List) { val diffUtilCallback = DiffUtilCallback(this.list, newList) val productDiffResult = DiffUtil.calculateDiff(diffUtilCallback) @@ -88,12 +86,9 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole productDiffResult.dispatchUpdatesTo(this) } - interface OnDeleteContactListener { - fun onDeleteContact(contactWithPubKeys: RecipientWithPubKeys) - } - - interface OnContactClickListener { - fun onContactClick(contactWithPubKeys: RecipientWithPubKeys) + interface OnContactActionsListener { + fun onDeleteContact(contactEntity: ContactEntity) + fun onContactClick(contactEntity: ContactEntity) } /** @@ -107,13 +102,13 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } inner class DiffUtilCallback( - private val oldList: List, - private val newList: List + private val oldList: List, + private val newList: List ) : DiffUtil.Callback() { override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldList[oldItemPosition] val newItem = newList[newItemPosition] - return oldItem.publicKeys == newItem.publicKeys + return oldItem.email == newItem.email } override fun getOldListSize(): Int = oldList.size diff --git a/FlowCrypt/src/main/res/values/strings.xml b/FlowCrypt/src/main/res/values/strings.xml index 8f3812524c..ca124420da 100644 --- a/FlowCrypt/src/main/res/values/strings.xml +++ b/FlowCrypt/src/main/res/values/strings.xml @@ -535,4 +535,5 @@ Security threat!\n\nMessage is missing integrity checks (MDC). The sender should update their outdated software.\n\nDisplay the message at your own risk. This message contained a Public Key that was not valid.\n\n%1$s This message contained a block with type = %1$s that was not valid.\n\n%2$s + Couldn\'t save a new recipient From 77c885570bdad3bfcd82c5e75d2dda5f6b317715 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 13:09:38 +0300 Subject: [PATCH 03/38] Fixed using ContactsDao.getAllContactsWithPgp()/getAllContactsWithPgpWhichMatched().| #1188 --- .../email/database/dao/ContactsDao.kt | 8 ++++---- .../email/database/entity/PublicKeyEntity.kt | 2 +- .../jetpack/viewmodel/ContactsViewModel.kt | 19 ++++++++----------- .../email/ui/activity/EditContactActivity.kt | 2 +- .../ui/activity/ImportPublicKeyActivity.kt | 2 +- .../ui/activity/SelectContactsActivity.kt | 2 +- .../fragment/base/CreateMessageFragment.kt | 3 +-- 7 files changed, 17 insertions(+), 21 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt index 5792f3e775..89b9f1b920 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt @@ -33,12 +33,12 @@ interface ContactsDao : BaseDao { @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") fun getAllContactsWithPgpLD(): LiveData> - @Query("SELECT * FROM contacts") - //@Query("SELECT * FROM contacts WHERE has_pgp = 1") + //fixed + @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") suspend fun getAllContactsWithPgp(): List - @Query("SELECT * FROM contacts WHERE (email LIKE :searchPattern OR name LIKE :searchPattern)") - //@Query("SELECT * FROM contacts WHERE has_pgp = 1 AND (email LIKE :searchPattern OR name LIKE :searchPattern)") + //fixed + @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient WHERE (email LIKE :searchPattern OR name LIKE :searchPattern) GROUP BY contacts.email ORDER BY contacts._id") suspend fun getAllContactsWithPgpWhichMatched(searchPattern: String): List @Query("SELECT * FROM contacts WHERE email = :email") diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt index ede6790155..2f18932c1a 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt @@ -43,7 +43,7 @@ import androidx.room.PrimaryKey ) ] ) -class PublicKeyEntity( +data class PublicKeyEntity( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = BaseColumns._ID) val id: Long? = null, @ColumnInfo(name = "recipient") val recipient: String, @ColumnInfo(name = "fingerprint") val fingerprint: String, diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index 99bdd11525..9788b531ca 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -72,7 +72,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application val pubKeysFromServerLiveData: MutableLiveData> = MutableLiveData() - fun updateContactPgpInfo(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { + fun copyPubKeysToRecipient(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { viewModelScope.launch { val contact = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) if (contact != null) { @@ -90,16 +90,13 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } } - fun updateContactPgpInfo(email: String, contactEntity: ContactEntity) { + fun copyPubKeysToRecipient(email: String, contactEntity: ContactEntity) { viewModelScope.launch { - val originalContactEntity = roomDatabase.contactsDao().getContactByEmailSuspend(email) - ?: return@launch - roomDatabase.contactsDao().updateSuspend( - originalContactEntity.copy( - /*publicKey = contactEntity.publicKey, - fingerprint = contactEntity.fingerprint, - hasPgp = true*/ - ) + val pubKeysOfCopyCandidate = + roomDatabase.pubKeysDao().getPublicKeysByRecipient(contactEntity.email) + if (pubKeysOfCopyCandidate.isEmpty()) return@launch + roomDatabase.pubKeysDao().insertSuspend( + pubKeysOfCopyCandidate.map { it.copy(id = null, recipient = email) } ) } } @@ -268,7 +265,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } } - fun updateContactPgpInfo(contactEntity: ContactEntity?, pgpKeyDetails: PgpKeyDetails) { + fun copyPubKeysToRecipient(contactEntity: ContactEntity?, pgpKeyDetails: PgpKeyDetails) { viewModelScope.launch { contactEntity?.let { val contactEntityFromPrimaryPgpContact = pgpKeyDetails.primaryPgpContact.toContactEntity() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt index 89f7df6dba..64cdb2c6f1 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt @@ -96,7 +96,7 @@ class EditContactActivity : BaseImportKeyActivity(), } override fun onKeySelected(pgpKeyDetails: PgpKeyDetails) { - contactsViewModel.updateContactPgpInfo(contactEntity, pgpKeyDetails) + contactsViewModel.copyPubKeysToRecipient(contactEntity, pgpKeyDetails) finish() } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt index fc91497fef..5db23edc5e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt @@ -82,7 +82,7 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { val pgpContactFromKey = keyDetails.primaryPgpContact pgpContact?.pubkey = pgpContactFromKey.pubkey pgpContact?.hasPgp = pgpContact?.pubkey?.isNotEmpty() == true - pgpContact?.let { contactsViewModel.updateContactPgpInfo(it, pgpContactFromKey) } + pgpContact?.let { contactsViewModel.copyPubKeysToRecipient(it, pgpContactFromKey) } } companion object { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index 4523aba626..ec10cf5372 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -146,7 +146,7 @@ class SelectContactsActivity : BaseBackStackActivity(), if (it.data.isNullOrEmpty()) { UIUtil.exchangeViewVisibility(true, emptyView, recyclerViewContacts) } else { - //contactsRecyclerViewAdapter.swap(it.data) + contactsRecyclerViewAdapter.swap(it.data) UIUtil.exchangeViewVisibility(false, emptyView, recyclerViewContacts) } countingIdlingResourceForFilter.decrementSafely() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index 71ece35998..f9ee141932 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -432,9 +432,8 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, val contactEntity = data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) contactEntity?.let { - //pgpContactWithNoPublicKey?.pubkey = String(contactEntity.publicKey ?: byteArrayOf()) pgpContactWithNoPublicKey?.email?.let { email -> - contactsViewModel.updateContactPgpInfo( + contactsViewModel.copyPubKeysToRecipient( email, contactEntity ) From faa2e23465ff769db5d9a76bbc679db490eca810 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 13:47:12 +0300 Subject: [PATCH 04/38] Renamed ContactEntity to RecipientEntity.| #1188 --- .../email/database/FlowCryptRoomDatabase.kt | 4 +- .../email/database/dao/ContactsDao.kt | 24 ++++---- .../email/database/entity/PublicKeyEntity.kt | 2 +- .../{ContactEntity.kt => RecipientEntity.kt} | 8 +-- .../entity/relation/RecipientWithPubKeys.kt | 8 +-- .../jetpack/viewmodel/ContactsViewModel.kt | 58 +++++++++---------- .../workmanager/sync/LoadContactsWorker.kt | 10 ++-- .../com/flowcrypt/email/model/PgpContact.kt | 6 +- .../flowcrypt/email/model/PublicKeyInfo.kt | 6 +- .../email/ui/activity/EditContactActivity.kt | 18 +++--- .../ui/activity/SelectContactsActivity.kt | 10 ++-- .../activity/fragment/ContactsListFragment.kt | 12 ++-- .../PreviewImportPgpContactFragment.kt | 4 +- .../fragment/PublicKeyDetailsFragment.kt | 14 ++--- .../fragment/base/CreateMessageFragment.kt | 38 ++++++------ .../ui/adapter/ContactsRecyclerViewAdapter.kt | 14 ++--- 16 files changed, 118 insertions(+), 118 deletions(-) rename FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/{ContactEntity.kt => RecipientEntity.kt} (88%) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt index aefbaf0325..df0340e992 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt @@ -31,11 +31,11 @@ import com.flowcrypt.email.database.entity.AccountAliasesEntity import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.ActionQueueEntity import com.flowcrypt.email.database.entity.AttachmentEntity -import com.flowcrypt.email.database.entity.ContactEntity import com.flowcrypt.email.database.entity.KeyEntity import com.flowcrypt.email.database.entity.LabelEntity import com.flowcrypt.email.database.entity.MessageEntity import com.flowcrypt.email.database.entity.PublicKeyEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.security.pgp.PgpKey import org.pgpainless.key.OpenPgpV4Fingerprint @@ -55,7 +55,7 @@ import org.pgpainless.key.OpenPgpV4Fingerprint AccountEntity::class, ActionQueueEntity::class, AttachmentEntity::class, - ContactEntity::class, + RecipientEntity::class, KeyEntity::class, LabelEntity::class, MessageEntity::class, diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt index 89b9f1b920..c0caf57714 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt @@ -9,10 +9,10 @@ import android.database.Cursor import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Query -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity /** - * This object describes a logic of work with [ContactEntity]. + * This object describes a logic of work with [RecipientEntity]. * * @author DenBond7 * Date: 17.05.2017 @@ -20,38 +20,38 @@ import com.flowcrypt.email.database.entity.ContactEntity * E-mail: DenBond7@gmail.com */ @Dao -interface ContactsDao : BaseDao { +interface ContactsDao : BaseDao { //fixed @Query("SELECT * FROM contacts") - suspend fun getAllContacts(): List + suspend fun getAllContacts(): List //fixed @Query("SELECT * FROM contacts") - fun getAllContactsLD(): LiveData> + fun getAllContactsLD(): LiveData> //fixed @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") - fun getAllContactsWithPgpLD(): LiveData> + fun getAllContactsWithPgpLD(): LiveData> //fixed @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") - suspend fun getAllContactsWithPgp(): List + suspend fun getAllContactsWithPgp(): List //fixed @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient WHERE (email LIKE :searchPattern OR name LIKE :searchPattern) GROUP BY contacts.email ORDER BY contacts._id") - suspend fun getAllContactsWithPgpWhichMatched(searchPattern: String): List + suspend fun getAllContactsWithPgpWhichMatched(searchPattern: String): List @Query("SELECT * FROM contacts WHERE email = :email") - suspend fun getContactByEmailSuspend(email: String): ContactEntity? + suspend fun getContactByEmailSuspend(email: String): RecipientEntity? @Query("SELECT * FROM contacts WHERE email = :email") - fun getContactByEmail(email: String): ContactEntity? + fun getContactByEmail(email: String): RecipientEntity? @Query("SELECT * FROM contacts WHERE email = :email") - fun getContactByEmailLD(email: String): LiveData + fun getContactByEmailLD(email: String): LiveData @Query("SELECT * FROM contacts WHERE email IN (:emails)") - fun getContactsByEmails(emails: Collection): List + fun getContactsByEmails(emails: Collection): List @Query("SELECT * FROM contacts WHERE email LIKE :searchPattern ORDER BY last_use DESC") fun getFilteredCursor(searchPattern: String): Cursor? diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt index 2f18932c1a..9ca55aa7ae 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt @@ -36,7 +36,7 @@ import androidx.room.PrimaryKey ], foreignKeys = [ ForeignKey( - entity = ContactEntity::class, + entity = RecipientEntity::class, parentColumns = ["email"], childColumns = ["recipient"], onDelete = ForeignKey.CASCADE diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt similarity index 88% rename from FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt rename to FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt index 9dcc19a2fe..1c3cef8560 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/ContactEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt @@ -30,7 +30,7 @@ import com.flowcrypt.email.security.model.PgpKeyDetails Index(name = "email_in_contacts", value = ["email"], unique = true) ] ) -data class ContactEntity( +data class RecipientEntity( @PrimaryKey(autoGenerate = true) @ColumnInfo(name = BaseColumns._ID) val id: Long? = null, val email: String, @ColumnInfo(defaultValue = "NULL") val name: String? = null, @@ -75,8 +75,8 @@ data class ContactEntity( return 0 } - companion object CREATOR : Parcelable.Creator { - override fun createFromParcel(parcel: Parcel): ContactEntity = ContactEntity(parcel) - override fun newArray(size: Int): Array = arrayOfNulls(size) + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): RecipientEntity = RecipientEntity(parcel) + override fun newArray(size: Int): Array = arrayOfNulls(size) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt index b0ecf5a914..18a7d6137d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt @@ -9,8 +9,8 @@ import android.os.Parcel import android.os.Parcelable import androidx.room.Embedded import androidx.room.Relation -import com.flowcrypt.email.database.entity.ContactEntity import com.flowcrypt.email.database.entity.PublicKeyEntity +import com.flowcrypt.email.database.entity.RecipientEntity /** * @author Denis Bondarenko @@ -19,7 +19,7 @@ import com.flowcrypt.email.database.entity.PublicKeyEntity * E-mail: DenBond7@gmail.com */ data class RecipientWithPubKeys( - @Embedded val contact: ContactEntity, + @Embedded val recipient: RecipientEntity, @Relation( parentColumn = "email", entityColumn = "recipient", @@ -29,12 +29,12 @@ data class RecipientWithPubKeys( val publicKeys: List ) : Parcelable { constructor(parcel: Parcel) : this( - requireNotNull(parcel.readParcelable(ContactEntity::class.java.classLoader)), + requireNotNull(parcel.readParcelable(RecipientEntity::class.java.classLoader)), requireNotNull(parcel.createTypedArrayList(PublicKeyEntity)) ) override fun writeToParcel(parcel: Parcel, flags: Int) { - parcel.writeParcelable(contact, flags) + parcel.writeParcelable(recipient, flags) parcel.writeTypedList(publicKeys) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index 9788b531ca..f35cdc8ad8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -19,7 +19,7 @@ import com.flowcrypt.email.api.retrofit.FlowcryptApiRepository import com.flowcrypt.email.api.retrofit.response.attester.PubResponse import com.flowcrypt.email.api.retrofit.response.base.ApiError import com.flowcrypt.email.api.retrofit.response.base.Result -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.security.pgp.PgpKey @@ -46,15 +46,15 @@ class ContactsViewModel(application: Application) : AccountViewModel(application private val apiRepository: ApiRepository = FlowcryptApiRepository() private val searchPatternLiveData: MutableLiveData = MutableLiveData() - val allContactsLiveData: LiveData> = + val allContactsLiveData: LiveData> = roomDatabase.contactsDao().getAllContactsLD() - val contactsWithPgpLiveData: LiveData>> = + val contactsWithPgpLiveData: LiveData>> = Transformations.switchMap(roomDatabase.contactsDao().getAllContactsWithPgpLD()) { liveData { emit(Result.success(it)) } } - val contactsWithPgpSearchLiveData: LiveData>> = + val contactsWithPgpSearchLiveData: LiveData>> = Transformations.switchMap(searchPatternLiveData) { liveData { emit(Result.loading()) @@ -90,10 +90,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } } - fun copyPubKeysToRecipient(email: String, contactEntity: ContactEntity) { + fun copyPubKeysToRecipient(email: String, recipientEntity: RecipientEntity) { viewModelScope.launch { val pubKeysOfCopyCandidate = - roomDatabase.pubKeysDao().getPublicKeysByRecipient(contactEntity.email) + roomDatabase.pubKeysDao().getPublicKeysByRecipient(recipientEntity.email) if (pubKeysOfCopyCandidate.isEmpty()) return@launch roomDatabase.pubKeysDao().insertSuspend( pubKeysOfCopyCandidate.map { it.copy(id = null, recipient = email) } @@ -101,8 +101,8 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } } - fun contactChangesLiveData(contactEntity: ContactEntity): LiveData { - return roomDatabase.contactsDao().getContactByEmailLD(contactEntity.email) + fun contactChangesLiveData(recipientEntity: RecipientEntity): LiveData { + return roomDatabase.contactsDao().getContactByEmailLD(recipientEntity.email) } /** @@ -124,7 +124,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application * 1. if no pubkey found, create `new PgpContact(js, email, null, null, null, null);` - this * means we know they don't currently have PGP */ - fun fetchAndUpdateInfoAboutContacts(type: ContactEntity.Type, emails: List) { + fun fetchAndUpdateInfoAboutContacts(type: RecipientEntity.Type, emails: List) { viewModelScope.launch { if (emails.isEmpty()) { return@launch @@ -200,23 +200,23 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } private suspend fun updateCachedInfoWithAttesterInfo( - cachedContactEntity: ContactEntity?, + cachedRecipientEntity: RecipientEntity?, attesterPgpContact: PgpContact, emailLowerCase: String - ): ContactEntity? { - cachedContactEntity ?: return null + ): RecipientEntity? { + cachedRecipientEntity ?: return null val updateCandidate = if ( - cachedContactEntity.name.isNullOrEmpty() - && cachedContactEntity.email.equals(attesterPgpContact.email, ignoreCase = true) + cachedRecipientEntity.name.isNullOrEmpty() + && cachedRecipientEntity.email.equals(attesterPgpContact.email, ignoreCase = true) ) { attesterPgpContact.toContactEntity().copy( - id = cachedContactEntity.id, - email = cachedContactEntity.email + id = cachedRecipientEntity.id, + email = cachedRecipientEntity.email ) } else { attesterPgpContact.toContactEntity().copy( - id = cachedContactEntity.id, - name = cachedContactEntity.name, - email = cachedContactEntity.email + id = cachedRecipientEntity.id, + name = cachedRecipientEntity.name, + email = cachedRecipientEntity.email ) } @@ -231,9 +231,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application return lastVersion } - fun deleteContact(contactEntity: ContactEntity) { + fun deleteContact(recipientEntity: RecipientEntity) { viewModelScope.launch { - roomDatabase.contactsDao().deleteSuspend(contactEntity) + roomDatabase.contactsDao().deleteSuspend(recipientEntity) } } @@ -265,14 +265,14 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } } - fun copyPubKeysToRecipient(contactEntity: ContactEntity?, pgpKeyDetails: PgpKeyDetails) { + fun copyPubKeysToRecipient(recipientEntity: RecipientEntity?, pgpKeyDetails: PgpKeyDetails) { viewModelScope.launch { - contactEntity?.let { + recipientEntity?.let { val contactEntityFromPrimaryPgpContact = pgpKeyDetails.primaryPgpContact.toContactEntity() roomDatabase.contactsDao().updateSuspend( contactEntityFromPrimaryPgpContact.copy( - id = contactEntity.id, - email = contactEntity.email.lowercase(Locale.US), + id = recipientEntity.id, + email = recipientEntity.email.lowercase(Locale.US), ) ) } @@ -305,19 +305,19 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } private fun setResultForRemoteContactsLiveData( - type: ContactEntity.Type, + type: RecipientEntity.Type, result: Result> ) { when (type) { - ContactEntity.Type.TO -> { + RecipientEntity.Type.TO -> { contactsToLiveData.value = result } - ContactEntity.Type.CC -> { + RecipientEntity.Type.CC -> { contactsCcLiveData.value = result } - ContactEntity.Type.BCC -> { + RecipientEntity.Type.BCC -> { contactsBccLiveData.value = result } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index db3e3e80ab..cf73484d6d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -20,7 +20,7 @@ import com.flowcrypt.email.api.email.gmail.GmailApiHelper import com.flowcrypt.email.api.email.gmail.api.GmaiAPIMimeMessage import com.flowcrypt.email.database.FlowCryptRoomDatabase import com.flowcrypt.email.database.entity.AccountEntity -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.model.EmailAndNamePair import com.sun.mail.imap.IMAPFolder import kotlinx.coroutines.Dispatchers @@ -165,10 +165,10 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : val contactsInDatabase = HashSet() val contactsWhichWillBeUpdated = HashSet() val contactsWhichWillBeCreated = HashSet() - val contactsByEmailMap = HashMap() + val contactsByEmailMap = HashMap() - val newCandidates = mutableListOf() - val updateCandidates = mutableListOf() + val newCandidates = mutableListOf() + val updateCandidates = mutableListOf() for (contact in availableContacts) { contactsInDatabase.add(contact.email.lowercase()) @@ -191,7 +191,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : emailAndNamePair.email?.let { contactsWhichWillBeCreated.add(it) newCandidates.add( - ContactEntity( + RecipientEntity( email = it, name = emailAndNamePair.name ) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt index 7117eb9c50..5cb3ad7b4e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt @@ -7,8 +7,8 @@ package com.flowcrypt.email.model import android.os.Parcel import android.os.Parcelable -import com.flowcrypt.email.database.entity.ContactEntity import com.flowcrypt.email.database.entity.PublicKeyEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.security.model.PgpKeyDetails import java.util.ArrayList import javax.mail.internet.AddressException @@ -59,8 +59,8 @@ data class PgpContact constructor( writeInt((if (hasNotUsablePubKey) 1 else 0)) } - fun toContactEntity(): ContactEntity { - return ContactEntity( + fun toContactEntity(): RecipientEntity { + return RecipientEntity( email = email.lowercase(), name = name, lastUse = lastUse diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt index ec6733a415..616a0974ee 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt @@ -7,7 +7,7 @@ package com.flowcrypt.email.model import android.os.Parcel import android.os.Parcelable -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity /** * This class describes information about some public key. @@ -46,8 +46,8 @@ data class PublicKeyInfo constructor( writeString(publicKey) } - fun toContactEntity(): ContactEntity { - return ContactEntity( + fun toContactEntity(): RecipientEntity { + return RecipientEntity( email = keyOwner.lowercase() ) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt index 64cdb2c6f1..48023cfcd1 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt @@ -15,7 +15,7 @@ import androidx.activity.viewModels import androidx.core.widget.addTextChangedListener import com.flowcrypt.email.R import com.flowcrypt.email.database.entity.AccountEntity -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.showDialogFragment import com.flowcrypt.email.extensions.showInfoDialogFragment import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel @@ -35,7 +35,7 @@ import com.flowcrypt.email.util.GeneralUtil class EditContactActivity : BaseImportKeyActivity(), UpdatePublicKeyOfContactDialogFragment.OnKeySelectedListener { private val contactsViewModel: ContactsViewModel by viewModels() - private var contactEntity: ContactEntity? = null + private var recipientEntity: RecipientEntity? = null private var editTextNewPubKey: EditText? = null override val contentViewResourceId: Int = R.layout.activity_edit_pgp_contact @@ -43,12 +43,12 @@ class EditContactActivity : BaseImportKeyActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - contactEntity = intent?.getParcelableExtra(KEY_EXTRA_CONTACT) - if (contactEntity == null) { + recipientEntity = intent?.getParcelableExtra(KEY_EXTRA_CONTACT) + if (recipientEntity == null) { finish() Toast.makeText(this, getString(R.string.contact_can_not_be_null), Toast.LENGTH_LONG).show() } else { - supportActionBar?.title = contactEntity?.email + supportActionBar?.title = recipientEntity?.email } } @@ -68,7 +68,7 @@ class EditContactActivity : BaseImportKeyActivity(), showDialogFragment( UpdatePublicKeyOfContactDialogFragment.newInstance( - contactEntity?.email, + recipientEntity?.email, keyDetailsList.first() ) ) @@ -96,7 +96,7 @@ class EditContactActivity : BaseImportKeyActivity(), } override fun onKeySelected(pgpKeyDetails: PgpKeyDetails) { - contactsViewModel.copyPubKeysToRecipient(contactEntity, pgpKeyDetails) + contactsViewModel.copyPubKeysToRecipient(recipientEntity, pgpKeyDetails) finish() } @@ -107,7 +107,7 @@ class EditContactActivity : BaseImportKeyActivity(), fun newIntent( context: Context, accountEntity: AccountEntity?, - contactEntity: ContactEntity? + recipientEntity: RecipientEntity? ): Intent { return newIntent( context = context, @@ -116,7 +116,7 @@ class EditContactActivity : BaseImportKeyActivity(), throwErrorIfDuplicateFoundEnabled = false, cls = EditContactActivity::class.java ).apply { - putExtra(KEY_EXTRA_CONTACT, contactEntity) + putExtra(KEY_EXTRA_CONTACT, recipientEntity) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index ec10cf5372..155bab1af5 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -22,7 +22,7 @@ import androidx.recyclerview.widget.RecyclerView import androidx.test.espresso.idling.CountingIdlingResource import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel @@ -33,7 +33,7 @@ import com.flowcrypt.email.util.UIUtil /** * This activity can be used for select single or multiply contacts (not implemented yet) from the local database. The - * activity returns [ContactEntity] as a result. + * activity returns [RecipientEntity] as a result. * * @author Denis Bondarenko * Date: 14.11.2017 @@ -108,14 +108,14 @@ class SelectContactsActivity : BaseBackStackActivity(), return super.onPrepareOptionsMenu(menu) } - override fun onContactClick(contactEntity: ContactEntity) { + override fun onContactClick(recipientEntity: RecipientEntity) { val intent = Intent() - intent.putExtra(KEY_EXTRA_PGP_CONTACT, contactEntity) + intent.putExtra(KEY_EXTRA_PGP_CONTACT, recipientEntity) setResult(Activity.RESULT_OK, intent) finish() } - override fun onDeleteContact(contactEntity: ContactEntity) {} + override fun onDeleteContact(recipientEntity: RecipientEntity) {} override fun onQueryTextSubmit(query: String): Boolean { searchPattern = query diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt index a40889a5f5..fbaecdfb8f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt @@ -17,7 +17,7 @@ import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.navController import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.ui.activity.ImportPgpContactActivity @@ -70,17 +70,17 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnConta } } - override fun onContactClick(contactEntity: ContactEntity) { + override fun onContactClick(recipientEntity: RecipientEntity) { navController?.navigate( ContactsListFragmentDirections - .actionContactsListFragmentToPublicKeyDetailsFragment(contactEntity) + .actionContactsListFragmentToPublicKeyDetailsFragment(recipientEntity) ) } - override fun onDeleteContact(contactEntity: ContactEntity) { - contactsViewModel.deleteContact(contactEntity) + override fun onDeleteContact(recipientEntity: RecipientEntity) { + contactsViewModel.deleteContact(recipientEntity) Toast.makeText( - context, getString(R.string.the_contact_was_deleted, contactEntity.email), + context, getString(R.string.the_contact_was_deleted, recipientEntity.email), Toast.LENGTH_SHORT ).show() } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index 7d382ca051..bdde85316f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -25,7 +25,7 @@ import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.Constants import com.flowcrypt.email.R import com.flowcrypt.email.database.FlowCryptRoomDatabase -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.model.PublicKeyInfo @@ -379,7 +379,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (updateCandidates.size - i > STEP_AMOUNT) i + STEP_AMOUNT else updateCandidates.size - 1 if (weakRef.get() != null) { - val contacts = mutableListOf() + val contacts = mutableListOf() val list = updateCandidates.subList(start, end + 1) list.forEach { pgpContact -> diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt index 314ad7ea98..dd43a554fa 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt @@ -28,7 +28,7 @@ import com.flowcrypt.email.NavGraphDirections import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.FlowCryptRoomDatabase -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.navController import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.jetpack.viewmodel.ParseKeysViewModel @@ -57,7 +57,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { private val contactsViewModel: ContactsViewModel by viewModels() private val parseKeysViewModel: ParseKeysViewModel by viewModels() - private var contactEntity: ContactEntity? = null + private var recipientEntity: RecipientEntity? = null private var details: PgpKeyDetails? = null private var layoutUsers: ViewGroup? = null private var layoutFingerprints: ViewGroup? = null @@ -76,7 +76,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - contactEntity = args.contactEntity + recipientEntity = args.contactEntity } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -133,7 +133,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { } private fun setupContactsViewModel() { - contactEntity?.let { + recipientEntity?.let { contactsViewModel.contactChangesLiveData(it).observe(viewLifecycleOwner, { contactEntity -> /*this.contactEntity = contactEntity parseKeysViewModel.fetchKeys(it.publicKey)*/ @@ -167,14 +167,14 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { R.id.menuActionDelete -> { lifecycleScope.launch { val roomDatabase = FlowCryptRoomDatabase.getDatabase(requireContext()) - contactEntity?.let { roomDatabase.contactsDao().deleteSuspend(it) } + recipientEntity?.let { roomDatabase.contactsDao().deleteSuspend(it) } navController?.navigateUp() } return true } R.id.menuActionEdit -> { - contactEntity?.let { + recipientEntity?.let { startActivity(EditContactActivity.newIntent(requireContext(), account, it)) } @@ -265,7 +265,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { intent.addCategory(Intent.CATEGORY_OPENABLE) intent.type = Constants.MIME_TYPE_PGP_KEY - val sanitizedEmail = contactEntity?.email?.replace("[^a-z0-9]".toRegex(), "") + val sanitizedEmail = recipientEntity?.email?.replace("[^a-z0-9]".toRegex(), "") val fileName = "0x" + details?.fingerprint + "-" + sanitizedEmail + "-publickey" + ".asc" intent.putExtra(Intent.EXTRA_TITLE, fileName) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index f9ee141932..3af528111c 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -52,7 +52,7 @@ import com.flowcrypt.email.api.email.model.ServiceInfo import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.FlowCryptRoomDatabase import com.flowcrypt.email.database.entity.AccountEntity -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.extensions.org.bouncycastle.openpgp.pgpContacts @@ -234,15 +234,15 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, } if (listener.msgEncryptionType === MessageEncryptionType.ENCRYPTED) { if (recipientsTo?.text?.isNotEmpty() == true && pgpContactsTo?.isEmpty() == true) { - fetchDetailsAboutContacts(ContactEntity.Type.TO) + fetchDetailsAboutContacts(RecipientEntity.Type.TO) return false } if (recipientsCc?.text?.isNotEmpty() == true && pgpContactsCc?.isEmpty() == true) { - fetchDetailsAboutContacts(ContactEntity.Type.CC) + fetchDetailsAboutContacts(RecipientEntity.Type.CC) return false } if (recipientsBcc?.text?.isNotEmpty() == true && pgpContactsBcc?.isEmpty() == true) { - fetchDetailsAboutContacts(ContactEntity.Type.BCC) + fetchDetailsAboutContacts(RecipientEntity.Type.BCC) return false } if (hasRecipientWithoutPgp(true, pgpContactsTo, pgpContactsCc, pgpContactsBcc)) { @@ -430,7 +430,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, when (resultCode) { Activity.RESULT_OK -> if (data != null) { val contactEntity = - data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) + data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) contactEntity?.let { pgpContactWithNoPublicKey?.email?.let { email -> contactsViewModel.copyPubKeysToRecipient( @@ -588,17 +588,17 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, when (v.id) { R.id.editTextRecipientTo -> runUpdatePgpContactsAction( pgpContactsTo, progressBarTo, - ContactEntity.Type.TO, hasFocus + RecipientEntity.Type.TO, hasFocus ) R.id.editTextRecipientCc -> runUpdatePgpContactsAction( pgpContactsCc, progressBarCc, - ContactEntity.Type.CC, hasFocus + RecipientEntity.Type.CC, hasFocus ) R.id.editTextRecipientBcc -> runUpdatePgpContactsAction( pgpContactsBcc, progressBarBcc, - ContactEntity.Type.BCC, hasFocus + RecipientEntity.Type.BCC, hasFocus ) R.id.editTextEmailSubject, R.id.editTextEmailMessage -> if (hasFocus) { @@ -832,7 +832,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, private fun updateRecipients() { recipientsTo?.chipAndTokenValues?.let { contactsViewModel.fetchAndUpdateInfoAboutContacts( - ContactEntity.Type.TO, + RecipientEntity.Type.TO, it ) } @@ -840,7 +840,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, if (layoutCc?.visibility == View.VISIBLE) { recipientsCc?.chipAndTokenValues?.let { contactsViewModel.fetchAndUpdateInfoAboutContacts( - ContactEntity.Type.CC, + RecipientEntity.Type.CC, it ) } @@ -852,7 +852,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, if (layoutBcc?.visibility == View.VISIBLE) { recipientsBcc?.chipAndTokenValues?.let { contactsViewModel.fetchAndUpdateInfoAboutContacts( - ContactEntity.Type.BCC, + RecipientEntity.Type.BCC, it ) } @@ -873,7 +873,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, */ private fun runUpdatePgpContactsAction( pgpContacts: MutableList?, progressBar: View?, - type: ContactEntity.Type, hasFocus: Boolean + type: RecipientEntity.Type, hasFocus: Boolean ): List? { if (listener.msgEncryptionType === MessageEncryptionType.ENCRYPTED) { if (hasFocus) { @@ -892,23 +892,23 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, return pgpContacts } - private fun fetchDetailsAboutContacts(type: ContactEntity.Type) { + private fun fetchDetailsAboutContacts(type: RecipientEntity.Type) { when (type) { - ContactEntity.Type.TO -> { + RecipientEntity.Type.TO -> { recipientsTo?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(ContactEntity.Type.TO, it) + contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.TO, it) } } - ContactEntity.Type.CC -> { + RecipientEntity.Type.CC -> { recipientsCc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(ContactEntity.Type.CC, it) + contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.CC, it) } } - ContactEntity.Type.BCC -> { + RecipientEntity.Type.BCC -> { recipientsBcc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(ContactEntity.Type.BCC, it) + contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.BCC, it) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt index 9241947235..71ef9fd955 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt @@ -13,7 +13,7 @@ import android.widget.TextView import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R -import com.flowcrypt.email.database.entity.ContactEntity +import com.flowcrypt.email.database.entity.RecipientEntity /** * This adapter describes logic to prepare show contacts from the database. @@ -26,7 +26,7 @@ import com.flowcrypt.email.database.entity.ContactEntity class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boolean = true) : RecyclerView.Adapter() { - private val list: MutableList = mutableListOf() + private val list: MutableList = mutableListOf() var onContactActionsListener: OnContactActionsListener? = null override fun onCreateViewHolder( @@ -77,7 +77,7 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole return list.size } - fun swap(newList: List) { + fun swap(newList: List) { val diffUtilCallback = DiffUtilCallback(this.list, newList) val productDiffResult = DiffUtil.calculateDiff(diffUtilCallback) @@ -87,8 +87,8 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } interface OnContactActionsListener { - fun onDeleteContact(contactEntity: ContactEntity) - fun onContactClick(contactEntity: ContactEntity) + fun onDeleteContact(recipientEntity: RecipientEntity) + fun onContactClick(recipientEntity: RecipientEntity) } /** @@ -102,8 +102,8 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } inner class DiffUtilCallback( - private val oldList: List, - private val newList: List + private val oldList: List, + private val newList: List ) : DiffUtil.Callback() { override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean { val oldItem = oldList[oldItemPosition] From fda5a7684a3d92194a2b8cfac271605d740c00cf Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 13:50:02 +0300 Subject: [PATCH 05/38] Renamed ContactsDao to RecipientDao.| #1188 --- .../email/rules/AddContactsToDatabaseRule.kt | 2 +- .../ui/activity/ContactsListFragmentTest.kt | 4 +- .../ui/activity/CreateMessageActivityTest.kt | 13 +++--- .../PreviewImportPgpContactActivityTest.kt | 2 +- .../activity/PublicKeyDetailsFragmentTest.kt | 3 +- .../ui/activity/SelectContactsActivityTest.kt | 2 +- .../email/database/FlowCryptRoomDatabase.kt | 4 +- .../dao/{ContactsDao.kt => RecipientDao.kt} | 2 +- .../jetpack/viewmodel/ContactsViewModel.kt | 44 +++++++++---------- .../jetpack/viewmodel/MsgDetailsViewModel.kt | 2 +- .../jetpack/viewmodel/PrivateKeysViewModel.kt | 12 ++--- .../workmanager/sync/LoadContactsWorker.kt | 2 +- .../flowcrypt/email/security/SecurityUtils.kt | 2 +- .../service/EmailAndNameUpdaterService.kt | 8 ++-- ...PrepareOutgoingMessagesJobIntentService.kt | 2 +- .../email/ui/activity/base/BaseActivity.kt | 2 +- .../PreviewImportPgpContactFragment.kt | 6 +-- .../fragment/PublicKeyDetailsFragment.kt | 2 +- .../fragment/base/CreateMessageFragment.kt | 2 +- 19 files changed, 58 insertions(+), 58 deletions(-) rename FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/{ContactsDao.kt => RecipientDao.kt} (97%) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt index 03b34cbee4..b9bfc8e3a9 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt @@ -24,7 +24,7 @@ class AddContactsToDatabaseRule(val pgpContacts: List) : BaseRule() override fun apply(base: Statement, description: Description): Statement { return object : Statement() { override fun evaluate() { - FlowCryptRoomDatabase.getDatabase(targetContext).contactsDao().insert( + FlowCryptRoomDatabase.getDatabase(targetContext).recipientDao().insert( pgpContacts.map { it.toContactEntity() }) base.evaluate() } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt index 7c4aeb3ad3..d8c1e51ed3 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt @@ -98,7 +98,7 @@ class ContactsListFragmentTest : BaseTest() { private fun addContactsToDatabase() { for (email in EMAILS) { val pgpContact = PgpContact(email, null, "", true, null, null, 0) - FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() .insert(pgpContact.toContactEntity()) } } @@ -115,7 +115,7 @@ class ContactsListFragmentTest : BaseTest() { fun clearContactsFromDatabase() { for (email in EMAILS) { val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()) - .contactsDao() + .recipientDao() val contact = dao.getContactByEmail(email) ?: continue dao.delete(contact) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt index 48a20a6250..c9ca657f33 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt @@ -40,7 +40,6 @@ import com.flowcrypt.email.api.email.EmailUtil import com.flowcrypt.email.api.email.model.AttachmentInfo import com.flowcrypt.email.api.email.model.IncomingMessageInfo import com.flowcrypt.email.database.FlowCryptRoomDatabase -import com.flowcrypt.email.extensions.org.bouncycastle.openpgp.expiration import com.flowcrypt.email.matchers.CustomMatchers.Companion.withAppBarLayoutBackgroundColor import com.flowcrypt.email.matchers.CustomMatchers.Companion.withChipsBackgroundColor import com.flowcrypt.email.model.KeyImportDetails @@ -385,8 +384,8 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { .perform(click()) val database = FlowCryptRoomDatabase.getDatabase(getTargetContext()) - val existedContact = requireNotNull(database.contactsDao().getContactByEmail(pgpContact.email)) - database.contactsDao().update( + val existedContact = requireNotNull(database.recipientDao().getContactByEmail(pgpContact.email)) + database.recipientDao().update( existedContact.copy( publicKey = pgpContact.pubkey?.toByteArray(), hasPgp = true @@ -586,7 +585,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { PrivateKeysManager.getPgpKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") val contact = keyDetails.primaryPgpContact FlowCryptRoomDatabase.getDatabase(getTargetContext()) - .contactsDao().insert(contact.toContactEntity()) + .recipientDao().insert(contact.toContactEntity()) activeActivityRule?.launch(intent) registerAllIdlingResources() @@ -626,7 +625,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { pubkey = keyWithSHA1Algo ) FlowCryptRoomDatabase.getDatabase(getTargetContext()) - .contactsDao().insert(contact.toContactEntity()) + .recipientDao().insert(contact.toContactEntity()) activeActivityRule?.launch(intent) registerAllIdlingResources() @@ -661,7 +660,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { val keyDetailsFromAssets = PrivateKeysManager.getPgpKeyDetailsFromAssets("pgp/expired_fixed@flowcrypt.test_expired_pub.asc") val contact = keyDetailsFromAssets.primaryPgpContact - val contactsDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + val contactsDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() contactsDao.insert(contact.toContactEntity()) val existedContact = contactsDao.getContactByEmail(contact.email) ?: throw IllegalArgumentException("Contact not found") @@ -704,7 +703,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { } private fun savePublicKeyInDatabase() { - FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() .insert(pgpContact.toContactEntity()) } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt index 9019bd51bd..abf1ba4843 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt @@ -82,7 +82,7 @@ class PreviewImportPgpContactActivityTest : BaseTest() { "default@flowcrypt.test", null, singlePublicKeyForUnsavedContact, true, null, null, 0 ) - FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() .insert(pgpContact.toContactEntity()) activeActivityRule.launch( PreviewImportPgpContactActivity.newIntent( diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt index d95eb72ff1..f7ac91f765 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt @@ -218,7 +218,8 @@ class PublicKeyDetailsFragmentTest : BaseTest() { @JvmStatic fun removeContactFromDatabase() { val dao = - FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()).contactsDao() + FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()) + .recipientDao() dao.getContactByEmail(EMAIL_DENBOND7)?.let { dao.delete(it) } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt index 5e04309b0b..6a59701fe5 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt @@ -149,7 +149,7 @@ class SelectContactsActivityTest : BaseTest() { } private fun clearContactsFromDatabase() { - val dao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).contactsDao() + val dao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() for (email in EMAILS) { val contact = dao.getContactByEmail(email) ?: continue dao.delete(contact) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt index df0340e992..c8f0e426ea 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt @@ -22,11 +22,11 @@ import com.flowcrypt.email.database.dao.AccountAliasesDao import com.flowcrypt.email.database.dao.AccountDao import com.flowcrypt.email.database.dao.ActionQueueDao import com.flowcrypt.email.database.dao.AttachmentDao -import com.flowcrypt.email.database.dao.ContactsDao import com.flowcrypt.email.database.dao.KeysDao import com.flowcrypt.email.database.dao.LabelDao import com.flowcrypt.email.database.dao.MessageDao import com.flowcrypt.email.database.dao.PubKeysDao +import com.flowcrypt.email.database.dao.RecipientDao import com.flowcrypt.email.database.entity.AccountAliasesEntity import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.ActionQueueEntity @@ -79,7 +79,7 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { abstract fun keysDao(): KeysDao - abstract fun contactsDao(): ContactsDao + abstract fun recipientDao(): RecipientDao abstract fun pubKeysDao(): PubKeysDao diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt similarity index 97% rename from FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt rename to FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt index c0caf57714..792fe26fbc 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/ContactsDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt @@ -20,7 +20,7 @@ import com.flowcrypt.email.database.entity.RecipientEntity * E-mail: DenBond7@gmail.com */ @Dao -interface ContactsDao : BaseDao { +interface RecipientDao : BaseDao { //fixed @Query("SELECT * FROM contacts") suspend fun getAllContacts(): List diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index f35cdc8ad8..da5d2ccbc4 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -47,9 +47,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application private val searchPatternLiveData: MutableLiveData = MutableLiveData() val allContactsLiveData: LiveData> = - roomDatabase.contactsDao().getAllContactsLD() + roomDatabase.recipientDao().getAllContactsLD() val contactsWithPgpLiveData: LiveData>> = - Transformations.switchMap(roomDatabase.contactsDao().getAllContactsWithPgpLD()) { + Transformations.switchMap(roomDatabase.recipientDao().getAllContactsWithPgpLD()) { liveData { emit(Result.success(it)) } @@ -59,9 +59,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application liveData { emit(Result.loading()) val foundContacts = if (it.isNullOrEmpty()) { - roomDatabase.contactsDao().getAllContactsWithPgp() + roomDatabase.recipientDao().getAllContactsWithPgp() } else { - roomDatabase.contactsDao().getAllContactsWithPgpWhichMatched("%$it%") + roomDatabase.recipientDao().getAllContactsWithPgpWhichMatched("%$it%") } emit(Result.success(foundContacts)) } @@ -74,17 +74,17 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun copyPubKeysToRecipient(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) if (contact != null) { val updateCandidate = pgpContact.toContactEntity().copy(id = contact.id) - roomDatabase.contactsDao().updateSuspend(updateCandidate) + roomDatabase.recipientDao().updateSuspend(updateCandidate) } if (!pgpContact.email.equals(pgpContactFromKey.email, ignoreCase = true)) { val existedContact = - roomDatabase.contactsDao().getContactByEmailSuspend(pgpContactFromKey.email) + roomDatabase.recipientDao().getContactByEmailSuspend(pgpContactFromKey.email) if (existedContact == null) { - roomDatabase.contactsDao().insertSuspend(pgpContactFromKey.toContactEntity()) + roomDatabase.recipientDao().insertSuspend(pgpContactFromKey.toContactEntity()) } } } @@ -102,7 +102,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } fun contactChangesLiveData(recipientEntity: RecipientEntity): LiveData { - return roomDatabase.contactsDao().getContactByEmailLD(recipientEntity.email) + return roomDatabase.recipientDao().getContactByEmailLD(recipientEntity.email) } /** @@ -138,13 +138,13 @@ class ContactsViewModel(application: Application) : AccountViewModel(application if (GeneralUtil.isEmailValid(email)) { val emailLowerCase = email.lowercase(Locale.getDefault()) var cachedContactEntity = - roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) + roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) if (cachedContactEntity == null) { cachedContactEntity = PgpContact(emailLowerCase, null).toContactEntity() - roomDatabase.contactsDao().insertSuspend(cachedContactEntity) + roomDatabase.recipientDao().insertSuspend(cachedContactEntity) cachedContactEntity = - roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) + roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) } else { try { /*cachedContactEntity.publicKey?.let { @@ -220,8 +220,8 @@ class ContactsViewModel(application: Application) : AccountViewModel(application ) } - roomDatabase.contactsDao().updateSuspend(updateCandidate) - val lastVersion = roomDatabase.contactsDao().getContactByEmailSuspend(emailLowerCase) + roomDatabase.recipientDao().updateSuspend(updateCandidate) + val lastVersion = roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) /*lastVersion?.publicKey?.let { val result = PgpKey.parseKeys(it).pgpKeyDetailsList @@ -233,15 +233,15 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun deleteContact(recipientEntity: RecipientEntity) { viewModelScope.launch { - roomDatabase.contactsDao().deleteSuspend(recipientEntity) + roomDatabase.recipientDao().deleteSuspend(recipientEntity) } } fun addContact(pgpContact: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) if (contact == null) { - val isInserted = roomDatabase.contactsDao().insertSuspend(pgpContact.toContactEntity()) > 0 + val isInserted = roomDatabase.recipientDao().insertSuspend(pgpContact.toContactEntity()) > 0 if (isInserted) { roomDatabase.pubKeysDao().insertSuspend(pgpContact.toPubKey()) } else { @@ -257,10 +257,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun updateContact(pgpContact: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) if (contact != null) { val updateCandidate = pgpContact.toContactEntity().copy(id = contact.id) - roomDatabase.contactsDao().updateSuspend(updateCandidate) + roomDatabase.recipientDao().updateSuspend(updateCandidate) } } } @@ -269,7 +269,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application viewModelScope.launch { recipientEntity?.let { val contactEntityFromPrimaryPgpContact = pgpKeyDetails.primaryPgpContact.toContactEntity() - roomDatabase.contactsDao().updateSuspend( + roomDatabase.recipientDao().updateSuspend( contactEntityFromPrimaryPgpContact.copy( id = recipientEntity.id, email = recipientEntity.email.lowercase(Locale.US), @@ -285,8 +285,8 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun deleteContactByEmail(email: String) { viewModelScope.launch { - roomDatabase.contactsDao().getContactByEmailSuspend(email)?.let { - roomDatabase.contactsDao().deleteSuspend(it) + roomDatabase.recipientDao().getContactByEmailSuspend(email)?.let { + roomDatabase.recipientDao().deleteSuspend(it) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 0cf9574770..25c088922b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -414,7 +414,7 @@ class MsgDetailsViewModel( if (block is PublicKeyMsgBlock) { val keyDetails = block.keyDetails ?: continue val pgpContact = keyDetails.primaryPgpContact - val contactEntity = roomDatabase.contactsDao().getContactByEmailSuspend(pgpContact.email) + val contactEntity = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) //block.existingPgpContact = contactEntity?.toPgpContact() } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index 3fbbc609d1..4782a21c89 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -205,13 +205,13 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat } if (roomDatabase.keysDao().getKeyByAccountAndFingerprintSuspend( - accountEntity.email.toLowerCase(Locale.US), + accountEntity.email.lowercase(Locale.US), fingerprint ) == null ) { if (addAccountIfNotExist) { val existedAccount = roomDatabase.accountDao() - .getAccountSuspend(accountEntity.email.toLowerCase(Locale.US)) + .getAccountSuspend(accountEntity.email.lowercase(Locale.US)) if (existedAccount == null) { roomDatabase.accountDao().addAccountSuspend(accountEntity) } @@ -244,7 +244,7 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat ) } //update contacts table - val contactsDao = roomDatabase.contactsDao() + val contactsDao = roomDatabase.recipientDao() for (pgpContact in keyDetails.pgpContacts) { pgpContact.pubkey = keyDetails.publicKey val temp = contactsDao.getContactByEmailSuspend(pgpContact.email) @@ -341,7 +341,7 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat ).toPgpKeyDetails().copy(passphraseType = passphraseType) val existedAccount = - roomDatabase.accountDao().getAccountSuspend(accountEntity.email.toLowerCase(Locale.US)) + roomDatabase.accountDao().getAccountSuspend(accountEntity.email.lowercase(Locale.US)) if (existedAccount == null) { roomDatabase.accountDao().addAccountSuspend(accountEntity) } @@ -368,10 +368,10 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat val allKeyEntitiesOfAccount = roomDatabase.keysDao().getAllKeysByAccountSuspend(accountEntity.email) val fingerprintListOfDeleteCandidates = keys.map { - it.fingerprint.toLowerCase(Locale.US) + it.fingerprint.lowercase(Locale.US) } val deleteCandidates = allKeyEntitiesOfAccount.filter { - fingerprintListOfDeleteCandidates.contains(it.fingerprint.toLowerCase(Locale.US)) + fingerprintListOfDeleteCandidates.contains(it.fingerprint.lowercase(Locale.US)) } if (keys.size == allKeyEntitiesOfAccount.size) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index cf73484d6d..7143e6cdb9 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -159,7 +159,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : emailAndNamePairs.addAll(parseRecipients(msg, Message.RecipientType.BCC)) } - val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).contactsDao() + val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() val availableContacts = contactsDao.getAllContacts() val contactsInDatabase = HashSet() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt index 75026e8012..fc84738861 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt @@ -116,7 +116,7 @@ class SecurityUtils { @JvmStatic fun getRecipientsPubKeys(context: Context, emails: MutableList): MutableList { val publicKeys = mutableListOf() - val contacts = FlowCryptRoomDatabase.getDatabase(context).contactsDao() + val contacts = FlowCryptRoomDatabase.getDatabase(context).recipientDao() .getContactsByEmails(emails) for (contact in contacts) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 0dfc438104..74c576d3c2 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -10,7 +10,7 @@ import android.content.Intent import androidx.core.app.JobIntentService import com.flowcrypt.email.BuildConfig import com.flowcrypt.email.database.FlowCryptRoomDatabase -import com.flowcrypt.email.database.dao.ContactsDao +import com.flowcrypt.email.database.dao.RecipientDao import com.flowcrypt.email.jobscheduler.JobIdManager import com.flowcrypt.email.model.EmailAndNamePair import com.flowcrypt.email.model.PgpContact @@ -39,7 +39,7 @@ import java.util.Locale * E-mail: DenBond7@gmail.com */ class EmailAndNameUpdaterService : JobIntentService() { - private var contactsDao: ContactsDao = FlowCryptRoomDatabase.getDatabase(this).contactsDao() + private var recipientDao: RecipientDao = FlowCryptRoomDatabase.getDatabase(this).recipientDao() override fun onHandleWork(intent: Intent) { val pairs = @@ -48,13 +48,13 @@ class EmailAndNameUpdaterService : JobIntentService() { for (pair in pairs) { val email = pair.email?.lowercase(Locale.getDefault()) ?: continue - val contactEntity = contactsDao.getContactByEmail(email) + val contactEntity = recipientDao.getContactByEmail(email) if (contactEntity != null) { /*if (contactEntity.name.isNullOrEmpty()) { contactsDao.update(contactEntity.copy(name = pair.name)) }*/ } else { - contactsDao.insert(PgpContact(email, pair.name).toContactEntity()) + recipientDao.insert(PgpContact(email, pair.name).toContactEntity()) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index 95e489d34d..a8f200d57b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -378,7 +378,7 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { */ private fun updateContactsLastUseDateTime(msgInfo: OutgoingMessageInfo) { try { - val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).contactsDao() + val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() for (email in msgInfo.getAllRecipients()) { val contactEntity = contactsDao.getContactByEmail(email) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseActivity.kt index 1e22725cbb..392afc292e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseActivity.kt @@ -238,7 +238,7 @@ abstract class BaseActivity : AppCompatActivity() { val newActiveAccount = roomDatabase.accountDao().getActiveAccountSuspend() if (newActiveAccount == null) { - roomDatabase.contactsDao().deleteAll() + roomDatabase.recipientDao().deleteAll() stopService(Intent(applicationContext, IdleService::class.java)) val intent = Intent(applicationContext, SignInActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TOP diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index bdde85316f..e1a05bc596 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -356,7 +356,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (weakRef.get() != null) { FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .contactsDao() + .recipientDao() .insert(newCandidates.subList(start, end).map { it.toContactEntity() }) } i = end @@ -385,7 +385,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, list.forEach { pgpContact -> val foundContactEntity = FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .contactsDao().getContactByEmail(pgpContact.email) + .recipientDao().getContactByEmail(pgpContact.email) foundContactEntity?.let { entity -> /*contacts.add( pgpContact.toContactEntity().copy(id = entity.id) @@ -393,7 +393,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, } } - FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!).contactsDao() + FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!).recipientDao() .update(contacts) } i = end + 1 diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt index dd43a554fa..56ed09e46d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt @@ -167,7 +167,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { R.id.menuActionDelete -> { lifecycleScope.launch { val roomDatabase = FlowCryptRoomDatabase.getDatabase(requireContext()) - recipientEntity?.let { roomDatabase.contactsDao().deleteSuspend(it) } + recipientEntity?.let { roomDatabase.recipientDao().deleteSuspend(it) } navController?.navigateUp() } return true diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index 3af528111c..9380e062ac 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -1477,7 +1477,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, val pgpContactAdapter = PgpContactAdapter(requireContext(), null, true) //setup a search contacts logic in the database pgpContactAdapter.filterQueryProvider = FilterQueryProvider { constraint -> - val dao = FlowCryptRoomDatabase.getDatabase(requireContext()).contactsDao() + val dao = FlowCryptRoomDatabase.getDatabase(requireContext()).recipientDao() dao.getFilteredCursor("%$constraint%") } From 91de167fa5856c985a7caf413060415fe0244507 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 14:36:16 +0300 Subject: [PATCH 06/38] Refactored code.| #1188 --- .../email/rules/AddContactsToDatabaseRule.kt | 2 +- .../ui/activity/ContactsListFragmentTest.kt | 4 +- .../ui/activity/CreateMessageActivityTest.kt | 15 ++-- .../PreviewImportPgpContactActivityTest.kt | 2 +- .../activity/PublicKeyDetailsFragmentTest.kt | 6 +- .../ui/activity/SelectContactsActivityTest.kt | 2 +- .../src/devTest/res/navigation/nav_graph.xml | 4 +- .../email/database/dao/RecipientDao.kt | 40 +++++----- .../email/database/entity/RecipientEntity.kt | 8 +- .../jetpack/viewmodel/ContactsViewModel.kt | 78 ++++++++++--------- .../jetpack/viewmodel/MsgDetailsViewModel.kt | 5 +- .../jetpack/viewmodel/PrivateKeysViewModel.kt | 4 +- .../workmanager/sync/LoadContactsWorker.kt | 8 +- .../com/flowcrypt/email/model/PgpContact.kt | 2 +- .../flowcrypt/email/model/PublicKeyInfo.kt | 2 +- .../flowcrypt/email/security/SecurityUtils.kt | 2 +- .../service/EmailAndNameUpdaterService.kt | 10 +-- ...PrepareOutgoingMessagesJobIntentService.kt | 8 +- .../PreviewImportPgpContactFragment.kt | 10 +-- .../fragment/PublicKeyDetailsFragment.kt | 6 +- .../fragment/base/CreateMessageFragment.kt | 6 +- .../ui/adapter/ContactsRecyclerViewAdapter.kt | 14 ++-- .../src/main/res/navigation/nav_graph.xml | 4 +- 23 files changed, 124 insertions(+), 118 deletions(-) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt index b9bfc8e3a9..bf2702b0a4 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/rules/AddContactsToDatabaseRule.kt @@ -25,7 +25,7 @@ class AddContactsToDatabaseRule(val pgpContacts: List) : BaseRule() return object : Statement() { override fun evaluate() { FlowCryptRoomDatabase.getDatabase(targetContext).recipientDao().insert( - pgpContacts.map { it.toContactEntity() }) + pgpContacts.map { it.toRecipientEntity() }) base.evaluate() } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt index d8c1e51ed3..c8c2a14bdb 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt @@ -99,7 +99,7 @@ class ContactsListFragmentTest : BaseTest() { for (email in EMAILS) { val pgpContact = PgpContact(email, null, "", true, null, null, 0) FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() - .insert(pgpContact.toContactEntity()) + .insert(pgpContact.toRecipientEntity()) } } @@ -117,7 +117,7 @@ class ContactsListFragmentTest : BaseTest() { val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()) .recipientDao() - val contact = dao.getContactByEmail(email) ?: continue + val contact = dao.getRecipientByEmail(email) ?: continue dao.delete(contact) } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt index c9ca657f33..73bbee917f 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt @@ -384,7 +384,8 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { .perform(click()) val database = FlowCryptRoomDatabase.getDatabase(getTargetContext()) - val existedContact = requireNotNull(database.recipientDao().getContactByEmail(pgpContact.email)) + val existedContact = + requireNotNull(database.recipientDao().getRecipientByEmail(pgpContact.email)) database.recipientDao().update( existedContact.copy( publicKey = pgpContact.pubkey?.toByteArray(), @@ -481,7 +482,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { fillInAllFields(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER) val result = Intent() - result.putExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT, pgpContact.toContactEntity()) + result.putExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT, pgpContact.toRecipientEntity()) intending(hasComponent(ComponentName(getTargetContext(), SelectContactsActivity::class.java))) .respondWith(Instrumentation.ActivityResult(Activity.RESULT_OK, result)) onView(withId(R.id.menuActionSend)) @@ -585,7 +586,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { PrivateKeysManager.getPgpKeyDetailsFromAssets("pgp/expired@flowcrypt.test_pub.asc") val contact = keyDetails.primaryPgpContact FlowCryptRoomDatabase.getDatabase(getTargetContext()) - .recipientDao().insert(contact.toContactEntity()) + .recipientDao().insert(contact.toRecipientEntity()) activeActivityRule?.launch(intent) registerAllIdlingResources() @@ -625,7 +626,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { pubkey = keyWithSHA1Algo ) FlowCryptRoomDatabase.getDatabase(getTargetContext()) - .recipientDao().insert(contact.toContactEntity()) + .recipientDao().insert(contact.toRecipientEntity()) activeActivityRule?.launch(intent) registerAllIdlingResources() @@ -661,8 +662,8 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { PrivateKeysManager.getPgpKeyDetailsFromAssets("pgp/expired_fixed@flowcrypt.test_expired_pub.asc") val contact = keyDetailsFromAssets.primaryPgpContact val contactsDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() - contactsDao.insert(contact.toContactEntity()) - val existedContact = contactsDao.getContactByEmail(contact.email) + contactsDao.insert(contact.toRecipientEntity()) + val existedContact = contactsDao.getRecipientByEmail(contact.email) ?: throw IllegalArgumentException("Contact not found") val existedKeyExpiration = PgpKey.parseKeys( @@ -704,7 +705,7 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { private fun savePublicKeyInDatabase() { FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() - .insert(pgpContact.toContactEntity()) + .insert(pgpContact.toRecipientEntity()) } private fun deleteAtt(att: File) { diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt index abf1ba4843..a43dae5086 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivityTest.kt @@ -83,7 +83,7 @@ class PreviewImportPgpContactActivityTest : BaseTest() { singlePublicKeyForUnsavedContact, true, null, null, 0 ) FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() - .insert(pgpContact.toContactEntity()) + .insert(pgpContact.toRecipientEntity()) activeActivityRule.launch( PreviewImportPgpContactActivity.newIntent( getTargetContext(), diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt index f7ac91f765..c8181cef6a 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/PublicKeyDetailsFragmentTest.kt @@ -73,10 +73,10 @@ class PublicKeyDetailsFragmentTest : BaseTest() { uri = "flowcrypt://email.flowcrypt.com/settings/contacts/details", extras = Bundle().apply { putParcelable( - "contactEntity", PgpContact( + "recipientEntity", PgpContact( EMAIL_DENBOND7, USER_DENBOND7, keyDetails.publicKey, true, null, null, 0 - ).toContactEntity() + ).toRecipientEntity() ) } ) @@ -220,7 +220,7 @@ class PublicKeyDetailsFragmentTest : BaseTest() { val dao = FlowCryptRoomDatabase.getDatabase(ApplicationProvider.getApplicationContext()) .recipientDao() - dao.getContactByEmail(EMAIL_DENBOND7)?.let { dao.delete(it) } + dao.getRecipientByEmail(EMAIL_DENBOND7)?.let { dao.delete(it) } } } } diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt index 6a59701fe5..aeff448015 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/SelectContactsActivityTest.kt @@ -151,7 +151,7 @@ class SelectContactsActivityTest : BaseTest() { private fun clearContactsFromDatabase() { val dao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() for (email in EMAILS) { - val contact = dao.getContactByEmail(email) ?: continue + val contact = dao.getRecipientByEmail(email) ?: continue dao.delete(contact) } } diff --git a/FlowCrypt/src/devTest/res/navigation/nav_graph.xml b/FlowCrypt/src/devTest/res/navigation/nav_graph.xml index e66e84179a..4f392d726c 100644 --- a/FlowCrypt/src/devTest/res/navigation/nav_graph.xml +++ b/FlowCrypt/src/devTest/res/navigation/nav_graph.xml @@ -151,8 +151,8 @@ android:id="@+id/deepLink" app:uri="flowcrypt://email.flowcrypt.com/settings/contacts/details" /> + android:name="recipientEntity" + app:argType="com.flowcrypt.email.database.entity.RecipientEntity" /> { //fixed - @Query("SELECT * FROM contacts") - suspend fun getAllContacts(): List + @Query("SELECT * FROM recipients") + suspend fun getAllRecipients(): List //fixed - @Query("SELECT * FROM contacts") - fun getAllContactsLD(): LiveData> + @Query("SELECT * FROM recipients") + fun getAllRecipientsLD(): LiveData> //fixed - @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") - fun getAllContactsWithPgpLD(): LiveData> + @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient GROUP BY recipients.email ORDER BY recipients._id") + fun getAllRecipientsWithPgpLD(): LiveData> //fixed - @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient GROUP BY contacts.email ORDER BY contacts._id") - suspend fun getAllContactsWithPgp(): List + @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient GROUP BY recipients.email ORDER BY recipients._id") + suspend fun getAllRecipientsWithPgp(): List //fixed - @Query("SELECT contacts.* FROM contacts INNER JOIN public_keys ON contacts.email = public_keys.recipient WHERE (email LIKE :searchPattern OR name LIKE :searchPattern) GROUP BY contacts.email ORDER BY contacts._id") - suspend fun getAllContactsWithPgpWhichMatched(searchPattern: String): List + @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient WHERE (email LIKE :searchPattern OR name LIKE :searchPattern) GROUP BY recipients.email ORDER BY recipients._id") + suspend fun getAllRecipientsWithPgpWhichMatched(searchPattern: String): List - @Query("SELECT * FROM contacts WHERE email = :email") - suspend fun getContactByEmailSuspend(email: String): RecipientEntity? + @Query("SELECT * FROM recipients WHERE email = :email") + suspend fun getRecipientByEmailSuspend(email: String): RecipientEntity? - @Query("SELECT * FROM contacts WHERE email = :email") - fun getContactByEmail(email: String): RecipientEntity? + @Query("SELECT * FROM recipients WHERE email = :email") + fun getRecipientByEmail(email: String): RecipientEntity? - @Query("SELECT * FROM contacts WHERE email = :email") - fun getContactByEmailLD(email: String): LiveData + @Query("SELECT * FROM recipients WHERE email = :email") + fun getRecipientByEmailLD(email: String): LiveData - @Query("SELECT * FROM contacts WHERE email IN (:emails)") - fun getContactsByEmails(emails: Collection): List + @Query("SELECT * FROM recipients WHERE email IN (:emails)") + fun getRecipientsByEmails(emails: Collection): List - @Query("SELECT * FROM contacts WHERE email LIKE :searchPattern ORDER BY last_use DESC") + @Query("SELECT * FROM recipients WHERE email LIKE :searchPattern ORDER BY last_use DESC") fun getFilteredCursor(searchPattern: String): Cursor? - @Query("DELETE FROM contacts") + @Query("DELETE FROM recipients") suspend fun deleteAll(): Int } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt index 1c3cef8560..201fe278d1 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt @@ -23,11 +23,11 @@ import com.flowcrypt.email.security.model.PgpKeyDetails * E-mail: DenBond7@gmail.com */ @Entity( - tableName = "contacts", + tableName = "recipients", indices = [ - Index(name = "name_in_contacts", value = ["name"]), - Index(name = "last_use_in_contacts", value = ["last_use"]), - Index(name = "email_in_contacts", value = ["email"], unique = true) + Index(name = "name_in_recipients", value = ["name"]), + Index(name = "last_use_in_recipients", value = ["last_use"]), + Index(name = "email_in_recipients", value = ["email"], unique = true) ] ) data class RecipientEntity( diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt index da5d2ccbc4..44b1bd9247 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt @@ -47,9 +47,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application private val searchPatternLiveData: MutableLiveData = MutableLiveData() val allContactsLiveData: LiveData> = - roomDatabase.recipientDao().getAllContactsLD() + roomDatabase.recipientDao().getAllRecipientsLD() val contactsWithPgpLiveData: LiveData>> = - Transformations.switchMap(roomDatabase.recipientDao().getAllContactsWithPgpLD()) { + Transformations.switchMap(roomDatabase.recipientDao().getAllRecipientsWithPgpLD()) { liveData { emit(Result.success(it)) } @@ -59,9 +59,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application liveData { emit(Result.loading()) val foundContacts = if (it.isNullOrEmpty()) { - roomDatabase.recipientDao().getAllContactsWithPgp() + roomDatabase.recipientDao().getAllRecipientsWithPgp() } else { - roomDatabase.recipientDao().getAllContactsWithPgpWhichMatched("%$it%") + roomDatabase.recipientDao().getAllRecipientsWithPgpWhichMatched("%$it%") } emit(Result.success(foundContacts)) } @@ -74,17 +74,17 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun copyPubKeysToRecipient(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) if (contact != null) { - val updateCandidate = pgpContact.toContactEntity().copy(id = contact.id) + val updateCandidate = pgpContact.toRecipientEntity().copy(id = contact.id) roomDatabase.recipientDao().updateSuspend(updateCandidate) } if (!pgpContact.email.equals(pgpContactFromKey.email, ignoreCase = true)) { val existedContact = - roomDatabase.recipientDao().getContactByEmailSuspend(pgpContactFromKey.email) + roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContactFromKey.email) if (existedContact == null) { - roomDatabase.recipientDao().insertSuspend(pgpContactFromKey.toContactEntity()) + roomDatabase.recipientDao().insertSuspend(pgpContactFromKey.toRecipientEntity()) } } } @@ -102,7 +102,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } fun contactChangesLiveData(recipientEntity: RecipientEntity): LiveData { - return roomDatabase.recipientDao().getContactByEmailLD(recipientEntity.email) + return roomDatabase.recipientDao().getRecipientByEmailLD(recipientEntity.email) } /** @@ -137,23 +137,25 @@ class ContactsViewModel(application: Application) : AccountViewModel(application for (email in emails) { if (GeneralUtil.isEmailValid(email)) { val emailLowerCase = email.lowercase(Locale.getDefault()) - var cachedContactEntity = - roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) - - if (cachedContactEntity == null) { - cachedContactEntity = PgpContact(emailLowerCase, null).toContactEntity() - roomDatabase.recipientDao().insertSuspend(cachedContactEntity) - cachedContactEntity = - roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) + var cachedRecipientEntity = + roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) + + if (cachedRecipientEntity == null) { + cachedRecipientEntity = PgpContact(emailLowerCase, null).toRecipientEntity() + roomDatabase.recipientDao().insertSuspend(cachedRecipientEntity) + cachedRecipientEntity = + roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) } else { try { - /*cachedContactEntity.publicKey?.let { + /*cachedRecipientEntity.publicKey?.let { val result = PgpKey.parseKeys(it).pgpKeyDetailsList - cachedContactEntity?.pgpKeyDetails = result.firstOrNull() + cachedRecipientEntity?.pgpKeyDetails = result.firstOrNull() }*/ } catch (e: Exception) { e.printStackTrace() - pgpContacts.add(cachedContactEntity.toPgpContact().copy(hasNotUsablePubKey = true)) + pgpContacts.add( + cachedRecipientEntity.toPgpContact().copy(hasNotUsablePubKey = true) + ) continue } } @@ -161,13 +163,13 @@ class ContactsViewModel(application: Application) : AccountViewModel(application try { if (true) { getPgpContactInfoFromServer(email = emailLowerCase)?.let { - cachedContactEntity = - updateCachedInfoWithAttesterInfo(cachedContactEntity, it, emailLowerCase) + cachedRecipientEntity = + updateCachedInfoWithAttesterInfo(cachedRecipientEntity, it, emailLowerCase) } } else { - cachedContactEntity?.pgpKeyDetails?.fingerprint?.let { fingerprint -> + cachedRecipientEntity?.pgpKeyDetails?.fingerprint?.let { fingerprint -> getPgpContactInfoFromServer(fingerprint = fingerprint)?.let { - val cacheLastModified = cachedContactEntity?.pgpKeyDetails?.lastModified ?: 0 + val cacheLastModified = cachedRecipientEntity?.pgpKeyDetails?.lastModified ?: 0 val attesterLastModified = it.pgpKeyDetails?.lastModified ?: 0 val attesterFingerprint = it.pgpKeyDetails?.fingerprint @@ -176,14 +178,14 @@ class ContactsViewModel(application: Application) : AccountViewModel(application true ) ) { - cachedContactEntity = - updateCachedInfoWithAttesterInfo(cachedContactEntity, it, emailLowerCase) + cachedRecipientEntity = + updateCachedInfoWithAttesterInfo(cachedRecipientEntity, it, emailLowerCase) } } } } - cachedContactEntity?.let { pgpContacts.add(it.toPgpContact()) } + cachedRecipientEntity?.let { pgpContacts.add(it.toPgpContact()) } } catch (e: Exception) { e.printStackTrace() ExceptionUtil.handleError(e) @@ -208,12 +210,12 @@ class ContactsViewModel(application: Application) : AccountViewModel(application cachedRecipientEntity.name.isNullOrEmpty() && cachedRecipientEntity.email.equals(attesterPgpContact.email, ignoreCase = true) ) { - attesterPgpContact.toContactEntity().copy( + attesterPgpContact.toRecipientEntity().copy( id = cachedRecipientEntity.id, email = cachedRecipientEntity.email ) } else { - attesterPgpContact.toContactEntity().copy( + attesterPgpContact.toRecipientEntity().copy( id = cachedRecipientEntity.id, name = cachedRecipientEntity.name, email = cachedRecipientEntity.email @@ -221,7 +223,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application } roomDatabase.recipientDao().updateSuspend(updateCandidate) - val lastVersion = roomDatabase.recipientDao().getContactByEmailSuspend(emailLowerCase) + val lastVersion = roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) /*lastVersion?.publicKey?.let { val result = PgpKey.parseKeys(it).pgpKeyDetailsList @@ -239,9 +241,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun addContact(pgpContact: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) if (contact == null) { - val isInserted = roomDatabase.recipientDao().insertSuspend(pgpContact.toContactEntity()) > 0 + val isInserted = + roomDatabase.recipientDao().insertSuspend(pgpContact.toRecipientEntity()) > 0 if (isInserted) { roomDatabase.pubKeysDao().insertSuspend(pgpContact.toPubKey()) } else { @@ -257,9 +260,9 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun updateContact(pgpContact: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) + val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) if (contact != null) { - val updateCandidate = pgpContact.toContactEntity().copy(id = contact.id) + val updateCandidate = pgpContact.toRecipientEntity().copy(id = contact.id) roomDatabase.recipientDao().updateSuspend(updateCandidate) } } @@ -268,9 +271,10 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun copyPubKeysToRecipient(recipientEntity: RecipientEntity?, pgpKeyDetails: PgpKeyDetails) { viewModelScope.launch { recipientEntity?.let { - val contactEntityFromPrimaryPgpContact = pgpKeyDetails.primaryPgpContact.toContactEntity() + val recipientEntityFromPrimaryPgpContact = + pgpKeyDetails.primaryPgpContact.toRecipientEntity() roomDatabase.recipientDao().updateSuspend( - contactEntityFromPrimaryPgpContact.copy( + recipientEntityFromPrimaryPgpContact.copy( id = recipientEntity.id, email = recipientEntity.email.lowercase(Locale.US), ) @@ -285,7 +289,7 @@ class ContactsViewModel(application: Application) : AccountViewModel(application fun deleteContactByEmail(email: String) { viewModelScope.launch { - roomDatabase.recipientDao().getContactByEmailSuspend(email)?.let { + roomDatabase.recipientDao().getRecipientByEmailSuspend(email)?.let { roomDatabase.recipientDao().deleteSuspend(it) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 25c088922b..202501e4ee 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -414,8 +414,9 @@ class MsgDetailsViewModel( if (block is PublicKeyMsgBlock) { val keyDetails = block.keyDetails ?: continue val pgpContact = keyDetails.primaryPgpContact - val contactEntity = roomDatabase.recipientDao().getContactByEmailSuspend(pgpContact.email) - //block.existingPgpContact = contactEntity?.toPgpContact() + val recipientEntity = + roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) + //block.existingPgpContact = recipientEntity?.toPgpContact() } if (block is DecryptErrorMsgBlock) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index 4782a21c89..5293607b71 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -247,9 +247,9 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat val contactsDao = roomDatabase.recipientDao() for (pgpContact in keyDetails.pgpContacts) { pgpContact.pubkey = keyDetails.publicKey - val temp = contactsDao.getContactByEmailSuspend(pgpContact.email) + val temp = contactsDao.getRecipientByEmailSuspend(pgpContact.email) if (temp == null && GeneralUtil.isEmailValid(pgpContact.email)) { - contactsDao.insertWithReplaceSuspend(pgpContact.toContactEntity()) + contactsDao.insertWithReplaceSuspend(pgpContact.toRecipientEntity()) //todo-DenBond7 Need to resolve a situation with different public keys. For example // we can have a situation when we have to different public keys with the same email } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index 7143e6cdb9..7a0f4104b8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -160,7 +160,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : } val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() - val availableContacts = contactsDao.getAllContacts() + val availableContacts = contactsDao.getAllRecipients() val contactsInDatabase = HashSet() val contactsWhichWillBeUpdated = HashSet() @@ -177,13 +177,13 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : for (emailAndNamePair in emailAndNamePairs) { if (contactsInDatabase.contains(emailAndNamePair.email)) { - val contactEntity = contactsByEmailMap[emailAndNamePair.email] - if (contactEntity?.email.isNullOrEmpty()) { + val recipientEntity = contactsByEmailMap[emailAndNamePair.email] + if (recipientEntity?.email.isNullOrEmpty()) { if (!contactsWhichWillBeUpdated.contains(emailAndNamePair.email)) { emailAndNamePair.email?.let { contactsWhichWillBeUpdated.add(it) } - contactEntity?.copy(name = emailAndNamePair.name)?.let { updateCandidates.add(it) } + recipientEntity?.copy(name = emailAndNamePair.name)?.let { updateCandidates.add(it) } } } } else { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt index 5cb3ad7b4e..223acdd797 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt @@ -59,7 +59,7 @@ data class PgpContact constructor( writeInt((if (hasNotUsablePubKey) 1 else 0)) } - fun toContactEntity(): RecipientEntity { + fun toRecipientEntity(): RecipientEntity { return RecipientEntity( email = email.lowercase(), name = name, diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt index 616a0974ee..58033f860e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt @@ -46,7 +46,7 @@ data class PublicKeyInfo constructor( writeString(publicKey) } - fun toContactEntity(): RecipientEntity { + fun toRecipientEntity(): RecipientEntity { return RecipientEntity( email = keyOwner.lowercase() ) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt index fc84738861..83de62a8d6 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt @@ -117,7 +117,7 @@ class SecurityUtils { fun getRecipientsPubKeys(context: Context, emails: MutableList): MutableList { val publicKeys = mutableListOf() val contacts = FlowCryptRoomDatabase.getDatabase(context).recipientDao() - .getContactsByEmails(emails) + .getRecipientsByEmails(emails) for (contact in contacts) { /*if (contact.publicKey?.isNotEmpty() == true) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 74c576d3c2..31fc64c5c4 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -48,13 +48,13 @@ class EmailAndNameUpdaterService : JobIntentService() { for (pair in pairs) { val email = pair.email?.lowercase(Locale.getDefault()) ?: continue - val contactEntity = recipientDao.getContactByEmail(email) - if (contactEntity != null) { - /*if (contactEntity.name.isNullOrEmpty()) { - contactsDao.update(contactEntity.copy(name = pair.name)) + val recipientEntity = recipientDao.getRecipientByEmail(email) + if (recipientEntity != null) { + /*if (recipientEntity.name.isNullOrEmpty()) { + contactsDao.update(recipientEntity.copy(name = pair.name)) }*/ } else { - recipientDao.insert(PgpContact(email, pair.name).toContactEntity()) + recipientDao.insert(PgpContact(email, pair.name).toRecipientEntity()) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index a8f200d57b..6af833a8f5 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -381,11 +381,11 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() for (email in msgInfo.getAllRecipients()) { - val contactEntity = contactsDao.getContactByEmail(email) - if (contactEntity == null) { - contactsDao.insert(PgpContact(email, null).toContactEntity()) + val recipientEntity = contactsDao.getRecipientByEmail(email) + if (recipientEntity == null) { + contactsDao.insert(PgpContact(email, null).toRecipientEntity()) } else { - //contactsDao.update(contactEntity.copy(lastUse = System.currentTimeMillis())) + //contactsDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) } } } catch (e: Exception) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index e1a05bc596..ce1a15be03 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -357,7 +357,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (weakRef.get() != null) { FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) .recipientDao() - .insert(newCandidates.subList(start, end).map { it.toContactEntity() }) + .insert(newCandidates.subList(start, end).map { it.toRecipientEntity() }) } i = end @@ -383,12 +383,12 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, val list = updateCandidates.subList(start, end + 1) list.forEach { pgpContact -> - val foundContactEntity = + val foundRecipientEntity = FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .recipientDao().getContactByEmail(pgpContact.email) - foundContactEntity?.let { entity -> + .recipientDao().getRecipientByEmail(pgpContact.email) + foundRecipientEntity?.let { entity -> /*contacts.add( - pgpContact.toContactEntity().copy(id = entity.id) + pgpContact.toRecipientEntity().copy(id = entity.id) )*/ } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt index 56ed09e46d..b4b39ee92c 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt @@ -76,7 +76,7 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setHasOptionsMenu(true) - recipientEntity = args.contactEntity + recipientEntity = args.recipientEntity } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -134,8 +134,8 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { private fun setupContactsViewModel() { recipientEntity?.let { - contactsViewModel.contactChangesLiveData(it).observe(viewLifecycleOwner, { contactEntity -> - /*this.contactEntity = contactEntity + contactsViewModel.contactChangesLiveData(it).observe(viewLifecycleOwner, { recipientEntity -> + /*this.recipientEntity = recipientEntity parseKeysViewModel.fetchKeys(it.publicKey)*/ }) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index 9380e062ac..53c1b4d11e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -429,13 +429,13 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, REQUEST_CODE_COPY_PUBLIC_KEY_FROM_OTHER_CONTACT -> { when (resultCode) { Activity.RESULT_OK -> if (data != null) { - val contactEntity = + val recipientEntity = data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) - contactEntity?.let { + recipientEntity?.let { pgpContactWithNoPublicKey?.email?.let { email -> contactsViewModel.copyPubKeysToRecipient( email, - contactEntity + recipientEntity ) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt index 71ef9fd955..e39c176292 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ContactsRecyclerViewAdapter.kt @@ -39,14 +39,14 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole } override fun onBindViewHolder(viewHolder: ContactsRecyclerViewAdapter.ViewHolder, position: Int) { - val contactEntity = list[position] + val recipientEntity = list[position] - if (contactEntity.name.isNullOrEmpty()) { + if (recipientEntity.name.isNullOrEmpty()) { viewHolder.textViewName.visibility = View.GONE viewHolder.textViewEmail.visibility = View.GONE viewHolder.textViewOnlyEmail.visibility = View.VISIBLE - viewHolder.textViewOnlyEmail.text = contactEntity.email + viewHolder.textViewOnlyEmail.text = recipientEntity.email viewHolder.textViewEmail.text = null viewHolder.textViewName.text = null } else { @@ -54,22 +54,22 @@ class ContactsRecyclerViewAdapter constructor(private val isDeleteEnabled: Boole viewHolder.textViewEmail.visibility = View.VISIBLE viewHolder.textViewOnlyEmail.visibility = View.GONE - viewHolder.textViewEmail.text = contactEntity.email - viewHolder.textViewName.text = contactEntity.name + viewHolder.textViewEmail.text = recipientEntity.email + viewHolder.textViewName.text = recipientEntity.name viewHolder.textViewOnlyEmail.text = null } if (isDeleteEnabled) { viewHolder.imageButtonDeleteContact.visibility = View.VISIBLE viewHolder.imageButtonDeleteContact.setOnClickListener { - onContactActionsListener?.onDeleteContact(contactEntity) + onContactActionsListener?.onDeleteContact(recipientEntity) } } else { viewHolder.imageButtonDeleteContact.visibility = View.GONE } viewHolder.itemView.setOnClickListener { - onContactActionsListener?.onContactClick(contactEntity) + onContactActionsListener?.onContactClick(recipientEntity) } } diff --git a/FlowCrypt/src/main/res/navigation/nav_graph.xml b/FlowCrypt/src/main/res/navigation/nav_graph.xml index 266425e44c..bba38e20d0 100644 --- a/FlowCrypt/src/main/res/navigation/nav_graph.xml +++ b/FlowCrypt/src/main/res/navigation/nav_graph.xml @@ -136,8 +136,8 @@ android:label="PublicKeyDetailsFragment" tools:layout="@layout/fragment_public_key_details"> + android:name="recipientEntity" + app:argType="com.flowcrypt.email.database.entity.RecipientEntity" /> Date: Tue, 26 Oct 2021 17:38:41 +0300 Subject: [PATCH 07/38] Renamed ContactsViewModel to RecipientsViewModel.| #1188 --- .../27.json | 22 ++++++++--------- ...ctsViewModel.kt => RecipientsViewModel.kt} | 2 +- .../email/ui/activity/EditContactActivity.kt | 6 ++--- .../ui/activity/ImportPgpContactActivity.kt | 8 +++---- .../ui/activity/ImportPublicKeyActivity.kt | 6 ++--- .../ui/activity/SelectContactsActivity.kt | 16 ++++++------- .../activity/fragment/ContactsListFragment.kt | 8 +++---- .../fragment/MessageDetailsFragment.kt | 10 ++++---- .../PreviewImportPgpContactFragment.kt | 8 +++---- .../fragment/PublicKeyDetailsFragment.kt | 13 +++++----- .../fragment/base/CreateMessageFragment.kt | 24 +++++++++---------- 11 files changed, 62 insertions(+), 61 deletions(-) rename FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/{ContactsViewModel.kt => RecipientsViewModel.kt} (99%) diff --git a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json index e506c24d8a..aa73cf348b 100644 --- a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json +++ b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 27, - "identityHash": "eaedc306ac21cf0fe3b68066c95d72e8", + "identityHash": "df7631eb8344e5890023dcb59321a47a", "entities": [ { "tableName": "accounts_aliases", @@ -471,7 +471,7 @@ ] }, { - "tableName": "contacts", + "tableName": "recipients", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `name` TEXT DEFAULT NULL, `last_use` INTEGER NOT NULL DEFAULT 0)", "fields": [ { @@ -509,28 +509,28 @@ }, "indices": [ { - "name": "name_in_contacts", + "name": "name_in_recipients", "unique": false, "columnNames": [ "name" ], - "createSql": "CREATE INDEX IF NOT EXISTS `name_in_contacts` ON `${TABLE_NAME}` (`name`)" + "createSql": "CREATE INDEX IF NOT EXISTS `name_in_recipients` ON `${TABLE_NAME}` (`name`)" }, { - "name": "last_use_in_contacts", + "name": "last_use_in_recipients", "unique": false, "columnNames": [ "last_use" ], - "createSql": "CREATE INDEX IF NOT EXISTS `last_use_in_contacts` ON `${TABLE_NAME}` (`last_use`)" + "createSql": "CREATE INDEX IF NOT EXISTS `last_use_in_recipients` ON `${TABLE_NAME}` (`last_use`)" }, { - "name": "email_in_contacts", + "name": "email_in_recipients", "unique": true, "columnNames": [ "email" ], - "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_in_contacts` ON `${TABLE_NAME}` (`email`)" + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_in_recipients` ON `${TABLE_NAME}` (`email`)" } ], "foreignKeys": [] @@ -921,7 +921,7 @@ }, { "tableName": "public_keys", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `recipient` TEXT NOT NULL, `fingerprint` TEXT NOT NULL, `public_key` BLOB NOT NULL, FOREIGN KEY(`recipient`) REFERENCES `contacts`(`email`) ON UPDATE NO ACTION ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `recipient` TEXT NOT NULL, `fingerprint` TEXT NOT NULL, `public_key` BLOB NOT NULL, FOREIGN KEY(`recipient`) REFERENCES `recipients`(`email`) ON UPDATE NO ACTION ON DELETE CASCADE )", "fields": [ { "fieldPath": "id", @@ -975,7 +975,7 @@ ], "foreignKeys": [ { - "table": "contacts", + "table": "recipients", "onDelete": "CASCADE", "onUpdate": "NO ACTION", "columns": [ @@ -991,7 +991,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'eaedc306ac21cf0fe3b68066c95d72e8')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'df7631eb8344e5890023dcb59321a47a')" ] } } \ No newline at end of file diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt similarity index 99% rename from FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt rename to FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt index 44b1bd9247..4851b291e9 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/ContactsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt @@ -42,7 +42,7 @@ import java.util.* * Time: 11:19 AM * E-mail: DenBond7@gmail.com */ -class ContactsViewModel(application: Application) : AccountViewModel(application) { +class RecipientsViewModel(application: Application) : AccountViewModel(application) { private val apiRepository: ApiRepository = FlowcryptApiRepository() private val searchPatternLiveData: MutableLiveData = MutableLiveData() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt index 48023cfcd1..7b47e03353 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/EditContactActivity.kt @@ -18,7 +18,7 @@ import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.showDialogFragment import com.flowcrypt.email.extensions.showInfoDialogFragment -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.KeyImportDetails import com.flowcrypt.email.model.KeyImportModel import com.flowcrypt.email.security.model.PgpKeyDetails @@ -34,7 +34,7 @@ import com.flowcrypt.email.util.GeneralUtil */ class EditContactActivity : BaseImportKeyActivity(), UpdatePublicKeyOfContactDialogFragment.OnKeySelectedListener { - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private var recipientEntity: RecipientEntity? = null private var editTextNewPubKey: EditText? = null @@ -96,7 +96,7 @@ class EditContactActivity : BaseImportKeyActivity(), } override fun onKeySelected(pgpKeyDetails: PgpKeyDetails) { - contactsViewModel.copyPubKeysToRecipient(recipientEntity, pgpKeyDetails) + recipientsViewModel.copyPubKeysToRecipient(recipientEntity, pgpKeyDetails) finish() } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt index 5c548bd23d..5749dbe706 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt @@ -24,7 +24,7 @@ import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.KeyImportDetails import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.ui.activity.base.BaseImportKeyActivity @@ -43,7 +43,7 @@ import java.util.* * E-mail: DenBond7@gmail.com */ class ImportPgpContactActivity : BaseImportKeyActivity() { - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private var editTextEmailOrId: EditText? = null private var isSearchingActiveNow: Boolean = false @@ -158,7 +158,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { if (GeneralUtil.isConnected(this)) { editTextEmailOrId?.text?.toString()?.let { fetchPubKeysRequestCode = System.currentTimeMillis() - contactsViewModel.fetchPubKeys(it, fetchPubKeysRequestCode) + recipientsViewModel.fetchPubKeys(it, fetchPubKeysRequestCode) } } else { showInfoSnackbar(rootView, getString(R.string.internet_connection_is_not_available)) @@ -166,7 +166,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { } private fun setupContactsViewModel() { - contactsViewModel.pubKeysFromServerLiveData.observe(this, Observer { + recipientsViewModel.pubKeysFromServerLiveData.observe(this, Observer { if (it.requestCode != fetchPubKeysRequestCode) return@Observer when (it.status) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt index 5db23edc5e..fef8af9233 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt @@ -12,7 +12,7 @@ import android.os.Bundle import androidx.activity.viewModels import com.flowcrypt.email.R import com.flowcrypt.email.database.entity.AccountEntity -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.KeyImportDetails import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.model.PgpKeyDetails @@ -31,7 +31,7 @@ import com.google.android.material.snackbar.Snackbar class ImportPublicKeyActivity : BaseImportKeyActivity() { private var pgpContact: PgpContact? = null - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() override val contentViewResourceId: Int get() = R.layout.activity_import_public_key_for_pgp_contact @@ -82,7 +82,7 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { val pgpContactFromKey = keyDetails.primaryPgpContact pgpContact?.pubkey = pgpContactFromKey.pubkey pgpContact?.hasPgp = pgpContact?.pubkey?.isNotEmpty() == true - pgpContact?.let { contactsViewModel.copyPubKeysToRecipient(it, pgpContactFromKey) } + pgpContact?.let { recipientsViewModel.copyPubKeysToRecipient(it, pgpContactFromKey) } } companion object { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index 155bab1af5..5ab0f4336a 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -25,7 +25,7 @@ import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.ui.activity.base.BaseBackStackActivity import com.flowcrypt.email.ui.adapter.ContactsRecyclerViewAdapter import com.flowcrypt.email.util.GeneralUtil @@ -49,7 +49,7 @@ class SelectContactsActivity : BaseBackStackActivity(), private val contactsRecyclerViewAdapter: ContactsRecyclerViewAdapter = ContactsRecyclerViewAdapter(false) private var searchPattern: String? = null - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() @VisibleForTesting private val countingIdlingResourceForFilter = CountingIdlingResource( @@ -119,22 +119,22 @@ class SelectContactsActivity : BaseBackStackActivity(), override fun onQueryTextSubmit(query: String): Boolean { searchPattern = query - contactsViewModel.filterContacts(searchPattern) + recipientsViewModel.filterContacts(searchPattern) return true } override fun onQueryTextChange(newText: String): Boolean { searchPattern = newText - contactsViewModel.filterContacts(searchPattern) + recipientsViewModel.filterContacts(searchPattern) return true } private fun setupContactsViewModel() { - contactsViewModel.allContactsLiveData.observe(this, { - contactsViewModel.filterContacts(searchPattern) + recipientsViewModel.allContactsLiveData.observe(this, { + recipientsViewModel.filterContacts(searchPattern) }) - contactsViewModel.contactsWithPgpSearchLiveData.observe(this, { + recipientsViewModel.contactsWithPgpSearchLiveData.observe(this, { when (it.status) { Result.Status.LOADING -> { countingIdlingResourceForFilter.incrementSafely("searchPattern = $searchPattern") @@ -158,7 +158,7 @@ class SelectContactsActivity : BaseBackStackActivity(), } }) - contactsViewModel.filterContacts(searchPattern) + recipientsViewModel.filterContacts(searchPattern) } companion object { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt index fbaecdfb8f..3507d066d2 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/ContactsListFragment.kt @@ -19,7 +19,7 @@ import com.flowcrypt.email.R import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.navController -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.ui.activity.ImportPgpContactActivity import com.flowcrypt.email.ui.activity.fragment.base.BaseFragment import com.flowcrypt.email.ui.adapter.ContactsRecyclerViewAdapter @@ -40,7 +40,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnConta private var emptyView: View? = null private val contactsRecyclerViewAdapter: ContactsRecyclerViewAdapter = ContactsRecyclerViewAdapter(true) - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() override val contentResourceId: Int = R.layout.fragment_contacts_list @@ -78,7 +78,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnConta } override fun onDeleteContact(recipientEntity: RecipientEntity) { - contactsViewModel.deleteContact(recipientEntity) + recipientsViewModel.deleteContact(recipientEntity) Toast.makeText( context, getString(R.string.the_contact_was_deleted, recipientEntity.email), Toast.LENGTH_SHORT @@ -110,7 +110,7 @@ class ContactsListFragment : BaseFragment(), ContactsRecyclerViewAdapter.OnConta } private fun setupContactsViewModel() { - contactsViewModel.contactsWithPgpLiveData.observe(viewLifecycleOwner, { + recipientsViewModel.contactsWithPgpLiveData.observe(viewLifecycleOwner, { when (it.status) { Result.Status.LOADING -> { UIUtil.exchangeViewVisibility(true, progressBar, recyclerViewContacts) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt index 1de7b4a81d..9a9d8571d3 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt @@ -66,9 +66,9 @@ import com.flowcrypt.email.extensions.showTwoWayDialog import com.flowcrypt.email.extensions.toast import com.flowcrypt.email.extensions.visible import com.flowcrypt.email.extensions.visibleOrGone -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.jetpack.viewmodel.LabelsViewModel import com.flowcrypt.email.jetpack.viewmodel.MsgDetailsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.jetpack.viewmodel.factory.MsgDetailsViewModelFactory import com.flowcrypt.email.model.MessageEncryptionType import com.flowcrypt.email.model.MessageType @@ -191,7 +191,7 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi private var msgInfo: IncomingMessageInfo? = null private var folderType: FoldersManager.FolderType? = null private val labelsViewModel: LabelsViewModel by viewModels() - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private val msgDetailsAdapter = MsgDetailsRecyclerViewAdapter() private var isAdditionalActionEnabled: Boolean = false @@ -1031,7 +1031,7 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi button.setOnClickListener { v -> val pgpContact = block.keyDetails?.primaryPgpContact if (pgpContact != null) { - contactsViewModel.addContact(pgpContact) + recipientsViewModel.addContact(pgpContact) v.visibility = View.GONE } else { Toast.makeText( @@ -1055,7 +1055,7 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi button.setOnClickListener { v -> val pgpContact = block.keyDetails?.primaryPgpContact if (pgpContact != null) { - contactsViewModel.updateContact(pgpContact) + recipientsViewModel.updateContact(pgpContact) Toast.makeText(context, R.string.contact_successfully_updated, Toast.LENGTH_SHORT).show() v.visibility = View.GONE } else { @@ -1080,7 +1080,7 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi button.setOnClickListener { v -> val pgpContact = block.keyDetails?.primaryPgpContact if (pgpContact != null) { - contactsViewModel.updateContact(pgpContact) + recipientsViewModel.updateContact(pgpContact) Toast.makeText(context, R.string.contact_successfully_replaced, Toast.LENGTH_SHORT).show() v.visibility = View.GONE } else { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index ce1a15be03..6debc39152 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -26,7 +26,7 @@ import com.flowcrypt.email.Constants import com.flowcrypt.email.R import com.flowcrypt.email.database.FlowCryptRoomDatabase import com.flowcrypt.email.database.entity.RecipientEntity -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.model.PublicKeyInfo import com.flowcrypt.email.model.results.LoaderResult @@ -69,7 +69,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, private var publicKeysString: String? = null private var publicKeysFileUri: Uri? = null - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private val adapter: ImportPgpContactsRecyclerViewAdapter = ImportPgpContactsRecyclerViewAdapter() private var isParsingStarted: Boolean = false @@ -149,11 +149,11 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, } override fun onSaveContactClick(publicKeyInfo: PublicKeyInfo) { - contactsViewModel.addContact(publicKeyInfo.toPgpContact()) + recipientsViewModel.addContact(publicKeyInfo.toPgpContact()) } override fun onUpdateContactClick(publicKeyInfo: PublicKeyInfo) { - contactsViewModel.updateContact(publicKeyInfo.toPgpContact()) + recipientsViewModel.updateContact(publicKeyInfo.toPgpContact()) } private fun initViews(root: View) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt index b4b39ee92c..87b6896531 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PublicKeyDetailsFragment.kt @@ -30,8 +30,8 @@ import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.FlowCryptRoomDatabase import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.navController -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel import com.flowcrypt.email.jetpack.viewmodel.ParseKeysViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.ui.activity.EditContactActivity import com.flowcrypt.email.ui.activity.fragment.base.BaseFragment @@ -54,7 +54,7 @@ import java.util.Date class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { private val args by navArgs() - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private val parseKeysViewModel: ParseKeysViewModel by viewModels() private var recipientEntity: RecipientEntity? = null @@ -134,10 +134,11 @@ class PublicKeyDetailsFragment : BaseFragment(), ProgressBehaviour { private fun setupContactsViewModel() { recipientEntity?.let { - contactsViewModel.contactChangesLiveData(it).observe(viewLifecycleOwner, { recipientEntity -> - /*this.recipientEntity = recipientEntity - parseKeysViewModel.fetchKeys(it.publicKey)*/ - }) + recipientsViewModel.contactChangesLiveData(it) + .observe(viewLifecycleOwner, { recipientEntity -> + /*this.recipientEntity = recipientEntity + parseKeysViewModel.fetchKeys(it.publicKey)*/ + }) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt index 53c1b4d11e..8c0bc07b5a 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/base/CreateMessageFragment.kt @@ -60,7 +60,7 @@ import com.flowcrypt.email.extensions.showInfoDialog import com.flowcrypt.email.extensions.showKeyboard import com.flowcrypt.email.extensions.showNeedPassphraseDialog import com.flowcrypt.email.jetpack.viewmodel.AccountAliasesViewModel -import com.flowcrypt.email.jetpack.viewmodel.ContactsViewModel +import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.MessageEncryptionType import com.flowcrypt.email.model.MessageType import com.flowcrypt.email.model.PgpContact @@ -115,7 +115,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, private lateinit var draftCacheDir: File private val accountAliasesViewModel: AccountAliasesViewModel by viewModels() - private val contactsViewModel: ContactsViewModel by viewModels() + private val recipientsViewModel: RecipientsViewModel by viewModels() private var pgpContactsTo: MutableList? = null private var pgpContactsCc: MutableList? = null @@ -433,7 +433,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, data.getParcelableExtra(SelectContactsActivity.KEY_EXTRA_PGP_CONTACT) recipientEntity?.let { pgpContactWithNoPublicKey?.email?.let { email -> - contactsViewModel.copyPubKeysToRecipient( + recipientsViewModel.copyPubKeysToRecipient( email, recipientEntity ) @@ -831,7 +831,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, private fun updateRecipients() { recipientsTo?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts( + recipientsViewModel.fetchAndUpdateInfoAboutContacts( RecipientEntity.Type.TO, it ) @@ -839,7 +839,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, if (layoutCc?.visibility == View.VISIBLE) { recipientsCc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts( + recipientsViewModel.fetchAndUpdateInfoAboutContacts( RecipientEntity.Type.CC, it ) @@ -851,7 +851,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, if (layoutBcc?.visibility == View.VISIBLE) { recipientsBcc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts( + recipientsViewModel.fetchAndUpdateInfoAboutContacts( RecipientEntity.Type.BCC, it ) @@ -896,19 +896,19 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, when (type) { RecipientEntity.Type.TO -> { recipientsTo?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.TO, it) + recipientsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.TO, it) } } RecipientEntity.Type.CC -> { recipientsCc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.CC, it) + recipientsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.CC, it) } } RecipientEntity.Type.BCC -> { recipientsBcc?.chipAndTokenValues?.let { - contactsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.BCC, it) + recipientsViewModel.fetchAndUpdateInfoAboutContacts(RecipientEntity.Type.BCC, it) } } } @@ -1674,7 +1674,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, } private fun handleUpdatingToContacts() { - contactsViewModel.contactsToLiveData.observe(viewLifecycleOwner, { + recipientsViewModel.contactsToLiveData.observe(viewLifecycleOwner, { when (it.status) { Result.Status.LOADING -> { hostActivity?.countingIdlingResource?.incrementSafely() @@ -1705,7 +1705,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, } private fun handleUpdatingCcContacts() { - contactsViewModel.contactsCcLiveData.observe(viewLifecycleOwner, { + recipientsViewModel.contactsCcLiveData.observe(viewLifecycleOwner, { when (it.status) { Result.Status.LOADING -> { hostActivity?.countingIdlingResource?.incrementSafely() @@ -1736,7 +1736,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, } private fun handleUpdatingBccContacts() { - contactsViewModel.contactsBccLiveData.observe(viewLifecycleOwner, { + recipientsViewModel.contactsBccLiveData.observe(viewLifecycleOwner, { when (it.status) { Result.Status.LOADING -> { hostActivity?.countingIdlingResource?.incrementSafely() From 55355f089a4b6f1e2c78f918fd524bfb4c883689 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 18:39:39 +0300 Subject: [PATCH 08/38] Fixed a few methods in RecipientDao. Refactored code.| #1188 --- .../email/ui/activity/CreateMessageActivityTest.kt | 6 +++--- .../flowcrypt/email/database/dao/RecipientDao.kt | 8 +++++++- .../email/jetpack/viewmodel/MsgDetailsViewModel.kt | 1 + .../email/jetpack/viewmodel/PrivateKeysViewModel.kt | 6 +++--- .../email/jetpack/viewmodel/RecipientsViewModel.kt | 6 +++--- .../jetpack/workmanager/sync/LoadContactsWorker.kt | 8 ++++---- .../com/flowcrypt/email/security/SecurityUtils.kt | 13 +++++++------ .../email/service/EmailAndNameUpdaterService.kt | 2 +- .../PrepareOutgoingMessagesJobIntentService.kt | 8 ++++---- .../fragment/PreviewImportPgpContactFragment.kt | 2 +- 10 files changed, 34 insertions(+), 26 deletions(-) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt index 73bbee917f..8778481558 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageActivityTest.kt @@ -661,9 +661,9 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { val keyDetailsFromAssets = PrivateKeysManager.getPgpKeyDetailsFromAssets("pgp/expired_fixed@flowcrypt.test_expired_pub.asc") val contact = keyDetailsFromAssets.primaryPgpContact - val contactsDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() - contactsDao.insert(contact.toRecipientEntity()) - val existedContact = contactsDao.getRecipientByEmail(contact.email) + val recipientDao = FlowCryptRoomDatabase.getDatabase(getTargetContext()).recipientDao() + recipientDao.insert(contact.toRecipientEntity()) + val existedContact = recipientDao.getRecipientByEmail(contact.email) ?: throw IllegalArgumentException("Contact not found") val existedKeyExpiration = PgpKey.parseKeys( diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt index a3517084a3..dbff2cc8de 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt @@ -9,7 +9,9 @@ import android.database.Cursor import androidx.lifecycle.LiveData import androidx.room.Dao import androidx.room.Query +import androidx.room.Transaction import com.flowcrypt.email.database.entity.RecipientEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys /** * This object describes a logic of work with [RecipientEntity]. @@ -50,12 +52,16 @@ interface RecipientDao : BaseDao { @Query("SELECT * FROM recipients WHERE email = :email") fun getRecipientByEmailLD(email: String): LiveData + //fixed + @Transaction @Query("SELECT * FROM recipients WHERE email IN (:emails)") - fun getRecipientsByEmails(emails: Collection): List + fun getRecipientsWithPubKeysByEmails(emails: Collection): List + //fixed @Query("SELECT * FROM recipients WHERE email LIKE :searchPattern ORDER BY last_use DESC") fun getFilteredCursor(searchPattern: String): Cursor? + //fixed @Query("DELETE FROM recipients") suspend fun deleteAll(): Int } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 202501e4ee..3454035a48 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -414,6 +414,7 @@ class MsgDetailsViewModel( if (block is PublicKeyMsgBlock) { val keyDetails = block.keyDetails ?: continue val pgpContact = keyDetails.primaryPgpContact + //todo-denbond7 need to rework on this code val recipientEntity = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) //block.existingPgpContact = recipientEntity?.toPgpContact() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index 5293607b71..8cae15aaa2 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -244,12 +244,12 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat ) } //update contacts table - val contactsDao = roomDatabase.recipientDao() + val recipientDao = roomDatabase.recipientDao() for (pgpContact in keyDetails.pgpContacts) { pgpContact.pubkey = keyDetails.publicKey - val temp = contactsDao.getRecipientByEmailSuspend(pgpContact.email) + val temp = recipientDao.getRecipientByEmailSuspend(pgpContact.email) if (temp == null && GeneralUtil.isEmailValid(pgpContact.email)) { - contactsDao.insertWithReplaceSuspend(pgpContact.toRecipientEntity()) + recipientDao.insertWithReplaceSuspend(pgpContact.toRecipientEntity()) //todo-DenBond7 Need to resolve a situation with different public keys. For example // we can have a situation when we have to different public keys with the same email } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt index 4851b291e9..63a5b49034 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt @@ -74,9 +74,9 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati fun copyPubKeysToRecipient(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) - if (contact != null) { - val updateCandidate = pgpContact.toRecipientEntity().copy(id = contact.id) + val recipient = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) + if (recipient != null) { + val updateCandidate = pgpContact.toRecipientEntity().copy(id = recipient.id) roomDatabase.recipientDao().updateSuspend(updateCandidate) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index 7a0f4104b8..0382deecef 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -159,8 +159,8 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : emailAndNamePairs.addAll(parseRecipients(msg, Message.RecipientType.BCC)) } - val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() - val availableContacts = contactsDao.getAllRecipients() + val recipientDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() + val availableContacts = recipientDao.getAllRecipients() val contactsInDatabase = HashSet() val contactsWhichWillBeUpdated = HashSet() @@ -201,8 +201,8 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : } } - contactsDao.updateSuspend(updateCandidates) - contactsDao.insertSuspend(newCandidates) + recipientDao.updateSuspend(updateCandidates) + recipientDao.insertSuspend(newCandidates) } /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt index 83de62a8d6..a891ffca04 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/SecurityUtils.kt @@ -116,13 +116,14 @@ class SecurityUtils { @JvmStatic fun getRecipientsPubKeys(context: Context, emails: MutableList): MutableList { val publicKeys = mutableListOf() - val contacts = FlowCryptRoomDatabase.getDatabase(context).recipientDao() - .getRecipientsByEmails(emails) + val recipientsWithPubKeys = FlowCryptRoomDatabase.getDatabase(context).recipientDao() + .getRecipientsWithPubKeysByEmails(emails) - for (contact in contacts) { - /*if (contact.publicKey?.isNotEmpty() == true) { - contact.publicKey.let { publicKeys.add(String(it)) } - }*/ + //Note: for now we encrypt a message for all public keys of the given recipient + for (recipientWithPubKeys in recipientsWithPubKeys) { + if (recipientWithPubKeys.publicKeys.isNotEmpty()) { + publicKeys.addAll(recipientWithPubKeys.publicKeys.map { String(it.publicKey) }) + } } return publicKeys diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 31fc64c5c4..61fb1bdf4b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -51,7 +51,7 @@ class EmailAndNameUpdaterService : JobIntentService() { val recipientEntity = recipientDao.getRecipientByEmail(email) if (recipientEntity != null) { /*if (recipientEntity.name.isNullOrEmpty()) { - contactsDao.update(recipientEntity.copy(name = pair.name)) + recipientDao.update(recipientEntity.copy(name = pair.name)) }*/ } else { recipientDao.insert(PgpContact(email, pair.name).toRecipientEntity()) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index 6af833a8f5..3c3a76db4b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -378,14 +378,14 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { */ private fun updateContactsLastUseDateTime(msgInfo: OutgoingMessageInfo) { try { - val contactsDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() + val recipientDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() for (email in msgInfo.getAllRecipients()) { - val recipientEntity = contactsDao.getRecipientByEmail(email) + val recipientEntity = recipientDao.getRecipientByEmail(email) if (recipientEntity == null) { - contactsDao.insert(PgpContact(email, null).toRecipientEntity()) + recipientDao.insert(PgpContact(email, null).toRecipientEntity()) } else { - //contactsDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) + //recipientDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) } } } catch (e: Exception) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index 6debc39152..a5bbf8cb71 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -307,7 +307,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (weakRef.get() != null) { //todo-denbond7 fix me val contact = null/*FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .contactsDao().getContactByEmail(keyOwner)?.toPgpContact()*/ + .recipientDao().getContactByEmail(keyOwner)?.toPgpContact()*/ return PublicKeyInfo(fingerprint, keyOwner, contact, pgpKeyDetails.publicKey) } } From c36f3adb0c85d20a41b6d1558a7170f46529a084 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 18:52:39 +0300 Subject: [PATCH 09/38] Fixed RecipientDao.getRecipientByEmail().| #1188 --- .../email/database/dao/RecipientDao.kt | 4 ++++ .../email/service/EmailAndNameUpdaterService.kt | 4 ++-- .../PrepareOutgoingMessagesJobIntentService.kt | 2 +- .../fragment/PreviewImportPgpContactFragment.kt | 17 ++++++++--------- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt index dbff2cc8de..9d18007d2b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt @@ -46,6 +46,7 @@ interface RecipientDao : BaseDao { @Query("SELECT * FROM recipients WHERE email = :email") suspend fun getRecipientByEmailSuspend(email: String): RecipientEntity? + //fixed @Query("SELECT * FROM recipients WHERE email = :email") fun getRecipientByEmail(email: String): RecipientEntity? @@ -64,4 +65,7 @@ interface RecipientDao : BaseDao { //fixed @Query("DELETE FROM recipients") suspend fun deleteAll(): Int + + @Query("SELECT * FROM recipients WHERE email = :email") + fun getRecipientWithPubKeysByEmail(email: String): RecipientWithPubKeys? } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 61fb1bdf4b..4d99a02011 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -50,9 +50,9 @@ class EmailAndNameUpdaterService : JobIntentService() { val email = pair.email?.lowercase(Locale.getDefault()) ?: continue val recipientEntity = recipientDao.getRecipientByEmail(email) if (recipientEntity != null) { - /*if (recipientEntity.name.isNullOrEmpty()) { + if (recipientEntity.name.isNullOrEmpty()) { recipientDao.update(recipientEntity.copy(name = pair.name)) - }*/ + } } else { recipientDao.insert(PgpContact(email, pair.name).toRecipientEntity()) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index 3c3a76db4b..3cc3973e24 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -385,7 +385,7 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { if (recipientEntity == null) { recipientDao.insert(PgpContact(email, null).toRecipientEntity()) } else { - //recipientDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) + recipientDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) } } } catch (e: Exception) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index a5bbf8cb71..716509a5cb 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -326,6 +326,8 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, override fun doInBackground(vararg uris: Void): Boolean { val newCandidates = ArrayList() val updateCandidates = ArrayList() + val recipientDao = + FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!).recipientDao() for (publicKeyInfo in publicKeyInfoList) { val pgpContact = PgpContact( @@ -355,9 +357,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (newCandidates.size - i > STEP_AMOUNT) i + STEP_AMOUNT else newCandidates.size if (weakRef.get() != null) { - FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .recipientDao() - .insert(newCandidates.subList(start, end).map { it.toRecipientEntity() }) + recipientDao.insert(newCandidates.subList(start, end).map { it.toRecipientEntity() }) } i = end @@ -379,22 +379,21 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (updateCandidates.size - i > STEP_AMOUNT) i + STEP_AMOUNT else updateCandidates.size - 1 if (weakRef.get() != null) { - val contacts = mutableListOf() + val recipients = mutableListOf() val list = updateCandidates.subList(start, end + 1) list.forEach { pgpContact -> val foundRecipientEntity = - FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .recipientDao().getRecipientByEmail(pgpContact.email) + recipientDao.getRecipientWithPubKeysByEmail(pgpContact.email) foundRecipientEntity?.let { entity -> - /*contacts.add( + //todo-denbond7 fix me + /*recipients.add( pgpContact.toRecipientEntity().copy(id = entity.id) )*/ } } - FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!).recipientDao() - .update(contacts) + recipientDao.update(recipients) } i = end + 1 From 5803a9e37d72146518bcc7314a48e683156fc465 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Tue, 26 Oct 2021 19:11:16 +0300 Subject: [PATCH 10/38] Fixed some moments with adding/updating a recipient with a pub key.| #1188 --- .../email/database/dao/RecipientDao.kt | 1 + .../jetpack/viewmodel/PrivateKeysViewModel.kt | 9 +++-- .../workmanager/sync/LoadContactsWorker.kt | 7 +--- .../flowcrypt/email/model/PublicKeyInfo.kt | 38 +++---------------- .../service/EmailAndNameUpdaterService.kt | 7 ++-- ...PrepareOutgoingMessagesJobIntentService.kt | 6 +-- .../PreviewImportPgpContactFragment.kt | 35 +++++++++-------- .../ImportPgpContactsRecyclerViewAdapter.kt | 24 ++++-------- 8 files changed, 42 insertions(+), 85 deletions(-) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt index 9d18007d2b..22d26dfe66 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt @@ -66,6 +66,7 @@ interface RecipientDao : BaseDao { @Query("DELETE FROM recipients") suspend fun deleteAll(): Int + @Transaction @Query("SELECT * FROM recipients WHERE email = :email") fun getRecipientWithPubKeysByEmail(email: String): RecipientWithPubKeys? } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index 8cae15aaa2..5264628386 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -245,13 +245,14 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat } //update contacts table val recipientDao = roomDatabase.recipientDao() + val pubKeysDao = roomDatabase.pubKeysDao() for (pgpContact in keyDetails.pgpContacts) { pgpContact.pubkey = keyDetails.publicKey - val temp = recipientDao.getRecipientByEmailSuspend(pgpContact.email) - if (temp == null && GeneralUtil.isEmailValid(pgpContact.email)) { + val recipientWithPubKeys = + recipientDao.getRecipientByEmailSuspend(pgpContact.email) + if (recipientWithPubKeys == null && GeneralUtil.isEmailValid(pgpContact.email)) { recipientDao.insertWithReplaceSuspend(pgpContact.toRecipientEntity()) - //todo-DenBond7 Need to resolve a situation with different public keys. For example - // we can have a situation when we have to different public keys with the same email + pubKeysDao.insertWithReplaceSuspend(pgpContact.toPubKey()) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt index 0382deecef..c0f8b2cc4d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt @@ -190,12 +190,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : if (!contactsWhichWillBeCreated.contains(emailAndNamePair.email)) { emailAndNamePair.email?.let { contactsWhichWillBeCreated.add(it) - newCandidates.add( - RecipientEntity( - email = it, - name = emailAndNamePair.name - ) - ) + newCandidates.add(RecipientEntity(email = it, name = emailAndNamePair.name)) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt index 58033f860e..01ad2aefe0 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt @@ -5,9 +5,8 @@ package com.flowcrypt.email.model -import android.os.Parcel -import android.os.Parcelable import com.flowcrypt.email.database.entity.RecipientEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys /** * This class describes information about some public key. @@ -20,30 +19,11 @@ import com.flowcrypt.email.database.entity.RecipientEntity data class PublicKeyInfo constructor( val fingerprint: String, val keyOwner: String, - var pgpContact: PgpContact? = null, + var recipientWithPubKeys: RecipientWithPubKeys? = null, val publicKey: String -) : Parcelable { - val isUpdateEnabled: Boolean - get() = pgpContact != null && (pgpContact!!.fingerprint == null || pgpContact!!.fingerprint != fingerprint) - - fun hasPgpContact(): Boolean { - return pgpContact != null - } - - constructor(source: Parcel) : this( - source.readString()!!, - source.readString()!!, - source.readParcelable(PgpContact::class.java.classLoader), - source.readString()!! - ) - - override fun describeContents() = 0 - - override fun writeToParcel(dest: Parcel, flags: Int) = with(dest) { - writeString(fingerprint) - writeString(keyOwner) - writeParcelable(pgpContact, flags) - writeString(publicKey) +) { + fun hasPgp(): Boolean { + return recipientWithPubKeys?.publicKeys?.isNotEmpty() == true } fun toRecipientEntity(): RecipientEntity { @@ -63,12 +43,4 @@ data class PublicKeyInfo constructor( lastUse = 0 ) } - - companion object { - @JvmField - val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): PublicKeyInfo = PublicKeyInfo(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 4d99a02011..592efe46d3 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -11,11 +11,10 @@ import androidx.core.app.JobIntentService import com.flowcrypt.email.BuildConfig import com.flowcrypt.email.database.FlowCryptRoomDatabase import com.flowcrypt.email.database.dao.RecipientDao +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.jobscheduler.JobIdManager import com.flowcrypt.email.model.EmailAndNamePair -import com.flowcrypt.email.model.PgpContact import java.util.ArrayList -import java.util.Locale /** * This service does update a name of some email entry or creates a new email entry if it not @@ -47,14 +46,14 @@ class EmailAndNameUpdaterService : JobIntentService() { ?: return for (pair in pairs) { - val email = pair.email?.lowercase(Locale.getDefault()) ?: continue + val email = pair.email?.lowercase() ?: continue val recipientEntity = recipientDao.getRecipientByEmail(email) if (recipientEntity != null) { if (recipientEntity.name.isNullOrEmpty()) { recipientDao.update(recipientEntity.copy(name = pair.name)) } } else { - recipientDao.insert(PgpContact(email, pair.name).toRecipientEntity()) + recipientDao.insert(RecipientEntity(email = email, name = pair.name)) } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index 3cc3973e24..c45fd1bfb8 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -21,12 +21,12 @@ import com.flowcrypt.email.database.MessageState import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.AttachmentEntity import com.flowcrypt.email.database.entity.MessageEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.jetpack.workmanager.ForwardedAttachmentsDownloaderWorker import com.flowcrypt.email.jetpack.workmanager.MessagesSenderWorker import com.flowcrypt.email.jobscheduler.JobIdManager import com.flowcrypt.email.model.MessageEncryptionType import com.flowcrypt.email.model.MessageType -import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.SecurityUtils import com.flowcrypt.email.security.pgp.PgpEncrypt import com.flowcrypt.email.ui.notifications.ErrorNotificationManager @@ -379,11 +379,11 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { private fun updateContactsLastUseDateTime(msgInfo: OutgoingMessageInfo) { try { val recipientDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() - + //todo-denbond7 we can improve it to use a single request to the local database for (email in msgInfo.getAllRecipients()) { val recipientEntity = recipientDao.getRecipientByEmail(email) if (recipientEntity == null) { - recipientDao.insert(PgpContact(email, null).toRecipientEntity()) + recipientDao.insert(RecipientEntity(email = email)) } else { recipientDao.update(recipientEntity.copy(lastUse = System.currentTimeMillis())) } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt index 716509a5cb..a054aaa1e5 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/PreviewImportPgpContactFragment.kt @@ -25,7 +25,6 @@ import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.Constants import com.flowcrypt.email.R import com.flowcrypt.email.database.FlowCryptRoomDatabase -import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.model.PublicKeyInfo @@ -305,10 +304,10 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, emails.add(keyOwner) if (weakRef.get() != null) { - //todo-denbond7 fix me - val contact = null/*FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) - .recipientDao().getContactByEmail(keyOwner)?.toPgpContact()*/ - return PublicKeyInfo(fingerprint, keyOwner, contact, pgpKeyDetails.publicKey) + val recipientWithPubKeys = + FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) + .recipientDao().getRecipientWithPubKeysByEmail(keyOwner) + return PublicKeyInfo(fingerprint, keyOwner, recipientWithPubKeys, pgpKeyDetails.publicKey) } } return null @@ -326,8 +325,9 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, override fun doInBackground(vararg uris: Void): Boolean { val newCandidates = ArrayList() val updateCandidates = ArrayList() - val recipientDao = - FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!).recipientDao() + val roomDatabase = FlowCryptRoomDatabase.getDatabase(weakRef.get()?.requireContext()!!) + val recipientDao = roomDatabase.recipientDao() + val pubKeysDao = roomDatabase.pubKeysDao() for (publicKeyInfo in publicKeyInfoList) { val pgpContact = PgpContact( @@ -335,11 +335,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, true, null, publicKeyInfo.fingerprint, 0 ) - if (publicKeyInfo.hasPgpContact()) { - if (publicKeyInfo.isUpdateEnabled) { - updateCandidates.add(pgpContact) - } - } else { + if (!publicKeyInfo.hasPgp()) { newCandidates.add(pgpContact) } } @@ -357,7 +353,9 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, if (newCandidates.size - i > STEP_AMOUNT) i + STEP_AMOUNT else newCandidates.size if (weakRef.get() != null) { - recipientDao.insert(newCandidates.subList(start, end).map { it.toRecipientEntity() }) + val subList = newCandidates.subList(start, end) + recipientDao.insertWithReplace(subList.map { it.toRecipientEntity() }) + pubKeysDao.insert(subList.map { it.toPubKey() }) } i = end @@ -372,7 +370,8 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, } } - var i = 0 + //todo-denbond7 need to think about this a little more + /*var i = 0 while (i < updateCandidates.size) { val start = i val end = @@ -387,13 +386,13 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, recipientDao.getRecipientWithPubKeysByEmail(pgpContact.email) foundRecipientEntity?.let { entity -> //todo-denbond7 fix me - /*recipients.add( + *//*recipients.add( pgpContact.toRecipientEntity().copy(id = entity.id) - )*/ + )*//* } } - recipientDao.update(recipients) + //recipientDao.update(recipients) } i = end + 1 @@ -403,7 +402,7 @@ class PreviewImportPgpContactFragment : BaseFragment(), View.OnClickListener, lastProgress = progress } i++ - } + }*/ } catch (e: RemoteException) { e.printStackTrace() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ImportPgpContactsRecyclerViewAdapter.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ImportPgpContactsRecyclerViewAdapter.kt index 16eaec98ff..efca6becad 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ImportPgpContactsRecyclerViewAdapter.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/ImportPgpContactsRecyclerViewAdapter.kt @@ -15,6 +15,7 @@ import android.widget.TextView import android.widget.Toast import androidx.recyclerview.widget.RecyclerView import com.flowcrypt.email.R +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.model.PublicKeyInfo import com.flowcrypt.email.util.GeneralUtil @@ -61,21 +62,8 @@ class ImportPgpContactsRecyclerViewAdapter ), viewHolder.textViewFingerprintTemplate ) - if (publicKeyInfo.hasPgpContact()) { - if (publicKeyInfo.isUpdateEnabled) { - viewHolder.textViewAlreadyImported.visibility = View.GONE - viewHolder.buttonUpdateContact.visibility = View.VISIBLE - viewHolder.buttonUpdateContact.setOnClickListener { v -> - updateContact( - viewHolder.adapterPosition, - v, - context, - publicKeyInfo - ) - } - } else { - viewHolder.textViewAlreadyImported.visibility = View.VISIBLE - } + if (publicKeyInfo.hasPgp()) { + viewHolder.textViewAlreadyImported.visibility = View.VISIBLE } else { viewHolder.textViewAlreadyImported.visibility = View.GONE viewHolder.buttonSaveContact.visibility = View.VISIBLE @@ -109,7 +97,8 @@ class ImportPgpContactsRecyclerViewAdapter contactActionsListener?.onSaveContactClick(publicKeyInfo) Toast.makeText(context, R.string.contact_successfully_saved, Toast.LENGTH_SHORT).show() v.visibility = View.GONE - publicKeyInfo.pgpContact = pgpContact + publicKeyInfo.recipientWithPubKeys = + RecipientWithPubKeys(pgpContact.toRecipientEntity(), listOf(pgpContact.toPubKey())) notifyItemChanged(position) } @@ -127,7 +116,8 @@ class ImportPgpContactsRecyclerViewAdapter contactActionsListener?.onUpdateContactClick(publicKeyInfo) Toast.makeText(context, R.string.contact_successfully_updated, Toast.LENGTH_SHORT).show() v.visibility = View.GONE - publicKeyInfo.pgpContact = pgpContact + publicKeyInfo.recipientWithPubKeys = + RecipientWithPubKeys(pgpContact.toRecipientEntity(), listOf(pgpContact.toPubKey())) notifyItemChanged(position) } From 8f1644ac90d0549dc0a6e388c6b3b3c136b27e9b Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 1 Nov 2021 10:20:58 +0200 Subject: [PATCH 11/38] Made a workable version after switching to use 'recipients' and 'pub_keys' tables.| #1188 --- .../27.json | 12 +- ...tTest.kt => RecipientsListFragmentTest.kt} | 2 +- .../src/devTest/res/navigation/nav_graph.xml | 12 +- .../flowcrypt/email/api/email/EmailUtil.kt | 6 +- .../response/model/PublicKeyMsgBlock.kt | 10 +- .../email/database/FlowCryptRoomDatabase.kt | 35 +- .../dao/{PubKeysDao.kt => PubKeyDao.kt} | 8 +- .../email/database/dao/RecipientDao.kt | 14 +- .../email/database/entity/PublicKeyEntity.kt | 26 +- .../email/database/entity/RecipientEntity.kt | 20 +- .../entity/relation/RecipientWithPubKeys.kt | 12 + .../org/bouncycastle/openpgp/PGPKeyRingExt.kt | 6 - .../jetpack/viewmodel/AccountViewModel.kt | 4 +- .../jetpack/viewmodel/MsgDetailsViewModel.kt | 30 +- .../jetpack/viewmodel/PrivateKeysViewModel.kt | 68 ++-- .../jetpack/viewmodel/RecipientsViewModel.kt | 254 +++++++------- ...tactsWorker.kt => LoadRecipientsWorker.kt} | 42 +-- .../flowcrypt/email/model/KeyImportDetails.kt | 73 ++-- .../com/flowcrypt/email/model/PgpContact.kt | 105 ------ .../flowcrypt/email/model/PublicKeyInfo.kt | 12 - .../email/security/model/PgpKeyDetails.kt | 61 ++-- .../service/EmailAndNameUpdaterService.kt | 2 +- ...PrepareOutgoingMessagesJobIntentService.kt | 3 +- .../ui/activity/ImportPgpContactActivity.kt | 14 +- .../ui/activity/ImportPublicKeyActivity.kt | 21 +- .../PreviewImportPgpContactActivity.kt | 17 +- .../ui/activity/SelectContactsActivity.kt | 14 +- .../ui/activity/base/BaseSyncActivity.kt | 4 +- .../fragment/MessageDetailsFragment.kt | 48 +-- .../PreviewImportPgpContactFragment.kt | 99 +++--- .../fragment/PrivateKeyDetailsFragment.kt | 7 +- .../fragment/PublicKeyDetailsFragment.kt | 12 +- ...tFragment.kt => RecipientsListFragment.kt} | 25 +- .../ui/activity/fragment/base/BaseFragment.kt | 2 +- .../fragment/base/CreateMessageFragment.kt | 317 +++++++++--------- .../dialog/ChoosePublicKeyDialogFragment.kt | 14 +- .../dialog/NoPgpFoundDialogFragment.kt | 42 +-- .../email/ui/adapter/AttesterKeyAdapter.kt | 4 +- .../ImportPgpContactsRecyclerViewAdapter.kt | 48 +-- .../email/ui/adapter/PgpContactAdapter.kt | 4 +- .../adapter/PrivateKeysRecyclerViewAdapter.kt | 3 +- .../ui/adapter/PrvKeysRecyclerViewAdapter.kt | 2 +- ...er.kt => RecipientsRecyclerViewAdapter.kt} | 13 +- ..._list.xml => fragment_recipients_list.xml} | 0 .../src/main/res/navigation/nav_graph.xml | 10 +- FlowCrypt/src/main/res/values/strings.xml | 2 +- 46 files changed, 745 insertions(+), 794 deletions(-) rename FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/{ContactsListFragmentTest.kt => RecipientsListFragmentTest.kt} (98%) rename FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/{PubKeysDao.kt => PubKeyDao.kt} (77%) rename FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/{LoadContactsWorker.kt => LoadRecipientsWorker.kt} (87%) delete mode 100644 FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt rename FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/{ContactsListFragment.kt => RecipientsListFragment.kt} (83%) rename FlowCrypt/src/main/java/com/flowcrypt/email/ui/adapter/{ContactsRecyclerViewAdapter.kt => RecipientsRecyclerViewAdapter.kt} (90%) rename FlowCrypt/src/main/res/layout/{fragment_contacts_list.xml => fragment_recipients_list.xml} (100%) diff --git a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json index aa73cf348b..0ce62d800c 100644 --- a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json +++ b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/27.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 27, - "identityHash": "df7631eb8344e5890023dcb59321a47a", + "identityHash": "f9ed281f0ebf8698ba19b1bd8dde0336", "entities": [ { "tableName": "accounts_aliases", @@ -964,6 +964,14 @@ ], "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `recipient_fingerprint_in_public_keys` ON `${TABLE_NAME}` (`recipient`, `fingerprint`)" }, + { + "name": "recipient_in_public_keys", + "unique": false, + "columnNames": [ + "recipient" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `recipient_in_public_keys` ON `${TABLE_NAME}` (`recipient`)" + }, { "name": "fingerprint_in_public_keys", "unique": false, @@ -991,7 +999,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'df7631eb8344e5890023dcb59321a47a')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f9ed281f0ebf8698ba19b1bd8dde0336')" ] } } \ No newline at end of file diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/RecipientsListFragmentTest.kt similarity index 98% rename from FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt rename to FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/RecipientsListFragmentTest.kt index c8c2a14bdb..8051c52a76 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/ContactsListFragmentTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/RecipientsListFragmentTest.kt @@ -45,7 +45,7 @@ import org.junit.runner.RunWith */ @MediumTest @RunWith(AndroidJUnit4::class) -class ContactsListFragmentTest : BaseTest() { +class RecipientsListFragmentTest : BaseTest() { override val activityScenarioRule = activityScenarioRule( TestGeneralUtil.genIntentForNavigationComponent( diff --git a/FlowCrypt/src/devTest/res/navigation/nav_graph.xml b/FlowCrypt/src/devTest/res/navigation/nav_graph.xml index 4f392d726c..84756b7df1 100644 --- a/FlowCrypt/src/devTest/res/navigation/nav_graph.xml +++ b/FlowCrypt/src/devTest/res/navigation/nav_graph.xml @@ -38,8 +38,8 @@ android:id="@+id/action_mainSettingsFragment_to_experimentalSettingsFragment" app:destination="@id/experimentalSettingsFragment" /> + android:id="@+id/action_mainSettingsFragment_to_recipientsListFragment" + app:destination="@id/recipientsListFragment" /> + tools:layout="@layout/fragment_recipients_list"> diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt index e7d0010d6e..bf74e8f203 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/email/EmailUtil.kt @@ -201,9 +201,9 @@ class EmailUtil { * @param pgpKeyDetails The key details * @return A generated [AttachmentInfo]. */ - fun genAttInfoFromPubKey(pgpKeyDetails: PgpKeyDetails?): AttachmentInfo? { + fun genAttInfoFromPubKey(pgpKeyDetails: PgpKeyDetails?, email: String): AttachmentInfo? { if (pgpKeyDetails != null) { - val fileName = "0x" + pgpKeyDetails.fingerprint.toUpperCase(Locale.getDefault()) + ".asc" + val fileName = "0x" + pgpKeyDetails.fingerprint.uppercase() + ".asc" return if (!TextUtils.isEmpty(pgpKeyDetails.publicKey)) { val attachmentInfo = AttachmentInfo() @@ -212,7 +212,7 @@ class EmailUtil { attachmentInfo.encodedSize = pgpKeyDetails.publicKey.length.toLong() attachmentInfo.rawData = pgpKeyDetails.publicKey.toByteArray() attachmentInfo.type = Constants.MIME_TYPE_PGP_KEY - attachmentInfo.email = pgpKeyDetails.primaryPgpContact.email + attachmentInfo.email = email attachmentInfo.id = generateContentId() attachmentInfo.isEncryptionAllowed = false diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/PublicKeyMsgBlock.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/PublicKeyMsgBlock.kt index 790d6f916c..ca2c8d054c 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/PublicKeyMsgBlock.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/api/retrofit/response/model/PublicKeyMsgBlock.kt @@ -7,7 +7,8 @@ package com.flowcrypt.email.api.retrofit.response.model import android.os.Parcel import android.os.Parcelable -import com.flowcrypt.email.model.PgpContact +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys + import com.flowcrypt.email.security.model.PgpKeyDetails import com.google.gson.annotations.Expose @@ -29,7 +30,7 @@ data class PublicKeyMsgBlock constructor( @Expose override val type: MsgBlock.Type = MsgBlock.Type.PUBLIC_KEY - var existingPgpContact: PgpContact? = null + var existingRecipientWithPubKeys: RecipientWithPubKeys? = null constructor(parcel: Parcel) : this( parcel.readString(), @@ -37,7 +38,8 @@ data class PublicKeyMsgBlock constructor( parcel.readParcelable(PgpKeyDetails::class.java.classLoader), parcel.readParcelable(MsgBlockError::class.java.classLoader), ) { - existingPgpContact = parcel.readParcelable(PgpContact::class.java.classLoader) + existingRecipientWithPubKeys = + parcel.readParcelable(RecipientWithPubKeys::class.java.classLoader) } override fun writeToParcel(parcel: Parcel, flags: Int) = @@ -47,7 +49,7 @@ data class PublicKeyMsgBlock constructor( writeInt((if (complete) 1 else 0)) writeParcelable(keyDetails, flags) writeParcelable(error, flags) - writeParcelable(existingPgpContact, flags) + writeParcelable(existingRecipientWithPubKeys, flags) } override fun describeContents(): Int = 0 diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt index c8f0e426ea..68db82ed3b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt @@ -25,7 +25,7 @@ import com.flowcrypt.email.database.dao.AttachmentDao import com.flowcrypt.email.database.dao.KeysDao import com.flowcrypt.email.database.dao.LabelDao import com.flowcrypt.email.database.dao.MessageDao -import com.flowcrypt.email.database.dao.PubKeysDao +import com.flowcrypt.email.database.dao.PubKeyDao import com.flowcrypt.email.database.dao.RecipientDao import com.flowcrypt.email.database.entity.AccountAliasesEntity import com.flowcrypt.email.database.entity.AccountEntity @@ -81,7 +81,7 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { abstract fun recipientDao(): RecipientDao - abstract fun pubKeysDao(): PubKeysDao + abstract fun pubKeyDao(): PubKeyDao @WorkerThread fun forceDatabaseCreationIfNeeded() { @@ -517,6 +517,34 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { } } + /** + * Here we do preparation for https://github.com/FlowCrypt/flowcrypt-android/issues/1188 + */ + @VisibleForTesting + val MIGRATION_26_27 = object : FlowCryptMigration(26, 27) { + override fun doMigration(database: SupportSQLiteDatabase) { + database.execSQL("CREATE TEMP TABLE IF NOT EXISTS contacts_temp AS SELECT * FROM contacts;") + database.execSQL("DROP TABLE IF EXISTS contacts;") + + //create `recipients` table + database.execSQL("CREATE TABLE IF NOT EXISTS `recipients` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `email` TEXT NOT NULL, `name` TEXT DEFAULT NULL, `last_use` INTEGER NOT NULL DEFAULT 0)") + database.execSQL("CREATE INDEX IF NOT EXISTS `name_in_recipients` ON `recipients` (`name`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `last_use_in_recipients` ON `recipients` (`last_use`)") + database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `email_in_recipients` ON `recipients` (`email`)") + database.execSQL("INSERT INTO recipients(email, name, last_use) SELECT email, name, last_use FROM contacts_temp") + + //create `public_keys` table + database.execSQL("CREATE TABLE IF NOT EXISTS `public_keys` (`_id` INTEGER PRIMARY KEY AUTOINCREMENT, `recipient` TEXT NOT NULL, `fingerprint` TEXT NOT NULL, `public_key` BLOB NOT NULL, FOREIGN KEY(`recipient`) REFERENCES `recipients`(`email`) ON UPDATE NO ACTION ON DELETE CASCADE )") + database.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS `recipient_fingerprint_in_public_keys` ON `public_keys` (`recipient`, `fingerprint`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `recipient_in_public_keys` ON `public_keys` (`recipient`)") + database.execSQL("CREATE INDEX IF NOT EXISTS `fingerprint_in_public_keys` ON `public_keys` (`fingerprint`)") + database.execSQL("INSERT INTO public_keys(recipient, fingerprint, public_key) SELECT email, fingerprint, public_key FROM contacts_temp WHERE contacts_temp.public_key NOT NULL") + + //delete unused `contacts_temp` table + database.execSQL("DROP TABLE IF EXISTS contacts_temp;") + } + } + // Singleton prevents multiple instances of database opening at the same time. @Volatile private var INSTANCE: FlowCryptRoomDatabase? = null @@ -556,7 +584,8 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { MIGRATION_22_23, MIGRATION_23_24, MIGRATION_24_25, - MIGRATION_25_26 + MIGRATION_25_26, + MIGRATION_26_27 ).build() INSTANCE = instance return instance diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeyDao.kt similarity index 77% rename from FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt rename to FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeyDao.kt index fde7f7d864..93ba38bf1e 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeysDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/PubKeyDao.kt @@ -17,7 +17,7 @@ import com.flowcrypt.email.database.entity.PublicKeyEntity * E-mail: DenBond7@gmail.com */ @Dao -interface PubKeysDao : BaseDao { +interface PubKeyDao : BaseDao { @Query("SELECT * FROM public_keys") suspend fun getAllPublicKeys(): List @@ -29,4 +29,10 @@ interface PubKeysDao : BaseDao { @Query("SELECT * FROM public_keys WHERE fingerprint = :fingerprint") suspend fun getPublicKeysByFingerprint(fingerprint: String): List + + @Query("SELECT * FROM public_keys WHERE recipient = :recipient AND fingerprint = :fingerprint") + suspend fun getPublicKeyByRecipientAndFingerprint( + recipient: String, + fingerprint: String + ): PublicKeyEntity? } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt index 22d26dfe66..983585d1ec 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/dao/RecipientDao.kt @@ -23,50 +23,42 @@ import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys */ @Dao interface RecipientDao : BaseDao { - //fixed @Query("SELECT * FROM recipients") suspend fun getAllRecipients(): List - //fixed @Query("SELECT * FROM recipients") fun getAllRecipientsLD(): LiveData> - //fixed @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient GROUP BY recipients.email ORDER BY recipients._id") fun getAllRecipientsWithPgpLD(): LiveData> - //fixed @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient GROUP BY recipients.email ORDER BY recipients._id") suspend fun getAllRecipientsWithPgp(): List - //fixed @Query("SELECT recipients.* FROM recipients INNER JOIN public_keys ON recipients.email = public_keys.recipient WHERE (email LIKE :searchPattern OR name LIKE :searchPattern) GROUP BY recipients.email ORDER BY recipients._id") suspend fun getAllRecipientsWithPgpWhichMatched(searchPattern: String): List @Query("SELECT * FROM recipients WHERE email = :email") suspend fun getRecipientByEmailSuspend(email: String): RecipientEntity? - //fixed @Query("SELECT * FROM recipients WHERE email = :email") fun getRecipientByEmail(email: String): RecipientEntity? + @Transaction @Query("SELECT * FROM recipients WHERE email = :email") - fun getRecipientByEmailLD(email: String): LiveData + fun getRecipientsWithPubKeysByEmailsLD(email: String): LiveData - //fixed @Transaction @Query("SELECT * FROM recipients WHERE email IN (:emails)") fun getRecipientsWithPubKeysByEmails(emails: Collection): List - //fixed @Query("SELECT * FROM recipients WHERE email LIKE :searchPattern ORDER BY last_use DESC") fun getFilteredCursor(searchPattern: String): Cursor? - //fixed @Query("DELETE FROM recipients") suspend fun deleteAll(): Int @Transaction @Query("SELECT * FROM recipients WHERE email = :email") - fun getRecipientWithPubKeysByEmail(email: String): RecipientWithPubKeys? + suspend fun getRecipientWithPubKeysByEmail(email: String): RecipientWithPubKeys? } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt index 9ca55aa7ae..3584607d22 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/PublicKeyEntity.kt @@ -11,8 +11,10 @@ import android.provider.BaseColumns import androidx.room.ColumnInfo import androidx.room.Entity import androidx.room.ForeignKey +import androidx.room.Ignore import androidx.room.Index import androidx.room.PrimaryKey +import com.flowcrypt.email.security.model.PgpKeyDetails /** * @author Denis Bondarenko @@ -28,6 +30,11 @@ import androidx.room.PrimaryKey value = ["recipient", "fingerprint"], unique = true ), + Index( + name = "recipient_in_public_keys", + value = ["recipient"], + unique = false + ), Index( name = "fingerprint_in_public_keys", value = ["fingerprint"], @@ -49,18 +56,31 @@ data class PublicKeyEntity( @ColumnInfo(name = "fingerprint") val fingerprint: String, @ColumnInfo(name = "public_key") val publicKey: ByteArray ) : Parcelable { + + @Ignore + var pgpKeyDetails: PgpKeyDetails? = null + + @Ignore + var isNotUsable: Boolean? = null + constructor(parcel: Parcel) : this( parcel.readValue(Long::class.java.classLoader) as? Long, requireNotNull(parcel.readString()), requireNotNull(parcel.readString()), requireNotNull(parcel.createByteArray()) - ) + ) { + pgpKeyDetails = parcel.readParcelable(PgpKeyDetails::class.java.classLoader) + isNotUsable = parcel.readValue(Boolean::class.java.classLoader) as? Boolean + } + override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeValue(id) parcel.writeString(recipient) parcel.writeString(fingerprint) parcel.writeByteArray(publicKey) + parcel.writeParcelable(pgpKeyDetails, flags) + parcel.writeValue(isNotUsable) } override fun describeContents(): Int { @@ -77,6 +97,8 @@ data class PublicKeyEntity( if (recipient != other.recipient) return false if (fingerprint != other.fingerprint) return false if (!publicKey.contentEquals(other.publicKey)) return false + if (pgpKeyDetails != other.pgpKeyDetails) return false + if (isNotUsable != other.isNotUsable) return false return true } @@ -86,6 +108,8 @@ data class PublicKeyEntity( result = 31 * result + recipient.hashCode() result = 31 * result + fingerprint.hashCode() result = 31 * result + publicKey.contentHashCode() + result = 31 * result + (pgpKeyDetails?.hashCode() ?: 0) + result = 31 * result + (isNotUsable?.hashCode() ?: 0) return result } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt index 201fe278d1..aeb9ac5ba5 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/RecipientEntity.kt @@ -10,11 +10,8 @@ import android.os.Parcelable import android.provider.BaseColumns import androidx.room.ColumnInfo import androidx.room.Entity -import androidx.room.Ignore import androidx.room.Index import androidx.room.PrimaryKey -import com.flowcrypt.email.model.PgpContact -import com.flowcrypt.email.security.model.PgpKeyDetails /** * @author Denis Bondarenko @@ -37,26 +34,12 @@ data class RecipientEntity( @ColumnInfo(name = "last_use", defaultValue = "0") val lastUse: Long = 0 ) : Parcelable { - @Ignore - var pgpKeyDetails: PgpKeyDetails? = null - constructor(parcel: Parcel) : this( parcel.readValue(Long::class.java.classLoader) as? Long, requireNotNull(parcel.readString()), parcel.readString(), parcel.readLong() - ) { - pgpKeyDetails = parcel.readParcelable(PgpKeyDetails::class.java.classLoader) - } - - fun toPgpContact(): PgpContact { - return PgpContact( - email = email, - name = name, - lastUse = lastUse, - pgpKeyDetails = pgpKeyDetails - ) - } + ) //todo-denbond7 need to think about this class. enum class Type { @@ -68,7 +51,6 @@ data class RecipientEntity( parcel.writeString(email) parcel.writeString(name) parcel.writeLong(lastUse) - parcel.writeParcelable(pgpKeyDetails, flags) } override fun describeContents(): Int { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt index 18a7d6137d..4fc4ad395d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/relation/RecipientWithPubKeys.kt @@ -42,6 +42,18 @@ data class RecipientWithPubKeys( return 0 } + fun hasPgp(): Boolean { + return publicKeys.isNotEmpty() + } + + fun hasNotExpiredKeys(): Boolean { + return publicKeys.any { it.pgpKeyDetails?.isExpired?.not() ?: false } + } + + fun hasUsableKeys(): Boolean { + return publicKeys.any { if (it.isNotUsable != null) it.isNotUsable?.not() ?: false else true } + } + companion object CREATOR : Parcelable.Creator { override fun createFromParcel(parcel: Parcel) = RecipientWithPubKeys(parcel) override fun newArray(size: Int): Array = arrayOfNulls(size) diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt index 6527be5175..414b83e4ed 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/extensions/org/bouncycastle/openpgp/PGPKeyRingExt.kt @@ -6,7 +6,6 @@ package com.flowcrypt.email.extensions.org.bouncycastle.openpgp import androidx.annotation.WorkerThread -import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.model.Algo import com.flowcrypt.email.security.model.KeyId import com.flowcrypt.email.security.model.PgpKeyDetails @@ -85,11 +84,6 @@ fun PGPKeyRing.toPgpKeyDetails(): PgpKeyDetails { ) } -fun PGPKeyRing.pgpContacts(): List { - val list = publicKey.userIDs.iterator().asSequence().toList() - return PgpContact.determinePgpContacts(list) -} - @Throws(IOException::class) fun PGPKeyRing.armor(headers: List>? = PgpArmor.FLOWCRYPT_HEADERS): String { ByteArrayOutputStream().use { out -> diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountViewModel.kt index b6128533dd..3bf911daa4 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/AccountViewModel.kt @@ -17,7 +17,7 @@ import com.flowcrypt.email.R import com.flowcrypt.email.api.email.model.AuthCredentials import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.AccountEntity -import com.flowcrypt.email.jetpack.workmanager.sync.LoadContactsWorker +import com.flowcrypt.email.jetpack.workmanager.sync.LoadRecipientsWorker import com.flowcrypt.email.security.KeyStoreCryptoManager import com.flowcrypt.email.service.IdleService import kotlinx.coroutines.Dispatchers @@ -84,7 +84,7 @@ open class AccountViewModel(application: Application) : RoomBasicViewModel(appli ) } - LoadContactsWorker.enqueue(getApplication()) + LoadRecipientsWorker.enqueue(getApplication()) addNewAccountLiveData.value = Result.success(true) } catch (e: Exception) { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt index 3454035a48..665b5c5d3a 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/MsgDetailsViewModel.kt @@ -411,22 +411,22 @@ class MsgDetailsViewModel( private suspend fun preResultsProcessing(blocks: List) { for (block in blocks) { - if (block is PublicKeyMsgBlock) { - val keyDetails = block.keyDetails ?: continue - val pgpContact = keyDetails.primaryPgpContact - //todo-denbond7 need to rework on this code - val recipientEntity = - roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) - //block.existingPgpContact = recipientEntity?.toPgpContact() - } + when (block) { + is PublicKeyMsgBlock -> { + val keyDetails = block.keyDetails ?: continue + val recipient = keyDetails.mimeAddresses.firstOrNull()?.address ?: continue + block.existingRecipientWithPubKeys = + roomDatabase.recipientDao().getRecipientWithPubKeysByEmail(recipient) + } - if (block is DecryptErrorMsgBlock) { - if (block.decryptErr?.details?.type == PgpDecrypt.DecryptionErrorType.NEED_PASSPHRASE) { - val fingerprints = block.decryptErr.fingerprints ?: emptyList() - if (fingerprints.isEmpty()) { - ExceptionUtil.handleError(IllegalStateException("Fingerprints were not provided")) - } else { - passphraseNeededLiveData.postValue(fingerprints) + is DecryptErrorMsgBlock -> { + if (block.decryptErr?.details?.type == PgpDecrypt.DecryptionErrorType.NEED_PASSPHRASE) { + val fingerprints = block.decryptErr.fingerprints ?: emptyList() + if (fingerprints.isEmpty()) { + ExceptionUtil.handleError(IllegalStateException("Fingerprints were not provided")) + } else { + passphraseNeededLiveData.postValue(fingerprints) + } } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt index 5264628386..da19a11f3f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/PrivateKeysViewModel.kt @@ -30,11 +30,11 @@ import com.flowcrypt.email.api.retrofit.response.model.OrgRules import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.ActionQueueEntity import com.flowcrypt.email.database.entity.KeyEntity +import com.flowcrypt.email.database.entity.RecipientEntity import com.flowcrypt.email.extensions.org.bouncycastle.openpgp.toPgpKeyDetails import com.flowcrypt.email.extensions.org.pgpainless.util.asString import com.flowcrypt.email.model.KeyImportDetails import com.flowcrypt.email.model.KeyImportModel -import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.KeyStoreCryptoManager import com.flowcrypt.email.security.KeysStorageImpl import com.flowcrypt.email.security.SecurityUtils @@ -205,13 +205,12 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat } if (roomDatabase.keysDao().getKeyByAccountAndFingerprintSuspend( - accountEntity.email.lowercase(Locale.US), - fingerprint + accountEntity.email.lowercase(), fingerprint ) == null ) { if (addAccountIfNotExist) { val existedAccount = roomDatabase.accountDao() - .getAccountSuspend(accountEntity.email.lowercase(Locale.US)) + .getAccountSuspend(accountEntity.email.lowercase()) if (existedAccount == null) { roomDatabase.accountDao().addAccountSuspend(accountEntity) } @@ -243,16 +242,24 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat passphraseType = KeyEntity.PassphraseType.RAM ) } - //update contacts table + + //update pub keys val recipientDao = roomDatabase.recipientDao() - val pubKeysDao = roomDatabase.pubKeysDao() - for (pgpContact in keyDetails.pgpContacts) { - pgpContact.pubkey = keyDetails.publicKey - val recipientWithPubKeys = - recipientDao.getRecipientByEmailSuspend(pgpContact.email) - if (recipientWithPubKeys == null && GeneralUtil.isEmailValid(pgpContact.email)) { - recipientDao.insertWithReplaceSuspend(pgpContact.toRecipientEntity()) - pubKeysDao.insertWithReplaceSuspend(pgpContact.toPubKey()) + val pubKeysDao = roomDatabase.pubKeyDao() + for (mimeAddress in keyDetails.mimeAddresses) { + val address = mimeAddress.address.lowercase() + val name = mimeAddress.personal + + val existedRecipientWithPubKeys = + recipientDao.getRecipientWithPubKeysByEmail(address) + if (existedRecipientWithPubKeys == null) { + recipientDao.insertSuspend(RecipientEntity(email = address, name = name)) + } + + val existedPubKeyEntity = + pubKeysDao.getPublicKeyByRecipientAndFingerprint(address, keyDetails.fingerprint) + if (existedPubKeyEntity == null) { + pubKeysDao.insertSuspend(keyDetails.toPublicKeyEntity(address)) } } } @@ -334,6 +341,7 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat createPrivateKeyLiveData.value = Result.loading() var pgpKeyDetails: PgpKeyDetails? = null try { + //use genUserIds() pgpKeyDetails = PGPainless.generateKeyRing().simpleEcKeyRing( UserId.nameAndEmail( accountEntity.displayName @@ -342,7 +350,7 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat ).toPgpKeyDetails().copy(passphraseType = passphraseType) val existedAccount = - roomDatabase.accountDao().getAccountSuspend(accountEntity.email.lowercase(Locale.US)) + roomDatabase.accountDao().getAccountSuspend(accountEntity.email.lowercase()) if (existedAccount == null) { roomDatabase.accountDao().addAccountSuspend(accountEntity) } @@ -369,10 +377,10 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat val allKeyEntitiesOfAccount = roomDatabase.keysDao().getAllKeysByAccountSuspend(accountEntity.email) val fingerprintListOfDeleteCandidates = keys.map { - it.fingerprint.lowercase(Locale.US) + it.fingerprint.lowercase() } val deleteCandidates = allKeyEntitiesOfAccount.filter { - fingerprintListOfDeleteCandidates.contains(it.fingerprint.lowercase(Locale.US)) + fingerprintListOfDeleteCandidates.contains(it.fingerprint.lowercase()) } if (keys.size == allKeyEntitiesOfAccount.size) { @@ -555,28 +563,36 @@ class PrivateKeysViewModel(application: Application) : AccountViewModel(applicat } } - private suspend fun genContacts(accountEntity: AccountEntity): List = + private suspend fun genUserIds(accountEntity: AccountEntity): List = withContext(Dispatchers.IO) { - val pgpContactMain = PgpContact(accountEntity.email, accountEntity.displayName) - val contacts = ArrayList() + val userIds = ArrayList() + userIds.add(UserId.newBuilder().withEmail(accountEntity.email).apply { + accountEntity.displayName?.let { name -> + withName(name) + } + }.build()) - when (accountEntity.accountType) { - AccountEntity.ACCOUNT_TYPE_GOOGLE -> { - contacts.add(pgpContactMain) + if (accountEntity.accountType == AccountEntity.ACCOUNT_TYPE_GOOGLE) { + try { val gmail = GmailApiHelper.generateGmailApiService(getApplication(), accountEntity) val aliases = gmail.users().settings().sendAs().list(GmailApiHelper.DEFAULT_USER_ID).execute() for (alias in aliases.sendAs) { if (alias.verificationStatus != null) { - contacts.add(PgpContact(alias.sendAsEmail, alias.displayName)) + userIds.add(UserId.newBuilder().withEmail(alias.sendAsEmail).apply { + alias.displayName?.let { name -> + withName(name) + } + }.build()) } } + } catch (e: Exception) { + //skip any issues + e.printStackTrace() } - - else -> contacts.add(pgpContactMain) } - return@withContext contacts + return@withContext userIds } /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt index 63a5b49034..af306d2146 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/viewmodel/RecipientsViewModel.kt @@ -20,7 +20,7 @@ import com.flowcrypt.email.api.retrofit.response.attester.PubResponse import com.flowcrypt.email.api.retrofit.response.base.ApiError import com.flowcrypt.email.api.retrofit.response.base.Result import com.flowcrypt.email.database.entity.RecipientEntity -import com.flowcrypt.email.model.PgpContact +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.security.pgp.PgpKey import com.flowcrypt.email.util.GeneralUtil @@ -66,43 +66,14 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati emit(Result.success(foundContacts)) } } - val contactsToLiveData: MutableLiveData>> = MutableLiveData() - val contactsCcLiveData: MutableLiveData>> = MutableLiveData() - val contactsBccLiveData: MutableLiveData>> = MutableLiveData() + val recipientsToLiveData: MutableLiveData>> = MutableLiveData() + val recipientsCcLiveData: MutableLiveData>> = MutableLiveData() + val recipientsBccLiveData: MutableLiveData>> = MutableLiveData() val pubKeysFromServerLiveData: MutableLiveData> = MutableLiveData() - fun copyPubKeysToRecipient(pgpContact: PgpContact, pgpContactFromKey: PgpContact) { - viewModelScope.launch { - val recipient = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) - if (recipient != null) { - val updateCandidate = pgpContact.toRecipientEntity().copy(id = recipient.id) - roomDatabase.recipientDao().updateSuspend(updateCandidate) - } - - if (!pgpContact.email.equals(pgpContactFromKey.email, ignoreCase = true)) { - val existedContact = - roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContactFromKey.email) - if (existedContact == null) { - roomDatabase.recipientDao().insertSuspend(pgpContactFromKey.toRecipientEntity()) - } - } - } - } - - fun copyPubKeysToRecipient(email: String, recipientEntity: RecipientEntity) { - viewModelScope.launch { - val pubKeysOfCopyCandidate = - roomDatabase.pubKeysDao().getPublicKeysByRecipient(recipientEntity.email) - if (pubKeysOfCopyCandidate.isEmpty()) return@launch - roomDatabase.pubKeysDao().insertSuspend( - pubKeysOfCopyCandidate.map { it.copy(id = null, recipient = email) } - ) - } - } - - fun contactChangesLiveData(recipientEntity: RecipientEntity): LiveData { - return roomDatabase.recipientDao().getRecipientByEmailLD(recipientEntity.email) + fun contactChangesLiveData(recipientEntity: RecipientEntity): LiveData { + return roomDatabase.recipientDao().getRecipientsWithPubKeysByEmailsLD(recipientEntity.email) } /** @@ -116,15 +87,15 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati * call * to see if you can now get the pubkey. If a pubkey is available, save it back to the database. * c) no record in the db found: - * 1. save an empty record eg `new PgpContact(email, null);` - this means we don't know if they have PGP yet + * 1. save an empty record eg `new RecipientWithPubKeys(email, null);` - this means we don't know if they have PGP yet * 1. look up the email on `flowcrypt.com/attester/pub/EMAIL>` - * 1. if pubkey comes back, create something like `new PgpContact(js, email, null, pubkey, - * client);`. The PgpContact constructor will define has_pgp, fingerprint, etc + * 1. if pubkey comes back, create something like `new RecipientWithPubKeys(js, email, null, pubkey, + * client);`. The RecipientWithPubKeys constructor will define has_pgp, fingerprint, etc * for you. Then save that object into database. - * 1. if no pubkey found, create `new PgpContact(js, email, null, null, null, null);` - this + * 1. if no pubkey found, create `new RecipientWithPubKeys(js, email, null, null, null, null);` - this * means we know they don't currently have PGP */ - fun fetchAndUpdateInfoAboutContacts(type: RecipientEntity.Type, emails: List) { + fun fetchAndUpdateInfoAboutRecipients(type: RecipientEntity.Type, emails: List) { viewModelScope.launch { if (emails.isEmpty()) { return@launch @@ -132,67 +103,70 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati setResultForRemoteContactsLiveData(type, Result.loading()) - val pgpContacts = ArrayList() + val recipients = ArrayList() try { for (email in emails) { if (GeneralUtil.isEmailValid(email)) { val emailLowerCase = email.lowercase(Locale.getDefault()) - var cachedRecipientEntity = - roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) - - if (cachedRecipientEntity == null) { - cachedRecipientEntity = PgpContact(emailLowerCase, null).toRecipientEntity() - roomDatabase.recipientDao().insertSuspend(cachedRecipientEntity) - cachedRecipientEntity = - roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) + var cachedRecipientWithPubKeys = + roomDatabase.recipientDao().getRecipientWithPubKeysByEmail(emailLowerCase) + + if (cachedRecipientWithPubKeys == null) { + roomDatabase.recipientDao().insertSuspend(RecipientEntity(email = emailLowerCase)) + cachedRecipientWithPubKeys = + roomDatabase.recipientDao().getRecipientWithPubKeysByEmail(emailLowerCase) } else { - try { - /*cachedRecipientEntity.publicKey?.let { - val result = PgpKey.parseKeys(it).pgpKeyDetailsList - cachedRecipientEntity?.pgpKeyDetails = result.firstOrNull() - }*/ - } catch (e: Exception) { - e.printStackTrace() - pgpContacts.add( - cachedRecipientEntity.toPgpContact().copy(hasNotUsablePubKey = true) - ) - continue + for (publicKeyEntity in cachedRecipientWithPubKeys.publicKeys) { + try { + val result = PgpKey.parseKeys(publicKeyEntity.publicKey).pgpKeyDetailsList + publicKeyEntity.pgpKeyDetails = result.firstOrNull() + } catch (e: Exception) { + e.printStackTrace() + publicKeyEntity.isNotUsable = true + } } } try { - if (true) { - getPgpContactInfoFromServer(email = emailLowerCase)?.let { - cachedRecipientEntity = - updateCachedInfoWithAttesterInfo(cachedRecipientEntity, it, emailLowerCase) + if (cachedRecipientWithPubKeys?.hasPgp() == false) { + getPgpInfoFromServer(email = emailLowerCase)?.let { pgpKeyDetailsList -> + cachedRecipientWithPubKeys = cachedRecipientWithPubKeys?.let { + updateCachedInfoWithPubKeysFromAttester(it, pgpKeyDetailsList, emailLowerCase) + } } } else { - cachedRecipientEntity?.pgpKeyDetails?.fingerprint?.let { fingerprint -> - getPgpContactInfoFromServer(fingerprint = fingerprint)?.let { - val cacheLastModified = cachedRecipientEntity?.pgpKeyDetails?.lastModified ?: 0 - val attesterLastModified = it.pgpKeyDetails?.lastModified ?: 0 - val attesterFingerprint = it.pgpKeyDetails?.fingerprint - - if (attesterLastModified > cacheLastModified && fingerprint.equals( - attesterFingerprint, - true - ) + //todo-denbond7 need to think about this code. Clarify can we have a few pubkeys as a single source + for (publicKeyEntity in cachedRecipientWithPubKeys?.publicKeys ?: emptyList()) { + val pgpKeyDetails = publicKeyEntity.pgpKeyDetails ?: continue + getPgpInfoFromServer(fingerprint = publicKeyEntity.fingerprint)?.let { + val cacheLastModified = pgpKeyDetails.lastModified ?: 0 + val attesterLastModified = it.firstOrNull()?.lastModified ?: 0 + val attesterFingerprint = it.firstOrNull()?.fingerprint + + if (attesterLastModified > cacheLastModified + && publicKeyEntity.fingerprint.equals(attesterFingerprint, true) ) { - cachedRecipientEntity = - updateCachedInfoWithAttesterInfo(cachedRecipientEntity, it, emailLowerCase) + cachedRecipientWithPubKeys = + cachedRecipientWithPubKeys?.let { recipientWithPubKeys -> + updateCachedInfoWithPubKeysFromAttester( + recipientWithPubKeys, + listOf(pgpKeyDetails), + emailLowerCase + ) + } } } } } - cachedRecipientEntity?.let { pgpContacts.add(it.toPgpContact()) } + cachedRecipientWithPubKeys?.let { recipients.add(it) } } catch (e: Exception) { e.printStackTrace() ExceptionUtil.handleError(e) } } } - setResultForRemoteContactsLiveData(type, Result.success(pgpContacts)) + setResultForRemoteContactsLiveData(type, Result.success(recipients)) } catch (e: Exception) { e.printStackTrace() ExceptionUtil.handleError(e) @@ -201,35 +175,23 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati } } - private suspend fun updateCachedInfoWithAttesterInfo( - cachedRecipientEntity: RecipientEntity?, - attesterPgpContact: PgpContact, emailLowerCase: String - ): RecipientEntity? { - cachedRecipientEntity ?: return null - val updateCandidate = if ( - cachedRecipientEntity.name.isNullOrEmpty() - && cachedRecipientEntity.email.equals(attesterPgpContact.email, ignoreCase = true) - ) { - attesterPgpContact.toRecipientEntity().copy( - id = cachedRecipientEntity.id, - email = cachedRecipientEntity.email - ) - } else { - attesterPgpContact.toRecipientEntity().copy( - id = cachedRecipientEntity.id, - name = cachedRecipientEntity.name, - email = cachedRecipientEntity.email - ) + private suspend fun updateCachedInfoWithPubKeysFromAttester( + cachedRecipientEntity: RecipientWithPubKeys, + list: List, emailLowerCase: String + ): RecipientWithPubKeys { + val publicKeyEntities = list.map { it.toPublicKeyEntity(cachedRecipientEntity.recipient.email) } + roomDatabase.pubKeyDao().insertWithReplaceSuspend(publicKeyEntities) + val lastVersion = + requireNotNull(roomDatabase.recipientDao().getRecipientWithPubKeysByEmail(emailLowerCase)) + for (publicKeyEntity in lastVersion.publicKeys) { + try { + val result = PgpKey.parseKeys(publicKeyEntity.publicKey).pgpKeyDetailsList + publicKeyEntity.pgpKeyDetails = result.firstOrNull() + } catch (e: Exception) { + e.printStackTrace() + publicKeyEntity.isNotUsable = true + } } - - roomDatabase.recipientDao().updateSuspend(updateCandidate) - val lastVersion = roomDatabase.recipientDao().getRecipientByEmailSuspend(emailLowerCase) - - /*lastVersion?.publicKey?.let { - val result = PgpKey.parseKeys(it).pgpKeyDetailsList - lastVersion.pgpKeyDetails = result.firstOrNull() - }*/ - return lastVersion } @@ -239,14 +201,15 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati } } - fun addContact(pgpContact: PgpContact) { + fun addRecipientsBasedOnPgpKeyDetails(pgpKeyDetails: PgpKeyDetails) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) + val primaryAddress = pgpKeyDetails.mimeAddresses.firstOrNull()?.address ?: return@launch + val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(primaryAddress) if (contact == null) { val isInserted = - roomDatabase.recipientDao().insertSuspend(pgpContact.toRecipientEntity()) > 0 + roomDatabase.recipientDao().insertSuspend(RecipientEntity(email = primaryAddress)) > 0 if (isInserted) { - roomDatabase.pubKeysDao().insertSuspend(pgpContact.toPubKey()) + roomDatabase.pubKeyDao().insertSuspend(pgpKeyDetails.toPublicKeyEntity(primaryAddress)) } else { val context: Context = getApplication() Toast.makeText( @@ -258,27 +221,47 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati } } - fun updateContact(pgpContact: PgpContact) { + fun copyPubKeysToRecipient(recipientEntity: RecipientEntity?, pgpKeyDetails: PgpKeyDetails) { viewModelScope.launch { - val contact = roomDatabase.recipientDao().getRecipientByEmailSuspend(pgpContact.email) - if (contact != null) { - val updateCandidate = pgpContact.toRecipientEntity().copy(id = contact.id) - roomDatabase.recipientDao().updateSuspend(updateCandidate) + recipientEntity?.let { + val existedPubKey = roomDatabase.pubKeyDao() + .getPublicKeyByRecipientAndFingerprint(recipientEntity.email, pgpKeyDetails.fingerprint) + if (existedPubKey == null) { + roomDatabase.pubKeyDao() + .insertSuspend(pgpKeyDetails.toPublicKeyEntity(recipientEntity.email)) + } } } } - fun copyPubKeysToRecipient(recipientEntity: RecipientEntity?, pgpKeyDetails: PgpKeyDetails) { + fun copyPubKeysBetweenRecipients( + sourceRecipientEntity: RecipientEntity?, + destinationRecipientEntity: RecipientEntity? + ) { viewModelScope.launch { - recipientEntity?.let { - val recipientEntityFromPrimaryPgpContact = - pgpKeyDetails.primaryPgpContact.toRecipientEntity() - roomDatabase.recipientDao().updateSuspend( - recipientEntityFromPrimaryPgpContact.copy( - id = recipientEntity.id, - email = recipientEntity.email.lowercase(Locale.US), + sourceRecipientEntity ?: return@launch + destinationRecipientEntity ?: return@launch + + val existedPubKeysOfSource = + roomDatabase.pubKeyDao().getPublicKeysByRecipient(sourceRecipientEntity.email) + + if (existedPubKeysOfSource.isNotEmpty()) { + for (existedPubKey in existedPubKeysOfSource) { + val fetchedPubKey = roomDatabase.pubKeyDao().getPublicKeyByRecipientAndFingerprint( + destinationRecipientEntity.email, + existedPubKey.fingerprint ) - ) + + if (fetchedPubKey == null) { + roomDatabase.pubKeyDao() + .insertSuspend( + existedPubKey.copy( + id = null, + recipient = destinationRecipientEntity.email.lowercase() + ) + ) + } + } } } } @@ -310,34 +293,34 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati private fun setResultForRemoteContactsLiveData( type: RecipientEntity.Type, - result: Result> + result: Result> ) { when (type) { RecipientEntity.Type.TO -> { - contactsToLiveData.value = result + recipientsToLiveData.value = result } RecipientEntity.Type.CC -> { - contactsCcLiveData.value = result + recipientsCcLiveData.value = result } RecipientEntity.Type.BCC -> { - contactsBccLiveData.value = result + recipientsBccLiveData.value = result } } } /** - * Get information about [PgpContact] from the remote server. + * Get information about [RecipientWithPubKeys] from the remote server. * * @param email Used to generate a request to the server. - * @return [PgpContact] + * @return [RecipientWithPubKeys] * @throws IOException */ - private suspend fun getPgpContactInfoFromServer( + private suspend fun getPgpInfoFromServer( email: String? = null, fingerprint: String? = null - ): PgpContact? = withContext(Dispatchers.IO) { + ): List? = withContext(Dispatchers.IO) { try { val activeAccount = getActiveAccountSuspend() val response = apiRepository.pubLookup( @@ -350,10 +333,9 @@ class RecipientsViewModel(application: Application) : AccountViewModel(applicati Result.Status.SUCCESS -> { val pubKeyString = response.data?.pubkey if (pubKeyString?.isNotEmpty() == true) { - PgpKey.parseKeys(pubKeyString).pgpKeyDetailsList.firstOrNull()?.let { - val pgpContact = it.primaryPgpContact - pgpContact.pgpKeyDetails = it - return@withContext pgpContact + val parsedResult = PgpKey.parseKeys(pubKeyString).pgpKeyDetailsList + if (parsedResult.isNotEmpty()) { + return@withContext parsedResult } } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadRecipientsWorker.kt similarity index 87% rename from FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt rename to FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadRecipientsWorker.kt index c0f8b2cc4d..0da073b3ed 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadContactsWorker.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/jetpack/workmanager/sync/LoadRecipientsWorker.kt @@ -35,14 +35,14 @@ import javax.mail.Store import javax.mail.internet.InternetAddress /** - * This [CoroutineWorker] loads information about contacts from the SENT folder. + * This [CoroutineWorker] loads information about recipients from the SENT folder. * * @author Denis Bondarenko * Date: 23.04.2018 * Time: 14:53 * E-mail: DenBond7@gmail.com */ -class LoadContactsWorker(context: Context, params: WorkerParameters) : +class LoadRecipientsWorker(context: Context, params: WorkerParameters) : BaseSyncWorker(context, params) { override suspend fun runIMAPAction(accountEntity: AccountEntity, store: Store) { fetchContacts(accountEntity, store) @@ -65,9 +65,9 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : if (msgs.isNotEmpty()) { val fetchProfile = FetchProfile() - fetchProfile.add(Message.RecipientType.TO.toString().uppercase(Locale.getDefault())) - fetchProfile.add(Message.RecipientType.CC.toString().uppercase(Locale.getDefault())) - fetchProfile.add(Message.RecipientType.BCC.toString().uppercase(Locale.getDefault())) + fetchProfile.add(Message.RecipientType.TO.toString().uppercase()) + fetchProfile.add(Message.RecipientType.CC.toString().uppercase()) + fetchProfile.add(Message.RecipientType.BCC.toString().uppercase()) imapFolder.fetch(msgs, fetchProfile) return@fetchContactsInternal msgs @@ -160,36 +160,36 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : } val recipientDao = FlowCryptRoomDatabase.getDatabase(applicationContext).recipientDao() - val availableContacts = recipientDao.getAllRecipients() + val availableRecipients = recipientDao.getAllRecipients() - val contactsInDatabase = HashSet() - val contactsWhichWillBeUpdated = HashSet() - val contactsWhichWillBeCreated = HashSet() - val contactsByEmailMap = HashMap() + val recipientsInDatabase = HashSet() + val recipientsWhichWillBeUpdated = HashSet() + val recipientsWhichWillBeCreated = HashSet() + val recipientsByEmailMap = HashMap() val newCandidates = mutableListOf() val updateCandidates = mutableListOf() - for (contact in availableContacts) { - contactsInDatabase.add(contact.email.lowercase()) - contactsByEmailMap[contact.email.lowercase()] = contact + for (recipientEntity in availableRecipients) { + recipientsInDatabase.add(recipientEntity.email.lowercase()) + recipientsByEmailMap[recipientEntity.email.lowercase()] = recipientEntity } for (emailAndNamePair in emailAndNamePairs) { - if (contactsInDatabase.contains(emailAndNamePair.email)) { - val recipientEntity = contactsByEmailMap[emailAndNamePair.email] + if (recipientsInDatabase.contains(emailAndNamePair.email)) { + val recipientEntity = recipientsByEmailMap[emailAndNamePair.email] if (recipientEntity?.email.isNullOrEmpty()) { - if (!contactsWhichWillBeUpdated.contains(emailAndNamePair.email)) { + if (!recipientsWhichWillBeUpdated.contains(emailAndNamePair.email)) { emailAndNamePair.email?.let { - contactsWhichWillBeUpdated.add(it) + recipientsWhichWillBeUpdated.add(it) } recipientEntity?.copy(name = emailAndNamePair.name)?.let { updateCandidates.add(it) } } } } else { - if (!contactsWhichWillBeCreated.contains(emailAndNamePair.email)) { + if (!recipientsWhichWillBeCreated.contains(emailAndNamePair.email)) { emailAndNamePair.email?.let { - contactsWhichWillBeCreated.add(it) + recipientsWhichWillBeCreated.add(it) newCandidates.add(RecipientEntity(email = it, name = emailAndNamePair.name)) } } @@ -222,7 +222,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : for (address in addresses) { emailAndNamePairs.add( EmailAndNamePair( - address.address.lowercase(Locale.getDefault()), address.personal + address.address.lowercase(), address.personal ) ) } @@ -254,7 +254,7 @@ class LoadContactsWorker(context: Context, params: WorkerParameters) : .enqueueUniqueWork( GROUP_UNIQUE_TAG, ExistingWorkPolicy.KEEP, - OneTimeWorkRequestBuilder() + OneTimeWorkRequestBuilder() .addTag(TAG_SYNC) .setConstraints(constraints) .build() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/KeyImportDetails.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/KeyImportDetails.kt index 4155e8b356..1e71c1f154 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/KeyImportDetails.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/KeyImportDetails.kt @@ -7,6 +7,7 @@ package com.flowcrypt.email.model import android.os.Parcel import android.os.Parcelable +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.security.model.PrivateKeySourceType /** @@ -28,18 +29,45 @@ data class KeyImportDetails constructor( val value: String, val sourceType: SourceType, val isPrivateKey: Boolean = false, - val pgpContact: PgpContact? = null + val recipientWithPubKeys: RecipientWithPubKeys? = null ) : Parcelable { - constructor(value: String, sourceType: SourceType) : this(null, value, sourceType, true) + constructor(parcel: Parcel) : this( + parcel.readString(), + parcel.readString()!!, + parcel.readParcelable(SourceType::class.java.classLoader)!!, + parcel.readByte() != 0.toByte(), + parcel.readParcelable(RecipientWithPubKeys::class.java.classLoader) + ) + + constructor(value: String, sourceType: SourceType) : this( + keyName = null, + value = value, + sourceType = sourceType, + isPrivateKey = true + ) + constructor(value: String, sourceType: SourceType, isPrivateKey: Boolean) : this( - null, - value, - sourceType, - isPrivateKey, - null + keyName = null, + value = value, + sourceType = sourceType, + isPrivateKey = isPrivateKey, + recipientWithPubKeys = null ) + override fun describeContents(): Int { + return 0 + } + + override fun writeToParcel(dest: Parcel, flags: Int) = + with(dest) { + writeString(keyName) + writeString(value) + writeParcelable(sourceType, flags) + writeInt((if (isPrivateKey) 1 else 0)) + writeParcelable(recipientWithPubKeys, flags) + } + /** * The key available types. */ @@ -71,33 +99,8 @@ data class KeyImportDetails constructor( } } - constructor(source: Parcel) : this( - source.readString(), - source.readString()!!, - source.readParcelable(SourceType::class.java.classLoader)!!, - source.readInt() == 1, - source.readParcelable(PgpContact::class.java.classLoader)!! - ) - - override fun describeContents(): Int { - return 0 - } - - override fun writeToParcel(dest: Parcel, flags: Int) = - with(dest) { - writeString(keyName) - writeString(value) - writeParcelable(sourceType, flags) - writeInt((if (isPrivateKey) 1 else 0)) - writeParcelable(pgpContact, flags) - } - - companion object { - @JvmField - val CREATOR: Parcelable.Creator = - object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): KeyImportDetails = KeyImportDetails(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } + companion object CREATOR : Parcelable.Creator { + override fun createFromParcel(parcel: Parcel): KeyImportDetails = KeyImportDetails(parcel) + override fun newArray(size: Int): Array = arrayOfNulls(size) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt deleted file mode 100644 index 223acdd797..0000000000 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PgpContact.kt +++ /dev/null @@ -1,105 +0,0 @@ -/* - * © 2016-present FlowCrypt a.s. Limitations apply. Contact human@flowcrypt.com - * Contributors: DenBond7 - */ - -package com.flowcrypt.email.model - -import android.os.Parcel -import android.os.Parcelable -import com.flowcrypt.email.database.entity.PublicKeyEntity -import com.flowcrypt.email.database.entity.RecipientEntity -import com.flowcrypt.email.security.model.PgpKeyDetails -import java.util.ArrayList -import javax.mail.internet.AddressException -import javax.mail.internet.InternetAddress - -data class PgpContact constructor( - var email: String, - var name: String? = null, - var pubkey: String? = null, - var hasPgp: Boolean = false, - var client: String? = null, - var fingerprint: String? = null, - var lastUse: Long = 0, - var pgpKeyDetails: PgpKeyDetails? = null, - var hasNotUsablePubKey: Boolean = false -) : Parcelable { - - constructor(source: Parcel) : this( - source.readString()!!, - source.readString(), - source.readString(), - source.readInt() == 1, - source.readString(), - source.readString(), - source.readLong(), - source.readParcelable(PgpKeyDetails::class.java.classLoader), - source.readInt() == 1 - ) - - constructor(email: String, name: String?) : this(email) { - this.name = name - } - - override fun describeContents(): Int { - return 0 - } - - override fun writeToParcel(dest: Parcel, flags: Int) = - with(dest) { - writeString(email) - writeString(name) - writeString(pubkey) - writeInt((if (hasPgp) 1 else 0)) - writeString(client) - writeString(fingerprint) - writeLong(lastUse) - writeParcelable(pgpKeyDetails, flags) - writeInt((if (hasNotUsablePubKey) 1 else 0)) - } - - fun toRecipientEntity(): RecipientEntity { - return RecipientEntity( - email = email.lowercase(), - name = name, - lastUse = lastUse - ) - } - - fun toPubKey(): PublicKeyEntity { - return PublicKeyEntity( - recipient = email, - fingerprint = fingerprint!!, - publicKey = pubkey!!.toByteArray() - ) - } - - companion object { - @JvmField - val CREATOR: Parcelable.Creator = object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): PgpContact = PgpContact(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - - fun determinePgpContacts(users: List): ArrayList { - val pgpContacts = ArrayList() - for (user in users) { - try { - val internetAddresses = InternetAddress.parse(user) - - for (internetAddress in internetAddresses) { - val email = internetAddress.address.lowercase() - val name = internetAddress.personal - - pgpContacts.add(PgpContact(email, name)) - } - } catch (e: AddressException) { - e.printStackTrace() - } - } - - return pgpContacts - } - } -} diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt index 01ad2aefe0..27b4feca9c 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/model/PublicKeyInfo.kt @@ -31,16 +31,4 @@ data class PublicKeyInfo constructor( email = keyOwner.lowercase() ) } - - fun toPgpContact(): PgpContact { - return PgpContact( - email = keyOwner, - name = null, - pubkey = publicKey, - hasPgp = true, - client = null, - fingerprint = fingerprint, - lastUse = 0 - ) - } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/security/model/PgpKeyDetails.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/security/model/PgpKeyDetails.kt index cd7086bd87..2c9f940262 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/security/model/PgpKeyDetails.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/security/model/PgpKeyDetails.kt @@ -10,11 +10,9 @@ import android.os.Parcelable import android.util.Patterns import com.flowcrypt.email.database.entity.AccountEntity import com.flowcrypt.email.database.entity.KeyEntity -import com.flowcrypt.email.model.PgpContact -import com.flowcrypt.email.util.exception.FlowCryptException +import com.flowcrypt.email.database.entity.PublicKeyEntity import com.google.gson.annotations.Expose import com.google.gson.annotations.SerializedName -import java.util.ArrayList import java.util.Locale import javax.mail.internet.AddressException import javax.mail.internet.InternetAddress @@ -42,11 +40,6 @@ data class PgpKeyDetails constructor( var tempPassphrase: CharArray? = null, var passphraseType: KeyEntity.PassphraseType? = null ) : Parcelable { - - val primaryPgpContact: PgpContact - get() = determinePrimaryPgpContact() - val pgpContacts: ArrayList - get() = PgpContact.determinePgpContacts(users) val fingerprint: String get() = ids.first().fingerprint val isPrivate: Boolean @@ -97,37 +90,12 @@ data class PgpKeyDetails constructor( writeParcelable(passphraseType, flags) } - private fun determinePrimaryPgpContact(): PgpContact { - val address = users.first() - val fingerprintFromKeyId = ids.first().fingerprint - var email: String? = null - var name: String? = null - try { - val internetAddresses = InternetAddress.parse(address) - email = internetAddresses.first().address - name = internetAddresses.first().personal - } catch (e: AddressException) { - e.printStackTrace() - val pattern = Patterns.EMAIL_ADDRESS - val matcher = pattern.matcher(users.first()) - if (matcher.find()) { - email = matcher.group() - name = email - } - } - - if (email == null) { - throw object : FlowCryptException("No user ids with mail address") {} - } + fun getUserIdsAsSingleString(): String { + return mimeAddresses.joinToString { it.address } + } - return PgpContact( - email = email.toLowerCase(Locale.US), - name = name, - pubkey = publicKey, - hasPgp = true, - client = null, - fingerprint = fingerprintFromKeyId - ) + fun getPrimaryInternetAddress(): InternetAddress? { + return mimeAddresses.firstOrNull() } private fun parseMimeAddresses(): List { @@ -137,7 +105,12 @@ data class PgpKeyDetails constructor( try { results.addAll(listOf(*InternetAddress.parse(user))) } catch (e: AddressException) { - //do nothing + e.printStackTrace() + val pattern = Patterns.EMAIL_ADDRESS + val matcher = pattern.matcher(user) + if (matcher.find()) { + results.add(InternetAddress(matcher.group())) + } } } @@ -147,7 +120,7 @@ data class PgpKeyDetails constructor( fun toKeyEntity(accountEntity: AccountEntity): KeyEntity { return KeyEntity( fingerprint = fingerprint, - account = accountEntity.email.toLowerCase(Locale.US), + account = accountEntity.email.lowercase(Locale.US), accountType = accountEntity.accountType, source = PrivateKeySourceType.BACKUP.toString(), publicKey = publicKey.toByteArray(), @@ -159,6 +132,14 @@ data class PgpKeyDetails constructor( ) } + fun toPublicKeyEntity(recipient: String): PublicKeyEntity { + return PublicKeyEntity( + recipient = recipient, + fingerprint = fingerprint, + publicKey = publicKey.toByteArray() + ) + } + override fun equals(other: Any?): Boolean { if (this === other) return true if (javaClass != other?.javaClass) return false diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt index 592efe46d3..5c24b8aa04 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/EmailAndNameUpdaterService.kt @@ -29,7 +29,7 @@ import java.util.ArrayList * "save that person's name into the existing DB record" * * * else: - * "save that email, name pair into DB like so: new PgpContact(email, name);" + * "save that email, name pair into DB like so: new RecipientEntity(email, name);" * * * @author DenBond7 diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt index c45fd1bfb8..c68c2050ff 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/service/PrepareOutgoingMessagesJobIntentService.kt @@ -43,7 +43,6 @@ import java.io.File import java.io.IOException import java.io.InputStream import java.util.ArrayList -import java.util.Locale import java.util.UUID import javax.mail.Message @@ -79,7 +78,7 @@ class PrepareOutgoingMessagesJobIntentService : JobIntentService() { intent.getParcelableExtra(EXTRA_KEY_OUTGOING_MESSAGE_INFO) ?: return val accountEntity = - roomDatabase.accountDao().getAccount(outgoingMsgInfo.account.lowercase(Locale.US)) + roomDatabase.accountDao().getAccount(outgoingMsgInfo.account.lowercase()) ?: return val uid = outgoingMsgInfo.uid diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt index 5749dbe706..2714c9838b 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPgpContactActivity.kt @@ -35,14 +35,14 @@ import java.util.* /** * This [Activity] retrieves a public keys string from the different sources and sends it to - * [PreviewImportPgpContactActivity] + * [PreviewImportRecipientWithPubKeysActivity] * * @author Denis Bondarenko * Date: 04.05.2018 * Time: 17:07 * E-mail: DenBond7@gmail.com */ -class ImportPgpContactActivity : BaseImportKeyActivity() { +class ImportRecipientWithPubKeysActivity : BaseImportKeyActivity() { private val recipientsViewModel: RecipientsViewModel by viewModels() private var editTextEmailOrId: EditText? = null @@ -110,7 +110,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { if (keyDetailsList.isNotEmpty()) { UIUtil.exchangeViewVisibility(true, layoutProgress, layoutContentView) startActivityForResult( - PreviewImportPgpContactActivity.newIntent( + PreviewImportRecipientWithPubKeysActivity.newIntent( this, keyImportModel!! .keyString ), REQUEST_CODE_RUN_PREVIEW_ACTIVITY @@ -125,7 +125,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { override fun handleSelectedFile(uri: Uri) { UIUtil.exchangeViewVisibility(true, layoutProgress, layoutContentView) startActivityForResult( - PreviewImportPgpContactActivity.newIntent(this, uri), + PreviewImportRecipientWithPubKeysActivity.newIntent(this, uri), REQUEST_CODE_RUN_PREVIEW_ACTIVITY ) } @@ -147,7 +147,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { private fun fetchPubKey() { val v = editTextEmailOrId ?: return - UIUtil.hideSoftInput(this@ImportPgpContactActivity, v) + UIUtil.hideSoftInput(this@ImportRecipientWithPubKeysActivity, v) if (v.text.isNullOrEmpty()) { Toast.makeText(this, R.string.please_type_key_id_or_email, Toast.LENGTH_SHORT).show() @@ -207,7 +207,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { val pubkey = pubResponse.pubkey if (!pubkey.isNullOrEmpty()) { startActivityForResult( - PreviewImportPgpContactActivity.newIntent(this, pubkey), + PreviewImportRecipientWithPubKeysActivity.newIntent(this, pubkey), REQUEST_CODE_RUN_PREVIEW_ACTIVITY ) } else { @@ -226,7 +226,7 @@ class ImportPgpContactActivity : BaseImportKeyActivity() { accountEntity = accountEntity, title = context.getString(R.string.add_public_keys_of_your_contacts), throwErrorIfDuplicateFoundEnabled = false, - cls = ImportPgpContactActivity::class.java + cls = ImportRecipientWithPubKeysActivity::class.java ) } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt index fef8af9233..08b49ab809 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/ImportPublicKeyActivity.kt @@ -12,9 +12,9 @@ import android.os.Bundle import androidx.activity.viewModels import com.flowcrypt.email.R import com.flowcrypt.email.database.entity.AccountEntity +import com.flowcrypt.email.database.entity.relation.RecipientWithPubKeys import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.model.KeyImportDetails -import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.model.PgpKeyDetails import com.flowcrypt.email.ui.activity.base.BaseImportKeyActivity import com.flowcrypt.email.util.GeneralUtil @@ -30,7 +30,7 @@ import com.google.android.material.snackbar.Snackbar */ class ImportPublicKeyActivity : BaseImportKeyActivity() { - private var pgpContact: PgpContact? = null + private var recipientWithPubKeys: RecipientWithPubKeys? = null private val recipientsViewModel: RecipientsViewModel by viewModels() override val contentViewResourceId: Int @@ -42,7 +42,7 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) if (intent != null && intent.hasExtra(KEY_EXTRA_PGP_CONTACT)) { - this.pgpContact = intent.getParcelableExtra(KEY_EXTRA_PGP_CONTACT) + this.recipientWithPubKeys = intent.getParcelableExtra(KEY_EXTRA_PGP_CONTACT) } else { finish() } @@ -67,7 +67,7 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { return } - updateInformationAboutPgpContact(key) + updateInformationAboutRecipientWithPubKeys(key) setResult(Activity.RESULT_OK) finish() } else { @@ -78,11 +78,10 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { } } - private fun updateInformationAboutPgpContact(keyDetails: PgpKeyDetails) { - val pgpContactFromKey = keyDetails.primaryPgpContact - pgpContact?.pubkey = pgpContactFromKey.pubkey - pgpContact?.hasPgp = pgpContact?.pubkey?.isNotEmpty() == true - pgpContact?.let { recipientsViewModel.copyPubKeysToRecipient(it, pgpContactFromKey) } + private fun updateInformationAboutRecipientWithPubKeys(keyDetails: PgpKeyDetails) { + recipientWithPubKeys?.recipient?.let { + recipientsViewModel.copyPubKeysToRecipient(it, keyDetails) + } } companion object { @@ -95,13 +94,13 @@ class ImportPublicKeyActivity : BaseImportKeyActivity() { context: Context?, accountEntity: AccountEntity?, title: String, - pgpContact: PgpContact + recipientWithPubKeys: RecipientWithPubKeys ): Intent { val intent = newIntent( context = context, accountEntity = accountEntity, title = title, throwErrorIfDuplicateFoundEnabled = false, cls = ImportPublicKeyActivity::class.java ) - intent.putExtra(KEY_EXTRA_PGP_CONTACT, pgpContact) + intent.putExtra(KEY_EXTRA_PGP_CONTACT, recipientWithPubKeys) return intent } } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivity.kt index 2ec7200d79..9a2c4b87b1 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/PreviewImportPgpContactActivity.kt @@ -15,7 +15,7 @@ import android.view.MenuItem import android.view.View import com.flowcrypt.email.R import com.flowcrypt.email.ui.activity.base.BaseBackStackActivity -import com.flowcrypt.email.ui.activity.fragment.PreviewImportPgpContactFragment +import com.flowcrypt.email.ui.activity.fragment.PreviewImportRecipientWithPubKeysFragment import com.flowcrypt.email.ui.activity.settings.FeedbackActivity import com.flowcrypt.email.util.GeneralUtil @@ -27,7 +27,7 @@ import com.flowcrypt.email.util.GeneralUtil * Time: 18:01 * E-mail: DenBond7@gmail.com */ -class PreviewImportPgpContactActivity : BaseBackStackActivity() { +class PreviewImportRecipientWithPubKeysActivity : BaseBackStackActivity() { override val contentViewResourceId: Int get() = R.layout.activity_preview_import_pgp_contact @@ -49,10 +49,11 @@ class PreviewImportPgpContactActivity : BaseBackStackActivity() { val fragmentManager = supportFragmentManager var fragment = - fragmentManager.findFragmentById(R.id.layoutContent) as PreviewImportPgpContactFragment? + fragmentManager.findFragmentById(R.id.layoutContent) as PreviewImportRecipientWithPubKeysFragment? if (fragment == null) { - fragment = PreviewImportPgpContactFragment.newInstance(publicKeysString, publicKeysFileUri) + fragment = + PreviewImportRecipientWithPubKeysFragment.newInstance(publicKeysString, publicKeysFileUri) fragmentManager.beginTransaction().add(R.id.layoutContent, fragment).commit() } } @@ -77,22 +78,22 @@ class PreviewImportPgpContactActivity : BaseBackStackActivity() { val KEY_EXTRA_PUBLIC_KEY_STRING = GeneralUtil.generateUniqueExtraKey( "KEY_EXTRA_PUBLIC_KEY_STRING", - PreviewImportPgpContactActivity::class.java + PreviewImportRecipientWithPubKeysActivity::class.java ) val KEY_EXTRA_PUBLIC_KEYS_FILE_URI = GeneralUtil.generateUniqueExtraKey( "KEY_EXTRA_PUBLIC_KEYS_FILE_URI", - PreviewImportPgpContactActivity::class.java + PreviewImportRecipientWithPubKeysActivity::class.java ) fun newIntent(context: Context, publicKeysString: String?): Intent { - val intent = Intent(context, PreviewImportPgpContactActivity::class.java) + val intent = Intent(context, PreviewImportRecipientWithPubKeysActivity::class.java) intent.putExtra(KEY_EXTRA_PUBLIC_KEY_STRING, publicKeysString) return intent } fun newIntent(context: Context, publicKeysFileUri: Uri): Intent { - val intent = Intent(context, PreviewImportPgpContactActivity::class.java) + val intent = Intent(context, PreviewImportRecipientWithPubKeysActivity::class.java) intent.putExtra(KEY_EXTRA_PUBLIC_KEYS_FILE_URI, publicKeysFileUri) return intent } diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt index 5ab0f4336a..08921a399f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/SelectContactsActivity.kt @@ -27,7 +27,7 @@ import com.flowcrypt.email.extensions.decrementSafely import com.flowcrypt.email.extensions.incrementSafely import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.ui.activity.base.BaseBackStackActivity -import com.flowcrypt.email.ui.adapter.ContactsRecyclerViewAdapter +import com.flowcrypt.email.ui.adapter.RecipientsRecyclerViewAdapter import com.flowcrypt.email.util.GeneralUtil import com.flowcrypt.email.util.UIUtil @@ -41,13 +41,13 @@ import com.flowcrypt.email.util.UIUtil * E-mail: DenBond7@gmail.com */ class SelectContactsActivity : BaseBackStackActivity(), - ContactsRecyclerViewAdapter.OnContactActionsListener, SearchView.OnQueryTextListener { + RecipientsRecyclerViewAdapter.OnContactActionsListener, SearchView.OnQueryTextListener { private var progressBar: View? = null private var recyclerViewContacts: RecyclerView? = null private var emptyView: View? = null - private val contactsRecyclerViewAdapter: ContactsRecyclerViewAdapter = - ContactsRecyclerViewAdapter(false) + private val recipientsRecyclerViewAdapter: RecipientsRecyclerViewAdapter = + RecipientsRecyclerViewAdapter(false) private var searchPattern: String? = null private val recipientsViewModel: RecipientsViewModel by viewModels() @@ -65,7 +65,7 @@ class SelectContactsActivity : BaseBackStackActivity(), override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - contactsRecyclerViewAdapter.onContactActionsListener = this + recipientsRecyclerViewAdapter.onContactActionsListener = this //todo-denbond7 need to fix this in the future. Not urgent //val isMultiply = intent.getBooleanExtra(KEY_EXTRA_IS_MULTIPLY, false) @@ -80,7 +80,7 @@ class SelectContactsActivity : BaseBackStackActivity(), drawable?.let { decoration.setDrawable(drawable) } recyclerViewContacts?.addItemDecoration(decoration) recyclerViewContacts?.layoutManager = manager - recyclerViewContacts?.adapter = contactsRecyclerViewAdapter + recyclerViewContacts?.adapter = recipientsRecyclerViewAdapter if (!TextUtils.isEmpty(title)) { supportActionBar?.title = title @@ -146,7 +146,7 @@ class SelectContactsActivity : BaseBackStackActivity(), if (it.data.isNullOrEmpty()) { UIUtil.exchangeViewVisibility(true, emptyView, recyclerViewContacts) } else { - contactsRecyclerViewAdapter.swap(it.data) + recipientsRecyclerViewAdapter.swap(it.data) UIUtil.exchangeViewVisibility(false, emptyView, recyclerViewContacts) } countingIdlingResourceForFilter.decrementSafely() diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseSyncActivity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseSyncActivity.kt index ee0f1c158b..c6b3cec86d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseSyncActivity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/base/BaseSyncActivity.kt @@ -9,7 +9,7 @@ import com.flowcrypt.email.jetpack.workmanager.sync.ArchiveMsgsWorker import com.flowcrypt.email.jetpack.workmanager.sync.DeleteMessagesPermanentlyWorker import com.flowcrypt.email.jetpack.workmanager.sync.DeleteMessagesWorker import com.flowcrypt.email.jetpack.workmanager.sync.EmptyTrashWorker -import com.flowcrypt.email.jetpack.workmanager.sync.LoadContactsWorker +import com.flowcrypt.email.jetpack.workmanager.sync.LoadRecipientsWorker import com.flowcrypt.email.jetpack.workmanager.sync.MovingToInboxWorker import com.flowcrypt.email.jetpack.workmanager.sync.UpdateLabelsWorker import com.flowcrypt.email.jetpack.workmanager.sync.UpdateMsgsSeenStateWorker @@ -35,7 +35,7 @@ abstract class BaseSyncActivity : BaseActivity() { * Load information about contacts. */ fun loadContactsIfNeeded() { - LoadContactsWorker.enqueue(this) + LoadRecipientsWorker.enqueue(this) } /** diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt index 9a9d8571d3..0905aa2691 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MessageDetailsFragment.kt @@ -72,7 +72,6 @@ import com.flowcrypt.email.jetpack.viewmodel.RecipientsViewModel import com.flowcrypt.email.jetpack.viewmodel.factory.MsgDetailsViewModelFactory import com.flowcrypt.email.model.MessageEncryptionType import com.flowcrypt.email.model.MessageType -import com.flowcrypt.email.model.PgpContact import com.flowcrypt.email.security.SecurityUtils import com.flowcrypt.email.security.pgp.PgpDecrypt import com.flowcrypt.email.service.attachment.AttachmentDownloadManagerService @@ -983,11 +982,11 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi } val keyDetails = block.keyDetails - val pgpContact = keyDetails?.primaryPgpContact ?: PgpContact(email = "") + val userIds = keyDetails?.getUserIdsAsSingleString() - if (!TextUtils.isEmpty(pgpContact.email)) { + if (userIds?.isNotEmpty() == true) { val keyOwner = pubKeyView.findViewById(R.id.textViewKeyOwnerTemplate) - keyOwner.text = getString(R.string.template_message_part_public_key_owner, pgpContact.email) + keyOwner.text = getString(R.string.template_message_part_public_key_owner, userIds) } val fingerprint = pubKeyView.findViewById(R.id.textViewFingerprintTemplate) @@ -1000,38 +999,41 @@ class MessageDetailsFragment : BaseFragment(), ProgressBehaviour, View.OnClickLi textViewPgpPublicKey.text = clipLargeText(block.keyDetails?.publicKey ?: block.content) - val existingPgpContact = block.existingPgpContact + val existingRecipientWithPubKeys = block.existingRecipientWithPubKeys val button = pubKeyView.findViewById