The Bazaar User API is a Spring Boot microservice responsible for managing user identities, session authorization, and access control across the Bazaar ecosystem. It handles user lifecycle tasks, authentication (local credentials & Google SSO), profile administration, and security controls such as blocking/unblocking accounts.
- Core Features
- System Architecture
- Technology Stack
- Database Schema
- Environment Configuration
- Getting Started
- API Reference
- Background & Scheduled Jobs
- Robust Authentication:
- Email & Password sign-in/registration with BCrypt hashing.
- Google Identity Provider (SSO) integration (Federated authentication).
- JWT Access/Refresh Token cycle. Login revokes previous sessions on other devices for enhanced security.
- Profile Personalization:
- Edit name, surname, and description.
- Multi-part upload support for profile images integrated directly with Cloudinary.
- Separation of Public Profile (minimal viewable fields) and Private Profile (complete PII data).
- Administration & Security controls:
- Detailed, paginated user registry with name and email filtering.
- Lock/Unlock accounts instantly by flagging user statuses.
- Registration metrics and rates reporting.
- Deep Linking / App Links Support:
- Exposes official Android Digital Asset Links
.well-known/assetlinks.jsonmapping for secure client redirection.
- Exposes official Android Digital Asset Links
- Observability & Health Checks:
- Integrated OpenTelemetry Javaagent for APM tracing & metrics (compatible with Prometheus/Grafana).
- Actuator metrics, and dedicated, lightweight Liveness (
/livez) and Readiness (/readyz) endpoints.
The User API operates in a routed architecture, designed to sit behind an API Gateway:
graph TD
Client([Client / App Mobile]) --> |HTTP Requests| Gateway[API Gateway]
Gateway -->|Forwards with X-User-Id & X-User-Role headers| UserService[User Microservice]
subgraph User Service Internals
UserService --> |Reads/Writes| PostgreSQL[(PostgreSQL Database)]
PasswordResetCleanupScheduler[PasswordResetCleanupScheduler] --> |Purges expired reset records| PostgreSQL
end
UserService -->|Uploads Profile Images| Cloudinary[Cloudinary CDN]
UserService -->|Sends Reset Password Emails| EmailService[SendGrid / SMTP Relay]
UserService -->|HTTP Client| GoogleAPI[Google OAuth2 API]
UserService -->|HTTP Client| CatalogService[Catalog Microservice]
UserService -->|HTTP Client| OrdersService[Orders Microservice]
Note
Spring Security is configured to allow routing for these endpoints, trusting the API Gateway to inject authorization headers such as X-User-Id (authenticated user context) and X-User-Role (authorization roles).
- Framework: Spring Boot 4.0.3, Spring Security, Spring Web, Spring Actuator
- Language: Java 21
- Database: PostgreSQL 15
- Database Migrations: Flyway Database Migration
- Caching: Spring Cache with Caffeine Provider
- Storage Integrations: Cloudinary API (HTTP5 Client) for media hosting
- Notification Services: SendGrid Java SDK & Spring Mail Starter (configured via SMTP-relay)
- Monitoring & Observability: OpenTelemetry JVM Agent, Slf4j, Spring Boot Actuator
- Testing Tools: JUnit 5, Spring WebTestClient, Testcontainers (PostgreSQL container integration)
Database migrations are managed automatically via Flyway scripts (src/main/resources/db/migration):
users: Contains registry data (name,surname,email,password,image_url,description,role,status,account_source).tokens: Stores active hashes of user refresh tokens mapped one-to-one to enforce session rotation.federated_identities: Maps Google provider IDs (provider_subject) to localizeduser_idaccounts.password_reset_tokens&password_reset_attempt: Manages verification tokens for forgot/reset password operations.
To configure the application, create a .env file in the root directory based on the .env.example template:
cp .env.example .env| Variable | Description | Default / Example |
|---|---|---|
| Server Settings | ||
PORT |
Local port of the Spring Boot application | 8080 |
HOST |
Bind address of the service | 0.0.0.0 |
ENVIRONMENT |
Running environment mode (local, production) |
local |
| Database | ||
DATABASE_HOST |
Host address of the PostgreSQL database | database-host |
DATABASE_NAME |
Database name | database-name |
DATABASE_PORT |
Database port | 5432 |
DATABASE_USER |
PostgreSQL user | postgres |
DATABASE_PASSWORD |
PostgreSQL password | your-secure-password |
EXPOSE_PORT |
Docker host-mapped port for PostgreSQL | 9000 |
| JWT Config | ||
JWT_SECRET |
Secret key used to verify/sign authentication tokens | (Keep secure) |
JWT_ISSUER |
String representing the token issuer authority | bazaar-auth |
| Google SSO | ||
GOOGLE_CLIENT_ID |
OAuth2 Google Client ID used by Android/Web | (From Google console) |
GOOGLE_API_URL |
Token validation endpoint | https://oauth2.googleapis.com |
| Cloudinary | ||
CLOUDINARY_CLOUD_NAME |
Cloudinary storage account name | (From Cloudinary console) |
CLOUDINARY_API_KEY |
Cloudinary authorization API key | (From Cloudinary console) |
CLOUDINARY_API_SECRET |
Cloudinary authorization API secret | (From Cloudinary console) |
| Email SMTP | ||
GMAIL_NAME |
Username login for SMTP host (Brevo integration) | your-smtp-username |
GMAIL_KEY |
Password / Key for SMTP host | your-smtp-password |
GMAIL_ADDRESS |
From-address used in transactional emails | noreply@bazaar.com |
SENDERGRID_KEY |
SendGrid client key alternative | your-sendgrid-key |
APP_BASE_URL |
Microservice base routing path (for links generation) | http://localhost:8080 |
APP_SHA256_CERT_FINGERPRINT |
Cert fingerprint for App Links verification | (SHA-256 hex string) |
| Integrations | ||
API_CATALOG_URL |
Microservice endpoint routing for Catalog API | http://localhost:8081 |
API_ORDERS_URL |
Microservice endpoint routing for Orders API | http://localhost:8083 |
| Telemetry (Grafana) | ||
OTEL_SERVICE_NAME |
Service label reported in OpenTelemetry traces | user-service |
OTEL_EXPORTER_OTLP_ENDPOINT |
Collector server endpoint | http://otel-collector:4317 |
- Java Development Kit (JDK) 21
- Maven 3.9+ (or use the provided
mvnwwrapper) - Docker & Docker Compose
To launch the microservice alongside its PostgreSQL dependency, run:
- Create the shared network (if not already existing):
docker network create bazaar-network
- Build and start the containers:
docker-compose up --build
- Stop the environment:
docker-compose down -v
For development, you can spin up the PostgreSQL database in Docker and run the Spring Boot app locally:
- Start PostgreSQL only:
docker-compose up postgres-user -d
- Compile and run the Spring Boot app:
./mvnw spring-boot:run
Run the test suite, which uses Testcontainers for database operations:
./mvnw clean testInteractive API documentation (Swagger UI) is available once the application runs at:
- Swagger UI:
http://localhost:8080/swagger-ui.html
- OpenAPI Definition JSON:
http://localhost:8080/v3/api-docs
Or if you use the service in the cloud, it is available at:
- Swagger UI:
https://api-auth-7tzt.onrender.com/swagger-ui/index.html#/ - OpenAPI Definition JSON:
https://api-auth-7tzt.onrender.com/v3/api-docs
The service runs a background execution scheduler (PasswordResetCleanupScheduler) using Spring's scheduling capabilities.
It wakes up periodically to safely purge expired verification records:
- Deletes stale reset tokens from the
password_reset_tokenstable. - Cleans up password recovery attempts from the
password_reset_attemptlog table. This keeps database indices optimized and prevents bloating from unused metadata.