Mon 17/07 19:14, I have added one more thing to improve in the list of bugs and short comings
This app is a demo to display dummy transactions to the user
Accessing those transactions must happen either after Registration or Login
First time users to the app must register first, later on the user can login
demo.mp4
- Open the app
- Wait for the loading bar
- Click register
- Enter your email
- To verify the email, you must enter the code that was "sent" to your email. Since this is a dummy
process, just insert any 4 digits code with
0
in it - Click confirm
- Insert a password of your choice twice. Password must contain digits and letters
- Click confirm
- Congratulations you are now registered
- The transaction screen will open up, where you will see a list of dummy 100 transactions
- Open the transactions screen
- Click on the top right corner log out icon
- The screen will close and you will be greeted with the welcome screen again
- Open the app
- Wait for the loading bar
- Click sign in
- Insert your email and your password
- Click sign in
- You are now in the transactions screen
This project follows Google's recommendation regarding the structure. It has three main components:
- Data
- Domain
- UI
This project is using the following:
- MVVM
- Hilt (Dependency Injection)
- Navigation component
- Argon2 for hashing password (Winner of 2015 Password Hashing Competition)
- JUnit (Testing)
- Mockito (Mocks for testing)
- Crypto (Encrypting SharedPreferences)
I have tried to make the app as clean as possible. I have also ventured in a lot of unfamiliar areas for me, so I could be rusty in making those decisions.
At the beginning I tried to encrypt the passwords that I save, but it turns out this is not the
recommended way for saving passwords.
I used CryptoManager
to encrypt and decrypt the data.
Later, I discovered that hashing is the way to go as it is one way function and not reversible.
I saw two options BCrypt and Argon2 (There is more). I found out later Argon2 is the recommended way
to go.
For Argon2, there are certain parameters that can be tweaked to get the hashed value in a fast manner. I didn't have time to investigate what the best values are, so I used the default ones.
I decided to save the following data
- list of registered users and their passwords. This list will be used in the login to verify if the email and password are correct.
- Current user. This value will indicate whether the user is already logged in or not.
I wanted to be able to save the data in somewhere encrypted. There is ProtoDataStore (currently recommended option from Google) and EncryptedSharedPreferences. I chose EncryptedSharedPreferences because it was easier and I was a bit tight regarding time.
I tried to split the domain to multiple classes as much as possible. I tried to make each class has one responsibility.
I also did something new for myself, I tried to have each interactor package contain all its own data and its own exceptions. This way it is clearer when an exception is thrown to easily map it an explainable error message.
I was planning on adding RxJava to the project, but due to the limited time, I focused more on the structure of the app the test cases.
Due to the time limit, I opted to go for very simple UI. I realised that there can be more to be done like, toolbars, animations ... etc.
The app is not bug free, but once again due to the time limit, I really couldn't follow up on them all. The list of known bugs is:
- Trying to go back in the verification code screen to email submission screen doesn't work.
- Keyboard doesn't show up automatically when a text field is focused.
- Animation between activities could be better.
- No every error should be a child of an exception. Exception is used to be thrown when something un expected happens. I should have not made all the validation errors children of exceptions.
- Handle going back in the verification code screen
- Handle autofocus on text fields
- Replace SharedPreference with ProtoDataStore
- Navigation testing
- Testing domain
- Testing viewModels
- Entry fragment
- Navigation
- Encryption
- Nested Navigation
- Replace BCrypt with Argon2Kt https://github.com/lambdapioneer/argon2kt based on https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#argon2id or https://github.com/phxql/argon2-jvm
- Check best practices for either creating a cipher every time or reuse the old one
- Login
- Improve UI
- Unify Result class
- Error Handling
- Create model for UI state similar to LoginFormState in d5af9968
-
Add Splash screenAdded progress bar instead - Handle register with previous email