The most challenging bit in the implementation of the first version wasn’t even the primary functionality of the application.
It was privacy.
The idea behind the app is that it should not be possible (even with direct access to the database) to provably tell which account owns which salary entry. At the same time, the user should be able to see which entry they own and have the capability to edit it, delete it, and so on.
The solution was to generate an asymmetric encryption key for each user during the registration and encrypt their private key with their password so that only when they log in, they can read the private encrypted information.
Now, when the application needs to store any encrypted information that only the user would be able to read—it can use the user’s public key to encrypt it.
This has posed another challenge: what to do about password reset?
As it stands with the solution described above, it wouldn’t be possible to do a password reset and recover the encrypted data!
The solution is to have a second pair of keys—recovery keys and have the private recovery key be encrypted with a recovery code, that is not stored anywhere and is sent to the user securely when they create their password.
Now, when the user wants to reset their password, they’ll have to upload a recovery code file, and the system will be able to decrypt their existing data and re-encrypt it with their new password!
Of course, there was much more interesting work here, as the main features of the application: viewing your company wage entries, searching other companies, editing and deleting your data, privacy consent, integrating with Stripe, etc.