A production-ready authentication system built from scratch, demonstrating how Authentication actually works under the hood.
Goal: This project implements secure authentication (JWT, Password Hashing, Validation) without using any external authentication libraries like Passport.js, Auth.js, or class-validator. It helps you understand the core principles of security.
This project is a Monorepo containing:
- Frontend (
/frontend): A modern Next.js application where users sign up, log in, and view their profile. - Backend (
/backend): A NestJS API that handles strict validation, security, and database operations. - Database: A PostgreSQL database storing users and refresh tokens.
All of these run together seamlessly using Docker.
- Zero External Auth Libraries: Every security logic (Hashing, Tokens) is written manually for learning.
- Security Best Practices:
- PBKDF2 Password Hashing (using Node.js
crypto). - JWT Implementation: Manual creation and verification of Access & Refresh tokens.
- Secure Cookies: Tokens are stored in HTTP-Only, Secure, SameSite cookies (not LocalStorage).
- PBKDF2 Password Hashing (using Node.js
- Strict Validation: Custom validation pipes for Email, Password Strength, and Input Sanitization.
- Token Rotation: Secure refresh token mechanism with 7-day expiry and automatic rotation.
- Testing: Comprehensive table-driven unit tests for backend logic.
- Framework: NestJS (Node.js)
- Language: TypeScript
- Database Access: Raw SQL (using
pglibrary) - No ORM, just pure SQL. - Testing: Jest (Unit & Table-driven tests)
- Framework: Next.js 14 (App Router)
- Styling: Tailwind CSS
- Language: TypeScript
- Docker: Containerization for all services.
- PostgreSQL: Relational database.
Before you start, make sure you have the following installed:
- Docker Desktop (Essential for running the database and app easily).
- (Optional) Node.js v18+ (If you want to run the app locally without Docker).
The easiest way to run the entire system is with Docker.
-
Clone the project
git clone <repo-url> cd assignment
-
Setup Environment Variables Copy the example environment file:
cp .env.example .env
You can leave the default values for local development.
-
Start the Application Run the following command to build and start everything:
docker-compose up --build
-
Access the App
- Frontend: http://localhost:3000
- Backend API: http://localhost:3001
Understanding the codebase layout:
📦 assignment
┣ 📂 backend # NestJS API
┃ ┣ 📂 src
┃ ┃ ┣ 📂 auth # Auth module (Controller, Service, Guards)
┃ ┃ │ ┣ 📂 pipes # Custom Validation Pipes (No Class-Validator!)
┃ ┃ │ ┗ 📂 dto # Data Transfer Objects
┃ ┃ ┣ 📂 common # Shared Services (Crypto, Validation)
┃ ┃ ┗ 📂 database # Raw SQL Database Connection
┃ ┗ 📂 test # End-to-End Tests
┃
┣ 📂 frontend # Next.js App
┃ ┣ 📂 src
┃ ┃ ┣ 📂 app # App Router Pages
┃ ┃ ┗ 📂 components # UI Components
┃
┗ 📜 docker-compose.yml # Orchestration configThe Backend runs on port 3001 and provides these REST endpoints:
| Method | Endpoint | Description | Body |
|---|---|---|---|
POST |
/auth/signup |
Register a new user | { email, password, name } |
POST |
/auth/signin |
Log in and receive cookies | { email, password } |
POST |
/auth/refresh |
Get new Access Token | (Uses Refresh Token Cookie) |
POST |
/auth/logout |
Clear all sessions | - |
GET |
/auth/me |
Get Profile (Protected) | - |
We have written strict unit tests to ensure our custom validation and security logic works correctly.
-
Navigate to the backend folder:
cd backend -
Install dependencies (if running locally):
npm install
-
Run the tests:
npm testYou should see 35 passing tests covering all validation scenarios.
The .env file controls important configurations.
| Variable | Default | Description |
|---|---|---|
DB_HOST |
postgres |
Hostname for the database (use localhost if running locally without docker-compose network) |
DB_USER |
postgres |
Database username |
DB_PASSWORD |
postgres |
Database password |
JWT_SECRET |
secret |
Secret key for signing Access Tokens |
REFRESH_TOKEN_SECRET |
refresh_secret |
Secret key for signing Refresh Tokens |
This project is for educational purposes. Feel free to use it to learn how Authentication works!