Files
warpbox-dev/CLAUDE.md
Daniel Legt 830d2a885c
All checks were successful
Build and Publish Docker Image / deploy (push) Successful in 1m8s
refactor(ui): remaster settings and navigation layout
- Update navigation labels from "My Account" to "Dashboard" and "Login" to "Sign in", updating tests accordingly.
- Redesign settings forms into structured sections with improved spacing and layout.
- Add CSS styles for tabs, small buttons, and responsive settings sections to enhance the user experience.
2026-05-30 18:17:13 +03:00

4.5 KiB

CLAUDE.md

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

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.