From 773d548c71a1871d43789fb1cef0839f3d4f9603 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 24 Jan 2022 11:50:25 +0200 Subject: [PATCH 1/2] Disabled password-protected messages for accounts if FES is not used. Refactored code.| #1621 --- .../30.json | 1026 +++++++++++++++++ .../flowcrypt/email/database/MigrationTest.kt | 3 +- .../email/database/FlowCryptRoomDatabase.kt | 12 +- .../email/database/entity/AccountEntity.kt | 88 +- .../fragment/CreateMessageFragment.kt | 3 +- .../activity/fragment/MainSignInFragment.kt | 9 +- 6 files changed, 1094 insertions(+), 47 deletions(-) create mode 100644 FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/30.json diff --git a/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/30.json b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/30.json new file mode 100644 index 0000000000..03f1312ad2 --- /dev/null +++ b/FlowCrypt/schemas/com.flowcrypt.email.database.FlowCryptRoomDatabase/30.json @@ -0,0 +1,1026 @@ +{ + "formatVersion": 1, + "database": { + "version": 30, + "identityHash": "7f7020d8429731c8a4e8725981745d1b", + "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, `use_fes` 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" + }, + { + "fieldPath": "useFES", + "columnName": "use_fes", + "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, `decrypt_when_forward` INTEGER NOT NULL DEFAULT 0, `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": "decryptWhenForward", + "columnName": "decrypt_when_forward", + "affinity": "INTEGER", + "notNull": true, + "defaultValue": "0" + }, + { + "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": "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": [ + { + "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_recipients", + "unique": false, + "columnNames": [ + "name" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `name_in_recipients` ON `${TABLE_NAME}` (`name`)" + }, + { + "name": "last_use_in_recipients", + "unique": false, + "columnNames": [ + "last_use" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `last_use_in_recipients` ON `${TABLE_NAME}` (`last_use`)" + }, + { + "name": "email_in_recipients", + "unique": true, + "columnNames": [ + "email" + ], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `email_in_recipients` 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, `password` BLOB 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" + }, + { + "fieldPath": "password", + "columnName": "password", + "affinity": "BLOB", + "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 `recipients`(`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": "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, + "columnNames": [ + "fingerprint" + ], + "createSql": "CREATE INDEX IF NOT EXISTS `fingerprint_in_public_keys` ON `${TABLE_NAME}` (`fingerprint`)" + } + ], + "foreignKeys": [ + { + "table": "recipients", + "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, '7f7020d8429731c8a4e8725981745d1b')" + ] + } +} \ No newline at end of file diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt index 7e48756a46..cd353f2bf6 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/database/MigrationTest.kt @@ -39,7 +39,8 @@ class MigrationTest { FlowCryptRoomDatabase.MIGRATION_25_26, FlowCryptRoomDatabase.MIGRATION_26_27, FlowCryptRoomDatabase.MIGRATION_27_28, - FlowCryptRoomDatabase.MIGRATION_28_29 + FlowCryptRoomDatabase.MIGRATION_28_29, + FlowCryptRoomDatabase.MIGRATION_29_30 ) @get:Rule 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 def323f3fd..df98f02283 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/FlowCryptRoomDatabase.kt @@ -90,7 +90,7 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { companion object { const val DB_NAME = "flowcrypt.db" - const val DB_VERSION = 29 + const val DB_VERSION = 30 private val MIGRATION_1_3 = object : FlowCryptMigration(1, 3) { override fun doMigration(database: SupportSQLiteDatabase) { @@ -559,6 +559,13 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { } } + @VisibleForTesting + val MIGRATION_29_30 = object : FlowCryptMigration(29, 30) { + override fun doMigration(database: SupportSQLiteDatabase) { + database.execSQL("ALTER TABLE accounts ADD COLUMN use_fes INTEGER NOT NULL DEFAULT 0;") + } + } + // Singleton prevents multiple instances of database opening at the same time. @Volatile private var INSTANCE: FlowCryptRoomDatabase? = null @@ -601,7 +608,8 @@ abstract class FlowCryptRoomDatabase : RoomDatabase() { MIGRATION_25_26, MIGRATION_26_27, MIGRATION_27_28, - MIGRATION_28_29 + MIGRATION_28_29, + MIGRATION_29_30 ).build() INSTANCE = instance return instance diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/AccountEntity.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/AccountEntity.kt index 8969a6bb09..fb676df03d 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/AccountEntity.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/database/entity/AccountEntity.kt @@ -21,7 +21,6 @@ import com.flowcrypt.email.api.email.model.SecurityType import com.flowcrypt.email.api.retrofit.response.model.OrgRules import com.flowcrypt.email.util.FlavorSettings import com.google.android.gms.auth.api.signin.GoogleSignInAccount -import java.util.Locale /** * @author Denis Bondarenko @@ -74,57 +73,61 @@ data class AccountEntity constructor( name = "client_configuration", defaultValue = "NULL" ) val clientConfiguration: OrgRules? = null, - @ColumnInfo(name = "use_api", defaultValue = "0") val useAPI: Boolean = false + @ColumnInfo(name = "use_api", defaultValue = "0") val useAPI: Boolean = false, + @ColumnInfo(name = "use_fes", defaultValue = "0") val useFES: Boolean = false ) : Parcelable { @Ignore val account: Account = Account( this.email, accountType - ?: this.email.substring(this.email.indexOf('@') + 1).toLowerCase(Locale.US) + ?: this.email.substring(this.email.indexOf('@') + 1).lowercase() ) val useOAuth2: Boolean get() = JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2 == imapAuthMechanisms constructor( - googleSignInAccount: GoogleSignInAccount, uuid: String? = null, orgRules: OrgRules? = null - ) : - this( - email = googleSignInAccount.email!!.toLowerCase(Locale.US), - accountType = googleSignInAccount.account?.type?.toLowerCase(Locale.US), - displayName = googleSignInAccount.displayName, - givenName = googleSignInAccount.givenName, - familyName = googleSignInAccount.familyName, - photoUrl = googleSignInAccount.photoUrl?.toString(), - isEnabled = true, - isActive = false, - username = googleSignInAccount.email!!, - password = "", - imapServer = GmailConstants.GMAIL_IMAP_SERVER, - imapPort = GmailConstants.GMAIL_IMAP_PORT, - imapUseSslTls = true, - imapUseStarttls = false, - imapAuthMechanisms = JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2, - smtpServer = GmailConstants.GMAIL_SMTP_SERVER, - smtpPort = GmailConstants.GMAIL_SMTP_PORT, - smtpUseSslTls = true, - smtpUseStarttls = false, - smtpAuthMechanisms = JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2, - smtpUseCustomSign = false, - smtpUsername = null, - smtpPassword = null, - contactsLoaded = false, - showOnlyEncrypted = false, - uuid = uuid, - clientConfiguration = orgRules, - useAPI = FlavorSettings.isGMailAPIEnabled() - ) + googleSignInAccount: GoogleSignInAccount, + uuid: String? = null, + orgRules: OrgRules? = null, + useFES: Boolean + ) : this( + email = googleSignInAccount.email!!.lowercase(), + accountType = googleSignInAccount.account?.type?.lowercase(), + displayName = googleSignInAccount.displayName, + givenName = googleSignInAccount.givenName, + familyName = googleSignInAccount.familyName, + photoUrl = googleSignInAccount.photoUrl?.toString(), + isEnabled = true, + isActive = false, + username = googleSignInAccount.email!!, + password = "", + imapServer = GmailConstants.GMAIL_IMAP_SERVER, + imapPort = GmailConstants.GMAIL_IMAP_PORT, + imapUseSslTls = true, + imapUseStarttls = false, + imapAuthMechanisms = JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2, + smtpServer = GmailConstants.GMAIL_SMTP_SERVER, + smtpPort = GmailConstants.GMAIL_SMTP_PORT, + smtpUseSslTls = true, + smtpUseStarttls = false, + smtpAuthMechanisms = JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2, + smtpUseCustomSign = false, + smtpUsername = null, + smtpPassword = null, + contactsLoaded = false, + showOnlyEncrypted = false, + uuid = uuid, + clientConfiguration = orgRules, + useAPI = FlavorSettings.isGMailAPIEnabled(), + useFES = useFES + ) constructor(authCredentials: AuthCredentials, uuid: String? = null, orgRules: OrgRules? = null) : this( - email = authCredentials.email.toLowerCase(Locale.US), - accountType = authCredentials.email.substring(authCredentials.email.indexOf('@') + 1) - .toLowerCase(Locale.getDefault()), + email = authCredentials.email.lowercase(), + accountType = + authCredentials.email.substring(authCredentials.email.indexOf('@') + 1).lowercase(), displayName = authCredentials.displayName, givenName = null, familyName = null, @@ -133,12 +136,12 @@ data class AccountEntity constructor( isActive = false, username = authCredentials.username, password = authCredentials.password, - imapServer = authCredentials.imapServer.toLowerCase(Locale.US), + imapServer = authCredentials.imapServer.lowercase(), imapPort = authCredentials.imapPort, imapUseSslTls = authCredentials.imapOpt === SecurityType.Option.SSL_TLS, imapUseStarttls = authCredentials.imapOpt === SecurityType.Option.STARTLS, imapAuthMechanisms = if (authCredentials.useOAuth2) JavaEmailConstants.AUTH_MECHANISMS_XOAUTH2 else null, - smtpServer = authCredentials.smtpServer.toLowerCase(Locale.US), + smtpServer = authCredentials.smtpServer.lowercase(), smtpPort = authCredentials.smtpPort, smtpUseSslTls = authCredentials.smtpOpt === SecurityType.Option.SSL_TLS, smtpUseStarttls = authCredentials.smtpOpt === SecurityType.Option.STARTLS, @@ -150,7 +153,8 @@ data class AccountEntity constructor( showOnlyEncrypted = false, uuid = uuid, clientConfiguration = orgRules, - useAPI = false + useAPI = false, + useFES = false ) constructor(email: String) : @@ -214,6 +218,7 @@ data class AccountEntity constructor( source.readValue(Boolean::class.java.classLoader) as Boolean?, source.readString(), source.readParcelable(OrgRules::class.java.classLoader), + source.readValue(Boolean::class.java.classLoader) as Boolean, source.readValue(Boolean::class.java.classLoader) as Boolean ) @@ -281,6 +286,7 @@ data class AccountEntity constructor( writeString(uuid) writeParcelable(clientConfiguration, flags) writeValue(useAPI) + writeValue(useFES) } companion object { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/CreateMessageFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/CreateMessageFragment.kt index 27f25713a0..d827564f25 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/CreateMessageFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/CreateMessageFragment.kt @@ -1872,8 +1872,7 @@ class CreateMessageFragment : BaseSyncFragment(), View.OnFocusChangeListener, } private fun isPasswordProtectedFunctionalityEnabled(): Boolean { - val account = accountViewModel.activeAccountLiveData.value?.email ?: return false - return EmailUtil.getDomain(account) in listOf("flowcrypt.com", "flowcrypt.test") + return accountViewModel.activeAccountLiveData.value?.useFES ?: return false } private fun getForwardedAttachments(): List { diff --git a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MainSignInFragment.kt b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MainSignInFragment.kt index e6d213c43f..417c8e241f 100644 --- a/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MainSignInFragment.kt +++ b/FlowCrypt/src/main/java/com/flowcrypt/email/ui/activity/fragment/MainSignInFragment.kt @@ -193,7 +193,14 @@ class MainSignInFragment : BaseSingInFragment() { } override fun getTempAccount(): AccountEntity? { - return googleSignInAccount?.let { AccountEntity(it, uuid, orgRules) } + return googleSignInAccount?.let { + AccountEntity( + googleSignInAccount = it, + uuid = uuid, + orgRules = orgRules, + useFES = fesUrl?.isNotEmpty() == true + ) + } } override fun returnResultOk() { From 338cdbff4ec881a60c877367810073fc95c40452 Mon Sep 17 00:00:00 2001 From: DenBond7 Date: Mon, 24 Jan 2022 14:29:47 +0200 Subject: [PATCH 2/2] Fixed and updated tests.| #1621 --- .../ui/activity/CreateMessageActivityTest.kt | 20 +++++++++++++++++++ ...ateMessageFragmentPasswordProtectedTest.kt | 5 +++++ 2 files changed, 25 insertions(+) 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 2d383b2740..848b0a323e 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 @@ -713,6 +713,26 @@ class CreateMessageActivityTest : BaseCreateMessageActivityTest() { ) } + @Test + fun testWebPortalPasswordButtonIsHidden() { + activeActivityRule?.launch(intent) + registerAllIdlingResources() + + onView(withId(R.id.editTextRecipientTo)) + .perform( + typeText(TestConstants.RECIPIENT_WITHOUT_PUBLIC_KEY_ON_ATTESTER), + closeSoftKeyboard() + ) + + //need to leave focus from 'To' field. move the focus to the next view + onView(withId(R.id.editTextEmailSubject)) + .perform(scrollTo(), click()) + + //because account.useFES == false btnSetWebPortalPassword should not be visible + onView(withId(R.id.btnSetWebPortalPassword)) + .check(matches(not(isDisplayed()))) + } + private fun checkIsDisplayedEncryptedAttributes() { onView(withId(R.id.underToolbarTextTextView)) .check(matches(not(isDisplayed()))) diff --git a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageFragmentPasswordProtectedTest.kt b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageFragmentPasswordProtectedTest.kt index 80bf499f00..4ca3c7caea 100644 --- a/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageFragmentPasswordProtectedTest.kt +++ b/FlowCrypt/src/androidTest/java/com/flowcrypt/email/ui/activity/CreateMessageFragmentPasswordProtectedTest.kt @@ -22,11 +22,13 @@ import com.flowcrypt.email.R import com.flowcrypt.email.TestConstants import com.flowcrypt.email.matchers.CustomMatchers.Companion.withTextViewDrawable import com.flowcrypt.email.matchers.TextViewDrawableMatcher +import com.flowcrypt.email.rules.AddAccountToDatabaseRule import com.flowcrypt.email.rules.AddPrivateKeyToDatabaseRule import com.flowcrypt.email.rules.ClearAppSettingsRule import com.flowcrypt.email.rules.RetryRule import com.flowcrypt.email.rules.ScreenshotTestRule import com.flowcrypt.email.ui.activity.base.BaseCreateMessageActivityTest +import com.flowcrypt.email.util.AccountDaoManager import org.hamcrest.Matchers.not import org.junit.Rule import org.junit.Test @@ -47,6 +49,9 @@ class CreateMessageFragmentPasswordProtectedTest : BaseCreateMessageActivityTest private val addPrivateKeyToDatabaseRule = AddPrivateKeyToDatabaseRule() private val temporaryFolderRule = TemporaryFolder() + override val addAccountToDatabaseRule: AddAccountToDatabaseRule + get() = AddAccountToDatabaseRule(AccountDaoManager.getDefaultAccountDao().copy(useFES = true)) + @get:Rule var ruleChain: TestRule = RuleChain .outerRule(RetryRule.DEFAULT)