Current databases structure:
- There are two types of realm databases in our application:
basedatabase is meant to contain data which is either common for all accounts or necessary to be known before signing into an account. Currently, that’s
extension(not sure how the last one fits there, but whatever…). It is encrypted by randomly generated key.
accountdatabase contains all data related only to some specific account:
contactentities, etc. It is encrypted by key which is derived as hash of concatenation of the same randomly generated key (used for
base) and user’s password.
- There is only one
basedb in the app instance, and as many
accountdatabases as created accounts.
When a user enters their password the app derives a key for a chosen account database and makes attempt to open an
account's database. This operation may fail for three reasons:
- Wrong password (currently not an issue as a password is checked before this operation)
- A database file is decrypted via another key or file is corrupted. (we actually can’t distinguish these two reasons)
- Database migrations fail during opening the database. This one is the most common situation currently.
In any situation confirmation dialog with the following message is shown:
We detected a problem with the encryption key
To protect yourself, you need to create new account and erase your old data by tapping “Apply”. If you have an existing account and would like to save your recovery phrase then choose “Cancel”, back it up, and restart the app. We strongly recommend creating new account because the old one is stored unencrypted.
Which is only misleading because:
- if a user will choose “Cancel” and restart app they will end up in the same situation with no ability to save a recovery phrase.
- There might be no problem with an encryption key. I can be just migrations problem, or wrong password, and in these cases no need to erase the database.
Besides that, when a user taps “Apply” to erase an account’s database instead of removing that specific account and its database the whole realm dir is erased, including all
account databases and
base db. That doesn’t make sense at all.
What can be done to improve this situation:
- We need to separate different cases of the problem with opening
accountdatabase and propose the user an appropriate way to handle it.
- For the case when the operation fails because of db migration, we should print that specific error, ask the user to share it with us, and explain how to share. For iOS users we also can propose to downgrade app to the previous version until that specific problem will be fixed (it’s a bit vague on android and even if it is possible it might be problematic for an average user). Also
basedb version might be increased after upgrade an this and so app will not be dowgradeable. As a last resort, we can propose the user to erase an
accountdatabase without removing the account from
basedb, but we need to explain to the user that all account’s data will be lost.
- In case if an
accountdb file is corrupted or encrypted with a different key we need to propose user to erase this account with its db and show a similar message as we have now. The difference is that by tapping “Apply” the user will erase only specific account, not the whole application’s database.
- In case if the entered password was incorrect (can’t happen now, but can happen in future) we only need to inform the user that the password was wrong.
PS: the reason why this topic is touched now is that this stuff should be sorted out before continuing with an attempt to implement the next optimization related to slow sign in (from here):
No need to wait for Statusgo.Login callback in order to start unlocking realm-db: now it is encrypted via user’s password, so we can try to unlock it before starting node. That’s how we will check the user’s password. Right after that :home screen can be shown and starting node/Statusgo.Login call might be performed in parallel. D