Skip to content

Latest commit

ย 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿ” SFTG โ€” Secure File Transfer Gateway

A production-grade, full-stack secure file sharing platform built with Java Spring Boot and React. Designed with Fintech-level security standards including JWT authentication, token blacklisting, virus scanning, audit logging, and expiring share links.

Swagger UI: https://sftg-backend.onrender.com/swagger-ui/index.html


๐Ÿ“‹ Table of Contents


โœจ Features

Security

  • ๐Ÿ” JWT Authentication with DB-backed token blacklisting (survives server restarts)
  • ๐Ÿ“ง Email OTP Verification via Brevo API before account activation
  • ๐Ÿ”’ BCrypt Password Hashing with secure salting
  • ๐Ÿ›ก๏ธ Rate Limiting on public endpoints using Bucket4j token bucket algorithm
  • ๐Ÿฆ  Virus Scanning โ€” ClamAV (local Docker) / VirusTotal API (cloud)
  • ๐Ÿ” MIME Type Detection via Apache Tika (content-based, not extension-based)
  • ๐Ÿšซ Executable File Blocking โ€” rejects .exe, .sh, .bat uploads
  • ๐Ÿ›ก๏ธ Path Traversal Protection on all file operations

File Management

  • ๐Ÿ“ Secure File Upload with size validation (max 100MB)
  • โณ Auto File Expiry โ€” files automatically deleted after 1 hour
  • ๐Ÿ—‘๏ธ Scheduled Cleanup โ€” removes expired files and all associated data every 5 minutes
  • โ˜๏ธ Cloud Storage via Cloudinary โ€” stateless, no local disk dependency

Sharing

  • ๐Ÿ”— Expiring Share Links โ€” UUID tokens, expire in 1 hour
  • ๐Ÿ“Š Download Limits โ€” maximum 5 downloads per share link
  • ๐Ÿ“‹ Download Audit โ€” tracks who downloaded, when, from which IP
  • ๐Ÿ“ฑ QR Code Generation for share links

Monitoring & Audit

  • ๐Ÿ“Š Fintech-Style Audit Log โ€” every action logged with IP address and User-Agent
  • ๐Ÿ“ˆ Global Statistics โ€” total users, uploads, downloads
  • ๐Ÿ‘ค User Profile Dashboard โ€” complete activity history
  • ๐Ÿ”„ Keep-Alive Scheduler โ€” prevents cloud cold starts

๐Ÿ›  Tech Stack

Backend

Technology Version Purpose
Java 21 Core language
Spring Boot 3.4.11 Application framework
Spring Security 6.4.x Authentication & authorization
JJWT 0.11.5 JWT token generation & validation
Hibernate / JPA 6.6.x Database ORM
MySQL 8.0 Primary database
Bucket4j 8.15.0 Rate limiting
Apache Tika 2.8.0 MIME type detection
Cloudinary SDK 1.37.0 Cloud file storage
OkHttp 4.9.3 Brevo email API client
SpringDoc OpenAPI 2.8.5 Swagger documentation
Maven 3.x Build & dependency management

Frontend

Technology Version Purpose
React 19 UI framework
Vite 8.x Build tool
Material UI (MUI) 7.x Component library
React Router DOM 7.x Client-side routing
Axios 1.x HTTP client with interceptors
Tailwind CSS 4.x Utility CSS
qrcode.react 4.x QR code generation

Infrastructure

Service Purpose
Render Backend hosting (Docker)
Railway Frontend hosting (Docker) + MySQL database + ClamAV
Cloudinary Cloud file storage
Docker Hub Container image registry
UptimeRobot Keep-alive monitoring
Brevo Transactional email (OTP)

๐Ÿ— Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                    CLIENT (Browser)                      โ”‚
โ”‚              React + MUI + Vite (Railway)                โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚ HTTPS
                           โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                   SPRING BOOT API                        โ”‚
