Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 

Repository files navigation

URL Shortener

A full-stack URL shortener: Node/Express/MongoDB backend, React/Tailwind frontend.

Features (this build)

  • JWT auth (register, login, refresh, logout) with hashed passwords and revocable refresh tokens
  • Shorten URLs with custom alias or random code, with collision + duplicate detection
  • Fast redirect endpoint with click logging (IP, user agent, referrer, timestamp)
  • Per-URL analytics: total clicks, unique visitors, daily click chart, recent clicks
  • URL expiration by date or max click count
  • Search/filter/pagination on the URL list
  • Security: Helmet, CORS, rate limiting, Mongo sanitization, XSS cleaning, secure cookies
  • Centralized error handling with custom ApiError class
  • Winston + Morgan logging
  • Jest + Supertest integration tests (in-memory MongoDB)
  • Swagger UI at /api-docs
  • Dockerfiles for client + server, docker-compose for the full stack

Not included yet (roadmap)

Email verification, forgot/reset password, QR codes, bulk CSV shortening, admin panel, geo/device analytics (needs a GeoIP + UA-parsing library), Redis caching, Socket.io real-time analytics, PWA/offline support, webhook/API-key system, PDF/Excel export. Ask and these can be added incrementally on top of this base.

Project structure

server/    Express API (MVC-ish: models, controllers, routes, middleware, validators)
client/    React + Vite + Tailwind frontend
docker-compose.yml

Getting started (local, no Docker)

Backend

cd server
cp .env.example .env   # then edit secrets/URI
npm install
npm run dev             # starts on http://localhost:5000

Frontend

cd client
npm install
npm run dev              # starts on http://localhost:5173, proxies /api to :5000

Tests

cd server
npm test

Getting started (Docker)

cp server/.env.example server/.env   # edit secrets
docker compose up --build

Environment variables (server/.env)

Variable Description
PORT API port (default 5000)
MONGO_URI MongoDB connection string
JWT_ACCESS_SECRET / JWT_REFRESH_SECRET JWT signing secrets — change these
JWT_ACCESS_EXPIRES / JWT_REFRESH_EXPIRES Token lifetimes
CLIENT_URL Frontend origin, used for CORS
BASE_URL Public API base URL, used in Swagger
RATE_LIMIT_WINDOW_MS / RATE_LIMIT_MAX General rate limit config

API endpoints

POST   /api/auth/register
POST   /api/auth/login
POST   /api/auth/refresh
POST   /api/auth/logout

POST   /api/url            (auth required)
GET    /api/url             ?page=&limit=&search=&status=
GET    /api/url/:id
PUT    /api/url/:id
DELETE /api/url/:id
GET    /:shortCode          (public redirect)

GET    /api/analytics/:id   (auth required)

Troubleshooting

  • Mongo connection refused: make sure MongoDB is running and MONGO_URI matches (use mongo as host in docker-compose, localhost when running locally).
  • CORS errors: CLIENT_URL in .env must exactly match the frontend origin, including port.
  • 401 on every request: access tokens expire quickly (15m default); the axios instance in client/src/api/axios.js auto-refreshes using the httpOnly cookie — make sure cookies are enabled and withCredentials: true is set.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages