chapagainmanoj/threat-intelligence
GitHub: chapagainmanoj/threat-intelligence
Stars: 0 | Forks: 0
# Threat Intelligence Dashboard
A 3-tier security threat monitoring dashboard: **React SPA** → **Node.js GraphQL gateway** → **Python FastAPI data service**.
Browser → Nginx (:80)
├─ /graphql → backend (Apollo Server 4, :4000)
└─ / → web (React 19 / Vite, :5173)
backend ↔ HTTP ↔ threats-service (FastAPI, :8000)
↕ File I/O
threats.json
## Prerequisites
| Tool | Version | Check |
|------|---------|-------|
| Node.js | 20+ | `node -v` |
| npm | 10+ | `npm -v` |
| Python | 3.9+ (3.12 recommended) | `python3 --version` |
| pip | latest | `pip3 --version` |
| Docker + Compose *(optional)* | 24+ / v2+ | `docker --version && docker compose version` |
## Quick Start (Docker — recommended)
Start everything with a single command. No local installs needed beyond Docker.
docker compose -f docker/dev.compose.yaml up --build
Open **http://localhost** once all 4 containers are healthy. Login with `analyst` / `threatintel`.
To stop:
docker compose -f docker/dev.compose.yaml down
## Quick Start (Local — 3 terminals)
Services must start in this order: **threats-service → backend → web**.
### 1. Threats Service (Python — port 8000)
cd threats-service
uv sync
uv run uvicorn main:app --reload --port 8000
**Verify it's running:**
curl http://localhost:8000/threats
Expected output:
[{"id":"1","name":"Brute Force Attack","severity":"High","status":"Active"},...]
### 2. Backend (Node.js — port 4000)
Open a **new terminal** in the project root:
cd backend
npm install
npm run dev
You should see:
🚀 GraphQL backend ready at http://localhost:4000/graphql
**Verify it's running:**
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query":"mutation { login(username: \"analyst\", password: \"threatintel\") { token } }"}'
Expected: a JSON response containing `"token": "eyJ..."`.
### 3. Web (React — port 5173)
Open a **new terminal** in the project root:
cd web
npm install
npm run dev
You should see:
VITE v8.x.x ready in XXX ms
➜ Local: http://localhost:5173/
Open **http://localhost:5173** in your browser.
### Login Credentials
| Field | Value |
|-------|-------|
| Username | `analyst` |
| Password | `threatintel` |
## Environment Variables
All variables have defaults for local development. Only `JWT_SECRET` is **required** in production.
| Variable | Service | Default | Purpose |
|----------|---------|---------|---------|
| `JWT_SECRET` | backend | `threat-intel-dev-secret` | HMAC key for signing/verifying JWTs |
| `AUTH_USERNAME` | backend | `analyst` | Login username |
| `AUTH_PASSWORD` | backend | `threatintel` | Login password |
| `THREATS_SERVICE_URL` | backend | `http://localhost:8000` | Base URL for the Python data service |
| `PORT` | backend | `4000` | Express listen port |
| `DATA_FILE` | threats-service | `data/threats.json` | Path to the JSON threat data store |
To override locally:
JWT_SECRET=my-secret AUTH_USERNAME=admin npm run dev
Docker Compose sets `THREATS_SERVICE_URL=http://threats-service:8000` automatically for container networking.
## Running Tests
# Python (from project root)
cd threats-service && pytest -v
# Backend (from project root)
cd backend && npm test
# Web (from project root)
cd web && npm test
Watch modes:
cd backend && npm run test:watch
cd web && npm run test:watch
## Building for Production
# Backend — compiles TypeScript to dist/
cd backend && npm run build
# Web — type-checks then bundles with Vite to dist/
cd web && npm run build
Run the full production stack with Docker:
JWT_SECRET=your-production-secret docker compose -f docker/prod.compose.yaml up --build
## Linting & Formatting
# ESLint (React/TypeScript)
cd web && npm run lint
# Prettier (TypeScript + CSS)
npx prettier --check "backend/src/**/*.ts" "web/src/**/*.{ts,tsx,css}"
# Ruff (Python)
ruff check threats-service/
ruff format --check threats-service/
## Project Structure
threat-intelligence/
├── threats-service/ Python FastAPI data layer (reads/writes threats.json)
├── backend/ Node.js GraphQL gateway (JWT auth, delegates to Python)
├── web/ React SPA (login, dashboard, charts)
├── proxy/ Nginx configs (dev with HMR, prod with SPA fallback)
├── docker/ Docker Compose files (dev + prod)
└── .github/workflows/ CI pipeline (lint → test → build)
## API Reference
### REST — threats-service (:8000)
| Method | Path | Description |
|--------|------|-------------|
| `GET` | `/threats` | List all threats |
| `POST` | `/threats/acknowledge` | Acknowledge a threat (body: `{"id": "1"}`) |
### GraphQL — backend (:4000)
# Public
mutation Login($u: String!, $p: String!) {
login(username: $u, password: $p) { token user { username } }
}
# Requires Authorization: Bearer
query { getThreats { id name severity status } }
mutation { acknowledgeThreat(id: "1") { id name severity status } }
## Common Errors
### `ECONNREFUSED` on port 8000
**Cause:** The backend can't reach the Python threats-service.
**Fix:** Make sure threats-service is running first:
cd threats-service && uvicorn main:app --reload --port 8000
### `You must be logged in.` from GraphQL
**Cause:** Missing or expired JWT token in the request.
**Fix:** Login first via the UI or GraphQL mutation. The token is stored in `localStorage` and injected automatically by Apollo Client.
### `Module not found: pytest`
**Cause:** pytest not installed in the active Python environment.
**Fix:**
cd threats-service && pip3 install -r requirements.txt
### Frontend shows blank page / network errors
**Cause:** `/graphql` requests aren't reaching the backend (CORS or proxy issue).
**Fix (local without Docker):** Add a Vite proxy to `web/vite.config.ts`:
server: {
proxy: { '/graphql': 'http://localhost:4000' },
}
**Fix (Docker):** Use `http://localhost` (port 80) — Nginx handles routing.
### `threats.json` has stale data after failed tests
**Fix:**
git checkout threats-service/data/threats.json
## Services Overview
| Service | Port | Stack | Dockerfile |
|---------|------|------|------------|
| `threats-service` | 8000 | Python 3.12 · FastAPI · Pydantic · pydantic-settings | `threats-service/Dockerfile` |
| `backend` | 4000 | Node.js 20 · Apollo Server 4 · Express | `backend/Dockerfile` |
| `web` | 5173 | React 19 · Vite 8 · TypeScript 6 | `web/Dockerfile` |
| `proxy` | 80 | Nginx Alpine | Docker Hub image |
标签:自动化攻击