A secure, temporary note-sharing backend service built with Spring Boot. Create encrypted notes with expiration times and share them via unique URL codes.
- Temporary Notes: Create notes with customizable expiration times (1-730 hours)
- Secure Storage: AES encryption for note content
- HTML Sanitization: Protection against XSS attacks using JSoup
- Rate Limiting: Request throttling using Bucket4j
- Auto Cleanup: Scheduled task to automatically delete expired notes
- RESTful API: Clean REST endpoints for note management
- PostgreSQL Database: Persistent storage with JPA/Hibernate
- Cloud-Ready: Google Cloud SQL support for seamless cloud deployment
- Docker Support: Containerized deployment with included Dockerfile
- Java 21
- Spring Boot 3.5.6
- Spring Data JPA
- PostgreSQL
- Lombok
- Bucket4j 8.0.1 (Rate Limiting)
- JSoup 1.21.2 (HTML Sanitization)
- Google Cloud SQL Connector (Cloud deployment support)
- Maven
- Docker (Containerization)
- Java 21 or higher
- PostgreSQL 12+
- Maven 3.6+
- Docker (optional, for containerized deployment)
Create a PostgreSQL database:
CREATE DATABASE notesdb;Set the required environment variables:
# Windows (PowerShell)
$env:NOTE_SECRET_KEY="your-16-character-secret-key-here"
$env:APP_BASE_URL="http://localhost:8080"
$env:POSTGRESQL_URL="jdbc:postgresql://localhost:5432/notesdb"
$env:POSTGRESQL_USER="your_username"
$env:POSTGRESQL_PASSWORD="your_password"
# Linux/macOS
export NOTE_SECRET_KEY="your-16-character-secret-key-here"
export APP_BASE_URL="http://localhost:8080"
export POSTGRESQL_URL="jdbc:postgresql://localhost:5432/notesdb"
export POSTGRESQL_USER="your_username"
export POSTGRESQL_PASSWORD="your_password"Important: The application uses environment variables for sensitive configuration. Never commit credentials to version control.
./mvnw clean install./mvnw spring-boot:runThe application will start on http://localhost:8080
POST /api/notes
Content-Type: application/json
{
"content": "Your note content here",
"durationInHours": 24
}Response:
{
"urlCode": "aBcD1234",
"expiresAt": "2025-10-19T00:18:00"
}GET /api/notes/{urlCode}Response:
{
"urlCode": "aBcD1234",
"content": "Your note content here",
"expiresAt": "2025-10-19T00:18:00",
"createdAt": "2025-10-18T00:18:00",
"updatedAt": "2025-10-18T00:18:00"
}PUT /api/notes/{urlCode}
Content-Type: application/json
{
"content": "Updated note content"
}Response:
{
"urlCode": "aBcD1234",
"content": "Updated note content",
"expiresAt": "2025-10-19T00:18:00",
"createdAt": "2025-10-18T00:18:00",
"updatedAt": "2025-10-18T00:30:00"
}All note content is encrypted using AES encryption before storage and decrypted when retrieved.
User input is sanitized using JSoup to prevent XSS attacks and malicious HTML injection.
API endpoints are protected with rate limiting to prevent abuse.
The application is configured via environment variables for security. Key settings in application.properties:
# Server Configuration
server.port=8080
# Secret Key for AES Encryption
note.secret.key=${NOTE_SECRET_KEY}
# Base URL
app.base-url=${APP_BASE_URL}
# PostgreSQL Database Configuration
spring.datasource.url=${POSTGRESQL_URL}
spring.datasource.username=${POSTGRESQL_USER}
spring.datasource.password=${POSTGRESQL_PASSWORD}
# JPA Configuration
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
# Connection Pool (HikariCP)
spring.datasource.hikari.maximum-pool-size=10
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.idle-timeout=300000
# Logging
logging.level.com.note=DEBUGThe application includes a scheduled task that runs every 15 minutes to automatically delete expired notes, ensuring the database remains clean and efficient.
Notes Table:
id(Primary Key, Auto-increment)url_code(Unique, 8-character code)content(Encrypted text)expires_at(Expiration timestamp)created_at(Creation timestamp)updated_at(Last update timestamp)
src/
βββ main/
β βββ java/com/note/
β β βββ configuration/ # Rate limiting & CORS config
β β βββ controller/ # REST controllers
β β βββ dto/ # Data Transfer Objects
β β βββ entity/ # JPA entities
β β βββ exception/ # Custom exceptions
β β βββ mapper/ # Entity-DTO mappers
β β βββ repository/ # JPA repositories
β β βββ service/ # Business logic
β β βββ util/ # Utility classes (AES, HTML sanitization)
β βββ resources/
β βββ application.properties
βββ test/
The project includes a Dockerfile for containerized deployment.
docker build -t note-api .docker run -p 8080:8080 \
-e NOTE_SECRET_KEY="your-16-character-secret-key-here" \
-e APP_BASE_URL="http://localhost:8080" \
-e POSTGRESQL_URL="jdbc:postgresql://host.docker.internal:5432/notesdb" \
-e POSTGRESQL_USER="your_username" \
-e POSTGRESQL_PASSWORD="your_password" \
note-apiCreate a docker-compose.yml for running the application with PostgreSQL:
version: '3.8'
services:
db:
image: postgres:15
environment:
POSTGRES_DB: notesdb
POSTGRES_USER: your_username
POSTGRES_PASSWORD: your_password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
app:
build: .
ports:
- "8080:8080"
environment:
NOTE_SECRET_KEY: "your-16-character-secret-key-here"
APP_BASE_URL: "http://localhost:8080"
POSTGRESQL_URL: "jdbc:postgresql://db:5432/notesdb"
POSTGRESQL_USER: "your_username"
POSTGRESQL_PASSWORD: "your_password"
depends_on:
- db
volumes:
postgres_data:Run with: docker-compose up
Run tests with:
./mvnw test- Content: Cannot be blank
- Duration: Must be between 1 and 730 hours (1 hour to 30 days)
The API provides descriptive error messages for common scenarios:
404 Not Found: Note does not exist410 Gone: Note has expired400 Bad Request: Invalid input or validation errors
The application includes support for Google Cloud SQL via the postgres-socket-factory dependency. This enables seamless deployment to Google Cloud Platform with Cloud SQL PostgreSQL instances.
For Google Cloud deployment, configure the POSTGRESQL_URL environment variable with the Cloud SQL connection string:
jdbc:postgresql:///<database>?cloudSqlInstance=<instance-connection-name>&socketFactory=com.google.cloud.sql.postgres.SocketFactoryThis is the backend API. A frontend application can be built to consume these endpoints.
- Encryption Key: Always use a strong, randomly generated 16-character key for
NOTE_SECRET_KEY - Environment Variables: Never commit sensitive credentials to version control
- Production: Use a secrets management system (e.g., AWS Secrets Manager, Azure Key Vault, Google Secret Manager)
- HTTPS: Always use HTTPS in production environments
- Database: Ensure PostgreSQL is configured with strong authentication and network security
Built with Spring Boot 3.5.6 and Java 21