Skip to content

haltacademy/Lab

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cyber Security Lab — Admin Portal

Dockerized React + TypeScript admin portal for a Cyber Security Lab. Neon-terminal aesthetic, JWT-protected login backed by a Node/Express API.

Stack

  • Frontend: Vite + React 18 + TypeScript + Tailwind CSS v4 + React Router
  • Backend: Node.js 22 + Express + jsonwebtoken + helmet + express-rate-limit
  • Infra: Docker Compose, Nginx (serves SPA + proxies /api → backend)

Quick start

cp .env.example .env       # optional — defaults work for local
docker compose up --build

Open http://localhost:8080. Login with:

username: admin
password: admin

Exam Portal

The Exam-Portal/ folder is shipped as a 4th compose service exam-portal (host port 3000). It runs its own Postgres + Nginx + Docker-in-Docker inside one container.

Single sign-on: The main backend and exam-portal share JWT_SECRET. When a logged-in user clicks an Exam Portal link from /admin or /student, the main frontend redirects to http://<host>:3000/sso?token=<jwt>&next=/admin (or /). The Sso page stores the token in localStorage and loads the app. On the first authenticated API call, exam-portal upserts the user (by username + role) into its own Postgres users table.

Admin control: /admin shows an "Exam Portal" card with:

  • Live summary (exam count, in-progress attempts, active labs) via GET /api/exam-portal/summary (proxied to the exam-portal container).
  • An "Enabled for students" toggle persisted to ${DATA_DIR}/exam_portal_settings.json. When off, the Exam Portal tile is hidden from /student.
  • An "Open Exam Portal Admin" button that opens /admin in exam-portal already logged in.

Required shared env: JWT_SECRET must be identical for backend and exam-portal. EXAM_PORTAL_PUBLIC_URL (default http://lab.upskillnexus.local:3000) is the URL the browser is sent to; EXAM_PORTAL_INTERNAL_URL (default http://exam-portal:4000) is used server-to-server for the summary widget.

Endpoints

  • POST /api/auth/login{username, password}{token, user}
  • GET /api/auth/meAuthorization: Bearer <token>{user}

Layout

frontend/  React SPA, multi-stage Docker → nginx:alpine
backend/   Express API, node:22-alpine
data/      Persisted curriculum + lab source (committed to git)

Persistence & GitHub workflow

The backend persists everything to ./data/ on the host (bind-mounted to /data in the container). That directory is part of the repo, so a normal git push / git pull carries your modules and uploaded lab source between machines.

What's committed:

  • data/modules.json — modules, subtopics, lab metadata (image tag, source dir, exposed port, etc.)
  • data/labs/<labId>/... — extracted lab source (Dockerfile + files) from each admin upload

What's NOT committed (per .gitignore):

  • data/sessions.json — per-machine runtime state (tokens, container IDs)
  • data/*.tmp — atomic-write temp files

Built docker images are not committed. On the first docker compose up after a pull, the backend automatically rebuilds any lab image that isn't already loaded — watch docker logs -f lab-backend for [reconcile] rebuilding image ...[reconcile] ready .... While a build is in progress the admin panel shows the lab as "Building…".

If a lab's source dir is missing on the new machine, that lab is marked "Build failed: lab source missing — re-upload zip" and the rest of the system stays healthy.

One-time migration from the old lab-data named volume

If you previously ran the stack with a Docker named volume, copy its contents into ./data/ before the first commit:

docker compose down
docker run --rm -v lab-data:/from -v "$PWD/data":/to alpine sh -c 'cp -a /from/. /to/'
git add data/
git commit -m "seed curriculum data"
docker compose up -d

If lab source ever exceeds ~50 MB total

Switch data/labs/** to Git LFS to keep clones fast.

About

Enterprise-grade Dockerized lab suite for Web Application Pentesting and specialized research.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors