A comprehensive RESTful API for managing library operations with authentication, role-based access control, and a complete book borrowing system.
- SETUP.md β getting a dev environment running (Docker or manual)
- API.md β full endpoint reference (generated β see below)
- Interactive docs β
GET /api/docson a running server (Swagger UI) - ARCHITECTURE.md β system design, DB schema, auth model
- SECURITY_TESTING.md β security posture + manual test procedures
- DOCKER.md β Docker-specific details
- TODO.md β prioritized punch list / completion record
- CONTRIBUTING.md β how to contribute
- CHANGELOG.md β release notes
- π JWT Authentication - Secure user authentication with JSON Web Tokens
- π₯ Role-Based Access Control - Three user roles (Admin, Librarian, User)
- π Book Borrowing System - Complete borrowing and return workflow with due date tracking
- β° Overdue Management - Automatic overdue detection and late fee calculation
- π Search & Pagination - Advanced search with pagination on all list endpoints
- β Input Validation - Comprehensive validation and sanitization
- π‘οΈ Rate Limiting - Role-based rate limiting for API security
- π Security Headers - Multiple security layers including CORS, XSS protection
- π Request Logging - Detailed logging of all API requests
- β Error Handling - Centralized error handling with proper HTTP status codes
- Runtime: Node.js
- Framework: Express.js
- Database: MySQL
- Authentication: JWT (jsonwebtoken)
- Password Hashing: bcrypt
- Environment Variables: dotenv
# Clone the repository
git clone <repository-url>
cd LMS-API
# Install dependencies
npm install
# Set up environment variables (dotenv loads this from src/, not the repo root)
cp src/.env.example src/.env
# Edit src/.env with your configuration β generate a JWT_SECRET with:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Set up database
mysql -u root -p < src/Database/library.database.sql
# Start the server
npm run devSee SETUP.md for the full walkthrough (including the Docker path) and DOCKER.md for Docker-specific details.
Create a src/.env file with the following variables:
# Server
PORT=5080
NODE_ENV=development
# Database
DB_HOST=localhost
DB_USER=root
DB_PASSWORD=your_password
DB_NAME=library_db
DB_PORT=3306
# JWT
JWT_SECRET=your_super_secret_key_here
JWT_EXPIRE=7d
# Security
CORS_ORIGINS=<http://localhost:3000,http://localhost:3001>
BCRYPT_ROUNDS=12
INITIAL_SETUP_KEY=your_secure_setup_key_here
The system uses 4 main tables:
- users - User accounts with roles (Admin, Librarian, User)
- authors - Book authors information
- books - Book inventory and availability
- borrow_records - Track book borrowing and returns
| Method | Endpoint | Description | Access |
|---|---|---|---|
| POST | /api/auth/register | Register new user | Public |
| POST | /api/auth/login | Login user | Public |
| GET | /api/auth/me | Get current user profile | Protected |
| POST | /api/auth/logout | Logout user | Protected |
| POST | /api/auth/refresh | Refresh JWT token | Protected |
| POST | /api/auth/change-password | Change password | Protected |
| POST | /api/auth/setup-admin | Initial admin setup | Public (with setup key) |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/authors | Get all authors | Public |
| GET | /api/authors/:id | Get author by ID | Public |
| POST | /api/authors | Create author | Admin/Librarian |
| PUT | /api/authors/:id | Update author | Admin/Librarian |
| DELETE | /api/authors/:id | Delete author | Admin/Librarian |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/books | Get all books with filters | Public |
| GET | /api/books/:id | Get book by ID | Public |
| POST | /api/books | Create book | Admin/Librarian |
| PUT | /api/books/:id | Update book | Admin/Librarian |
| DELETE | /api/books/:id | Delete book | Admin/Librarian |
| POST | /api/books/:id/borrow | Borrow a book | Authenticated |
| POST | /api/books/:id/return | Return a book | Authenticated |
| Method | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/users | Get all users | Admin |
| GET | /api/users/public | Get public users list | Public |
| GET | /api/users/profile | Get current user profile | Protected |
| GET | /api/users/:id | Get user by ID | Admin/Librarian/Own |
| GET | /api/users/:id/borrow-records | Get user borrow records | Protected |
| POST | /api/users | Create user | Admin |
| PUT | /api/users/:id | Update user | Admin/Own |
| DELETE | /api/users/:id | Delete user | Admin |
| col1 | Endpoint | Description | Access |
|---|---|---|---|
| GET | /api/borrow-records | Get all borrow records | Admin/Librarian |
| GET | /api/borrow-records/overdue | Get overdue records | Admin/Librarian |
| GET | /api/borrow-records/statistics | Get borrowing stats | Admin/Librarian |
| POST | /api/borrow-records/:id/extend | Extend due date | User/Admin/Librarian |
All protected endpoints require a JWT token in the Authorization header:
Authorization: Bearer <your_jwt_token>
curl -X POST http://localhost:5080/api/auth/login \
-H "Content-Type: application/json" \
-d '{
"emailOrUsername": "user@example.com",
"password": "Password123"
}'
- Full system access
- User management (CRUD operations)
- Book and author management
- View all borrow records and statistics
- System configuration
- Book and author management
- View and update user profiles
- Manage borrow records
- View statistics
- Cannot delete users or modify system settings
- Browse books and authors
- Borrow and return books
- View own borrow history
- Update own profile
- Cannot access admin features
- page - Page number (default: 1)
- limit - Items per page (default: 10, max: 100)
- search - Search query string across relevant fields
- status - Filter by status (Available, Borrowed, Overdue, etc.)
- author_id - Filter books by author
- genre - Filter books by genre
- role - Filter users by role
- is_active - Filter users by active status
- overdue_only - Filter for overdue records only
GET /api/books?page=1&limit=20&search=harry&genre=Fantasy&status=Available- Maximum 5 books per user simultaneously
- Default loan period: 14 days (configurable)
- Cannot borrow same book twice simultaneously
- Book must be available (available_copies > 0)
- Users must have active account status
- Late fee: $1 per day after due date
- Book becomes available immediately after return
- Overdue status automatically updated
- Due dates can be extended (once per borrow)
- Email must be unique and valid format
- ISBN must be unique
- Password minimum 8 characters with complexity requirements
- Phone numbers validated for format
- Required fields enforced on all models
- Guest: 20 requests/15 minutes
- User: 60 requests/15 minutes
- Librarian: 120 requests/15 minutes
- Admin: 300 requests/15 minutes
- XSS protection
- SQL injection prevention
- HTML tag removal
- Parameter validation
- X-Frame-Options: DENY
- X-Content-Type-Options: nosniff
- X-XSS-Protection: 1; mode=block
- Strict-Transport-Security
- Content Security Policy
All error responses follow this format:
{
"success": false,
"message": "Error description",
"error": "Detailed error message",
"errors": [] // Optional validation errors
}
- 200 - Success
- 201 - Created
- 400 - Bad Request / Validation Error
- 401 - Unauthorized
- 403 - Forbidden
- 404 - Not Found
- 409 - Conflict
- 429 - Too Many Requests
- 500 - Internal Server Error
See Installation above (or SETUP.md for the full walkthrough, including the Docker path).
# Use the setup key from your src/.env file
curl -X POST http://localhost:5080/api/auth/setup-admin \
-H "Content-Type: application/json" \
-d '{
"admin_email": "admin@yourlibrary.com",
"admin_password": "SecurePass123!",
"setup_key": "YOUR_SETUP_KEY_FROM_ENV"
}'
# Login as admin
curl -X POST <http://localhost:5080/api/auth/login> \
-H "Content-Type: application/json" \
-d '{
"emailOrUsername": "<admin@yourlibrary.com>",
"password": "SecurePass123!"
}'
# Use the returned token for protected endpoints
curl -X GET <http://localhost:5080/api/auth/me> \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-H "Content-Type: application/json"
LMS-API/
βββ src/
β βββ config/ # Database + auth/JWT/password/rate-limit config
β βββ controllers/ # Request handling, one file per resource
β βββ middlewares/ # Auth, validation, centralized error handling
β βββ models/ # All SQL lives here; row β API-shape formatting
β βββ routes/ # Express routers, one per resource
β βββ jobs/ # Scheduled jobs (overdue borrow-record sweep)
β βββ utils/ # Logger, cache, mailer, token/store helpers
β βββ validation/ # Zod request-body schemas
β βββ Database/ # library.database.sql (schema quick-start)
β βββ .env # Real env vars (gitignored) β loaded via __dirname, not CWD
β βββ .env.example # Template for src/.env
β βββ server.js # Entry point β middleware wiring, graceful shutdown
βββ migrations/ # Forward-only SQL migrations + schema_migrations tracking
βββ scripts/ # migrate.js (migration runner)
βββ tests/ # Jest + Supertest β api/, unit/, helpers/; .env.test lives here too
βββ docs/ # All documentation (this file included)
β βββ README.md # You are here
β βββ SETUP.md # Getting a dev environment running
β βββ API.md # Full endpoint reference
β βββ ARCHITECTURE.md # System design, DB schema, auth model
β βββ SECURITY_TESTING.md # Security posture + manual test procedures
β βββ TODO.md # Prioritized punch list / completion record
β βββ CONTRIBUTING.md # How to contribute
β βββ CHANGELOG.md # Release notes
β βββ DOCKER.md # Docker-specific details
βββ docker/ # Dockerfile, docker-compose.yml, .env.example
βββ .github/workflows/ # CI (lint β test β docker build)
βββ package.json
# Run in development mode with auto-reload
npm run dev
# Run in production mode
npm start
# Generate new secrets
node generate-secrets.js
curl -X POST http://localhost:5080/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"first_name": "John",
"last_name": "Doe",
"user_name": "johndoe",
"email": "john@example.com",
"password": "Password123"
}'
curl -X POST http://localhost:5080/api/books \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"isbn": "978-0451524935",
"title": "1984",
"author_id": 1,
"published_date": "1949-06-08",
"genre": "Dystopian Fiction",
"total_copies": 5
}'
curl -X POST http://localhost:5080/api/books/1/borrow \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"due_days": 21
}'
- Fork the repository
- 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