A production-ready NestJS authentication API with JWT implementation, comprehensive test coverage, and full Docker containerization. This project provides a robust, well-tested starting point for building secure web applications with modern development practices.
This API implements a secure JWT-based authentication system with these key features:
- Registration: Users create accounts with email, name, and password
- Login: Users authenticate to receive a JWT token
- Authentication Check: Simple endpoint to verify if a token is valid
- Password Security: Bcrypt hashing with strong password requirements
- Full Docker Support: Complete containerized environment with database and admin tools
- High Test Coverage: Comprehensive Jest testing suite ensuring code reliability
- Modern Stack: TypeScript, Prisma ORM, PostgreSQL, and pnpm for enhanced performance
# 1. Register a new user
POST /auth/signup
Body: { "name": "John Doe", "email": "[email protected]", "password": "StrongP@ss1", "passwordConfirm": "StrongP@ss1" }
Response: { "id": 1, "email": "[email protected]", "name": "John Doe" }
# 2. Login to get a token
POST /auth/login
Body: { "email": "[email protected]", "password": "StrongP@ss1" }
Response: { "accessToken": "eyJhbGciOiJIUzI1NiIsIn..." }
# 3. Check authentication status
GET /auth/check
Header: Authorization: Bearer eyJhbGciOiJIUzI1NiIsIn...
Response: { "isAuthenticated": true, "message": "You are authenticated. Thank you for using Enter The Nest." }
- Password Security: Passwords are hashed with bcrypt (cost factor 10)
- JWT Implementation: Tokens contain user data (id, name, email) with a 1-hour expiration
- Token Verification: AuthGuard middleware verifies tokens for protected routes
- Authentication Check: Simple endpoint returns authentication status without exposing user data
- Stateless Design: No server-side token storage for better scalability
Note on Token Expiration: The default token expiration is set to 1 hour (
expiresIn: '1h'
) inauth.module.ts
. For production environments, this should be paired with a refresh token mechanism for better security. You can modify this value based on your security requirements.
- User Authentication: Complete signup and login system
- JWT-based Authorization: Secure API endpoints with JSON Web Tokens
- Simple Auth Check: Lightweight endpoint to verify authentication status
- Data Validation: Strong request validation with custom decorators
- Password Security: Bcrypt hashing for secure password storage
- PostgreSQL Integration: Database persistence with Prisma ORM
- Docker Support: Containerized setup for easy deployment and development
- Comprehensive Testing: Jest testing framework with high coverage for reliable code quality
- Backend Framework: NestJS 11
- Language: TypeScript
- Database: PostgreSQL
- ORM: Prisma
- Package Manager: pnpm (with security-enhanced configuration)
- Authentication: JWT (JSON Web Tokens)
- Validation: class-validator & class-transformer
- Password Hashing: bcrypt
- Testing: Jest with comprehensive test coverage
- Containerization: Docker & Docker Compose
You can run this application either directly on your machine or using Docker.
- Docker installed on your machine
- Docker Compose installed on your machine
-
Clone the repository:
git clone https://github.com/codigoisaac/EnterTheNest.git cd EnterTheNest
-
Create environment file:
cp .env.example .env # Edit .env with your configuration if needed
-
Start the application using Docker Compose:
docker-compose up -d
This command starts three containers:
enter-the-nest_api
: The NestJS API running on port 3333enter-the-nest_postgres
: PostgreSQL database running on port 7777enter-the-nest_prismastudio
: Prisma Studio for database management running on port 5555
-
Access the application:
- API: http://localhost:3333
- Prisma Studio: http://localhost:5555
-
To stop the application:
docker-compose down
- Node.js (v18 or higher)
- pnpm (v8 or higher)
- PostgreSQL
-
Clone the repository:
git clone https://github.com/codigoisaac/EnterTheNest.git cd EnterTheNest
-
Install pnpm (if not already installed):
# Using npm npm install -g pnpm # Or using curl (recommended) curl -fsSL https://get.pnpm.io/install.sh | sh - # Or using your package manager (Linux) sudo apt install pnpm
-
Install dependencies and set up environment:
pnpm install cp .env.example .env # Edit .env with your configuration
-
PostgreSQL: Ensure your PostgreSQL server is running. This application requires PostgreSQL to function.
-
Configure your database connection in the
.env
file:DATABASE_URL="postgresql://username:password@localhost:5432/enter-the-nest?schema=public"
-
Apply migrations and generate the Prisma client:
pnpm exec prisma migrate dev pnpm exec prisma generate
# Development
pnpm run start:dev
# Production
pnpm run build
pnpm run start:prod
The API will be available at http://localhost:3333
(or the port specified in your env variables).
Prisma Studio is a visual editor for your database. To run it locally (without Docker):
pnpm exec prisma studio
This will start Prisma Studio at http://localhost:5555. You can use it to view and edit the data in your database with a user-friendly interface.
This project includes comprehensive testing using Jest to ensure code reliability and maintainability.
The testing suite covers all critical components:
- Authentication Service: Tests for user registration, login, and error handling
- Authentication Controller: Tests for endpoint behavior and request/response handling
- Authentication Guard: Tests for JWT token validation and authorization
- Data Transfer Objects (DTOs): Tests for validation rules and custom decorators
- Custom Validators: Tests for the Match decorator functionality
# Run all tests
pnpm test
# Run tests in watch mode (automatically re-runs when files change)
pnpm run test:w
# Run tests with coverage report
pnpm run test:c
# Run tests with verbose output
pnpm run test:v
# Run tests with verbose output and coverage
pnpm run test:vc
The project maintains high test coverage across all modules. Coverage reports are generated in the coverage/
directory when running tests with the coverage flag.
Jest is configured to:
- Use TypeScript with ts-jest transformer
- Support path mapping aliases (
@root/*
and@src/*
) - Exclude build artifacts and node_modules
- Generate coverage reports for all TypeScript files except configuration files
- Use Node.js test environment for backend testing
The Jest configuration can be found in the jest
section of package.json
.
This project includes a complete Docker setup optimized for both development and production environments:
- Main API Container: NestJS application with automatic database migrations on startup
- PostgreSQL Container: Database persistence with volume mapping
- Prisma Studio Container: Minimal web-based database management interface (optimized for resource efficiency)
-
api: The main NestJS application
- Builds from
Dockerfile
- Runs on port 3333 (configurable in .env)
- Automatically runs database migrations on startup
- Uses multi-stage build for production optimization
- Uses non-root user for enhanced security
- Builds from
-
postgres: PostgreSQL database
- Uses official PostgreSQL 16 Alpine image
- Runs on port 7777 (maps to internal 5432)
- Persists data using Docker volumes
-
prisma-studio: Web interface for database management
- Builds from
Dockerfile.prisma-studio
- Runs on port 5555
- Minimal installation (only Prisma dependencies)
- Provides a convenient UI for managing database records
- Builds from
# Start all services
docker-compose up -d
# View logs from all containers
docker-compose logs -f
# View logs from a specific container
docker-compose logs -f api
# Stop all services
docker-compose down
# Rebuild containers (after making changes)
docker-compose up -d --build
# Remove volumes (caution: this deletes all database data)
docker-compose down -v
This project uses pnpm for enhanced performance, security, and disk efficiency:
- Faster installations: ~2x speed improvement over npm
- Disk space efficiency: Shared dependencies across projects
- Enhanced security: Prevents phantom dependencies and blocks untrusted scripts by default
- Better monorepo support: Excellent workspace management
The project includes security-enhanced pnpm configuration in package.json
:
{
"pnpm": {
"onlyBuiltDependencies": [
"@nestjs/core",
"@prisma/client",
"@prisma/engines",
"bcrypt",
"prisma"
]
}
}
This configuration follows pnpm v10+ security best practices by only allowing trusted packages to run build scripts.
# Install dependencies
pnpm install
# Add a new dependency
pnpm add package-name
# Add a dev dependency
pnpm add -D package-name
# Remove a dependency
pnpm remove package-name
# Update dependencies
pnpm update
# Run scripts
pnpm run start:dev
pnpm run build
# Execute packages
pnpm exec prisma studio
pnpm exec nest generate module users
- POST /auth/signup - Register a new user
- POST /auth/login - Authenticate and receive token
- GET /auth/check - Check if current token is valid (protected route)
You can easily create additional protected routes in your application by using the AuthGuard
. Simply apply the @UseGuards(AuthGuard)
decorator to any controller method that should require authentication:
import { Controller, Get, UseGuards } from '@nestjs/common';
import { AuthGuard } from '../auth/auth.guard';
@Controller('items')
export class ItemsController {
// Public route - no authentication required
@Get('public')
getPublicItems() {
return { message: 'This is public data' };
}
// Protected route - requires a valid JWT token
@UseGuards(AuthGuard)
@Get('protected')
getProtectedItems() {
return { message: 'This is protected data' };
}
}
When the AuthGuard
is applied:
- Requests must include a valid JWT token in the Authorization header
- If the token is missing or invalid, the request will be rejected with a 401 Unauthorized error
- If the token is valid, the request proceeds and returns the expected response
You can protect individual routes or apply the guard to an entire controller by placing the decorator at the controller level.
The /auth/check
endpoint is perfect for frontend applications to verify if a user is still authenticated before accessing protected features.
- Minimum 8 characters
- At least 1 uppercase letter, 1 lowercase letter, 1 number, and 1 symbol
- JWT tokens expire after 1 hour by default (set in
auth.module.ts
) - For production, consider implementing a refresh token mechanism for better security
- The API uses global validation pipes to automatically validate incoming requests
- Custom validation decorator (
Match
) is implemented for password confirmation - Docker setup includes optimized containers with minimal attack surfaces
- pnpm configuration ensures secure dependency management and faster builds
- Comprehensive test suite ensures code reliability and facilitates safe refactoring
- Script execution control: Only trusted packages can run build scripts
- Dependency isolation: Prevents phantom dependencies and version conflicts
- Faster CI/CD: Improved build times in continuous integration pipelines
- Multi-stage builds: Minimal production images
- Resource efficiency: Prisma Studio container ~70% smaller than full dependency installation
- Security hardening: Non-root users in all containers
- High test coverage: Comprehensive testing ensures code reliability
- Automated validation: Jest runs validate business logic and data flow
- Continuous integration ready: Tests can be easily integrated into CI/CD pipelines
This project is licensed under the MIT License - see the LICENSE file for details.
The MIT License is a permissive license that allows anyone to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, subject to the condition that the original copyright notice and permission notice be included in all copies or substantial portions of the software.
Isaac Muniz - isaacmuniz.vercel.app