A browser-based, gamified security awareness platform that trains users to recognise phishing attempts through interactive simulations and immediate pedagogical feedback.
For AI coding agents and contributor setup: see
AGENTS.md.
Traditional security awareness training is perceived as monotonous, overly theoretical, and disconnected from real-world scenarios. This platform addresses that gap by combining a realistic phishing simulation pipeline with gamified recovery training, putting users through a controlled "Gotcha!" experience and then guiding them to understand exactly why they were fooled.
The core loop: Admin (or the automated scheduler) dispatches a personalised phishing email → User clicks the lure → User is redirected to an educational alert page → Tag-matching selects the most relevant training module → User completes a mini-game or SCORM course to regain their points.
Phishing campaigns can be triggered manually from the admin dashboard or dispatched automatically by the Hangfire-backed daily scheduler, which uses per-group policies to control timing, difficulty, and template selection.
- User registers → completes a short onboarding welcome screen
- Moderator assigns them to a group in User Management
NextPhishingAtis seeded → user enters the automated phishing rotation
- Admin opens Dashboard → Simulations, selects an email template and a target email
- Backend creates a
PhishingAttempt, personalises the email (name, pronouns), injects the tracking link and open-tracking pixel, and dispatches via sender-api - Confirmation panel shows the tracking link and send timestamp
- User clicks the tracking link → XP deducted,
ClickedAtrecorded, admin dashboard receives a real-time SignalR notification - User lands on the alert page – the original email is displayed with the phishing tactics and XP penalty highlighted
- Platform tag-matches the template's tags to the best available training instance
- User completes the training game → XP awarded → attempt marked
Remediated
- Moderator opens Dashboard → Phishing Scheduler, selects a group
- Configures a policy: frequency multiplier, difficulty range, required template tags, or disables phishing for the group entirely
- Daily Hangfire job (08:00 UTC) picks up users whose
NextPhishingAt ≤ nowand schedules a tag- and difficulty-filtered template per user, each with a random send-time offset so emails arrive throughout the day rather than in a single burst - Each user's next send interval is recalculated based on their recent click history and the group policy
- Admin opens Dashboard → Templates, clicks New Template
- Fills in subject, sender name, HTML body (with
{{TRACKING_LINK}}placeholder), phishing tactic tags, and difficulty (1–5) - Template is immediately available for manual sends and the automated scheduler
- Moderator opens Dashboard → Training Library, clicks New Module → Build from a game type
- Selects a game type (e.g. Phishing Quiz, URL Detective, Social Engineering Chat) from the dropdown
- Fills in the structured form: title, tags, difficulty, round count, and optional content filters
- The module is ready immediately for automated routing from failed phishing attempts and standalone library play. (Moderators can also choose Upload a SCORM package to bring a module from an external authoring tool.)
- Admin finds a module in the Training Library and clicks Export
- Backend resolves the config, fetches the SCORM shell from R2, and bakes
config.jsoninto a ZIP - The downloaded
.zipis self-contained – upload directly to Moodle, Cornerstone, SCORM Cloud, etc.
- Admin opens Dashboard → Simulations – the Live Activity panel sits beside the send form
- The panel connects to the SignalR hub and streams open and click events as they arrive
- Each event card shows target email, template name, event type, and timestamp – no polling or page refresh needed
- Admin or Moderator opens Dashboard → Statistics
- Views overview metrics, campaign timeline, template performance, per-group breakdowns, user leaderboard, risk overview, and training efficacy (per-tactic click-rate before vs after training)
- Exports all data as CSV for offline analysis
- User opens their Dashboard → Library and browses available training instances
- Completes a game → score and XP recorded as a standalone
SaveGame(no phishing attempt linked)
- On level-up the user earns a Challenge Token (held up to a maximum of 3)
- In Dashboard → Phish a Coworker they design a lure with a constrained builder (structured fields, no raw HTML) and choose a target: a mutually-accepted friend or a random coworker (anonymous)
- Sending spends one token; from there the flow is the normal phishing pipeline – click penalty → alert page → tag-matched training
- When the recipient completes their training, the sender earns scaled bonus XP – the reward is tied to the coworker learning, not to being fooled
- Admins can disable the feature org-wide (Dashboard → Settings); any user can opt out of being targeted. See
docs/workflows/peer-challenge-lifecycle.md
| Layer | Technology |
|---|---|
| Frontend framework | React 19 + TypeScript (Vite) |
| Styling | Tailwind CSS 4 + Shadcn UI |
| State management | Zustand |
| Animations | Framer Motion |
| Charts | Recharts |
| Icons | Lucide React |
| Real-time | SignalR (@microsoft/signalr) |
| HTTP client | Axios |
| Form validation | React Hook Form + Zod |
| Backend framework | ASP.NET Core Web API (.NET 10, C#) |
| ORM | Entity Framework Core |
| Database | PostgreSQL |
| Authentication | JWT + BCrypt |
| Background jobs | Hangfire (PostgreSQL storage) |
| Email delivery (dev) | Mailpit – local mock SMTP with browser UI |
| Email delivery (prod) | Postfix on a whitelisted VPS via sender-api |
| Object storage | Cloudflare R2 (S3-compatible, for SCORM packages) |
| API docs | Scalar (OpenAPI) |
- .NET 10 SDK
- Node.js 24.15.0 (exact version for the SCORM workspace)
- Docker (for the database and local mail stack)
- Cloudflare R2 bucket (for SCORM package storage)
A docker-compose.yml in the Database folder spins up a PostgreSQL 17 container. The
.env.example defaults already match these credentials, so no edits are needed for
local development.
cd backend/Database
docker compose up -d
# PostgreSQL: localhost:5432 (db: innovationsprojekt, user: postgres, password: postgres)Start Mailpit and the sender-api before running the backend. All outgoing emails are caught locally – nothing is sent to real inboxes.
cd backend/MailService
docker compose up -d
# Mailpit Web UI: http://localhost:8025
# sender-api: http://localhost:8080cd backend/Api
# Copy the example env file (dev defaults work out of the box)
cp .env.example .env
dotnet restore
dotnet ef database update # apply migrations
dotnet run
# API available at http://localhost:5000
# Scalar UI available at http://localhost:5000/scalarcd frontend
npm install
# Copy the example env file and fill in your values
cp .env.example .env
npm run dev
# App available at http://localhost:5173The seven training game modules (Phishing Quiz, URL Detective, etc.) are SCORM packages stored in Cloudflare R2. The backend seeder automatically creates the database rows for each template on first startup, but the actual files must be built and uploaded separately.
New first-party games are created from the supported SDK scaffold rather than by copying an existing game:
cd scorm-templates
npm install
npm run create:template -- invoice-investigator --registration-stubs
npm install
npm run build:allUse npm run dev:lab to exercise a built game under recording SCORM 2004, SCORM 1.2,
standalone, theme, resume, and injected-failure modes. See the
SCORM SDK quickstart before registering or releasing it.
Create a Cloudflare R2 bucket (the free tier is sufficient for dev), generate an API token
with Object Read & Write permissions, then fill in the four R2 variables in
backend/Api/.env:
R2__AccountId=<your Cloudflare account ID>
R2__AccessKeyId=<R2 API token ID>
R2__SecretAccessKey=<R2 API token secret>
R2__BucketName=<your bucket name>
Restart the backend after editing .env so the new credentials take effect.
scorm-templates/ is an npm workspace, so one install covers every template:
cd scorm-templates
npm install
npm run build:allEach build produces a dist/ folder inside the template directory. build:all also stamps
traceable bridge/SDK/UI/theme metadata and validates every manifest and offline package invariant.
During development, rebuild one template with npm run build --workspace <slug>, but run
npm run build:all before packaging or upload.
The upload endpoint (POST /api/admin/template-scorm/templates/{slug}/upload) accepts a
ZIP of the template's dist/ contents and requires an admin JWT.
First, obtain a token (the backend seeder creates the admin account on first run):
TOKEN=$(curl -s -X POST http://localhost:5000/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@Innovationsprojekt.com","password":"<Seed__AdminPassword from .env>"}' \
| grep -o '"token":"[^"]*"' | cut -d'"' -f4)Then build and upload each template in one pass:
for slug in phishing-quiz url-detective social-engineering-chat \
red-flag-spotter office-risk-spotter before-you-click-send data-sorter; do
# ZIP the dist/ contents (not the dist/ folder itself)
(cd scorm-templates/$slug/dist && zip -r /tmp/$slug.zip .)
curl -s -X POST http://localhost:5000/api/admin/template-scorm/templates/$slug/upload \
-H "Authorization: Bearer $TOKEN" \
-F "file=@/tmp/$slug.zip" \
| grep -o '"filesUploaded":[0-9]*'
echo " ← $slug"
doneThis mutable upload loop is for local development only. Before any deployment or customer export, follow the SCORM template release workflow; Plan 07 owns the future immutable upload, promotion, and rollback process.
A successful upload prints "filesUploaded":<n> for each template. After all seven are
uploaded the Training Library in the dashboard becomes fully functional and the
phishing-alert remediation flow can route users to the correct game module.
├── .github/workflows/ # CI: backend, frontend, SCORM, mail service
├── scripts/ # smoke.sh / smoke.ps1 – end-to-end smoke test
├── backend/
│ ├── Innovationsprojekt.slnx # Solution: Api + Api.Tests
│ ├── Api/ # ASP.NET Core Web API
│ │ ├── Controllers/ # HTTP endpoints
│ │ ├── Domain/ # Entities and domain logic
│ │ ├── Application/ # Services, DTOs, configuration, SignalR hub (Hubs/)
│ │ ├── Infrastructure/ # EF Core, R2 storage, Hangfire, SignalR adapter
│ │ ├── Extensions/ # Grouped DI & startup wiring (Program.cs helpers)
│ │ └── Migrations/ # EF Core migrations
│ ├── Api.Tests/ # xUnit tests (Domain/ = pure-domain tier)
│ ├── Database/ # Local database stack
│ │ └── docker-compose.yml # PostgreSQL
│ └── MailService/ # Local email delivery stack
│ ├── docker-compose.yml # Mailpit + sender-api
│ └── sender-api/ # Node/Express SMTP bridge (+ header validation & tests)
├── frontend/
│ ├── src/
│ │ ├── pages/ # Route-level components
│ │ ├── components/ # Shared UI components
│ │ ├── features/ # Feature-scoped modules (SCORM bridge, etc.)
│ │ ├── layouts/ # Layout wrapper components
│ │ ├── store/ # Zustand state stores
│ │ ├── hooks/ # Custom React hooks
│ │ ├── lib/ # Utilities and domain-sliced API client (api/)
│ │ └── styles/ # Global CSS & Tailwind tokens (globals.css)
│ └── public/
├── scorm-templates/ # npm workspace: SCORM 2004 game modules (React + Vite)
│ ├── package.json # Workspace root (single lockfile for all members)
│ ├── shared/scorm-bridge/ # Low-level SCORM 2004/1.2 adapters and legacy facade
│ ├── shared/sdk/ # Supported game bootstrap, lifecycle, config/resume contracts
│ ├── shared/testing/ # Recording runtimes and reusable lifecycle test tools
│ ├── tooling/ # Template creator and interactive runtime lab
│ ├── phishing-quiz/ # Multiple-choice phishing email quiz
│ ├── url-detective/ # Click the malicious URL segment
│ ├── social-engineering-chat/# Chat-based social engineering scenarios
│ ├── red-flag-spotter/ # Find every red flag in a full phishing email
│ ├── office-risk-spotter/ # Spot physical and digital risks in an office scene
│ ├── before-you-click-send/ # Decide whether outgoing messages are safe to send
│ └── data-sorter/ # Classify documents into the correct data categories
└── docs/ # Architecture and workflow documentation
├── adr/ # Architecture Decision Records (000–028)
├── architecture/ # Patterns, error handling, entity reference
├── audits/ # Point-in-time audits (security)
├── guides/ # Admin, SCORM SDK/testing, catalogue, frontend UI conventions
├── reference/ # Generated reference data (reserved lure paths)
├── systems/ # Email, scheduler, XP, security notes
└── workflows/ # Campaign lifecycle, SCORM authoring and release