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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,012 changes: 1,012 additions & 0 deletions FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/28.json

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ class MigrationTest {
FlowCryptRoomDatabase.MIGRATION_23_24,
FlowCryptRoomDatabase.MIGRATION_24_25,
FlowCryptRoomDatabase.MIGRATION_25_26,
FlowCryptRoomDatabase.MIGRATION_26_27
FlowCryptRoomDatabase.MIGRATION_26_27,
FlowCryptRoomDatabase.MIGRATION_27_28
)

@get:Rule
Expand Down
2 changes: 1 addition & 1 deletion FlowCrypt/src/main/java/com/flowcrypt/email/Constants.kt
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ class Constants {
const val PASSWORD_QUALITY_WEAK = "weak"
const val PASSWORD_QUALITY_POOR = "poor"

const val PGP_FILE_EXT = ".pgp"
const val PGP_FILE_EXT = "pgp"

val PASSWORD_WEAK_WORDS = arrayOf(
"crypt",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -677,14 +677,15 @@ class EmailUtil {
): Message {
val session = Session.getInstance(Properties())
val senderEmail = outgoingMsgInfo.from
val senderPgpKeyDetailsList =
SecurityUtils.getSenderPgpKeyDetailsList(context, accountEntity, senderEmail)
var pubKeys: List<String>? = null
var prvKeys: List<String>? = null
var ringProtector: SecretKeyRingProtector? = null

if (outgoingMsgInfo.encryptionType === MessageEncryptionType.ENCRYPTED) {
val recipients = outgoingMsgInfo.getAllRecipients().toMutableList()
val senderPgpKeyDetailsList =
SecurityUtils.getSenderPgpKeyDetailsList(context, accountEntity, senderEmail)

pubKeys = mutableListOf()
pubKeys.addAll(SecurityUtils.getRecipientsUsablePubKeys(context, recipients))
pubKeys.addAll(senderPgpKeyDetailsList.map { it.publicKey })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import android.os.Parcel
import android.os.Parcelable
import com.flowcrypt.email.Constants
import com.flowcrypt.email.security.SecurityUtils
import com.flowcrypt.email.security.pgp.PgpMsg

/**
* Simple POJO which defines information about email attachments.
Expand All @@ -36,7 +37,8 @@ data class AttachmentInfo constructor(
var isForwarded: Boolean = false,
var isDecrypted: Boolean = false,
var isEncryptionAllowed: Boolean = true,
var orderNumber: Int = 0
var orderNumber: Int = 0,
var decryptWhenForward: Boolean = false,
) : Parcelable {

val uniqueStringId: String
Expand Down Expand Up @@ -69,7 +71,8 @@ data class AttachmentInfo constructor(
source.readByte() != 0.toByte(),
source.readByte() != 0.toByte(),
source.readByte() != 0.toByte(),
source.readInt()
source.readInt(),
source.readByte() != 0.toByte(),
)

override fun describeContents(): Int {
Expand All @@ -95,6 +98,7 @@ data class AttachmentInfo constructor(
writeByte(if (isDecrypted) 1.toByte() else 0.toByte())
writeByte(if (isEncryptionAllowed) 1.toByte() else 0.toByte())
writeInt(orderNumber)
writeByte(if (decryptWhenForward) 1.toByte() else 0.toByte())
}
}

Expand Down Expand Up @@ -156,6 +160,10 @@ data class AttachmentInfo constructor(
fun isHidden() =
name.isNullOrEmpty() && type.lowercase() == "application/pgp-encrypted; name=\"\""

fun isPossiblyEncrypted(): Boolean {
return PgpMsg.ENCRYPTED_FILE_REGEX.containsMatchIn(name ?: "")
}

companion object {
const val DEPTH_SEPARATOR = "/"
const val INNER_ATTACHMENT_PREFIX = "inner_"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() {

companion object {
const val DB_NAME = "flowcrypt.db"
const val DB_VERSION = 27
const val DB_VERSION = 28

private val MIGRATION_1_3 = object : FlowCryptMigration(1, 3) {
override fun doMigration(database: SupportSQLiteDatabase) {
Expand Down Expand Up @@ -545,6 +545,13 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() {
}
}

@VisibleForTesting
val MIGRATION_27_28 = object : FlowCryptMigration(27, 28) {
override fun doMigration(database: SupportSQLiteDatabase) {
database.execSQL("ALTER TABLE attachment ADD COLUMN decrypt_when_forward INTEGER NOT NULL DEFAULT 0;")
}
}

// Singleton prevents multiple instances of database opening at the same time.
@Volatile
private var INSTANCE: FlowCryptRoomDatabase? = null
Expand Down Expand Up @@ -585,7 +592,8 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() {
MIGRATION_23_24,
MIGRATION_24_25,
MIGRATION_25_26,
MIGRATION_26_27
MIGRATION_26_27,
MIGRATION_27_28
).build()
INSTANCE = instance
return instance
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ 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.api.email.model.AttachmentInfo
Expand Down Expand Up @@ -49,9 +50,14 @@ data class AttachmentEntity(
@ColumnInfo(name = "file_uri") val fileUri: String?,
@ColumnInfo(name = "forwarded_folder") val forwardedFolder: String?,
@ColumnInfo(name = "forwarded_uid", defaultValue = "-1") val forwardedUid: Long?,
@ColumnInfo(name = "decrypt_when_forward", defaultValue = "0") val decryptWhenForward: Boolean,
val path: String
) {

@Ignore
val isForwarded: Boolean =
forwardedFolder?.isNotEmpty() == true && (forwardedUid != null && forwardedUid > 0)

fun toAttInfo(): AttachmentInfo {
return AttachmentInfo(
email = email,
Expand All @@ -65,8 +71,9 @@ data class AttachmentEntity(
fwdFolder = forwardedFolder,
fwdUid = forwardedUid ?: -1,
path = path,
isForwarded = forwardedFolder?.isNotEmpty() == true && (forwardedUid != null && forwardedUid > 0),
isEncryptionAllowed = true
isForwarded = isForwarded,
isEncryptionAllowed = true,
decryptWhenForward = decryptWhenForward
)
}

Expand All @@ -89,7 +96,8 @@ data class AttachmentEntity(
fileUri = if (uri != null) uri.toString() else null,
forwardedFolder = fwdFolder,
forwardedUid = fwdUid,
path = path
path = path,
decryptWhenForward = decryptWhenForward
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import com.flowcrypt.email.Constants
import com.flowcrypt.email.api.email.EmailUtil
import com.flowcrypt.email.api.email.JavaEmailConstants
import com.flowcrypt.email.api.email.gmail.GmailApiHelper
import com.flowcrypt.email.api.email.protocol.ImapProtocolUtil
Expand All @@ -27,8 +26,6 @@ import com.flowcrypt.email.database.entity.AttachmentEntity
import com.flowcrypt.email.database.entity.MessageEntity
import com.flowcrypt.email.extensions.kotlin.toHex
import com.flowcrypt.email.jetpack.viewmodel.AccountViewModel
import com.flowcrypt.email.security.SecurityUtils
import com.flowcrypt.email.security.pgp.PgpEncryptAndOrSign
import com.flowcrypt.email.ui.notifications.ErrorNotificationManager
import com.flowcrypt.email.util.FileAndDirectoryUtils
import com.flowcrypt.email.util.GeneralUtil
Expand All @@ -41,6 +38,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.apache.commons.io.FileUtils
import java.io.File
import java.io.FileOutputStream
import java.io.InputStream
import java.util.*
import javax.mail.Folder
Expand Down Expand Up @@ -224,19 +222,6 @@ class ForwardedAttachmentsDownloaderWorker(context: Context, params: WorkerParam
-> InputStream?
): MessageState = withContext(Dispatchers.IO) {
var msgState = MessageState.QUEUED
var pubKeys: List<String>? = null

if (msgEntity.isEncrypted == true) {
val senderEmail = EmailUtil.getFirstAddressString(msgEntity.from)
val recipients = msgEntity.allRecipients.toMutableList()
pubKeys = mutableListOf()
pubKeys.addAll(SecurityUtils.getRecipientsUsablePubKeys(applicationContext, recipients))
pubKeys.addAll(
SecurityUtils.getSenderPgpKeyDetailsList(applicationContext, account, senderEmail)
.map { it.publicKey }
)
}

for (attachmentEntity in atts) {
val attInfo = attachmentEntity.toAttInfo()

Expand All @@ -257,7 +242,11 @@ class ForwardedAttachmentsDownloaderWorker(context: Context, params: WorkerParam
val inputStream = action.invoke(attachmentEntity)
val tempFile = File(fwdAttsCacheDir, UUID.randomUUID().toString())
if (inputStream != null) {
downloadFile(msgEntity, pubKeys, tempFile, inputStream)
inputStream.use { srcStream ->
FileOutputStream(tempFile).use { destStream ->
srcStream.copyTo(destStream)
}
}

if (msgAttsDir.exists()) {
FileUtils.moveFile(tempFile, attFile)
Expand Down Expand Up @@ -288,19 +277,6 @@ class ForwardedAttachmentsDownloaderWorker(context: Context, params: WorkerParam
return@withContext msgState
}

private suspend fun downloadFile(
msgEntity: MessageEntity, pubKeys: List<String>?,
destFile: File, srcInputStream: InputStream
) =
withContext(Dispatchers.IO) {
if (msgEntity.isEncrypted == true) {
requireNotNull(pubKeys)
PgpEncryptAndOrSign.encryptAndOrSign(srcInputStream, destFile.outputStream(), pubKeys)
} else {
FileUtils.copyInputStreamToFile(srcInputStream, destFile)
}
}

companion object {
private val TAG = ForwardedAttachmentsDownloaderWorker::class.java.simpleName
val NAME = ForwardedAttachmentsDownloaderWorker::class.java.simpleName
Expand Down
Loading