# 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. Storage path 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_GB` | `0` | Per-file cap in GB using `1024^3` conversion; `0` means unlimited. Decimals allowed, like `0.5`. |
| `WARPBOX_GLOBAL_MAX_BOX_SIZE_GB` | `0` | Per-box cap in GB using `1024^3` conversion; `0` means unlimited. Decimals allowed. |
| `WARPBOX_DEFAULT_USER_MAX_FILE_SIZE_GB` | `0` | Default user file cap in GB using `1024^3` conversion. |
| `WARPBOX_DEFAULT_USER_MAX_BOX_SIZE_GB` | `0` | Default user box cap in GB using `1024^3` conversion. |
| `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. |

Legacy `_MB` and `_BYTES` size env names are still accepted for compatibility, but GB env names are the intended format now. GB input uses `1024^3` bytes so UI limits and displayed space stay consistent.

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).

## Docker / Podman

If you are using Podman, please pay attention in the [docker-compose.yml](./docker-compose.example.yml) example
file that has been provided, there's comments in regards to differences between the two.


When it comes to building the image, please make sure that you basically set the `--format docker` in the podman
build command, otherwise it won't have HealthChecks and other issues might arise.

Tip: Put the following in `~/.config/containers/containers.conf`
```toml
[engine]
image_default_format = "docker"
```

For just running the docker-compose.yml with docker image format:
```bash
BUILDAH_FORMAT=docker podman compose up --build
```


