TaskBro is a modern, responsive, and secure task management web application built with a React-Vite frontend, Express/Node.js backend, and MongoDB database. It features secure JWT-based HTTP-Only Cookie authentication and integrates a client-side state manager that persists tasks locally per-user.
This document serves as the complete technical specification, setup guide, and architectural layout for the TaskBro application.
TaskBro is built using a decoupled client-server architecture. Below is a conceptual view of how components interact:
sequenceDiagram
autonumber
actor User
participant Client as Frontend (Vite + React)
participant Server as Backend (Node + Express)
participant DB as Database (MongoDB)
User->>Client: Open Application / Register / Login
Client->>Server: HTTP POST /api/auth/login (Credentials)
Server->>DB: Check User profile & match Bcrypt Hash
DB-->>Server: User authenticated successfully
Server->>Server: Generate JWT Token
Server-->>Client: Set HTTP-Only Cookie (token) & return User JSON
Note over Client: Initialize tasks state from LocalStorage<br/>using key "taskflow-tasks-{userId}"
Client-->>User: Render Dashboard with task listing
User->>Client: Create / Modify / Delete Task
Client->>Client: Sync memory state & update LocalStorage
Client-->>User: Instantly updates UI
- π High-Security Authentication: Secure user registration and login utilizing JWT tokens passed via secure HTTP-Only Cookies to prevent XSS (Cross-Site Scripting) and CSRF (Cross-Site Request Forgery) vulnerabilities.
- πΌ Per-User Task Isolation: Encrypted database users coupled with client-side isolation ensuring tasks are mapped strictly to the logged-in user via unique identifiers (
taskflow-tasks-${userId}). - π Real-time Dashboard Analytics: Instant metrics visualization on completed, pending, and total tasks.
- π Instant Fuzzy Filtering: Real-time searching of tasks based on titles and descriptions.
- π Deadline Tracking: Add optional due dates to track task completion schedules.
- π‘οΈ Secure Password Management: Built-in functionality for users to change their password securely using bcrypt hashing.
- π± Fluid UI/UX: Crafted using React, styled with Tailwind CSS, and optimized with Vite for ultra-fast performance.
- π Toast Notifications: Global animated top-center toast system for success and error feedback across login, register, change-password, and task actions - no browser alerts.
- ποΈ Delete Task Modal: Inline styled modal matching the app's design language (consistent with AddTaskModal) used to confirm task deletion.
| Layer | Technology | Version | Description |
|---|---|---|---|
| Frontend Core | React | ^19.2.0 |
Declarative UI components & state management |
| Client Routing | React Router DOM | ^7.15.1 |
Handle application navigation paths client-side |
| Build Tooling | Vite | ^7.2.4 |
Superfast HMR development server and optimized bundler |
| Styling | Tailwind CSS | ^3.4.19 |
Utility-first styling framework for responsive web design |
| Backend Core | Node.js / Express | ^4.21.2 |
Minimalist web framework for routing and middleware orchestration |
| Database ORM | Mongoose | ^8.12.0 |
Object data modeling for MongoDB schema definition |
| Session Security | JWT / Cookies | ^9.0.2 / ^1.4.6 |
Session management via sign verification |
| Password Security | BcryptJS | ^3.0.2 |
Hashing function for securing stored credentials |
TaskBro/
βββ Backend/
β βββ src/
β β βββ config/
β β β βββ db.config.js # MongoDB connection database wrapper
β β βββ controllers/
β β β βββ auth.controller.js # Auth operations (login, register, logout, getMe, changePassword)
β β βββ middleware/
β β β βββ auth.middleware.js # Protect routes, check token, and attach user to req
β β βββ models/
β β β βββ user.model.js # User validation and mongoose schema model
β β βββ routes/
β β βββ auth.routes.js # API Route boundaries mapping middleware and controller
β βββ .env # Backend local configuration & secrets
β βββ server.js # Main entrypoint initializing express, middleware, routes
β βββ package-lock.json
β βββ package.json # Backend node package manifest
β
βββ Frontend/
β βββ public/ # Raw static public assets
β βββ src/
β β βββ assets/ # App-compiled asset structures
β β βββ components/
β β β βββ AddTaskModal.jsx # Modal form view to capture task fields
β β β βββ DeleteTaskModal.jsx # Confirmation modal for task deletion
β β β βββ SearchBar.jsx # Fuzzy text task filter input
β β β βββ TaskCard.jsx # Layout component for individual tasks
β β β βββ TaskList.jsx # Grid wrapper rendering multiple TaskCards
β β β βββ TaskStats.jsx # Dashboard statistics analytics banner
β β β βββ Toast.jsx # Animated top-center toast notification UI
β β βββ contexts/
β β β βββ ToastContext.jsx # Global toast state provider & useToast() hook
β β βββ pages/
β β β βββ ChangePassword.jsx # Form view to execute password update
β β β βββ Dashboard.jsx # Main layout displaying welcome, stats, task controls
β β β βββ Header.jsx # App navigation and logout trigger
β β β βββ Login.jsx # Secure login portal page
β β β βββ Register.jsx # Secure user registration portal
β β βββ services/
β β β βββ api.js # Centralized Axios API configuration and auth requests
β β βββ App.css # Root component animations & resets
β β βββ App.jsx # Router config, global state, task state lifecycles
β β βββ index.css # Entrypoint styling loading Tailwind directives
β β βββ main.jsx # ReactDOM container mounting index
β βββ .env # Frontend local configuration
β βββ .env.example # Frontend template local configuration
β βββ eslint.config.js # Linter configuration guidelines
β βββ postcss.config.js # Tailwind preprocessor config
β βββ tailwind.config.js # Tailwind styling constraints and custom themes
β βββ vite.config.js # Vite development environment variables
β βββ package-lock.json
β βββ package.json # Frontend package dependencies list
Before installing, ensure you have the following CLI utilities installed globally on your machine:
- NodeJS:
node -v(Should yield>= v18.0.0) - NPM:
npm -v(Should yield>= v9.0.0) - MongoDB: A running MongoDB instance locally or a connection string to MongoDB Atlas.
-
Navigate to the backend directory:
cd Backend -
Install dependencies:
npm install
-
Create a
.envfile in the root of theBackend/directory and configure the environment variables:PORT=5000 NODE_ENV=development MONGO_URI=your_mongodb_connection_string JWT_SECRET=your_jwt_strong_secret_key JWT_EXPIRES_IN=7d CLIENT_URL=http://localhost:5173
Environment Variable Parameter Matrix:
Key Default Description Requirement PORT5000Port Express backend binds to listen for API requests Optional (Defaults to 5000) NODE_ENVdevelopmentEnvironment mode flag ( development,production). Adjusts cookie secure tags and stack trace visibilityRequired MONGO_URINone Connection URL for MongoDB Database Instance Required JWT_SECRETNone Strong secret string used to sign and verify JSON Web Tokens Required JWT_EXPIRES_IN7dLifespan duration configuration string for issued JWTs Required CLIENT_URLhttp://localhost:5173Allowed frontend URL for CORS access control Required -
Start the backend development server:
npm run dev
The server will start on port
5000(or the configuredPORT).
- Navigate to the frontend directory:
cd ../Frontend - Install dependencies:
npm install
- Create a
.envfile in the root of theFrontend/directory and configure the environment variables:VITE_API_URL=http://localhost:5000
- Start the Vite development server:
By default, the frontend will be running on
npm run dev
http://localhost:5173.
All API requests must go to the backend host (default: http://localhost:5000). Make sure to enable credentials support on your HTTP Client (credentials: 'include') for httpOnly session validation.
- Method:
POST - Path:
/api/auth/register - Headers:
Content-Type: application/json - Request Body:
{ "username": "johndoe", "email": "johndoe@example.com", "password": "securepassword123" } - Success Response (201 Created):
{ "success": true, "message": "User registered successfully", "userId": "647209e86cfc7a001a1db902", "user": { "_id": "647209e86cfc7a001a1db902", "username": "johndoe", "email": "johndoe@example.com" }, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } - Failure Response (400 Bad Request):
{ "message": "User already exists with this email" }
- Method:
POST - Path:
/api/auth/login - Headers:
Content-Type: application/json - Request Body:
{ "email": "johndoe@example.com", "password": "securepassword123" } - Success Response (200 OK):
Sets HTTP-Only cookie
token{ "success": true, "user": { "_id": "647209e86cfc7a001a1db902", "username": "johndoe", "email": "johndoe@example.com" }, "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } - Failure Response (401 Unauthorized):
{ "message": "Invalid email or password" }
- Method:
POST - Path:
/api/auth/logout - Credentials: Required
- Success Response (200 OK):
Clears HTTP-Only cookie
token{ "success": true, "message": "Logged out successfully" }
- Method:
GET - Path:
/api/auth/me - Credentials: Required
- Success Response (200 OK):
{ "success": true, "user": { "_id": "647209e86cfc7a001a1db902", "username": "johndoe", "email": "johndoe@example.com", "createdAt": "2026-06-11T06:02:30.000Z", "updatedAt": "2026-06-11T06:02:30.000Z" } } - Failure Response (401 Unauthorized):
{ "message": "Not authorized, token failed" }
- Method:
PUT - Path:
/api/auth/change-password - Credentials: Required
- Request Body:
{ "currentPassword": "securepassword123", "newPassword": "newsecurepassword456" } - Success Response (200 OK):
{ "success": true, "message": "Password changed successfully" } - Failure Response (400 Bad Request):
{ "message": "Incorrect current password" }
TaskBro is engineered with secure-by-default architecture parameters:
-
Cookie-Based Token Distribution (HTTP-Only): Tokens generated at login/signup are distributed via server-write cookie options:
res.cookie('token', token, { httpOnly: true, // Disallows access from client-side Document.cookie API (Neutralizes XSS) secure: process.env.NODE_ENV === 'production', // Disallows transmitting token over unencrypted HTTP (True in prod) sameSite: 'Lax', // Mitigates CSRF requests while allowing standard cross-site redirection navigation maxAge: 7 * 24 * 60 * 60 * 1000, // Explicit token expiry tracking matching token signature (7 Days) });
-
Credentials Protection (Bcrypt Hash Engine): Passwords are never stored in plaintext format. When a new user registers or updates a password:
- A cryptographic salt factor of
10is generated. - The plaintext password is encrypted using the salt, making decryption extremely resource-heavy.
- User authentication works by running cryptographic comparison
bcrypt.compare(plaintext, hashed)on the MongoDB data structure.
- A cryptographic salt factor of
-
Restricted Cross-Origin Resource Sharing (CORS): Cross-site scripting attacks are countered on the router container level:
const allowedOrigins = [ 'http://localhost:5173', 'http://127.0.0.1:5173' ]; if (process.env.CLIENT_URL) { allowedOrigins.push(process.env.CLIENT_URL); } app.use(cors({ origin: allowedOrigins, credentials: true, }));
The frontend orchestrates tasks on the client-side to maximize application speed and minimize unnecessary server loads.
Instead of mixing global state, TaskBro divides tasks on a user-by-user basis using client-side partitioning key schemas:
- When user login state resolves:
- The app extracts user property
_id. - Sets storage target pointer key:
taskflow-tasks-${userId}.
- The app extracts user property
- In-memory state
tasksloads from corresponding key partition. - Every task state update (Add, Delete, Edit, Toggle) triggers a reactive state flush to the respective key.
- When a user logs out:
- In-memory task state is instantly reset to
[]. - Current user cache is deleted.
- Other user data in
localStorageremains untouched and completely isolated.
- In-memory task state is instantly reset to
{
"id": "2d7b2752-6cb0-466d-8848-936b8017c6a9",
"title": "Deploy Backend API to production server",
"description": "Ensure environmental secret credentials and CORS origins are configured before launch.",
"dueDate": "2026-06-18",
"completed": false,
"createdAt": "2026-06-11T11:42:38.283Z"
}- Symptom: Console outputs error matching
Access to fetch at 'http://localhost:5000/api/auth/me' from origin 'http://localhost:port' has been blocked by CORS policy. - Fix: Ensure your React application is running precisely on
http://localhost:5173. If you are using a different port or in production, add it to yourFRONTEND_URLenvironment variable inside your backend's.envconfiguration file:CLIENT_URL=http://localhost:NEW_PORT
- Symptom: Server crashes on startup with
MongooseServerSelectionError: connection timed out. - Fix:
- Ensure MongoDB server is active if running locally.
- If using MongoDB Atlas, check that you have added your current IP address to the Network Access whitelist inside the MongoDB Atlas Console.
- Symptom: User logs in successfully, but subsequent requests to
/api/auth/mereturn401 Unauthorized(no token provided). - Fix: Confirm that your API fetch calls in the React source code include the option
credentials: 'include'. Standard fetches do not attach cookies cross-origin by default without this flag.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature) - Commit your Changes (
git commit -m 'Add some AmazingFeature') - Push to the Branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Distributed under the MIT License. See LICENSE for more information.