This project is a backend system for a course marketplace where administrators can create and manage courses, while users can browse, purchase, and access their purchased courses. The system implements role-based authentication using JWT tokens to separate admin and user permissions.
The application follows a modular Express.js architecture with clear separation of concerns:
index.js - Entry point that initializes the Express server, connects to MongoDB, and mounts three main routers (/user, /admin, /course) on their respective paths.
db.js - Defines the MongoDB data models using Mongoose schemas:
- User Model: Stores user credentials (email, hashed password) and profile info (firstName, lastName)
- Admin Model: Similar to User but separate table for admin accounts
- Course Model: Contains course details (title, description, price, imgUrl) with a reference to the creator admin
- Purchase Model: Junction table linking users to their purchased courses
routes/user.js - Handles user-related operations:
/signup- Creates new user accounts with bcrypt password hashing/signin- Validates credentials and issues JWT tokens/purchases- Protected route (requires JWT) to view purchased courses/purchase- Protected route to buy a course
routes/admin.js - Manages admin operations:
/signup- Creates admin accounts with hashed passwords/signin- Validates admin credentials and returns JWT/course- Protected POST endpoint to create courses/course- Protected PUT endpoint to update existing courses/course/bulk- Protected GET endpoint to retrieve all courses created by the authenticated admin
routes/course.js - Public course browsing:
/preview- Returns all available courses without authentication
middleware/user.js - JWT verification middleware for user routes. Extracts the token from request headers, verifies it against JWT_USER_PASSWORD, and attaches the decoded user ID to the request object for downstream handlers.
middleware/admin.js - Similar JWT verification for admin routes using JWT_ADMIN_PASSWORD, ensuring only authenticated admins can create/modify courses.
utils/handlePassword.js - Encapsulates bcrypt operations for password hashing and comparison, providing a consistent interface for password security throughout the application.
- Separate Authentication Domains: Users and admins have distinct JWT secrets and authentication flows to prevent privilege escalation
- Password Security: All passwords are hashed with bcrypt before storage; plaintext passwords never persist
- Token-based Auth: Stateless JWT authentication allows horizontal scaling without session management
- Schema Validation: Mongoose schemas enforce data structure and unique email constraints at the database level
- Middleware Pattern: Authentication logic is centralized in middleware functions to keep route handlers clean and focused on business logic