diff --git a/FAQ.md b/FAQ.md
index 7352babe6e..7bb4d16374 100644
--- a/FAQ.md
+++ b/FAQ.md
@@ -702,11 +702,10 @@ Long version:
**(37) How are passwords stored?**
-On Android 6 Marshmallow and later passwords are stored encrypted in an app private database.
-Passwords are encrypted with the cipher AES/GCM/NoPadding
-and a generated secret key stored by the [Android keystore system](https://developer.android.com/training/articles/keystore).
-
-On earlier Android versions passwords are stored in plain text.
+Providers require passwords in plain text, so the background service that takes care of synchronizing messages needs to send passwords in plain text.
+Since encrypting passwords would require a secret and the background service needs to know this secret, this could only be done by storing that secret.
+Storing a secret together with encrypted passwords would not add anything, so passwords are stored in plain text in a safe, inaccessible place.
+Recent Android versions encrypt all user data anyway.
diff --git a/app/schemas/eu.faircode.email.DB/53.json b/app/schemas/eu.faircode.email.DB/53.json
deleted file mode 100644
index 00e8318005..0000000000
--- a/app/schemas/eu.faircode.email.DB/53.json
+++ /dev/null
@@ -1,1540 +0,0 @@
-{
- "formatVersion": 1,
- "database": {
- "version": 53,
- "identityHash": "cfa3a48b82bba1d9a9f736677e28d1dc",
- "entities": [
- {
- "tableName": "identity",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `email` TEXT NOT NULL, `account` INTEGER NOT NULL, `display` TEXT, `color` INTEGER, `signature` TEXT, `auth_type` INTEGER NOT NULL, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `realm` TEXT, `use_ip` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `replyto` TEXT, `bcc` TEXT, `plain_only` INTEGER NOT NULL, `encrypt` INTEGER NOT NULL, `delivery_receipt` INTEGER NOT NULL, `read_receipt` INTEGER NOT NULL, `store_sent` INTEGER NOT NULL, `sent_folder` INTEGER, `tbd` INTEGER, `state` TEXT, `error` TEXT, `last_connected` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "account",
- "columnName": "account",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "display",
- "columnName": "display",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "color",
- "columnName": "color",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "signature",
- "columnName": "signature",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "auth_type",
- "columnName": "auth_type",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "host",
- "columnName": "host",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "starttls",
- "columnName": "starttls",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "insecure",
- "columnName": "insecure",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "port",
- "columnName": "port",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "user",
- "columnName": "user",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "password",
- "columnName": "password",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "realm",
- "columnName": "realm",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "use_ip",
- "columnName": "use_ip",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "synchronize",
- "columnName": "synchronize",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "primary",
- "columnName": "primary",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "replyto",
- "columnName": "replyto",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "bcc",
- "columnName": "bcc",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "plain_only",
- "columnName": "plain_only",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "encrypt",
- "columnName": "encrypt",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "delivery_receipt",
- "columnName": "delivery_receipt",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "read_receipt",
- "columnName": "read_receipt",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "store_sent",
- "columnName": "store_sent",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "sent_folder",
- "columnName": "sent_folder",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "tbd",
- "columnName": "tbd",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "state",
- "columnName": "state",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "last_connected",
- "columnName": "last_connected",
- "affinity": "INTEGER",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_identity_account",
- "unique": false,
- "columnNames": [
- "account"
- ],
- "createSql": "CREATE INDEX `index_identity_account` ON `${TABLE_NAME}` (`account`)"
- },
- {
- "name": "index_identity_account_email",
- "unique": false,
- "columnNames": [
- "account",
- "email"
- ],
- "createSql": "CREATE INDEX `index_identity_account_email` ON `${TABLE_NAME}` (`account`, `email`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "account",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "account"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "account",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `auth_type` INTEGER NOT NULL, `pop` INTEGER NOT NULL, `host` TEXT NOT NULL, `starttls` INTEGER NOT NULL, `insecure` INTEGER NOT NULL, `port` INTEGER NOT NULL, `user` TEXT NOT NULL, `password` TEXT NOT NULL, `realm` TEXT, `name` TEXT, `signature` TEXT, `color` INTEGER, `synchronize` INTEGER NOT NULL, `ondemand` INTEGER NOT NULL, `primary` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `browse` INTEGER NOT NULL, `swipe_left` INTEGER, `swipe_right` INTEGER, `poll_interval` INTEGER NOT NULL, `prefix` TEXT, `created` INTEGER, `tbd` INTEGER, `state` TEXT, `error` TEXT, `last_connected` INTEGER)",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "auth_type",
- "columnName": "auth_type",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "pop",
- "columnName": "pop",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "host",
- "columnName": "host",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "starttls",
- "columnName": "starttls",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "insecure",
- "columnName": "insecure",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "port",
- "columnName": "port",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "user",
- "columnName": "user",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "password",
- "columnName": "password",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "realm",
- "columnName": "realm",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "signature",
- "columnName": "signature",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "color",
- "columnName": "color",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "synchronize",
- "columnName": "synchronize",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ondemand",
- "columnName": "ondemand",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "primary",
- "columnName": "primary",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "notify",
- "columnName": "notify",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "browse",
- "columnName": "browse",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "swipe_left",
- "columnName": "swipe_left",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "swipe_right",
- "columnName": "swipe_right",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "poll_interval",
- "columnName": "poll_interval",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "prefix",
- "columnName": "prefix",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "created",
- "columnName": "created",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "tbd",
- "columnName": "tbd",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "state",
- "columnName": "state",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "last_connected",
- "columnName": "last_connected",
- "affinity": "INTEGER",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "folder",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER, `name` TEXT NOT NULL, `type` TEXT NOT NULL, `level` INTEGER NOT NULL, `synchronize` INTEGER NOT NULL, `poll` INTEGER NOT NULL, `download` INTEGER NOT NULL, `sync_days` INTEGER NOT NULL, `keep_days` INTEGER NOT NULL, `display` TEXT, `hide` INTEGER NOT NULL, `unified` INTEGER NOT NULL, `notify` INTEGER NOT NULL, `total` INTEGER, `keywords` TEXT, `initialize` INTEGER NOT NULL, `tbc` INTEGER, `tbd` INTEGER, `state` TEXT, `sync_state` TEXT, `error` TEXT, `last_sync` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "account",
- "columnName": "account",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "level",
- "columnName": "level",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "synchronize",
- "columnName": "synchronize",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "poll",
- "columnName": "poll",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "download",
- "columnName": "download",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "sync_days",
- "columnName": "sync_days",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "keep_days",
- "columnName": "keep_days",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "display",
- "columnName": "display",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "hide",
- "columnName": "hide",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "unified",
- "columnName": "unified",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "notify",
- "columnName": "notify",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "total",
- "columnName": "total",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "keywords",
- "columnName": "keywords",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "initialize",
- "columnName": "initialize",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "tbc",
- "columnName": "tbc",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "tbd",
- "columnName": "tbd",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "state",
- "columnName": "state",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "sync_state",
- "columnName": "sync_state",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "last_sync",
- "columnName": "last_sync",
- "affinity": "INTEGER",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_folder_account_name",
- "unique": true,
- "columnNames": [
- "account",
- "name"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_folder_account_name` ON `${TABLE_NAME}` (`account`, `name`)"
- },
- {
- "name": "index_folder_account",
- "unique": false,
- "columnNames": [
- "account"
- ],
- "createSql": "CREATE INDEX `index_folder_account` ON `${TABLE_NAME}` (`account`)"
- },
- {
- "name": "index_folder_name",
- "unique": false,
- "columnNames": [
- "name"
- ],
- "createSql": "CREATE INDEX `index_folder_name` ON `${TABLE_NAME}` (`name`)"
- },
- {
- "name": "index_folder_type",
- "unique": false,
- "columnNames": [
- "type"
- ],
- "createSql": "CREATE INDEX `index_folder_type` ON `${TABLE_NAME}` (`type`)"
- },
- {
- "name": "index_folder_unified",
- "unique": false,
- "columnNames": [
- "unified"
- ],
- "createSql": "CREATE INDEX `index_folder_unified` ON `${TABLE_NAME}` (`unified`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "account",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "account"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "message",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `account` INTEGER NOT NULL, `folder` INTEGER NOT NULL, `identity` INTEGER, `extra` TEXT, `replying` INTEGER, `forwarding` INTEGER, `uid` INTEGER, `msgid` TEXT, `references` TEXT, `deliveredto` TEXT, `inreplyto` TEXT, `thread` TEXT, `avatar` TEXT, `sender` TEXT, `from` TEXT, `to` TEXT, `cc` TEXT, `bcc` TEXT, `reply` TEXT, `headers` TEXT, `raw` INTEGER, `subject` TEXT, `size` INTEGER, `content` INTEGER NOT NULL, `preview` TEXT, `sent` INTEGER, `received` INTEGER NOT NULL, `stored` INTEGER NOT NULL, `seen` INTEGER NOT NULL, `answered` INTEGER NOT NULL, `flagged` INTEGER NOT NULL, `flags` TEXT, `keywords` TEXT, `ui_seen` INTEGER NOT NULL, `ui_answered` INTEGER NOT NULL, `ui_flagged` INTEGER NOT NULL, `ui_hide` INTEGER NOT NULL, `ui_found` INTEGER NOT NULL, `ui_ignored` INTEGER NOT NULL, `ui_browsed` INTEGER NOT NULL, `ui_snoozed` INTEGER, `warning` TEXT, `error` TEXT, `last_attempt` INTEGER, FOREIGN KEY(`account`) REFERENCES `account`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`identity`) REFERENCES `identity`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`replying`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL , FOREIGN KEY(`forwarding`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE SET NULL )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "account",
- "columnName": "account",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "folder",
- "columnName": "folder",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "identity",
- "columnName": "identity",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "extra",
- "columnName": "extra",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "replying",
- "columnName": "replying",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "forwarding",
- "columnName": "forwarding",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "uid",
- "columnName": "uid",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "msgid",
- "columnName": "msgid",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "references",
- "columnName": "references",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "deliveredto",
- "columnName": "deliveredto",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "inreplyto",
- "columnName": "inreplyto",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "thread",
- "columnName": "thread",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "avatar",
- "columnName": "avatar",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "sender",
- "columnName": "sender",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "from",
- "columnName": "from",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "to",
- "columnName": "to",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "cc",
- "columnName": "cc",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "bcc",
- "columnName": "bcc",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "reply",
- "columnName": "reply",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "headers",
- "columnName": "headers",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "raw",
- "columnName": "raw",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "subject",
- "columnName": "subject",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "size",
- "columnName": "size",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "content",
- "columnName": "content",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "preview",
- "columnName": "preview",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "sent",
- "columnName": "sent",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "received",
- "columnName": "received",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "stored",
- "columnName": "stored",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "seen",
- "columnName": "seen",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "answered",
- "columnName": "answered",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "flagged",
- "columnName": "flagged",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "flags",
- "columnName": "flags",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "keywords",
- "columnName": "keywords",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "ui_seen",
- "columnName": "ui_seen",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_answered",
- "columnName": "ui_answered",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_flagged",
- "columnName": "ui_flagged",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_hide",
- "columnName": "ui_hide",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_found",
- "columnName": "ui_found",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_ignored",
- "columnName": "ui_ignored",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_browsed",
- "columnName": "ui_browsed",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "ui_snoozed",
- "columnName": "ui_snoozed",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "warning",
- "columnName": "warning",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "last_attempt",
- "columnName": "last_attempt",
- "affinity": "INTEGER",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_message_account",
- "unique": false,
- "columnNames": [
- "account"
- ],
- "createSql": "CREATE INDEX `index_message_account` ON `${TABLE_NAME}` (`account`)"
- },
- {
- "name": "index_message_folder",
- "unique": false,
- "columnNames": [
- "folder"
- ],
- "createSql": "CREATE INDEX `index_message_folder` ON `${TABLE_NAME}` (`folder`)"
- },
- {
- "name": "index_message_identity",
- "unique": false,
- "columnNames": [
- "identity"
- ],
- "createSql": "CREATE INDEX `index_message_identity` ON `${TABLE_NAME}` (`identity`)"
- },
- {
- "name": "index_message_folder_uid",
- "unique": true,
- "columnNames": [
- "folder",
- "uid"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_message_folder_uid` ON `${TABLE_NAME}` (`folder`, `uid`)"
- },
- {
- "name": "index_message_msgid_folder",
- "unique": true,
- "columnNames": [
- "msgid",
- "folder"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_message_msgid_folder` ON `${TABLE_NAME}` (`msgid`, `folder`)"
- },
- {
- "name": "index_message_thread",
- "unique": false,
- "columnNames": [
- "thread"
- ],
- "createSql": "CREATE INDEX `index_message_thread` ON `${TABLE_NAME}` (`thread`)"
- },
- {
- "name": "index_message_sender",
- "unique": false,
- "columnNames": [
- "sender"
- ],
- "createSql": "CREATE INDEX `index_message_sender` ON `${TABLE_NAME}` (`sender`)"
- },
- {
- "name": "index_message_received",
- "unique": false,
- "columnNames": [
- "received"
- ],
- "createSql": "CREATE INDEX `index_message_received` ON `${TABLE_NAME}` (`received`)"
- },
- {
- "name": "index_message_subject",
- "unique": false,
- "columnNames": [
- "subject"
- ],
- "createSql": "CREATE INDEX `index_message_subject` ON `${TABLE_NAME}` (`subject`)"
- },
- {
- "name": "index_message_ui_seen",
- "unique": false,
- "columnNames": [
- "ui_seen"
- ],
- "createSql": "CREATE INDEX `index_message_ui_seen` ON `${TABLE_NAME}` (`ui_seen`)"
- },
- {
- "name": "index_message_ui_flagged",
- "unique": false,
- "columnNames": [
- "ui_flagged"
- ],
- "createSql": "CREATE INDEX `index_message_ui_flagged` ON `${TABLE_NAME}` (`ui_flagged`)"
- },
- {
- "name": "index_message_ui_hide",
- "unique": false,
- "columnNames": [
- "ui_hide"
- ],
- "createSql": "CREATE INDEX `index_message_ui_hide` ON `${TABLE_NAME}` (`ui_hide`)"
- },
- {
- "name": "index_message_ui_found",
- "unique": false,
- "columnNames": [
- "ui_found"
- ],
- "createSql": "CREATE INDEX `index_message_ui_found` ON `${TABLE_NAME}` (`ui_found`)"
- },
- {
- "name": "index_message_ui_ignored",
- "unique": false,
- "columnNames": [
- "ui_ignored"
- ],
- "createSql": "CREATE INDEX `index_message_ui_ignored` ON `${TABLE_NAME}` (`ui_ignored`)"
- },
- {
- "name": "index_message_ui_browsed",
- "unique": false,
- "columnNames": [
- "ui_browsed"
- ],
- "createSql": "CREATE INDEX `index_message_ui_browsed` ON `${TABLE_NAME}` (`ui_browsed`)"
- },
- {
- "name": "index_message_ui_snoozed",
- "unique": false,
- "columnNames": [
- "ui_snoozed"
- ],
- "createSql": "CREATE INDEX `index_message_ui_snoozed` ON `${TABLE_NAME}` (`ui_snoozed`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "account",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "account"
- ],
- "referencedColumns": [
- "id"
- ]
- },
- {
- "table": "folder",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "folder"
- ],
- "referencedColumns": [
- "id"
- ]
- },
- {
- "table": "identity",
- "onDelete": "SET NULL",
- "onUpdate": "NO ACTION",
- "columns": [
- "identity"
- ],
- "referencedColumns": [
- "id"
- ]
- },
- {
- "table": "message",
- "onDelete": "SET NULL",
- "onUpdate": "NO ACTION",
- "columns": [
- "replying"
- ],
- "referencedColumns": [
- "id"
- ]
- },
- {
- "table": "message",
- "onDelete": "SET NULL",
- "onUpdate": "NO ACTION",
- "columns": [
- "forwarding"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "attachment",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `message` INTEGER NOT NULL, `sequence` INTEGER NOT NULL, `name` TEXT, `type` TEXT NOT NULL, `disposition` TEXT, `cid` TEXT, `encryption` INTEGER, `size` INTEGER, `progress` INTEGER, `available` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "message",
- "columnName": "message",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "sequence",
- "columnName": "sequence",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "disposition",
- "columnName": "disposition",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "cid",
- "columnName": "cid",
- "affinity": "TEXT",
- "notNull": false
- },
- {
- "fieldPath": "encryption",
- "columnName": "encryption",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "size",
- "columnName": "size",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "progress",
- "columnName": "progress",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "available",
- "columnName": "available",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_attachment_message",
- "unique": false,
- "columnNames": [
- "message"
- ],
- "createSql": "CREATE INDEX `index_attachment_message` ON `${TABLE_NAME}` (`message`)"
- },
- {
- "name": "index_attachment_message_sequence",
- "unique": true,
- "columnNames": [
- "message",
- "sequence"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_attachment_message_sequence` ON `${TABLE_NAME}` (`message`, `sequence`)"
- },
- {
- "name": "index_attachment_message_cid",
- "unique": true,
- "columnNames": [
- "message",
- "cid"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_attachment_message_cid` ON `${TABLE_NAME}` (`message`, `cid`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "message",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "message"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "operation",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `message` INTEGER, `name` TEXT NOT NULL, `args` TEXT NOT NULL, `created` INTEGER NOT NULL, `error` TEXT, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE , FOREIGN KEY(`message`) REFERENCES `message`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "folder",
- "columnName": "folder",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "message",
- "columnName": "message",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "args",
- "columnName": "args",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "created",
- "columnName": "created",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "error",
- "columnName": "error",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_operation_folder",
- "unique": false,
- "columnNames": [
- "folder"
- ],
- "createSql": "CREATE INDEX `index_operation_folder` ON `${TABLE_NAME}` (`folder`)"
- },
- {
- "name": "index_operation_message",
- "unique": false,
- "columnNames": [
- "message"
- ],
- "createSql": "CREATE INDEX `index_operation_message` ON `${TABLE_NAME}` (`message`)"
- },
- {
- "name": "index_operation_name",
- "unique": false,
- "columnNames": [
- "name"
- ],
- "createSql": "CREATE INDEX `index_operation_name` ON `${TABLE_NAME}` (`name`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "folder",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "folder"
- ],
- "referencedColumns": [
- "id"
- ]
- },
- {
- "table": "message",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "message"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "contact",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `type` INTEGER NOT NULL, `email` TEXT NOT NULL, `name` TEXT)",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "type",
- "columnName": "type",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "email",
- "columnName": "email",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": false
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_contact_email_type",
- "unique": true,
- "columnNames": [
- "email",
- "type"
- ],
- "createSql": "CREATE UNIQUE INDEX `index_contact_email_type` ON `${TABLE_NAME}` (`email`, `type`)"
- },
- {
- "name": "index_contact_name_type",
- "unique": false,
- "columnNames": [
- "name",
- "type"
- ],
- "createSql": "CREATE INDEX `index_contact_name_type` ON `${TABLE_NAME}` (`name`, `type`)"
- }
- ],
- "foreignKeys": []
- },
- {
- "tableName": "answer",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `name` TEXT NOT NULL, `text` TEXT NOT NULL)",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "text",
- "columnName": "text",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [],
- "foreignKeys": []
- },
- {
- "tableName": "rule",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `folder` INTEGER NOT NULL, `name` TEXT NOT NULL, `order` INTEGER NOT NULL, `enabled` INTEGER NOT NULL, `stop` INTEGER NOT NULL, `condition` TEXT NOT NULL, `action` TEXT NOT NULL, FOREIGN KEY(`folder`) REFERENCES `folder`(`id`) ON UPDATE NO ACTION ON DELETE CASCADE )",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "folder",
- "columnName": "folder",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "name",
- "columnName": "name",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "order",
- "columnName": "order",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "enabled",
- "columnName": "enabled",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "stop",
- "columnName": "stop",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "condition",
- "columnName": "condition",
- "affinity": "TEXT",
- "notNull": true
- },
- {
- "fieldPath": "action",
- "columnName": "action",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_rule_folder",
- "unique": false,
- "columnNames": [
- "folder"
- ],
- "createSql": "CREATE INDEX `index_rule_folder` ON `${TABLE_NAME}` (`folder`)"
- },
- {
- "name": "index_rule_order",
- "unique": false,
- "columnNames": [
- "order"
- ],
- "createSql": "CREATE INDEX `index_rule_order` ON `${TABLE_NAME}` (`order`)"
- }
- ],
- "foreignKeys": [
- {
- "table": "folder",
- "onDelete": "CASCADE",
- "onUpdate": "NO ACTION",
- "columns": [
- "folder"
- ],
- "referencedColumns": [
- "id"
- ]
- }
- ]
- },
- {
- "tableName": "log",
- "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `time` INTEGER NOT NULL, `data` TEXT NOT NULL)",
- "fields": [
- {
- "fieldPath": "id",
- "columnName": "id",
- "affinity": "INTEGER",
- "notNull": false
- },
- {
- "fieldPath": "time",
- "columnName": "time",
- "affinity": "INTEGER",
- "notNull": true
- },
- {
- "fieldPath": "data",
- "columnName": "data",
- "affinity": "TEXT",
- "notNull": true
- }
- ],
- "primaryKey": {
- "columnNames": [
- "id"
- ],
- "autoGenerate": true
- },
- "indices": [
- {
- "name": "index_log_time",
- "unique": false,
- "columnNames": [
- "time"
- ],
- "createSql": "CREATE INDEX `index_log_time` ON `${TABLE_NAME}` (`time`)"
- }
- ],
- "foreignKeys": []
- }
- ],
- "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, \"cfa3a48b82bba1d9a9f736677e28d1dc\")"
- ]
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/eu/faircode/email/DB.java b/app/src/main/java/eu/faircode/email/DB.java
index 6c6bc242c2..a607e8d79e 100644
--- a/app/src/main/java/eu/faircode/email/DB.java
+++ b/app/src/main/java/eu/faircode/email/DB.java
@@ -3,7 +3,6 @@ package eu.faircode.email;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
-import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
@@ -50,7 +49,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
// https://developer.android.com/topic/libraries/architecture/room.html
@Database(
- version = 53,
+ version = 52,
entities = {
EntityIdentity.class,
EntityAccount.class,
@@ -561,33 +560,6 @@ public abstract class DB extends RoomDatabase {
db.execSQL("ALTER TABLE `folder` ADD COLUMN `total` INTEGER");
}
})
- .addMigrations(new Migration(52, 53) {
- @Override
- public void migrate(SupportSQLiteDatabase db) {
- Log.i("DB migration from version " + startVersion + " to " + endVersion);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Cursor cursor = db.query("SELECT id, password FROM account");
- while (cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String plain = cursor.getString(1);
- db.execSQL("UPDATE account SET password = ? WHERE id = ?",
- new Object[]{id, Helper.encryptPassword(plain)});
- }
- cursor.close();
- }
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
- Cursor cursor = db.query("SELECT id, password FROM identity");
- while (cursor.moveToNext()) {
- long id = cursor.getLong(0);
- String plain = cursor.getString(1);
- db.execSQL("UPDATE identity SET password = ? WHERE id = ?",
- new Object[]{id, Helper.encryptPassword(plain)});
- }
- cursor.close();
- }
- }
- })
.build();
}
diff --git a/app/src/main/java/eu/faircode/email/EntityAccount.java b/app/src/main/java/eu/faircode/email/EntityAccount.java
index 471a54f5e8..90600fb921 100644
--- a/app/src/main/java/eu/faircode/email/EntityAccount.java
+++ b/app/src/main/java/eu/faircode/email/EntityAccount.java
@@ -95,20 +95,6 @@ public class EntityAccount implements Serializable {
return "imap" + (starttls ? "" : "s");
}
- String getPassword() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
- return this.password;
- else
- return Helper.decryptPassword(this.password);
- }
-
- void setPassword(String plain) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
- this.password = plain;
- else
- this.password = Helper.encryptPassword(plain);
- }
-
static String getNotificationChannelName(long account) {
return "notification" + (account == 0 ? "" : "." + account);
}
@@ -138,7 +124,7 @@ public class EntityAccount implements Serializable {
json.put("insecure", insecure);
json.put("port", port);
json.put("user", user);
- json.put("password", getPassword());
+ json.put("password", password);
json.put("realm", realm);
json.put("name", name);
@@ -170,7 +156,7 @@ public class EntityAccount implements Serializable {
account.insecure = (json.has("insecure") && json.getBoolean("insecure"));
account.port = json.getInt("port");
account.user = json.getString("user");
- account.setPassword(json.getString("password"));
+ account.password = json.getString("password");
if (json.has("realm"))
account.realm = json.getString("realm");
@@ -208,7 +194,7 @@ public class EntityAccount implements Serializable {
this.insecure == other.insecure &&
this.port.equals(other.port) &&
this.user.equals(other.user) &&
- this.getPassword().equals(other.getPassword()) &&
+ this.password.equals(other.password) &&
Objects.equals(this.realm, other.realm) &&
Objects.equals(this.name, other.name) &&
Objects.equals(this.color, other.color) &&
diff --git a/app/src/main/java/eu/faircode/email/EntityIdentity.java b/app/src/main/java/eu/faircode/email/EntityIdentity.java
index 416c983bae..9d41d4eb41 100644
--- a/app/src/main/java/eu/faircode/email/EntityIdentity.java
+++ b/app/src/main/java/eu/faircode/email/EntityIdentity.java
@@ -19,8 +19,6 @@ package eu.faircode.email;
Copyright 2018-2019 by Marcel Bokhorst (M66B)
*/
-import android.os.Build;
-
import org.json.JSONException;
import org.json.JSONObject;
@@ -101,20 +99,6 @@ public class EntityIdentity {
return (starttls ? "smtp" : "smtps");
}
- String getPassword() {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
- return this.password;
- else
- return Helper.decryptPassword(this.password);
- }
-
- void setPassword(String plain) {
- if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M)
- this.password = plain;
- else
- this.password = Helper.encryptPassword(plain);
- }
-
public JSONObject toJSON() throws JSONException {
JSONObject json = new JSONObject();
json.put("id", id);
@@ -132,7 +116,7 @@ public class EntityIdentity {
json.put("insecure", insecure);
json.put("port", port);
json.put("user", user);
- json.put("password", getPassword());
+ json.put("password", password);
json.put("realm", realm);
json.put("use_ip", use_ip);
@@ -170,7 +154,7 @@ public class EntityIdentity {
identity.insecure = (json.has("insecure") && json.getBoolean("insecure"));
identity.port = json.getInt("port");
identity.user = json.getString("user");
- identity.setPassword(json.getString("password"));
+ identity.password = json.getString("password");
if (json.has("realm"))
identity.realm = json.getString("realm");
if (json.has("use_ip"))
@@ -215,7 +199,7 @@ public class EntityIdentity {
this.insecure.equals(other.insecure) &&
this.port.equals(other.port) &&
this.user.equals(other.user) &&
- this.getPassword().equals(other.getPassword()) &&
+ this.password.equals(other.password) &&
Objects.equals(this.realm, other.realm) &&
this.use_ip == other.use_ip &&
this.synchronize.equals(other.synchronize) &&
diff --git a/app/src/main/java/eu/faircode/email/FragmentAccount.java b/app/src/main/java/eu/faircode/email/FragmentAccount.java
index cb623e0161..44b9f1127b 100644
--- a/app/src/main/java/eu/faircode/email/FragmentAccount.java
+++ b/app/src/main/java/eu/faircode/email/FragmentAccount.java
@@ -845,7 +845,7 @@ public class FragmentAccount extends FragmentBase {
boolean check = (synchronize && (account == null ||
auth_type != account.auth_type ||
!host.equals(account.host) || Integer.parseInt(port) != account.port ||
- !user.equals(account.user) || !password.equals(account.getPassword()) ||
+ !user.equals(account.user) || !password.equals(account.password) ||
!Objects.equals(realm, accountRealm)));
boolean reload = (check || account == null ||
!Objects.equals(account.prefix, prefix) ||
@@ -914,7 +914,7 @@ public class FragmentAccount extends FragmentBase {
account.insecure = insecure;
account.port = Integer.parseInt(port);
account.user = user;
- account.setPassword(password);
+ account.password = password;
account.realm = realm;
account.name = name;
@@ -1135,7 +1135,7 @@ public class FragmentAccount extends FragmentBase {
etUser.setTag(account == null || auth_type == Helper.AUTH_TYPE_PASSWORD ? null : account.user);
etUser.setText(account == null ? null : account.user);
- tilPassword.getEditText().setText(account == null ? null : account.getPassword());
+ tilPassword.getEditText().setText(account == null ? null : account.password);
etRealm.setText(account == null ? null : account.realm);
etName.setText(account == null ? null : account.name);
diff --git a/app/src/main/java/eu/faircode/email/FragmentIdentity.java b/app/src/main/java/eu/faircode/email/FragmentIdentity.java
index 0b032f964a..d5878436a2 100644
--- a/app/src/main/java/eu/faircode/email/FragmentIdentity.java
+++ b/app/src/main/java/eu/faircode/email/FragmentIdentity.java
@@ -237,7 +237,7 @@ public class FragmentIdentity extends FragmentBase {
etEmail.setText(account.user);
etUser.setTag(auth_type == Helper.AUTH_TYPE_PASSWORD ? null : account.user);
etUser.setText(account.user);
- tilPassword.getEditText().setText(account.getPassword());
+ tilPassword.getEditText().setText(account.password);
etRealm.setText(account.realm);
tilPassword.setEnabled(auth_type == Helper.AUTH_TYPE_PASSWORD);
etRealm.setEnabled(auth_type == Helper.AUTH_TYPE_PASSWORD);
@@ -589,7 +589,7 @@ public class FragmentIdentity extends FragmentBase {
boolean check = (synchronize && (identity == null ||
auth_type != identity.auth_type ||
!host.equals(identity.host) || Integer.parseInt(port) != identity.port ||
- !user.equals(identity.user) || !password.equals(identity.getPassword()) ||
+ !user.equals(identity.user) || !password.equals(identity.password) ||
!Objects.equals(realm, identityRealm) ||
use_ip != identity.use_ip));
boolean reload = (identity == null || identity.synchronize != synchronize || check);
@@ -655,7 +655,7 @@ public class FragmentIdentity extends FragmentBase {
identity.insecure = insecure;
identity.port = Integer.parseInt(port);
identity.user = user;
- identity.setPassword(password);
+ identity.password = password;
identity.realm = realm;
identity.use_ip = use_ip;
identity.synchronize = synchronize;
@@ -759,7 +759,7 @@ public class FragmentIdentity extends FragmentBase {
etPort.setText(identity == null ? null : Long.toString(identity.port));
etUser.setTag(identity == null || auth_type == Helper.AUTH_TYPE_PASSWORD ? null : identity.user);
etUser.setText(identity == null ? null : identity.user);
- tilPassword.getEditText().setText(identity == null ? null : identity.getPassword());
+ tilPassword.getEditText().setText(identity == null ? null : identity.password);
etRealm.setText(identity == null ? null : identity.realm);
cbUseIp.setChecked(identity == null ? true : identity.use_ip);
cbSynchronize.setChecked(identity == null ? true : identity.synchronize);
@@ -864,7 +864,7 @@ public class FragmentIdentity extends FragmentBase {
spAccount.setSelection(pos);
// OAuth token could be updated
if (pos > 0 && accounts.get(pos).auth_type != Helper.AUTH_TYPE_PASSWORD)
- tilPassword.getEditText().setText(accounts.get(pos).getPassword());
+ tilPassword.getEditText().setText(accounts.get(pos).password);
break;
}
}
diff --git a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java
index b55355c4ef..5cff1e03b2 100644
--- a/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java
+++ b/app/src/main/java/eu/faircode/email/FragmentQuickSetup.java
@@ -335,7 +335,7 @@ public class FragmentQuickSetup extends FragmentBase {
account.insecure = false;
account.port = provider.imap_port;
account.user = user;
- account.setPassword(password);
+ account.password = password;
account.name = provider.name;
account.color = null;
@@ -389,7 +389,7 @@ public class FragmentQuickSetup extends FragmentBase {
identity.insecure = false;
identity.port = provider.smtp_port;
identity.user = user;
- identity.setPassword(password);
+ identity.password = password;
identity.synchronize = true;
identity.primary = true;
diff --git a/app/src/main/java/eu/faircode/email/Helper.java b/app/src/main/java/eu/faircode/email/Helper.java
index de650a1736..c07e4573f8 100644
--- a/app/src/main/java/eu/faircode/email/Helper.java
+++ b/app/src/main/java/eu/faircode/email/Helper.java
@@ -42,10 +42,7 @@ import android.os.Build;
import android.os.Bundle;
import android.os.PowerManager;
import android.preference.PreferenceManager;
-import android.security.keystore.KeyGenParameterSpec;
-import android.security.keystore.KeyProperties;
import android.text.TextUtils;
-import android.util.Base64;
import android.view.Menu;
import android.view.View;
import android.view.ViewGroup;
@@ -80,8 +77,6 @@ import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
-import java.nio.charset.StandardCharsets;
-import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
@@ -96,10 +91,6 @@ import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ThreadFactory;
-import javax.crypto.Cipher;
-import javax.crypto.KeyGenerator;
-import javax.crypto.SecretKey;
-import javax.crypto.spec.GCMParameterSpec;
import javax.mail.Address;
import javax.mail.AuthenticationFailedException;
import javax.mail.FolderClosedException;
@@ -109,7 +100,6 @@ import javax.mail.internet.InternetAddress;
import javax.net.ssl.HttpsURLConnection;
import androidx.annotation.NonNull;
-import androidx.annotation.RequiresApi;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.Lifecycle;
@@ -819,12 +809,12 @@ public class Helper {
static void connect(Context context, IMAPStore istore, EntityAccount account) throws MessagingException {
try {
- istore.connect(account.host, account.port, account.user, account.getPassword());
+ istore.connect(account.host, account.port, account.user, account.password);
} catch (AuthenticationFailedException ex) {
if (account.auth_type == AUTH_TYPE_GMAIL) {
- account.setPassword(refreshToken(context, "com.google", account.user, account.getPassword()));
+ account.password = refreshToken(context, "com.google", account.user, account.password);
DB.getInstance(context).account().setAccountPassword(account.id, account.password);
- istore.connect(account.host, account.port, account.user, account.getPassword());
+ istore.connect(account.host, account.port, account.user, account.password);
} else
throw ex;
}
@@ -1053,56 +1043,4 @@ public class Helper {
return organization;
}
}
-
- @RequiresApi(api = Build.VERSION_CODES.M)
- private static SecretKey getSecretKey() throws Throwable {
- final String alias = BuildConfig.APPLICATION_ID + ".key";
-
- KeyStore store = KeyStore.getInstance("AndroidKeyStore");
- store.load(null);
-
- KeyStore.SecretKeyEntry entry = (KeyStore.SecretKeyEntry) store.getEntry(alias, null);
- if (entry != null)
- return entry.getSecretKey();
-
- KeyGenerator generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
- KeyGenParameterSpec spec = new KeyGenParameterSpec.Builder(alias,
- KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
- .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
- .build();
- generator.init(spec);
- return generator.generateKey();
- }
-
- @RequiresApi(api = Build.VERSION_CODES.M)
- static String decryptPassword(String secret) {
- try {
- int slash = secret.indexOf('/');
- byte[] iv = Base64.decode(secret.substring(0, slash), Base64.URL_SAFE);
- byte[] encrypted = Base64.decode(secret.substring(slash + 1), Base64.URL_SAFE);
- Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
- GCMParameterSpec spec = new GCMParameterSpec(128, iv);
- cipher.init(Cipher.DECRYPT_MODE, getSecretKey(), spec);
- byte[] decrypted = cipher.doFinal(encrypted);
- return new String(decrypted, StandardCharsets.UTF_8);
- } catch (Throwable ex) {
- Log.e(ex);
- return secret;
- }
- }
-
- @RequiresApi(api = Build.VERSION_CODES.M)
- static String encryptPassword(String plain) {
- try {
- Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
- cipher.init(Cipher.ENCRYPT_MODE, getSecretKey());
- byte[] iv = cipher.getIV();
- byte[] encrypted = cipher.doFinal(plain.getBytes(StandardCharsets.UTF_8));
- return Base64.encodeToString(iv, Base64.URL_SAFE) + "/" + Base64.encodeToString(encrypted, Base64.URL_SAFE);
- } catch (Throwable ex) {
- Log.e(ex);
- return plain;
- }
- }
}
diff --git a/app/src/main/java/eu/faircode/email/ServiceSend.java b/app/src/main/java/eu/faircode/email/ServiceSend.java
index dcbb13a500..f59536e927 100644
--- a/app/src/main/java/eu/faircode/email/ServiceSend.java
+++ b/app/src/main/java/eu/faircode/email/ServiceSend.java
@@ -294,13 +294,13 @@ public class ServiceSend extends LifecycleService {
// Connect transport
db.identity().setIdentityState(ident.id, "connecting");
try {
- itransport.connect(ident.host, ident.port, ident.user, ident.getPassword());
+ itransport.connect(ident.host, ident.port, ident.user, ident.password);
} catch (AuthenticationFailedException ex) {
if (ident.auth_type == Helper.AUTH_TYPE_GMAIL) {
EntityAccount account = db.account().getAccount(ident.account);
- ident.setPassword(Helper.refreshToken(this, "com.google", ident.user, account.getPassword()));
+ ident.password = Helper.refreshToken(this, "com.google", ident.user, account.password);
DB.getInstance(this).identity().setIdentityPassword(ident.id, ident.password);
- itransport.connect(ident.host, ident.port, ident.user, ident.getPassword());
+ itransport.connect(ident.host, ident.port, ident.user, ident.password);
} else
throw ex;
}