Skip to content

Repository files navigation

CTF://PROTOCOL

A real-time Capture The Flag competition platform with a brutalist retro-hacker aesthetic.

Built with Next.js 16, Convex (real-time backend), and Clerk (auth). Designed for cybersecurity competitions where teams register, solve challenges, and compete on a live scoreboard.


Features

For Participants

  • Team System — Create or join a team (up to 3 members) with a unique joining code
  • Challenge Dashboard — Browse challenges by difficulty (easy / medium / hard), submit flags, track progress
  • Live Activity Feed — Real-time sidebar showing solves and first bloods across all teams
  • Submission History — View all past attempts per challenge with timestamps
  • Public Leaderboard — Live-updating scoreboard at /leaderboard with animated podium, rankings, and activity ticker

For Admins (/admin)

  • Challenge Management — Create, edit, delete challenges with title, description, points, flag, category, and optional file links
  • Team Oversight — View all teams, members, scores, and solve history
  • Event Controls — Toggle event active/inactive, freeze scoreboard, open/close registration, lock/unlock dashboard
  • Audit Log — Timestamped log of all admin actions
  • Dashboard Stats — Real-time counts of teams, users, challenges, submissions, and solve rates

Design

  • Brutalist retro-hacker theme: VT323 display font, JetBrains Mono, pixel art SVG icons
  • Grain/scanline overlays, grid-paper background, crosshair cursor
  • #39FF14 neon green accent on dark #111111 and light #EDEDED palette
  • Custom animated cursor (GSAP) on the landing page
  • Responsive layout with mobile breakpoints

Tech Stack

Layer Technology
Framework Next.js 16 (App Router)
Runtime React 19
Backend Convex (real-time, serverless)
Auth Clerk (JWT → Convex integration)
Styling Tailwind CSS 4 + custom CSS tokens
Animation GSAP, Motion (framer-motion)
UI Radix UI primitives, Lucide icons
Language TypeScript

Project Structure

├── app/
│   ├── layout.tsx          # Root layout (Clerk + Convex providers)
│   ├── page.tsx            # Landing page → auth → dashboard routing
│   ├── globals.css         # Design tokens, brutalist theme, component styles
│   ├── admin/
│   │   ├── layout.tsx      # Admin sidebar layout
│   │   ├── page.tsx        # Admin dashboard with stats
│   │   ├── challenges/     # Challenge CRUD
│   │   ├── teams/          # Team management
│   │   ├── settings/       # Event config & access controls
│   │   └── audit/          # Audit log viewer
│   └── leaderboard/
│       └── page.tsx        # Public live scoreboard
├── components/
│   ├── ConvexClientProvider.tsx  # Convex + Clerk wiring
│   ├── Dashboard.tsx            # Main CTF challenge dashboard
│   ├── LandingPage.tsx          # Animated landing / login page
│   ├── Lobby.tsx                # Team creation / join lobby
│   ├── TargetCursor.jsx         # GSAP custom crosshair cursor
│   ├── DecryptedText.jsx        # Text reveal animation
│   └── Shuffle.tsx              # Shuffle text effect
├── convex/
│   ├── schema.ts           # Database schema (7 tables)
│   ├── admin.ts            # Admin mutations & queries
│   ├── challenges.ts       # Challenge & submission logic
│   ├── teams.ts            # Team creation / joining
│   ├── users.ts            # User sync & leaderboard query
│   └── auth.config.ts      # Clerk JWT config for Convex
├── lib/
│   └── utils.ts            # cn() utility (clsx + tailwind-merge)
└── middleware.ts            # Clerk auth middleware

Database Schema

Table Purpose
user Clerk-synced users with optional team assignment
teams Teams with name, joining code, leader, score
questions CTF challenges (title, description, points, flag)
submissions Flag submission attempts per team per challenge
config Event state (active, frozen, registration, dashboard)
activityFeed Real-time solve/first-blood events for live feed
auditLog Admin action history with timestamps

Prerequisites

  • Node.js ≥ 18
  • npm (or pnpm / yarn)
  • A Clerk account — clerk.com
  • A Convex account — convex.dev

Installation

1. Clone the repository

git clone <repo-url>
cd ctf

2. Install dependencies

npm install

3. Set up Clerk

  1. Create a new application at dashboard.clerk.com
  2. In Clerk → JWT Templates, create a template named convex with the Convex JWT format (see Convex docs)
  3. Copy your Publishable Key and Secret Key from Clerk → API Keys

4. Set up Convex

  1. If you haven't already, install the Convex CLI globally:

    npm install -g convex
  2. Initialize or link your Convex project:

    npx convex dev

    This will prompt you to log in and create/select a project. It will also generate the convex/_generated/ directory.

  3. In the Convex Dashboard → Settings → Environment Variables, add:

    CLERK_JWT_ISSUER_DOMAIN=<your-clerk-issuer-url>
    

    (Find this in Clerk → JWT Templates → convex template → Issuer URL)

5. Configure environment variables

Create a .env.local file in the project root:

# Clerk
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
CLERK_SECRET_KEY=sk_test_...

# Convex
NEXT_PUBLIC_CONVEX_URL=https://<your-project>.convex.cloud

6. Seed the config table

Before first use, ensure there's a config document in Convex. You can do this from the Convex Dashboard data browser or by running a one-off mutation. The config table expects:

{
  "isEventActive": false,
  "isScoreBoardFrozen": false,
  "isRegistrationOpen": true,
  "isDashboardOpen": false
}

7. Set up an admin user

  1. Sign in through the app with Clerk
  2. In the Convex Dashboard, find your user in the user table and set isAdmin: true
  3. You'll now have access to the /admin panel

Development

Start the Next.js dev server and Convex in parallel:

# Terminal 1 — Convex backend (watches for schema/function changes)
npx convex dev

# Terminal 2 — Next.js frontend
npm run dev

The app will be available at http://localhost:3000.


Production Build

npm run build
npm start

For Convex production deployment:

npx convex deploy

Set the same environment variables (CLERK_JWT_ISSUER_DOMAIN) in your Convex production environment via the dashboard.


Key Routes

Route Access Description
/ Public Landing page → login → dashboard
/leaderboard Public Live scoreboard (no auth required)
/admin Admin Admin dashboard with stats
/admin/challenges Admin Challenge management
/admin/teams Admin Team oversight
/admin/settings Admin Event config & access controls
/admin/audit Admin Audit log

Environment Variables Reference

Variable Where Description
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY .env.local Clerk publishable key
CLERK_SECRET_KEY .env.local Clerk secret key
NEXT_PUBLIC_CONVEX_URL .env.local Convex deployment URL
CLERK_JWT_ISSUER_DOMAIN Convex Dashboard Clerk JWT issuer for Convex auth

License

Private — not licensed for redistribution.

About

open-source Capture The Flag (CTF) platform for hosting Jeopardy-style hacking events.

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages