Skip to content

rix1/drop

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

drop

drop is a small local file sharing tool for machines that are reachable through a reverse tunnel such as Cloudflare Tunnel or Tailscale Funnel.

The intended workflow is explicit:

drop add ~/Desktop/file.md --expires 24h | pbcopy
drop share ~/Drop/file.md --expires 24h | pbcopy

The printed URL includes the filename for trust, but the random token is the only authority:

https://drop-1.rix1.dev/d/n4Ph7xQ9sL/file.md

Status

This is a pragmatic v1:

  • explicit shares only; no file watcher
  • one configured share root
  • random unguessable URLs
  • live filesystem checks, so deleted files become unavailable
  • direct file downloads
  • minimal directory listings
  • expiry and revoke support
  • basic analytics: access count, download count, bytes sent, IP, user agent
  • lock-file protected JSON database for concurrent CLI/server use
  • loopback-only server by default
  • symlink serving is rejected
  • no-cache, no-index, no-sniff, and frame-deny response headers
  • no third-party runtime dependencies
  • small HTTP serving surface in src/server.ts; CLI commands, shared storage/path-safety logic, and shared types live separately in src/cli.ts, src/core.ts, and src/types.ts

Quick Start

For local development:

deno task drop help
deno task drop serve

Add this checkout's bin directory to your shell path:

export PATH="/Users/rix1/Development/drop/bin:$PATH"

Then configure one machine:

mkdir -p "$HOME/Drop" "$HOME/.config/drop"

Create ~/.config/drop/config.json:

{
  "root": "~/Drop",
  "db": "~/.drop/drop-db.json",
  "baseUrl": "https://drop-1.rix1.dev",
  "bind": "127.0.0.1:7777",
  "maxEvents": 10000,
  "maxDirectoryEntries": 1000,
  "trustProxyHeaders": "cloudflare",
  "allowPublicBind": false
}

Smoke test locally:

drop config
drop serve

In another terminal:

curl http://127.0.0.1:7777/health
drop add README.md --expires 10min | pbcopy

Commands

drop share ~/Drop/file.md --expires 24h
drop add ~/Desktop/file.md --expires 24h
drop add ~/Desktop/file.md --move --expires 24h
drop add ~/Desktop/file.md --name readable-name.md --expires 24h
drop ls
drop stats file.md
drop events file.md
drop revoke file.md
drop serve

Expiry values support 10min, 1hr, 24hr, 7d, forever, plus simple durations such as 15m, 2h, and 3d.

Production Setup

Install prerequisites:

brew install deno cloudflared

Run checks before installing:

deno task check
deno task test

Use a restricted server command in production:

deno run \
  --allow-env=HOME,DROP_CONFIG,DROP_ROOT,DROP_DB,DROP_BASE_URL,DROP_BIND,DROP_TRUST_PROXY_HEADERS,DROP_ALLOW_PUBLIC_BIND \
  --allow-read="$HOME/Drop,$HOME/.drop,$HOME/.config/drop" \
  --allow-write="$HOME/Drop,$HOME/.drop" \
  --allow-net=127.0.0.1 \
  src/drop.ts serve

Keep bind on 127.0.0.1. drop serve --bind 0.0.0.0:7777 is refused unless --allow-public-bind is passed.

Cloudflare Tunnel

Point drop-1.rix1.dev at the local server:

cloudflared tunnel login
cloudflared tunnel create drop-imac
cloudflared tunnel route dns drop-imac drop-1.rix1.dev

Create ~/.cloudflared/config.yml:

tunnel: drop-imac
credentials-file: /Users/rix1/.cloudflared/drop-imac.json

ingress:
  - hostname: drop-1.rix1.dev
    service: http://127.0.0.1:7777
  - service: http_status:404

Run it:

cloudflared tunnel run drop-imac

drop uses CF-Connecting-IP when present, so analytics show the downloader IP behind Cloudflare Tunnel. Keep the server bound to 127.0.0.1 so that header cannot be spoofed by direct traffic.

launchd

Copy the template:

cp examples/dev.rix1.drop.plist "$HOME/Library/LaunchAgents/dev.rix1.drop.plist"

Edit paths if deno, the checkout, or your home directory differ:

plutil -lint "$HOME/Library/LaunchAgents/dev.rix1.drop.plist"
launchctl bootstrap "gui/$(id -u)" "$HOME/Library/LaunchAgents/dev.rix1.drop.plist"
launchctl kickstart -k "gui/$(id -u)/dev.rix1.drop"

Logs:

tail -f "$HOME/Library/Logs/drop.log" "$HOME/Library/Logs/drop.err.log"

For cloudflared, either run cloudflared service install or create a separate launchd service that runs cloudflared tunnel run drop-imac.

Configuration

Environment variables override the config file:

export DROP_ROOT="$HOME/Drop"
export DROP_DB="$HOME/.drop/drop-db.json"
export DROP_BASE_URL="https://drop-1.rix1.dev"
export DROP_BIND="127.0.0.1:7777"
export DROP_TRUST_PROXY_HEADERS="cloudflare"

trustProxyHeaders can be none, cloudflare, or all. Use cloudflare for Cloudflare Tunnel. Use all only behind a trusted reverse proxy that strips incoming client-supplied proxy headers.

Notes

Directory shares grant access to files under that directory through the same token. The URL path after the display name is still checked against the configured share root before anything is served.

download_count increments on successful full-file GET responses. Range requests are logged and counted as accesses, but not as complete downloads.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors