Files
warpbox-dev/CLAUDE.md
Daniel Legt ffe4201f05 feat(theme): introduce retro Windows 98-inspired theme
Add a new "retro" theme option that mimics the classic Windows 98 aesthetic, providing a nostalgic alternative to the modern and classic dark themes.

Changes include:
- Defining CSS variables for the retro theme in `00-base.css` (pixel fonts, silver/gray colors, and classic window shadows).
- Adding custom styling for cards, headers, buttons, and title bars to replicate classic OS windows.
- Adding a star background GIF (`stars1.gif`).
- Excluding the retro theme from modern "revamp" styles in `15-revamp.css`.
- Updating `CLAUDE.md` with instructions on screenshot verification.
2026-05-31 16:17:20 +03:00

4.6 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Important Nots

Do not take screenshots yourself, ask the user to take screenshots of your visual changes if you want to so that you can verify them.

Commands

Go Executable:

/home/linuxbrew/.linuxbrew/bin/go

Run dev server:

# First-time setup: copy the env template
cp scripts/env/dev.env.example scripts/env/dev.env
# Edit scripts/env/dev.env to set WARPBOX_ADMIN_TOKEN and other values, then:
./scripts/run/dev.sh

Run directly (one-off):

cd backend
go run ./cmd/warpbox

Run all tests:

cd backend
go test ./...

Run a single test or package:

cd backend
go test ./libs/services/... -run TestDeleteTokenVerification
go test ./libs/handlers/... -v

Build:

cd backend
go build ./cmd/warpbox

Architecture

Warpbox is a self-hosted file-sharing app. All code lives under backend/. There is no frontend build step — the server renders Go templates and serves static assets directly.

Startup flow

cmd/warpbox/main.goconfig.Load()httpserver.New()server.ListenAndServe()

httpserver.New() wires everything together:

  1. Creates web.Renderer (template engine)
  2. Creates UploadService (opens bbolt DB, creates files/ and db/ dirs)
  3. Creates AuthService (reuses same *bbolt.DB)
  4. Creates SettingsService (reuses same *bbolt.DB)
  5. Starts background jobs via jobs.StartAll
  6. Creates handlers.App with all services
  7. Registers all routes on a http.ServeMux
  8. Wraps the mux in middleware chain: Recoverer → RequestID → SecurityHeaders → Gzip → Logger

Services

The three services share a single bbolt database. Each owns distinct buckets:

Service Buckets
UploadService boxes
AuthService users, user_emails, sessions, invites, collections
SettingsService settings, usage

UploadService owns the DB handle. AuthService and SettingsService receive uploadService.DB().

Data model

  • Box — one upload session. Has expiry, optional download limit, optional password (SHA-256 salted hash), optional owner (OwnerID), optional collection. Stored as JSON in the boxes bucket.
  • File — belongs to a Box. Stored on disk as data/files/{boxID}/@each@{fileID}.ext. Thumbnails at @thumb@{fileID}.jpg.
  • Box metadata is also written to data/files/{boxID}/.warpbox.box.json on every save.
  • User passwords are hashed with argon2id. Session tokens are SHA-256 hashed before storage.
  • Delete tokens for anonymous boxes are one-time random IDs, stored only as a SHA-256 hash.

Handlers

handlers.App holds all three services plus config, logger, and renderer. RegisterRoutes maps every URL pattern. Handler files are split by concern: upload.go, download.go, dashboard.go (user /app), admin.go, auth.go, manage.go, pages.go.

Upload policy enforcement

SettingsService stores per-day usage records keyed by ip:{ip}:{date} or user:{userID}:{date}. The upload handler (handlers/upload.go) checks these against UploadPolicySettings before accepting a multipart form. Admins bypass all per-upload and daily limits.

Background jobs

jobs.StartAll launches goroutines for:

  • Cleanup (WARPBOX_CLEANUP_ENABLED): deletes expired boxes and boxes that hit their download limit.
  • Thumbnails (WARPBOX_THUMBNAIL_ENABLED): generates JPEG thumbnails for image/video files that don't have one yet.

Configuration

All config comes from env vars via config.Load(). The dev script sources scripts/env/dev.env. WARPBOX_BASE_URL is required and must not be empty. Size values accept an optional MB/Mb suffix and support fractions (e.g. 0.5 = 512 KiB).

Logging

Structured JSONL logs go to data/logs/{YYYY-MM-DD}.log via log/slog. Every log entry includes source (e.g. "user-upload", "admin") and severity fields. User-activity events include a numeric code field (e.g. 2001 = upload complete, 2101 = box deleted).

Template rendering

web.Renderer parses all templates from backend/templates/ at startup using html/template. Page data is passed as web.PageData. The base layout is templates/layouts/base.html. The current logged-in user is injected into every page render via a.currentPublicUser(r).

First-run bootstrap

On a fresh data/ directory, visit /register to create the first admin account. After bootstrap, normal registration is closed. Admins create invite links from /admin/users. The WARPBOX_ADMIN_TOKEN env var provides emergency fallback access at /admin/login.