Darkraise ee9c2a296f fix: harden security, improve type safety, and clean up code
- Pin DNS resolution to prevent SSRF rebinding between
  check and connect (GameDataDownloader)
- Fail-closed on realpath failure in GameZipServer
- Zip Slip validation before extraction (RuffleService)
- Escape LIKE wildcards in ActivityService queries
- Sanitize sort order to prevent SQL injection
- Whitelist sort order instead of passing raw user input
- Add headersSent guard to global error handler
- Remove cookie from CGI allowed headers, sanitize
  content-type against null/CR/LF injection
- Revoke refresh tokens on password change and user
  deactivation
- Wrap role/user uniqueness checks in transactions
  (TOCTOU fix)
- Fix concurrent ZIP mount race with deferred promise
  and double-close prevention via _manuallyClosed flag
- Handle client disconnect in collectRequestBody
- Tighten nginx CSP, repeat headers in location blocks,
  hide server version, pin nginx:1.27-alpine
- Fix health check endpoint path in backend Dockerfile
- Use wget instead of curl for frontend health checks
- Replace any types with proper types across backend
  and frontend
- Replace || with ?? for config/form defaults
- Replace hardcoded Tailwind colors with theme tokens
- Replace console.log/error with logger in ErrorReporter
  and ChartErrorBoundary
- Conditionally render AddToPlaylistModal to avoid
  hidden instances
- Add NaN guards for parseInt in GameBrowseLayout
- Standardize query key for publicSettings
- Simplify README to Docker-first quickstart with wiki
  link
- Fix license to GPL-3.0 in backend package.json
- Slow down particle animation speed
- Add Zod max-length limits on playlist/error schemas
- Ensure positive limit in parsePaginationQuery
- Validate settings category param against allowlist
- Fix static/parameterized route ordering in favorites
- Add asyncHandler to game-zip wildcard route
- Close readline/stream on error in getRecentErrors
- Add .catch() on fire-and-forget syncAndReload
- Fix LazyBackgroundImage cleanup on unmount
- Store NetworkStatusIndicator timeout in ref
- Add Flash/SWF condition to random game query
2026-02-09 09:17:18 +07:00
2026-01-31 17:29:07 +07:00
2026-01-28 19:21:02 +07:00
2026-02-01 01:21:28 +07:00
2026-01-28 19:21:02 +07:00
2026-01-13 10:09:15 +07:00

Flashpoint Web

A modern web interface for the Flashpoint Archive

Browse and play 200,000+ preserved Flash games and animations directly in your browser.

Node.js TypeScript React Express Vite Tailwind CSS SQLite Docker

License Node.js 20+ PRs Welcome


What is Flashpoint Web?

Flashpoint Web is a self-hosted web application for accessing your local Flashpoint Archive collection. It provides a modern, browser-based alternative to the Flashpoint Launcher with multi-user support, play tracking, and an intuitive interface.

Key Features

  • Browse & Search - Fast search across 200,000+ games with advanced filtering by platform, developer, tags, and more
  • Play in Browser - Flash games via Ruffle emulator, HTML5 games natively
  • Multi-User Support - Individual accounts with role-based permissions (admin, moderator, user, guest)
  • Play Tracking - Track playtime, completion status, and view play statistics
  • Playlists & Favorites - Organize your game collection with custom playlists
  • 22 Theme Palettes - Customizable dark/light modes with multiple color schemes
  • Responsive Design - Works on desktop and mobile devices
  • Database Hot-Reload - Automatically syncs when Flashpoint Launcher updates metadata

Getting Started

Prerequisites

1. Create a project directory

mkdir flashpoint-web && cd flashpoint-web

2. Create docker-compose.yml