โ”‚                   (Render - Docker)                      โ”‚
โ”‚                                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”‚
โ”‚  โ”‚  Security   โ”‚  โ”‚  Controllers  โ”‚  โ”‚   Schedulers  โ”‚  โ”‚
โ”‚  โ”‚  JWT Filter โ”‚  โ”‚  Auth/File/  โ”‚  โ”‚  Cleanup      โ”‚  โ”‚
โ”‚  โ”‚  Rate Limit โ”‚  โ”‚  Share/Stats โ”‚  โ”‚  KeepAlive    โ”‚  โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ”‚
โ”‚                           โ”‚                              โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚                   Services                        โ”‚   โ”‚
โ”‚  โ”‚  FileService โ”‚ AuthService โ”‚ FileShareService     โ”‚   โ”‚
โ”‚  โ”‚  VirusTotal  โ”‚ Cloudinary  โ”‚ TokenBlacklist       โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                           โ”‚                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                           โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ–ผ                โ–ผ                โ–ผ
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚   MySQL DB  โ”‚  โ”‚Cloudinary โ”‚  โ”‚  VirusTotal  โ”‚
   โ”‚  (Railway)  โ”‚  โ”‚  Storage  โ”‚  โ”‚     API      โ”‚
   โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Layered Architecture

Controller Layer   โ†’  Handles HTTP, validates input, returns responses
Service Layer      โ†’  Business logic, orchestration
Repository Layer   โ†’  Database operations via JPA
Security Layer     โ†’  JWT filter, rate limiting, CORS

๐Ÿ” Security Design

Authentication Flow

Register โ†’ OTP Email โ†’ Verify โ†’ Login โ†’ JWT Token โ†’ Authenticated Requests

Token Blacklisting โ€” Why DB-Backed?

Most tutorials use in-memory maps for token blacklisting. This project uses database storage because:

In-memory approach problem:
  Server restarts โ†’ blacklisted tokens become valid again
  Attacker with stolen token just waits for deployment

DB-backed solution:
  Token stored in blacklisted_tokens table on logout
  Every request: SELECT exists WHERE token = ?
  Index on token column โ†’ O(log n) lookup
  Hourly scheduler: DELETE WHERE expires_at < NOW()
  Tokens remain blacklisted across restarts

Security Layers

1. BCrypt (cost factor 10)      โ€” password hashing
2. Email OTP verification        โ€” prevents fake registrations
3. JWT (HS256, 2hr expiry)      โ€” stateless authentication
4. Token blacklist (DB-backed)   โ€” logout invalidation
5. Rate limiting (Bucket4j)      โ€” 5 req/min on share endpoints
6. MIME type detection (Tika)    โ€” content-based file validation
7. Executable blocking           โ€” rejects dangerous file types
8. Path traversal protection     โ€” filename sanitization
9. Virus scanning (VirusTotal)   โ€” malware detection
10. Ownership verification        โ€” users only access their own files
11. CORS configuration           โ€” locked to specific frontend origin

๐Ÿ“ก API Endpoints

Authentication (Public)

POST   /api/auth/register       Register with email + password
POST   /api/auth/verify-otp     Verify 6-digit OTP
POST   /api/auth/login          Login, returns JWT token
POST   /api/auth/logout         Blacklist current token (auth required)

Account (JWT Required)

GET    /api/account/me          Profile + full audit log

Files (JWT Required)

POST   /api/files/upload               Upload file (multipart/form-data)
GET    /api/files/download/{filename}  Download own file
GET    /api/files/my-files             List all uploaded files with details

Sharing

POST   /api/share/generate      Generate share link (JWT required)
GET    /api/share/download/{token}  Download via share link (public)

Statistics (JWT Required)

GET    /api/stats/global        Total users, uploads, downloads
GET    /api/stats/health        Health check endpoint

Documentation

GET    /swagger-ui/index.html   Interactive API documentation
GET    /v3/api-docs             OpenAPI JSON specification

๐Ÿ—„ Database Schema

users                    โ€” credentials, OTP, timestamps
user_roles               โ€” role assignments (ROLE_USER, ROLE_ADMIN)
files                    โ€” metadata, Cloudinary URL, expiry
shared_links             โ€” tokens, download limits, expiry
download_logs            โ€” who downloaded, when, IP address
user_activity_logs       โ€” full audit trail (LOGIN, LOGOUT, UPLOAD, DOWNLOAD)
blacklisted_tokens       โ€” DB-backed JWT blacklist with cleanup

