Subscription App (part 3)
Tags: webdev, javascript, programming, tutorial
Published: 2024-03-22 21:59:21

Following the validation of username, email, and password in the previous [post](https://dev.to/hestia/day-2-4-of-subscription-app-1kle), we'll now verify if the provided email address already exists within the database.

The steps for checking email:
- once we pass the validation step, 
- get the email and fetch a particular record in the database that has that email
- if we get back a record, then send a response that the "email is already used, you can't create an account with it."
- if it returns null, then this step is passed, and we can go ahead and hash the password.

Firstly, we need to setup and connect the database with the server to execute these steps.

Secondly, we need to define how the user entity will look inside the database.


## Setting up the database (MongoDB)

The [doc](https://www.mongodb.com/docs/guides/atlas/account/) is well detailed and very easy to follow to get started with MongoDB. 

Just follow the "Chapter 1 Atlas" six guides.

These guides provide clear and concise instructions to ensure a smooth and successful database launch.
 
NB: Copy your credentials from the security quick-start in a safe place.

The steps are:
- Sign Up for a MongoDB Account
- Create a Cluster
- Add a Database User
- Configure a Network Connection
- Load Sample Data (skip this step)
- Get Connection String

![connecting your app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wxi1xc5vrzqh0ilc0qsl.png)
- connecting your app

![copy the connection string](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/maow2hazqxamea525swa.png)
- copy the connection string👆


Once the above steps are done, save your connection string to your app.

### Save the URI
Copy the URI and save it to your app.
![save uri](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/my7zo9z29fpafjkk5cmu.png)

To save...
- inside the server, create a .env file
- then save your URI
" MONGO_URI=[ your URI ]"
- replace the password part with the credential you saved earlier from the security quick-start.


## Connecting the database

Mongoose package lib will be utilized to connect to the MongoDB database.

- install mongoose and dotenv packages. The dotenv package helps to readenvironment variables inside the .env file.
"npm install mongoose dotenv"

- inside index.ts, import mongoose and dotenv

![mongoose connected](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xnsa8y07wqqilp1xpr5w.png)

The code above:
- ln 9: read the URI inside the .env file.
- ln 16-23: connect to DB
- pass in the URI
- log some message if we're connected or catch any error if something went wrong.

Yay! MongoDB is connected.

NB: If you get this error when connecting to the database,
"Error: MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you're trying to access the database from an IP that isn't whitelisted. Make sure your current IP address is on your Atlas cluster's IP whitelist"

Simply do this:

![Access error fixed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vi3768dny3uhd6wof1tv.png)



## Define the user entity
- create a directory named "models" in the src directory.
- then create a user.ts file in the models directory. This is where we define the user entity.

![define user entity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h7yv9pubkrw511mro39g.png)

The code above:
- import mongoose
- get schema from mongoose
- create a new schema and define the properties we want a user to have.
- then export the userSchema


## 2. Verify if email already exists
Back to the auth file...
- import the userSchema as User (with this, we can perform CRUD operations on the DB)

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h81o765ffstins4s0j9b.png)

- ln 34: extract these values from the incoming request body object
- ln 36: the code here find a particular user that has the email we get from the req body in the DB
- since there's no user yet in our DB it will return null.
- we'll check this step later once we create a user
- ln 38: here we specify what should happen if there's a user (send a response that email is in use)
 


# 3. Hash the password

We'll be using the bcryptjs library to hash the passwords. It securely hashes a user's password before storing it in a database, protecting sensitive information from unauthorized access.

Install the package 
`npm install bcryptjs`

Also install the types
`npm install @types/bcryptjs --save-dev`


![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ibsfj6f6eeb3mcobv8se.png)

The code above:
- import bcrypt
- after checking the email, 
- ln 50: we declares a constant variable named `hashedPassword` to store the hashed password result. Then we call the `hash` function from the `bcrypt` library (which takes in a password and a salt value) and await its completion. 
- incase you're wondering what a salt value is: Bcrypt automatically generates a unique salt for each password, making it extremely difficult to crack even if multiple users have the same password.
 
Now that the password is secure, let's save the user.


# 4. Save the user to the DB

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cvh7gxfdy99ueq6q668t.png)

- ln 54: we declare a constant variable named `newUser` to store the newly created user object. Then calls the create function on the User model we imported
- pass in  the provided email and hashed password.
- waits for the user creation to complete before proceeding.

This will successfully create a new user record in the database.

#### Testing the code...

- Registration successful 👇

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ab111eb7rkljfso50go6.png)

- new user saved to the DB with a hashed password.👇

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jfmnt8ruicj8w9ognqt.png)

Let's see what we get if we use the same email.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b6q0380ybhwvbydzccst.png)
 Ta da! We got a response that it's in use👍



## Errors I got


#### ERROR 1
I wanted to restart the server, then I got this error

![error 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yxdgz67g2j93pkkz6j3t.png)

I realized I hadn't navigated to the server directory using the cd command. What a classic case.

Just in case you are about to smash your PC, please do this.

![error 1 fixed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hr7mo8g1l6qdxobwjt46.png)

### ERROR 2
Just when I thought I was done, another error popped up!

![error2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lz55rys5zlxgd2r4e0m8.png)

To resolve a process conflict, I terminated all running Node.js processes using the task manager and then re-executed the script within VSCode.

![error2 fixed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5puyhcuemhr9gcrsgws9.png)


The journey continues in the next post, where we'll explore token generation and transmission.