A production‑ready URL shortening platform built with Spring Boot 3, Spring Security (JWT), PostgreSQL, and OpenAPI/Swagger. The system supports user management, subscriptions for custom path prefixes, URL shortening, redirect handling, and detailed usage statistics.
-
Authentication & Authorization
- JWT-based authentication
- Role-based access control (USER, ADMIN)
- Secure password hashing (BCrypt)
- Access restrictions enforced at controller and service layers
-
User Management
- Registration and login
- Fetch user by ID or email
- Update user roles (ADMIN only)
- Delete user (self-delete or ADMIN)
- Extensive unit tests for service logic
-
URL Shortening
- Create short URLs with or without a prefix
- SHA-256 based suffix generation
- Reuse existing URL bindings when possible
- Reset redirect counter
- Delete URL bindings
- Redirect endpoint (hidden from Swagger)
-
Subscriptions
- Users can purchase subscriptions for custom prefixes
- Expired subscriptions can be reassigned
- Active subscriptions are exclusive
- Admin-controlled payment processing
- Subscription expiration logic
-
Statistics
- Total redirect count per user
- Redirect count per URL binding
- Top 10 most used URLs (ADMIN only)
-
URL Validation
- URL format validation
- UID format validation
- Safe redirect validation (blocks localhost, private networks)
-
API Documentation
- Fully documented with OpenAPI 3
- Swagger UI: http://localhost:8080/swagger-ui.html
- Redirect controller is hidden from Swagger
src/main/java/com/telran/org/urlshortener │ ├── controller # REST controllers ├── dto # Data transfer objects ├── entity # JPA entities ├── exception # Custom exceptions ├── mapper # DTO <-> Entity converters ├── model # Enums (RoleType, StatusState) ├── repository # Spring Data JPA repositories ├── security # JWT, filters, UserDetailsService ├── service # Business logic └── utility # Helpers (URL validation, masking)
TABLE: users
- id (BIGINT PK)
- email (TEXT, unique)
- password (TEXT, BCrypt hash)
- role (TEXT: USER / ADMIN)
TABLE: subscriptions
- id (BIGINT PK)
- path_prefix (TEXT)
- creation_date (DATE)
- expiration_date (DATE)
- status (TEXT: PAID / UNPAID)
- user_id (BIGINT FK)
TABLE: url_bindings
- id (BIGINT PK)
- uid (TEXT)
- original_url (TEXT)
- count (BIGINT)
- user_id (BIGINT FK)
Prerequisites:
- Java 21+
- Maven 3.9+
- PostgreSQL 14+
-
Clone the repository: git clone https://github.com/your-repo/url-shortener.git cd url-shortener
-
Configure environment variables: export DB_PASSWORD=postgres
-
Create database: createdb urlshortener
-
Run the application: mvn spring-boot:run
Login: POST /users/login
Response: { "token": "jwt-token-here" }
Use in protected endpoints: Authorization: Bearer
USERS: POST /users (public) Register POST /users/login (public) Login GET /users (admin) List all users GET /users/{id} (admin) Get user by ID GET /users/by-email (user/admin) Get user by email PATCH /users/{id}/role (admin) Update role DELETE /users/{id} (user/admin) Delete user
SUBSCRIPTIONS: POST /subscriptions (user) Create subscription GET /subscriptions/by-user/{id} (user/admin) List subscriptions GET /subscriptions/{id} (user/admin) Get subscription DELETE /subscriptions/{id} (user) Delete subscription POST /subscriptions/{id}/pay (admin) Process payment
URL BINDINGS: POST /url_bindings (user) Create short URL GET /url_bindings/by-user/{id} (user/admin) List bindings GET /url_bindings?uId=... (user/admin) Get binding PATCH /url_bindings/{id}/reset (user) Reset counter DELETE /url_bindings/{id} (user) Delete binding
REDIRECT (hidden from Swagger): GET /{shortPath}
Unit tests included for:
- UserServiceImplTest
- UrlBindingServiceImplTest
- SubscriptionServiceImplTest
- StatisticsServiceImplTest
- UrlValidationServiceTest
- JwtServiceTest
- JwtAuthenticationFilterTest (MockMvc)
Run tests: mvn test
- Java 21
- Spring Boot 3.3
- Spring Security (JWT)
- Spring Data JPA
- PostgreSQL
- Lombok
- Springdoc OpenAPI 3
- JUnit 5 / Mockito
This project is licensed under the MIT License.
Aleksandrs Lapickis URL Shortener Project 2025-2026