๐Ÿš€ Getting Started

Prerequisites

Java 21+
Maven 3.x
Node.js 20+
Docker + Docker Compose

Option A โ€” Local Development (Recommended)

1. Clone the repository

git clone https://github.com/anupkumar9705/SFTG.git
cd SFTG

2. Start dependencies (MySQL + ClamAV)

docker-compose up mysql_db clamav_service

3. Configure backend

Create src/main/resources/application-dev.properties:

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/SFTG?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
spring.datasource.username=your_mysql_user
spring.datasource.password=your_mysql_password

jwt.secret=your_64_byte_base64_secret
jwt.expirationMs=7200000

clamav.host=127.0.0.1
clamav.port=3310

spring.mail.host=smtp-relay.brevo.com
spring.mail.port=587
spring.mail.username=your_brevo_smtp_user
spring.mail.password=your_brevo_smtp_password

brevo.api.key=your_brevo_api_key

cloudinary.cloud_name=your_cloud_name
cloudinary.api_key=your_cloudinary_api_key
cloudinary.api_secret=your_cloudinary_api_secret

virustotal.api.key=your_virustotal_api_key

cors.allowed-origin=http://localhost:5173

4. Start backend

cd app/backendJava/SFTG-backend
mvn spring-boot:run

5. Start frontend

cd app/backendJava/SFTG-frontend
npm install
npm run dev

Access:

Option B โ€” Full Docker

docker-compose up --build

โš™๏ธ Environment Variables

Backend

Variable Description Example
SPRING_PROFILES_ACTIVE Active profile dev
DB_URL JDBC MySQL URL jdbc:mysql://host:port/SFTG?...
DB_USERNAME Database username root
DB_PASSWORD Database password strongpassword
JWT_SECRET 64-byte base64 secret openssl rand -base64 64
JWT_EXPIRATION_MS Token expiry in ms 7200000
CLAMAV_HOST ClamAV hostname 127.0.0.1
CLAMAV_PORT ClamAV port 3310
MAIL_HOST SMTP host smtp-relay.brevo.com
MAIL_PORT SMTP port 587
MAIL_USERNAME SMTP username brevo_user
MAIL_PASSWORD SMTP password brevo_smtp_key
BREVO_API_KEY Brevo REST API key xkeysib-...
CLOUDINARY_CLOUD_NAME Cloudinary cloud name myapp
CLOUDINARY_API_KEY Cloudinary API key 123456789
CLOUDINARY_API_SECRET Cloudinary secret abcdef...
VIRUSTOTAL_API_KEY VirusTotal API key abc123...
CORS_ALLOWED_ORIGIN Frontend URL https://myapp.railway.app
APP_BASE_URL Backend URL (keep-alive) https://myapi.onrender.com

Frontend (Build-time)

Variable Description Example
VITE_API_URL Backend API base URL https://sftg-backend.onrender.com/api

๐Ÿณ Docker Deployment

Build Images

# Backend
docker build -t yourusername/sftg-backend:latest \
  ./app/backendJava/SFTG-backend

# Frontend
docker build \
  --build-arg VITE_API_URL=https://your-backend.onrender.com/api \
  -t yourusername/sftg-frontend:latest \
  ./app/backendJava/SFTG-frontend

Push to Docker Hub

docker push yourusername/sftg-backend:latest
docker push yourusername/sftg-frontend:latest

Local Full Stack

docker-compose up --build

โ˜๏ธ Cloud Deployment

Current Setup

Service Platform Notes
Backend Render (free) Cold start ~90s, keep-alive via UptimeRobot
Frontend Railway (free) Always warm, instant load
Database Railway MySQL 1GB free monthly
File Storage Cloudinary 25GB free tier
Email Brevo 300 emails/day free
Virus Scan VirusTotal 500 requests/day free
Monitoring UptimeRobot 5-minute pings

Deploy Backend (Render)

  1. Create Web Service โ†’ Deploy existing Docker image
  2. Image: docker.io/yourusername/sftg-backend:latest
  3. Port: 8000
  4. Add all environment variables
  5. Deploy