services:
  backend:
    image: darkraise/flashpoint-backend:${IMAGE_TAG:-latest}
    container_name: flashpoint-backend
    restart: unless-stopped
    ports:
      - "${API_PORT:-3100}:3100"
    volumes:
      - ${FLASHPOINT_HOST_PATH:?FLASHPOINT_HOST_PATH is required}:/data/flashpoint:ro
      - ${DATA_PATH:-./data}:/app/data
      - ${LOGS_PATH:-./logs}:/app/logs
    environment:
      - PUID=${PUID:-1000}
      - PGID=${PGID:-1000}
      - NODE_ENV=production
      - TZ=${TZ:-UTC}
      - DOMAIN=${DOMAIN:-http://localhost:${WEB_PORT:-80}}
      - LOG_LEVEL=${LOG_LEVEL:-info}
      - JWT_SECRET=${JWT_SECRET:?JWT_SECRET is required}
      - ENABLE_LOCAL_DB_COPY=${ENABLE_LOCAL_DB_COPY:-false}
      - SQLITE_CACHE_SIZE=${SQLITE_CACHE_SIZE:--64000}
      - SQLITE_MMAP_SIZE=${SQLITE_MMAP_SIZE:-268435456}
      - ENABLE_CACHE_PREWARM=${ENABLE_CACHE_PREWARM:-true}
    healthcheck:
      test: ["CMD", "curl", "--fail", "http://localhost:3100/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

  frontend:
    image: darkraise/flashpoint-frontend:${IMAGE_TAG:-latest}
    container_name: flashpoint-frontend
    restart: unless-stopped
    ports:
      - "${WEB_PORT:-80}:8080"
    environment:
      - PUID=${PUID:-1000}
      - PGID=${PGID:-1000}
      - TZ=${TZ:-UTC}
      - BACKEND_HOST=${BACKEND_HOST:-backend}
      - BACKEND_PORT=${BACKEND_PORT:-3100}
    depends_on:
      backend:
        condition: service_healthy
    healthcheck:
      test: ["CMD", "wget", "--quiet", "--spider", "http://localhost:8080/"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 10s

3. Create .env

# Required — path to your Flashpoint installation on the host machine
FLASHPOINT_HOST_PATH=/path/to/Flashpoint

# Required — secret key for JWT authentication (use a long random string)
JWT_SECRET=your-secure-secret-key

# Optional — uncomment and edit as needed
# WEB_PORT=80              # Frontend port (default: 80)
# API_PORT=3100            # Backend API port (default: 3100)
# PUID=1000                # Host user ID (Linux — run 'id -u')
# PGID=1000                # Host group ID (Linux — run 'id -g')
# DOMAIN=http://localhost  # Public URL of the frontend
# LOG_LEVEL=info           # debug, info, warn, error
# TZ=UTC                   # Timezone
# DATA_PATH=./data         # Persistent app data
# LOGS_PATH=./logs         # Log files

# Database performance (for network storage / large collections)
# ENABLE_LOCAL_DB_COPY=false       # Copy flashpoint.sqlite to local storage
# SQLITE_CACHE_SIZE=-64000         # SQLite cache in KB (64MB default)
# SQLITE_MMAP_SIZE=268435456       # Memory-mapped I/O in bytes (256MB default)
# ENABLE_CACHE_PREWARM=true        # Pre-warm common queries on startup

4. Start the services

docker compose up -d

Open http://localhost in your browser. The first user to register automatically becomes the admin.

Default Ports

Service URL
Frontend http://localhost
Backend http://localhost:3100

Common Commands

docker compose up -d                # Start services
docker compose down                 # Stop services
docker compose logs -f              # View logs
docker compose logs -f backend      # Logs for a specific service
docker compose restart backend      # Restart a service
docker compose pull && docker compose up -d  # Update to latest images

Documentation

For architecture details, API reference, development setup, contributing guidelines, and more, visit the Wiki.

License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

Acknowledgments

  • Flashpoint Team - For preserving web gaming history
  • Ruffle Contributors - For making Flash playable in modern browsers
  • Community - For testing, feedback, and contributions

S
Description
Self-hosted flash game arcade for Flashpoint Ultimate, focused on game discovery, game support coverage, and theming. Not affiliated with the Flashpoint project.
Readme GPL-3.0
47 MiB
Languages
TypeScript 93.8%
JavaScript 3.5%
Shell 1.1%
CSS 0.6%
HTML 0.3%
Other 0.7%