TaskMaster is a backend REST API built using Node.js, Express, and MongoDB. The application allows users to register, authenticate, create projects, and manage tasks within those projects. Security is a core focus of this project. All protected routes use JWT authentication, and ownership-based authorization ensures users can only access their own projects and tasks.
- Node.js - JavaScript runtime
- Express.js - Web framework for building REST APIs
- MongoDB - NoSQL database
- Mongoose - MongoDB object modeling (ODM)
- JWT (jsonwebtoken) - Authentication via JSON Web Tokens
- bcrypt - Secure password hashing
- dotenv - Environment variable management
- User registration and login
- JWT-based authentication
- Secure password hashing with bcrypt
- Project CRUD operations
- Task CRUD operations linked to projects
- Ownership-based authorization (403 on unauthorized access)
- Debug logging for learning and troubleshooting
- Static file serving for frontend and videos
- PORT=3000
- MONGO_URI=mongodb_connection_string
- JWT_SECRET=jwt_secret
- This project uses JSON Web Tokens (JWT) for authentication. To securely sign and verify tokens, a strong random secret key is required.
- Generate the JWT Secret
- Run the following command once in your terminal:
- node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
- Clone the repository
- Install dependencies
- npm init -y
- npm install express mongoose bcrypt jsonwebtoken dotenv
- npm install -D nodemon
- Create a .env file and add environment variables
- Start the server npm run dev Server runs at: http://localhost:3000
- For GET requests: Body must be NONE
- All protected routes require Authorization header
- Format: Authorization: Bearer YOUR_TOKEN
- POST /api/users/register
- Body
- { "username": "userA", "email": "a@test.com", "password": "password123" }
- Expected Result: 201 Created
- POST /api/users/login
- Body
- { "email": "a@test.com", "password": "password123" }
- Expected Result: 200 OK
- Copy token as TOKEN_A
- POST /api/projects
- Header
- Authorization: Bearer TOKEN_A
- Body
- { "name": "Project A", "description": "User A project" }
- Expected Result: 201 Created
- Copy project _id as PROJECT_ID_A
- POST /api/projects/PROJECT_ID_A/tasks
- Header
- Authorization: Bearer TOKEN_A
- Body
- { "title": "Task A1", "description": "First task", "status": "To Do" }
- Expected Result: 201 Created
- Copy task _id as TASK_ID_A
- GET /api/projects/PROJECT_ID_A/tasks
- Header
- Authorization: Bearer TOKEN_A Expected Result: 200 OK
- Returns array with Task A1
- POST /api/users/register
- POST /api/users/login
- Copy token as TOKEN_B
- GET /api/projects/PROJECT_ID_A/tasks
- Header
- Authorization: Bearer TOKEN_B
- Expected Result: 403 Forbidden
- PUT /api/tasks/TASK_ID_A
- Header
- Authorization: Bearer TOKEN_B
- Body
- { "title": "Hacker task" }
- Expected Result: 403 Forbidden
- PUT /api/tasks/TASK_ID_A
- Header
- Authorization: Bearer TOKEN_A
- Body
- { "status": "Done" }
- Expected Result: 200 OK
- DELETE /api/tasks/TASK_ID_A
- Header
- Authorization: Bearer TOKEN_A
- Expected Result: 200 OK
This project helped me deeply understand how backend security works in real-world applications. Implementing JWT authentication and ownership-based authorization showed me why both authentication and authorization are critical. Debugging routing issues, authorization failures, and database mismatches strengthened my problem-solving skills. The most valuable lesson was learning how small routing decisions affect API behavior and security testing results. This project increased my confidence in building secure backend systems using Node.js and Express.
Special thanks to my instructors and mentors for their guidance and patience throughout this learning process. Thank you to the Per Scholas program for providing hands-on, real-world backend training. Grateful to classmates and peers who shared knowledge, debugged together, and supported one another.