Introduce new environment variables to control the behavior of one-time download boxes: - `WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS`: Sets the lifetime of a one-time box after uploads are complete. - `WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE`: Determines whether a box remains available if the ZIP creation or transfer fails. To support these settings, the ZIP delivery process was refactored to use a temporary file. This ensures that a one-time box is only marked as consumed after the file has been successfully transferred to the client, preventing data loss on network interruptions. Additionally, added a `DecorateFiles` helper in the box store to reduce code duplication.
192 lines
6.2 KiB
Markdown
192 lines
6.2 KiB
Markdown
# WarpBox
|
|
|
|
WarpBox is a small, self-hosted file sharing app with temporary upload boxes,
|
|
simple download links, optional passwords, ZIP downloads, generated image
|
|
thumbnails, and a very deliberate retro desktop mood.
|
|
|
|
It is meant to feel quick: pick files, choose how long the box should live,
|
|
upload, and share the link.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
User[Person in browser]
|
|
UI[WarpBox UI]
|
|
API[Go HTTP server]
|
|
Manifest[(Box manifest JSON)]
|
|
Files[(Uploaded files)]
|
|
Thumbs[(Thumbnail JPEGs)]
|
|
DB[(BadgerDB metadata)]
|
|
|
|
User --> UI
|
|
UI -->|create box / upload / poll status| API
|
|
API --> Manifest
|
|
API --> Files
|
|
API --> DB
|
|
Files -->|download files or build ZIP| API
|
|
Thumbs -->|preview URLs| UI
|
|
Files -->|scan image files| Thumbs
|
|
```
|
|
|
|
## Features
|
|
|
|
- Multi-file uploads through a browser UI.
|
|
- Temporary boxes with configurable retention choices.
|
|
- Optional password protection per box.
|
|
- Individual file downloads or a single ZIP download.
|
|
- One-time download mode for ZIP-only handoff.
|
|
- Background thumbnails for image files.
|
|
- Plain filesystem storage, with JSON manifests next to uploaded files.
|
|
- Local BadgerDB metadata store for users, tags, sessions, and settings.
|
|
- No external database service required.
|
|
|
|
## How It Fits Together
|
|
|
|
```mermaid
|
|
flowchart TB
|
|
Browser[Browser UI]
|
|
Server[Go HTTP server]
|
|
Manifest[Box manifest JSON]
|
|
Files[Uploaded files]
|
|
Thumbs[Generated thumbnails]
|
|
DB[(BadgerDB metadata)]
|
|
|
|
Browser -->|POST /box, uploads, status polls| Server
|
|
Server --> Manifest
|
|
Server --> Files
|
|
Server --> Thumbs
|
|
Server --> DB
|
|
Thumbs -->|preview URLs| Browser
|
|
Files -->|downloads / ZIP| Browser
|
|
```
|
|
|
|
## Quick Start
|
|
|
|
Requirements:
|
|
|
|
- Go 1.22 or newer.
|
|
|
|
Run the app:
|
|
|
|
```bash
|
|
go run ./cmd run
|
|
```
|
|
|
|
Then open:
|
|
|
|
```text
|
|
http://localhost:8080
|
|
```
|
|
|
|
To listen somewhere else:
|
|
|
|
```bash
|
|
go run ./cmd run --addr :3000
|
|
```
|
|
|
|
## Configuration
|
|
|
|
WarpBox loads defaults, applies environment variables at startup, then applies
|
|
safe admin settings overrides from BadgerDB. Hard storage and global limit
|
|
settings remain environment controlled.
|
|
|
|
| Variable | Default | What it does |
|
|
| --- | ---: | --- |
|
|
| `WARPBOX_DATA_DIR` | `./data` | Root directory for uploads and metadata. |
|
|
| `WARPBOX_ADMIN_PASSWORD` | empty | Bootstraps the first admin when set. |
|
|
| `WARPBOX_ADMIN_USERNAME` | `admin` | Bootstrap admin username. |
|
|
| `WARPBOX_ADMIN_EMAIL` | empty | Bootstrap admin email. |
|
|
| `WARPBOX_ADMIN_ENABLED` | `auto` | Admin login mode: `auto`, `true`, or `false`. |
|
|
| `WARPBOX_ALLOW_ADMIN_SETTINGS_OVERRIDE` | `true` | Allows safe settings overrides from `/admin/settings`. |
|
|
| `WARPBOX_ADMIN_COOKIE_SECURE` | `false` | Sets the Secure flag on admin session cookies. |
|
|
| `WARPBOX_GUEST_UPLOADS_ENABLED` | `true` | Enables guest uploads. |
|
|
| `WARPBOX_API_ENABLED` | `true` | Enables JSON/upload endpoints used by the UI. |
|
|
| `WARPBOX_ZIP_DOWNLOADS_ENABLED` | `true` | Enables ZIP downloads. |
|
|
| `WARPBOX_ONE_TIME_DOWNLOADS_ENABLED` | `true` | Enables one-time download boxes. |
|
|
| `WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS` | `604800` | One-time box lifetime after uploads finish; `0` disables timed expiry. |
|
|
| `WARPBOX_ONE_TIME_DOWNLOAD_RETRY_ON_FAILURE` | `false` | Keeps one-time boxes alive when ZIP build/send fails before completion. |
|
|
| `WARPBOX_RENEW_ON_ACCESS_ENABLED` | `false` | Renews expiring boxes on access. |
|
|
| `WARPBOX_RENEW_ON_DOWNLOAD_ENABLED` | `false` | Renews expiring boxes on download. |
|
|
| `WARPBOX_DEFAULT_GUEST_EXPIRY_SECONDS` | `10` | Default guest retention. |
|
|
| `WARPBOX_MAX_GUEST_EXPIRY_SECONDS` | `172800` | Max guest retention shown/accepted. |
|
|
| `WARPBOX_GLOBAL_MAX_FILE_SIZE_BYTES` | `0` | Hard per-file cap; `0` means unlimited. |
|
|
| `WARPBOX_GLOBAL_MAX_BOX_SIZE_BYTES` | `0` | Hard per-box cap; `0` means unlimited. |
|
|
| `WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_BYTES` | `0` | Default user file cap. |
|
|
| `WARPBOX_DEFAULT_USER_MAX_BOX_SIZE_BYTES` | `0` | Default user box cap. |
|
|
| `WARPBOX_SESSION_TTL_SECONDS` | `86400` | Admin session lifetime. |
|
|
| `WARPBOX_BOX_POLL_INTERVAL_MS` | `5000` | Browser polling interval for box/file status updates. |
|
|
| `WARPBOX_THUMBNAIL_BATCH_SIZE` | `10` | Number of pending thumbnails processed per worker pass. |
|
|
| `WARPBOX_THUMBNAIL_INTERVAL_SECONDS` | `30` | Delay between thumbnail worker passes. |
|
|
|
|
Size limits also accept `_MB` variants for the same settings.
|
|
|
|
Example:
|
|
|
|
```bash
|
|
WARPBOX_ADMIN_PASSWORD='change-me' \
|
|
WARPBOX_ONE_TIME_DOWNLOAD_EXPIRY_SECONDS=604800 \
|
|
WARPBOX_BOX_POLL_INTERVAL_MS=2000 \
|
|
WARPBOX_THUMBNAIL_BATCH_SIZE=20 \
|
|
WARPBOX_THUMBNAIL_INTERVAL_SECONDS=10 \
|
|
go run ./cmd run --addr :8080
|
|
```
|
|
|
|
Open `/admin/login` after startup to sign in with the bootstrap admin.
|
|
|
|
## Storage
|
|
|
|
Uploads are stored locally under:
|
|
|
|
```text
|
|
<WARPBOX_DATA_DIR>/uploads/
|
|
```
|
|
|
|
Each box gets its own directory containing the uploaded files and a
|
|
`.warpbox.json` manifest. Image thumbnails are stored inside a box-local
|
|
`.thumbnails` directory.
|
|
|
|
Persistent app metadata lives in BadgerDB under:
|
|
|
|
```text
|
|
<WARPBOX_DATA_DIR>/db/
|
|
```
|
|
|
|
```text
|
|
data/uploads/
|
|
+-- <box-id>/
|
|
+-- .warpbox.json
|
|
+-- file.txt
|
|
+-- .thumbnails/
|
|
+-- <file-id>.jpg
|
|
data/db/
|
|
```
|
|
|
|
## Project Layout
|
|
|
|
```text
|
|
cmd/ CLI entrypoint
|
|
lib/server/ HTTP handlers and server setup
|
|
lib/routing/ Route registration
|
|
lib/boxstore/ Box storage, manifests, downloads, thumbnails
|
|
lib/config/ Typed environment and runtime settings config
|
|
lib/metastore/ BadgerDB metadata store for users, tags, settings, sessions
|
|
lib/helpers/ Small shared helpers
|
|
lib/models/ Shared request/response models
|
|
templates/ Server-rendered HTML
|
|
static/css/ Stylesheets
|
|
static/js/ Browser scripts
|
|
static/img/ Icons, sprites, and backgrounds
|
|
static/fonts/ Bitmap/pixel fonts
|
|
static/cursors/ Custom cursor packs
|
|
static/popups/ HTML popup content
|
|
docs/ Project documentation
|
|
```
|
|
|
|
## Notes
|
|
|
|
WarpBox is intentionally simple. It uses the local filesystem for box data,
|
|
BadgerDB for app metadata, relies on generated box IDs for share links, and
|
|
keeps most behavior easy to follow from the Go handlers and the small browser
|
|
scripts.
|
|
|
|
For a short implementation overview, see [docs/tech.md](docs/tech.md).
|