A simple, production-ready authentication module built with:
- Frontend: React Router + TypeScript + Tailwind CSS + shadcn/ui
- Backend: NestJS + MongoDB (Mongoose) + JWT
- Architecture: Nx Monorepo with integrated tooling
This app lets users sign up, sign in, and access a protected page. It includes input validation, password hashing, JWT authentication, a protected endpoint, basic security hardening, and API docs.
This project uses Nx as a monorepo build system, providing:
- Unified workspace for frontend and backend applications
- Integrated testing with shared configuration
- Code generation and scaffolding tools
- Dependency graph visualization
- Efficient caching for builds and tests
- Parallel execution of tasks across projects
- Sign up with Email, Name (min 3 chars), Password (min 8 chars, 1 letter, 1 number, 1 special char)
- Sign in with Email + Password
- Protected application page with welcome message and logout
- NestJS backend with MongoDB, Mongoose, JWT, password hashing (Node.js native crypto/scrypt)
- One protected endpoint:
GET /api/auth/me
- Basic security: Helmet, global validation pipe, CORS
- API documentation via Swagger at
/api/docs
- Node.js 20+
- MongoDB (local or remote). If local, default used is
mongodb://localhost:27017/authapp
.
Create a .env
file in the repo root (or apps/backend/.env
). See .env.example
.
Required variables:
MONGODB_URI=mongodb://localhost:27017/authapp
JWT_SECRET=change_me_to_a_long_random_string
PORT=3000
npm install
npm run dev
- Frontend: http://localhost:4200
- Backend API: http://localhost:3000/api
- API Docs (Swagger): http://localhost:3000/api/docs
- POST
/api/auth/signup
— body:{ email, name, password }
— returns{ access_token, user }
- POST
/api/auth/signin
— body:{ email, password }
— returns{ access_token, user }
- GET
/api/auth/me
— requiresAuthorization: Bearer <token>
— returns{ userId, email }
Passwords are hashed using Node.js native scrypt (with random salt) and never returned by the API.
Routes:
/signin
(index) — Sign in form with validation/signup
— Sign up form with validation/app
— Protected page that shows "Welcome to the application." and a Logout button
A JWT token is stored in localStorage
on successful auth. The /app
page verifies the token by calling the protected GET /api/auth/me
endpoint and redirects to /signin
if unauthorized.
- Helmet enabled for basic HTTP headers security
- Global validation pipe with whitelist+transform
- CORS enabled for
http://localhost:4200
(adjust inapps/backend/src/main.ts
for production) - Keep
JWT_SECRET
long and random; rotate regularly in production - Use TLS/HTTPS and secure cookie storage for tokens in real production systems
This is an Nx monorepo with the following structure:
apps/frontend
— React Router app with Viteapps/backend
— NestJS app (Mongoose, Auth, Users)apps/frontend-e2e
— Cypress E2E tests for frontendapps/backend-e2e
— Jest E2E tests for backend API
Nx provides powerful commands for managing the monorepo:
# Run specific project
npx nx serve @auth-app/backend
npx nx serve @auth-app/frontend
# Run targets across all projects
npx nx run-many --target=build --all
npx nx run-many --target=test --all
npx nx run-many --target=lint --all
# View dependency graph
npx nx graph
npm run dev
— Run frontend and backend together (Nx run-many)npm start
— Start backend onlynpm test
— Run all unit testsnpm run test:e2e
— Run E2E testsnpm run test:coverage
— Run tests with coverage report
Run unit tests for the AuthService:
npx nx test @auth-app/backend
With coverage:
npx nx test @auth-app/backend --coverage
Run end-to-end tests for authentication flows:
# Start the backend first
npm start
# In another terminal, run E2E tests
npx nx e2e @auth-app/backend-e2e
The E2E tests cover:
- User signup with validation
- User signin with various scenarios
- Protected endpoint access
- Complete authentication flow
- Security tests
GitHub Actions workflow automatically runs on push/PR:
- Linting
- Unit tests with coverage
- Build verification
- E2E tests with MongoDB service
- Start MongoDB locally (or set MONGODB_URI to remote)
npm run dev
- Open http://localhost:4200
- Go to Sign Up, create a user
- You should be redirected to the app page and see the protected content
- Logout and try Sign In with the same credentials
- ✅ Logging via Nest Logger (startup) and structured module separation
- ✅ Swagger API docs at
/api/docs
- ✅ Unit tests for AuthService
- ✅ E2E tests for authentication flows
- ✅ GitHub Actions CI/CD pipeline
- ✅ Error handling throughout the application
MIT