A server-side URL shortener application built with Node.js, Express, MongoDB, and EJS, focusing on authentication, authorization, and backend correctness rather than frontend frameworks.
The application implements role-based access control (RBAC) with clear separation between NORMAL users and ADMIN users, and follows a traditional server-rendered architecture where both UI and business logic are handled on the backend.
-
User Authentication
- Secure login, signUp and logout
- Session / token-based authentication
- Protected routes
-
Role-Based Authorization (RBAC)
NORMALusers can create and manage their own short URLsADMINusers have elevated access (user management / global visibility)- Centralized authorization middleware
-
URL Shortening System
- Short URL generation
- Redirect handling
- Click tracking (optional if implemented)
- Ownership enforcement per user
-
Server-Rendered UI
- EJS templates
- No client-side framework dependency
- SEO-friendly and low JavaScript footprint
-
Backend Architecture
- Express.js with modular routing
- Mongoose schemas and validations
- Clean separation of concerns (routes, controllers, services, models)
- Centralized error handling
-
Database
- MongoDB for persistence
- Indexed fields for efficient lookups
- Relationship handling between users and URLs
| Layer | Technology |
|---|---|
| Runtime | bun |
| Framework | Express.js |
| Templating | EJS |
| Database | MongoDB |
| ODM | Mongoose |
| Auth | Custom authentication + RBAC |
| Architecture | Server-side rendered MVC |
This project intentionally avoids SPA frameworks to:
- Emphasize backend-first architecture
- Reduce frontend complexity
- Demonstrate control over authentication, authorization, and routing
- Show understanding of classic MVC patterns
- Build a production-style Express application
- Prioritize correctness, clarity, and maintainability
- Simple Simulation of real-world backend patterns
- Basic Implement secure role-based authorization
git clone <repo-url>
cd url-shortener
npm install
npm run devConfigure environment variables:
SERVER_PORT=
ONLINE_MONGO_URI=
NATIVE_URL=
LOCAL_MONGO_URI=
JWT_SECRET_KEY=