Detect and redact sensitive data in log files — instantly.
LogShield is a full-stack portfolio project that accepts .log and .txt uploads, scans them for credentials and PII, returns a redacted copy, and persists a searchable scan history.
Feature
Detail
Detection
Emails · IPv4 addresses · JWT tokens · API keys · Credit card numbers
Redaction
Placeholder substitution per category ([REDACTED_EMAIL], etc.)
Severity scoring
Category-weighted 0–100 score, bands: LOW / MEDIUM / HIGH / CRITICAL
Scan history
Persisted in PostgreSQL, searchable by filename, severity, and date
Redacted download
One-click download of the sanitised file
Copy to clipboard
Copy redacted output directly from the preview
Dark UI
Next.js 16 · TailwindCSS v4 · fully responsive
Docker
Single docker compose up starts the entire stack
┌─────────────────┐ HTTP / JSON ┌─────────────────────┐
│ Next.js 16 │ ───────────────────────── │ Spring Boot 4 │
│ (port 3000) │ POST /api/scans │ (port 8080) │
│ │ GET /api/scans │ │
│ App Router │ GET /api/scans/:id │ Detection Engine │
│ TailwindCSS v4 │ GET /api/scans/:id/ │ Redaction Service │
│ TypeScript │ download │ Severity Scorer │
└─────────────────┘ └──────────┬──────────┘
│ JPA / Hibernate
┌──────────┴───────────┐
│ PostgreSQL 16 │
│ scan_job │
│ scan_finding │
└──────────────────────┘
com.logshield.backend/
├── config/ CorsConfig (env-driven allowed origins)
├── controller/ REST endpoints (ScanController)
├── filter/ RateLimitFilter (20 uploads/min per IP)
├── service/ Business logic (ScanService + impl)
├── scanner/ Detection engine, rules, redactor, scorer
│ └── rules/ EmailRule, IpAddressRule, JwtTokenRule, ApiKeyRule, CreditCardRule
├── entity/ JPA entities (ScanJob, ScanFinding)
├── dto/ Request/response records
├── repository/ Spring Data interfaces
├── validation/ FileValidator
└── exception/ Custom exceptions + GlobalExceptionHandler
Route
Rendering
Purpose
/
Server
Landing page
/upload
Server shell + Client card
File upload + inline results
/history
Server async
Scan list with live filters
/scans/[id]
Server async
Full scan detail + download
Capture these after your first run and drop the images into docs/screenshots/.
Screen
Description
01-landing.png
Hero page with feature pills
02-upload.png
Drop zone before file is selected
03-scanning.png
Spinner during scan
04-results.png
Summary cards + findings table + redacted preview
05-history.png
History table with filters active
06-detail.png
Scan detail page with download button
Local setup (without Docker)
Tool
Version
Node.js
20+
Java
25
PostgreSQL
15+
CREATE DATABASE logshield ;
With PostgreSQL running:
cd backend
DB_PASSWORD=yourpassword ./mvnw spring-boot:run
# API → http://localhost:8080
Without PostgreSQL (H2 in-memory, dev profile):
cd backend
./mvnw spring-boot:run -Dspring-boot.run.profiles=dev
# API → http://localhost:8080 · H2 console → http://localhost:8080/h2-console
cd frontend
cp .env.local.example .env.local # no changes needed for local dev
npm install
npm run dev
# UI → http://localhost:3000
Docker setup (recommended)
One command starts everything — PostgreSQL, Spring Boot, and Next.js.
Copy the example env file and set a real DB password before starting:
cp .env.example .env # edit DB_PASSWORD at minimum
docker compose up --build
To stop and remove volumes:
Frontend (frontend/.env.local)
Variable
Default
Purpose
API_URL
http://localhost:8080
Rewrite proxy target (server startup)
INTERNAL_API_URL
http://localhost:8080
Server-side fetch base URL
Backend (env vars / .env for Docker)
Variable
Default
Purpose
DB_URL
jdbc:postgresql://localhost:5432/logshield
DB connection string
DB_USERNAME
postgres
DB user
DB_PASSWORD
postgres
DB password — change in production
CORS_ALLOWED_ORIGINS
http://localhost:3000
Comma-separated allowed origins
Copy .env.example → .env and set real values before running Docker.
Method
Path
Description
POST
/api/scans
Upload a .log/.txt file, scan and persist
GET
/api/scans
List all scan jobs (newest first)
GET
/api/scans/{id}
Full detail for one scan job
GET
/api/scans/{id}/download
Download redacted file as attachment
POST /api/scans — example response
{
"id" : 1 ,
"filename" : " server.log" ,
"uploadedAt" : " 2024-01-15T10:30:00" ,
"status" : " COMPLETED" ,
"severityScore" : 75 ,
"totalFindings" : 8 ,
"findingsByType" : {
"EMAIL" : [{ "id" : 1 , "matchedValue" : " user@corp.com" , "redactedValue" : " [REDACTED_EMAIL]" , "lineNumber" : 1 , "severity" : " LOW" }],
"JWT_TOKEN" : [{ "id" : 3 , "matchedValue" : " eyJ..." , "redactedValue" : " [REDACTED_JWT]" , "lineNumber" : 2 , "severity" : " HIGH" }],
"CREDIT_CARD" : [{ "id" : 4 , "matchedValue" : " 4111111111111111" , "redactedValue" : " [REDACTED_CARD]" , "lineNumber" : 3 , "severity" : " CRITICAL" }]
},
"redactedPreview" : " 2024-01-15 10:00:01 INFO user=[REDACTED_EMAIL] ip=[REDACTED_IP]..."
}
Two ready-to-upload samples live in samples/:
File
Contents
samples/clean.log
Standard application log — no sensitive data
samples/sensitive.log
Log with email, IP, JWT, API key, and credit card data
Score
Band
Typical trigger
0
—
No findings
1–15
LOW
Emails or IPs only (5 pts each)
16–40
MEDIUM
One JWT (20 pts) or one API key (25 pts)
41–75
HIGH
API key + email, or multiple JWTs
76–100
CRITICAL
Multiple credentials — capped at 100
Layer
Technology
Frontend
Next.js 16, React 19, TailwindCSS v4, TypeScript
Backend
Java 25, Spring Boot 4.0, Spring Data JPA, Lombok
Database
PostgreSQL 16
Build
Maven Wrapper, npm
CI
GitHub Actions
Infra
Docker, Docker Compose