Must/Should/Can - a Personal Organization System
Tags: react, rails
Published: 2022-02-20 23:17:04

Repo: [joedietrich-dev/must-should-can](https://github.com/joedietrich-dev/must-should-can)

## Inspiration

A little while ago, I found myself struggling to bring order to my tasks at work. I'd tried many different organizational systems. Some didn't suit my work style, others were way too complicated - adding to my daily tasks rather than making them easier. I decided to put together a system that worked for me.

## The System

I divide my tasks for the day into three buckets: Tasks I **must** do today, Tasks I **should** do today, Tasks I **can** do today. Every day, I rewrite and carry over any incomplete tasks to the next day. It's simple, but it works for me!

## Basic Features
I took the simple pen-and-paper tools and made them digital. The features of Must/Should/Can are straightforward, as is system itself:

- Account Creation and Login
- Task Creation, Editing, and Prioritization
- Task Resets
- Task Archiving and Deleting

## What I Used

### Backend

- [Ruby on Rails](https://rubyonrails.org/) as the framework for the API
- [ActiveModelSerializers](https://github.com/rails-api/active_model_serializers) to build JSON views
- [PostgreSQL](https://postgresql.org) as the database
- The [bcrypt](https://github.com/bcrypt-ruby/bcrypt-ruby) gem to improve password security in tandem with the ActiveRecord [`has_secure_password`](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password) feature

### Frontend
- [React](https://reactjs.org/) / [Create React App](https://create-react-app.dev/)
- [React Router v6](https://reactrouter.com/) - For client-side routing
- [Styled Components](https://styled-components.com/) to style the application

## Authorization, Passwords, and Salting
While building Must/Should/Can, it did not escape my attention that a user's tasks could be very private, so there was a need to protect them as much as possible. To ensure that privacy, I not only implemented user authorization and password authentication, I protected their passwords with the ActiveRecord `has_secure_password` feature.

### `has_secure_password`
If you're storing passwords in any system, it is a **very bad idea** to store them in plaintext **anywhere** in your application. Doing so exposes you and your users to potential data losses, which is a Bad Thing. The `has_secure_password` feature adds methods to an ActiveRecord model that make setting and authenticating securely hashed and salted passwords on your user models easy. 

Under the hood, `has_secure_password` uses the `bcrypt` gem to hash and salt your user's passwords. This process makes it very difficult for bad actors to access your users' password data, even if they manage to steal your database. 

Hashing is the process of taking data and processing it to create a new value, usually of a fixed length (sometimes called a fingerprint). The process is unidirectional, meaning once a value has been hashed, it is incredibly impractical (with current technology) to reverse the process to derive the original value from the hash. For example, using bcrypt, the password `Wolfgang the puppy` might hash to the value `$2a$12$j29LhAzasXWN7glfGjp9NuFXcOYBCffkE4RWcQJwBFzxsAsUsQ2nK`. This unidirectionality is what makes hashed passwords more secure than plaintext passwords - a hacker will need to do extra work to break the encryption involved.

Or they might have a Rainbow Table, which is a precomputed set of values that will let an attacker look up the password based on a given hash. If the hashing function is known to the attacker, hashing alone won't be enough to protect a user's password, since the same input value will always produce the same output hash.

This is why bcrypt will also **salt** a password before storing the hash in your database. A salt is data added to the input of a hash function. In bcrypt's implementation, a unique salt is added to every password on generation. This means that an attacker would need to use a different pre-computed Rainbow Table for every single password, which is computationally prohibitive. 

All of this means that, properly implemented, using `has_secure_password` and `bcrypt` in your application is one important step protect you and your users from bad actors.


## Next Steps

I plan to introduce the ability to add notes to tasks so you can, for example, sketch out an agenda for a meeting, or divide tasks into subtasks. I also plan to enhance the archive with grouping and sorting. Later on, I'll enhance the user's account management experience, letting them reset their password and edit their user name.

## End
Thanks for reading! For a walkthrough, take a look at the [demo video](https://youtu.be/rDLsf4lwwns). Access the application itself at [https://must-should-can.herokuapp.com/](https://must-should-can.herokuapp.com/).