Skip to content

yashav-shukla/Expense-Tracker-

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

9 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Expense Tracker - JWT Authentication & User Specific Expense Managemen

A full-stack Expense Tracker application built using Node.js, Express.js, MySQL, Sequelize ORM, bcrypt, and MVC Architecture. Users can securely sign up, log in, and manage their daily expenses.


πŸ“Œ Project Overview

This project implements the Secure User Authentication System for the Expense Tracker application.

Users can:

  • Register securely using bcrypt password hashing
  • Login using JWT Authentication
  • Create personal expenses
  • View only their own expenses
  • Delete only their own expenses
  • Store expenses linked to their account
  • Access protected routes using JWT tokens

The project follows the MVC (Model-View-Controller) Architecture and uses Sequelize ORM for database operations.


✨ Features

Authentication Features

  • User Registration
  • Login Authentication
  • bcrypt Password Hashing
  • JWT Token Generation
  • JWT Token Verification
  • Protected Routes
  • Authentication Middleware

Expense Management Features

  • Add Expense
  • View User Specific Expenses
  • Delete Own Expenses
  • Expense Categories
  • Expense Persistence
  • Expense Reload on Refresh

Database Features

  • User Table
  • Expense Table
  • One-To-Many Relationship
  • Foreign Key Mapping

New Section: JWT Authentication

## πŸ” JWT Authentication

### Why not send User ID from Frontend?

Sending userId directly from frontend is insecure because users can modify the request and access another user's data.

Example:

```json
{
  "userId": 5
}
```

A malicious user could change:

```json
{
  "userId": 1
}
```

and access someone else's expenses.

Therefore user identity must be verified using JWT.

---

### Token Generation

After successful login:

```text
User Login
      ↓
Verify Password
      ↓
Generate JWT Token
      ↓
Send Token To Frontend
```

Example:

```js
jwt.sign(
    {
        userId: user.id,
        name: user.name
    },
    'secretkey'
);
```

---

### Token Verification

Frontend sends token:

```text
Authorization: JWT_TOKEN
```

Backend verifies token:

```js
jwt.verify(token, 'secretkey');
```

If token is valid:

```js
req.user = decodedToken;
```

User information becomes available in all protected routes.

New Database Relationship Section

## πŸ”— User & Expense Relationship

### One User

Can Have

### Many Expenses

```text
User
  β”‚
  β”œβ”€β”€ Expense 1
  β”œβ”€β”€ Expense 2
  β”œβ”€β”€ Expense 3
```

### Sequelize Relationship

```js
User.hasMany(Expense);

Expense.belongsTo(User);
```

This automatically creates:

```text
userId
```

inside Expense Table.

Update Expense Schema

## πŸ—ƒ Expense Table Schema

| Field       | Type    |
|------------|---------|
| id         | INTEGER |
| amount     | FLOAT |
| description| STRING |
| category   | STRING |
| userId     | INTEGER |

New Protected Routes Section

## πŸ›‘ Protected Routes

### Add Expense

```http
POST /expense/add-expense
```

Protected using:

```js
auth
```

middleware.

---

### Get Expenses

```http
GET /expense/get-expenses
```

Returns only logged-in user's expenses.

---

### Delete Expense

```http
DELETE /expense/delete-expense/:id
```

User can delete only expenses created by them.

Update Expense Flow

## πŸ’° User Specific Expense Flow

```text
User Login
      ↓
JWT Token Generated
      ↓
Token Stored In LocalStorage
      ↓
Expense Added
      ↓
Token Sent In Header
      ↓
Middleware Verifies User
      ↓
userId Extracted
      ↓
Expense Saved With userId
      ↓
Expense Linked To User
```

New Middleware Section

## πŸ”’ Authentication Middleware

File:

```text
middleware/auth.js
```

Responsibilities:

```text
Read JWT Token
Verify Token
Extract User Information
Attach User To Request
Allow Access To Protected Routes
```

πŸ” Password Security

Before bcrypt

Database stored passwords like:

123456
admin123
password

This is unsafe because anyone with database access can view user passwords.

After bcrypt

Passwords are stored as hashes:

$2b$10$RkK9j...  
$2b$10$gXfP7...

Actual passwords are never stored in plain text.

Signup Flow

User Password
      β”‚
      β–Ό
bcrypt.hash()
      β”‚
      β–Ό
MySQL Database

Login Flow

User Password
      β”‚
      β–Ό
bcrypt.compare()
      β”‚
      β–Ό
Authentication Result

πŸ›  Tech Stack

  • Node.js
  • Express.js
  • bcrypt
  • MySQL
  • Sequelize ORM
  • JavaScript
  • HTML5
  • CSS3
  • Axios
  • CORS

πŸ“ Project Structure

expense-tracker
β”‚
β”œβ”€β”€ controllers
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ models
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ routes
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ util
β”‚   └── database.js
β”‚
β”œβ”€β”€ views
β”‚   β”œβ”€β”€ signup.html
β”‚   β”œβ”€β”€ signup.css
β”‚   β”œβ”€β”€ signup.js
β”‚   β”œβ”€β”€ login.html
β”‚   β”œβ”€β”€ login.css
β”‚   β”œβ”€β”€ login.js
β”‚   β”œβ”€β”€ expense.html
β”‚   β”œβ”€β”€ expense.css
β”‚   └── expense.js
β”‚
β”œβ”€β”€ images
β”‚
β”œβ”€β”€ app.js
β”œβ”€β”€ package.json
└── README.md

πŸ” Authentication APIs

Signup API

POST /user/signup