Deploy Frontend (Railway)

  1. Add Service โ†’ Docker Image
  2. Image: docker.io/yourusername/sftg-frontend:latest
  3. Networking โ†’ Generate Domain
  4. Port: 80

๐Ÿ“ Project Structure

SFTG/
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ backendJava/
โ”‚   โ”‚   โ”œโ”€โ”€ SFTG-backend/
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ src/main/java/com/securetransfer/SFTG/
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ config/          # CORS, Cloudinary, AppConfig
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ controller/      # Auth, File, Share, Account, Stats
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ dto/             # Request/Response objects
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ exception/       # Custom exceptions + global handler
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ model/           # JPA entities
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ repository/      # JPA repositories
โ”‚   โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ security/        # JWT filter, SecurityConfig, rate limiting
โ”‚   โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ service/         # Business logic layer
โ”‚   โ”‚   โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ”‚   โ”‚   โ””โ”€โ”€ pom.xml
โ”‚   โ”‚   โ”‚
โ”‚   โ”‚   โ””โ”€โ”€ SFTG-frontend/
โ”‚   โ”‚       โ”œโ”€โ”€ src/
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ api/             # Axios instance with interceptors
โ”‚   โ”‚       โ”‚   โ”œโ”€โ”€ components/      # Navbar, Layout, ProtectedRoute
โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ pages/           # Login, Register, Dashboard, Upload, etc.
โ”‚   โ”‚       โ”œโ”€โ”€ public/
โ”‚   โ”‚       โ”‚   โ””โ”€โ”€ _redirects       # Netlify/Railway React Router support
โ”‚   โ”‚       โ”œโ”€โ”€ nginx.conf
โ”‚   โ”‚       โ””โ”€โ”€ Dockerfile
โ”‚   โ”‚
โ”œโ”€โ”€ docker-compose.yml
โ””โ”€โ”€ README.md

๐Ÿง  Key Engineering Decisions

1. DB-Backed Token Blacklist

In-memory blacklists reset on server restart, making logged-out tokens valid again. Using MySQL with an index on the token column gives fast lookups with restart-proof persistence. A scheduled job cleans expired tokens hourly to keep the table small.

2. Non-Blocking Virus Scanner

ClamAV and VirusTotal are treated as non-blocking services. ConnectException and timeouts allow the upload to proceed with a warning log rather than failing the user request. Only a confirmed MALICIOUS result blocks the upload. This matches how production systems handle optional security services that may be temporarily unavailable.

3. Cascade Delete Order

Deleting a file requires deleting in FK-constrained order: download_logs โ†’ shared_links โ†’ files. The scheduler handles this explicitly in a @Transactional method rather than relying on JPA cascade, giving explicit control over the deletion sequence.

4. DTO Pattern Throughout

No JPA entity is ever returned directly from a controller. DTOs decouple the persistence layer from the API layer, prevent accidental data leaks, and allow the database schema to evolve without breaking API consumers.

5. MIME Detection Over Extension Checking

File extensions are trivially spoofed (malware.exe renamed to document.pdf). Apache Tika reads the actual file bytes to determine the real content type, making extension-based attacks ineffective.


๐Ÿ”ฎ Future Improvements

  • Refresh token strategy (15-min access + 7-day refresh)
  • Unit and integration tests (JUnit 5 + Mockito)
  • API versioning (/api/v1/)
  • File encryption at rest
  • Redis for token blacklist (faster than MySQL)
  • CI/CD pipeline (GitHub Actions)
  • Admin dashboard for user management
  • Configurable file expiry per upload

๐Ÿ‘จโ€๐Ÿ’ป Author

Anup Kumar Sharma
Computer Science Engineering Graduate, 2025
Backend Developer โ€” Security-Focused Engineering


๐Ÿ“„ License

This project is developed for educational and portfolio demonstration purposes.


Built with production-grade security patterns for Fintech readiness
Spring Boot ยท React ยท Docker ยท JWT ยท ClamAV ยท Cloudinary ยท VirusTotal

About

Production-grade secure file transfer system built with Java Spring Boot. JWT authentication with DB-backed token blacklisting, calmav scanning, expiring share links, Fintech-style audit logging, and full Docker deployment.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages