Node.js Β· Express Β· MongoDB Β· JWT Authentication
A secure, modular RESTful backend API for managing user-owned projects and tasks. This API enforces strict ownership-based authorization, ensuring users can only access and modify their own data.
Built as a capstone backend project to demonstrate real-world API design, authentication, authorization, and relational data modeling.
This project demonstrates proficiency in:
- JWT-based authentication
- Secure user registration and login
- Ownership-based authorization
- Relational data modeling with MongoDB & Mongoose
- Nested RESTful routes
- Clean controller-based architecture
- DRY middleware and authorization patterns
- Full CRUD operations on protected resources
Security and correctness were the primary focus.
- Register and log in
- Receive a JWT upon authentication
- Create projects they own
- View all their own projects
- Update and delete their own projects
- Create tasks within their projects
- View all tasks for a specific project
- Update tasks belonging to their projects
- Delete tasks belonging to their projects
- π« Access to other usersβ projects or tasks is strictly blocked
- Passwords hashed using bcrypt
- JWT issued on login
- Token verified via middleware
- Authenticated user attached to
req.user
- Projects reference their owning user
- Tasks reference their parent project
- Task authorization is enforced via parent project ownership
- All sensitive queries are filtered by ownership
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/users/register |
Register a new user |
| POST | /api/users/login |
Login and receive JWT |
All project routes require a valid JWT.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/projects |
Create a new project |
| GET | /api/projects |
Get all projects owned by user |
| GET | /api/projects/:id |
Get one project (owner only) |
| PUT | /api/projects/:id |
Update project (owner only) |
| DELETE | /api/projects/:id |
Delete project (owner only) |
Tasks are children of projects. Authorization is enforced through the parent project.
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/projects/:projectId/tasks |
Create task in owned project |
| GET | /api/projects/:projectId/tasks |
Get all tasks for owned project |
| PUT | /api/tasks/:taskId |
Update task (via parent project ownership) |
| DELETE | /api/tasks/:taskId |
Delete task (via parent project ownership) |
π Live API: π https://taskmaster-dths.onrender.com
β οΈ Important NoteThis project is a backend-only REST API. There is no frontend UI provided.
To interact with and test the API, please use an API client such as:
- Insomnia (recommended)
- Postman
- cURL
POST /api/users/register
{
"username": "testuser",
"email": "testuser@email.com",
"password": "password123"
}POST /api/users/login
{
"email": "testuser@email.com",
"password": "password123"
}βοΈ Copy the returned JWT token
For all protected routes, add this header:
Authorization: Bearer <YOUR_JWT_TOKEN>
POST /api/projects
{
"name": "My First Project",
"description": "Testing live API"
}POST /api/projects/:projectId/tasks
{
"title": "Finish backend",
"description": "Complete Tasks API",
"status": "To Do"
}PUT /api/tasks/:taskId
DELETE /api/tasks/:taskId
β οΈ Authorization is enforced:
- You must own the parent project
- Cross-user access is blocked with 403 Forbidden
- All project and task routes are JWT-protected
- Ownership checks are enforced at every level
- Tokens are required for all non-auth routes
- Node.js
- Express
- MongoDB Atlas
- Mongoose
- bcrypt
- jsonwebtoken
- dotenv
TaskMaster/
.
βββ README.md
βββ config
β βββ connection.js
βββ controllers
β βββ project
β β βββ createProjects.js
β β βββ deleteProject.js
β β βββ getProjects.js
β β βββ getProjectsById.js
β β βββ updateProject.js
β βββ task
β β βββ createTask.js
β β βββ deleteTask.js
β β βββ getTask.js
β β βββ updateTask.js
β βββ user
β βββ userLogin.js
β βββ userRegister.js
βββ models
β βββ Project.js
β βββ Task.js
β βββ User.js
βββ package-lock.json
βββ package.json
βββ routes
β βββ routes.js
βββ server.js
βββ utils
βββ auth.js
9 directories, 21 files
git clone <https://github.com/structbase/TaskMaster-Backend>npm installMONGO_URI=your_mongodb_connection_string
PORT=3000
JWT_SECRET=your_jwt_secret
SALTING_ROUNDS=10
npm run devServer will run at:
http://localhost:3000
- Verifies token from
Authorizationheader - Attaches authenticated user to
req.user - Protects all project and task routes
For update and delete operations:
- Find the task by
taskId - Find the parent project from
task.project - Verify project ownership matches
req.user._id
This ensures no task can be accessed outside its project context.
All endpoints were tested using Insomnia:
- Authentication flow
- JWT-protected routes
- Project CRUD operations
- Task CRUD operations
- Cross-user authorization rejection (403)
- Invalid access attempts (401 / 404)
This project reinforced how critical authorization design is in real-world APIs.
The most challenging aspect was implementing task-level security through parent project ownership without duplicating logic or leaking access. Carefully structuring queries and enforcing checks at the controller level ensured both correctness and security.
This backend provides a strong foundation for scalable, secure, production-ready APIs.
Developed by Abenezer
Junior Software Developer