Request Body

{
  "name": "Yash",
  "email": "yash@gmail.com",
  "password": "123456"
}

Process

Validate User
       ↓
Check Existing Email
       ↓
bcrypt.hash()
       ↓
Store Hashed Password
       ↓
Success Response

Success Response

{
  "message": "User created successfully"
}

Status Code:

201 Created

Duplicate User Response

{
  "message": "User already exists"
}

Status Code:

409 Conflict

Login API

POST /user/login

Request Body

{
  "email": "yash@gmail.com",
  "password": "123456"
}

Process

Find User
      ↓
bcrypt.compare()
      ↓
Password Match ?
      ↓
Login Success

Successful Login

{
  "message": "User login successful"
}

Status Code:

200 OK

Invalid Password

{
  "message": "User not authorized"
}

Status Code:

401 Unauthorized

User Not Found

{
  "message": "User not found"
}

Status Code:

404 Not Found

πŸ’° Expense APIs

Add Expense

POST /expense/add-expense

Request Body

{
  "amount": 500,
  "description": "Petrol",
  "category": "Fuel"
}

Success Response

{
  "success": true,
  "expense": {
    "id": 1,
    "amount": 500,
    "description": "Petrol",
    "category": "Fuel"
  }
}

Status Code:

201 Created

Get Expenses

GET /expense/get-expenses

Status Code:

200 OK

Delete Expense

DELETE /expense/delete-expense/:id

Status Code:

200 OK

πŸ“€ Authentication Flow

User
 ↓
Frontend Form
 ↓
Axios POST Request
 ↓
Route
 ↓
Controller
 ↓
Model
 ↓
MySQL Database
 ↓
Response
 ↓
Frontend Alert

πŸ—ƒ User Table Schema

Field Type
id INTEGER
name STRING
email STRING
password STRING

Add Expense Flow

## πŸ’° Expense Flow

```text
User Login
      ↓
Expense Page Opens
      ↓
Enter Expense Details
      ↓
Axios POST Request
      ↓
Expense Route
      ↓
Expense Controller
      ↓
Expense Model
      ↓
MySQL Database
      ↓
Expense Displayed on Screen

## πŸ— MVC Architecture

### View

```text
signup.html
signup.css
signup.js

login.html
login.css
login.js

Controller

controllers/user.js

Responsibilities:

Receive Requests
Validate Data
Check Existing Users
Verify Login Credentials
Send Responses

Model

models/user.js

Responsibilities:

Database Operations
Store User Data
Manage User Records

Previous MVC Architecture Diagram


MVC Architecture

Updated MVC Architecture Diagram


expense-tracker
β”‚
β”œβ”€β”€ controllers                 ←  Controller Layer
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ models                      ←  Model Layer               
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ routes                      ←  Route Layer
β”‚   β”œβ”€β”€ user.js
β”‚   └── expense.js
β”‚
β”œβ”€β”€ util
β”‚   └── database.js            ←  Database Configuration
β”‚
β”œβ”€β”€ views                      ←  View Layer
β”‚   β”‚
β”‚   β”œβ”€β”€ signup.html
β”‚   β”œβ”€β”€ signup.css
β”‚   β”œβ”€β”€ signup.js
β”‚   β”‚
β”‚   β”œβ”€β”€ login.html
β”‚   β”œβ”€β”€ login.css
β”‚   β”œβ”€β”€ login.js
β”‚   β”‚
β”‚   β”œβ”€β”€ expense.html
β”‚   β”œβ”€β”€ expense.css
β”‚   └── expense.js
β”‚
β”œβ”€β”€ images
β”‚   β”œβ”€β”€ signup-page.png
β”‚   β”œβ”€β”€ login-page.png
β”‚   β”œβ”€β”€ expense-page.png
β”‚   β”œβ”€β”€ add-expense.png
β”‚   β”œβ”€β”€ expense-table.png
β”‚   β”œβ”€β”€ delete-expense.png
β”‚   β”œβ”€β”€ mysql-data.png
β”‚   └── mvc-architecture.png
β”‚
β”œβ”€β”€ app.js                   ←  Application Entry Point
β”œβ”€β”€ package.json 
β”œβ”€β”€ package-lock.json
└── README.md

MVC Flow Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       VIEW          β”‚
β”‚ HTML β€’ CSS β€’ JS     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚      ROUTES         β”‚
β”‚ routes/user.js      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    CONTROLLER       β”‚
β”‚ controllers/user.js β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚       MODEL         β”‚
β”‚ models/user.js      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
           β”‚
           β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   MYSQL DATABASE    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ“Έ Project Screenshots

Signup Page

Signup Page

Login Page

Login Page

Network Requests

Network Request

Network Request

Successful Responses

Signup Success

Signup Success

Login Success

Error Handling

Unauthorized User

User Not Found

Password Bcrypt

Expense Dashboard

Expense Dashboard

Add Expense

Add Expense

Delete Expense

Delete Expense

User Per Login

Delete Expense

Database Records

MySQL Data

Expense List

Expense List

πŸš€ Future Improvements

* Premium Membership
* Leaderboard Feature
* Expense Pagination
* Download Expense Reports
* Forgot Password
* Razorpay Integration
* AWS Deployment
* Monthly Analytics
* AI Powered Expense Insights

πŸ‘¨β€πŸ’» Author

Yashav Shukla

Node.js β€’ Express.js β€’ MySQL β€’ JavaScript

🌐 GitHub Profile


⭐ If you found this project helpful, consider giving it a star on GitHub!

Releases

No releases published

Packages

 
 
 

Contributors