What it is
Self-hosted Google-Drive-style file sharing: accounts (guest/register, first user = admin ⭐), per-file & per-folder passwords, folders, trash, per-user stars, search, versions, ZIP downloads, and a launchd auto-start service with self-healing Cloudflare tunnel. Live at da.gd/isaacdrop.
Version history
Straight from the project’s own card data — what each version added.
Drop-style file sharing with links.
Drive-style: folders, trash, star, search, versions, ZIP, folder passwords.
Accounts + ownership: guests, register, admin role, owner-only manage.
Files on the site
By the numbers
Measured from the real working folder ~/Documents/projects/apps/IsaacDrop/ — not a claim, a count.
Mostly: JavaScript ×9 · Shell ×6 · Python ×6 · JSON ×2 · Markdown ×1 · TOML ×1
What broke, and what I’d change
Not written yet. This is the part only I can write — what actually went wrong, and what I’d do differently. It lives in builds/reflections/isaacdrop.md (see _TEMPLATE.md); as soon as that file has words in it, this section fills in on the next build.
Everything else on this page — the spec, the version history, the file counts — is generated from the project’s own build notes and files, so nothing here is guesswork.
Build spec
The project’s own build notes, rendered. Open the raw .md ↗
Show the spec
IsaacDrop — Self-Hosted File Sharing (Google-Drive-Style + Passwords)
Stack: Python FastAPI + uvicorn, single-file dark-theme HTML SPA, cloudflared tunnel + launchd, da.gd + GitHub Pages redirect. Lives at ~/Documents/projects/apps/IsaacDrop/, port 8585.
How it works
- Single
server/main.py(~1100 lines): JSON metadata (data/files.json), blobs indata/storage/, users indata/users.json. Stateless HMAC tokens: file-unlock tokens (6h), login tokens (7d,X-Auth-Token). run-servers.sh(launchd agentcom.isaac.isaacdrop, KeepAlive + RunAtLoad): boots uvicorn + cloudflared, extracts the trycloudflare URL, re-points~/Desktop/portfolio-deploy/camdrive.html(GitHub Pages redirect) to it, commits + pushes. Killed server/tunnel → loop exits → launchd restarts the pair with a fresh URL.caffeinate -skeeps the Mac awake on AC.- Public chain:
da.gd/isaacdrop→https://isaac1804.com/portfolio/camdrive.html→ tunnel → local server. (da.gd blacklists trycloudflare.com.)
Features
- Accounts: register/login (first account = admin ⭐), guests browse/upload/download. Every file/folder has an
owner; only owner or admin can rename/move/trash/restore/purge/protect/restore-version/create folders; uploads over a same-name file require ownership (409 otherwise). Admin Users panel: promote/demote (last-admin + self-demote guards), reset password, delete user. Guests get a delete-link for each upload. - Drive: folders + breadcrumbs, trash/restore, star (per-user), search, sort, multi-select ZIP download (incl. folders), version history (re-upload same name, restore any version), inline previews (image/video/audio/PDF/text), expiry per file.
- Protection: per-file AND per-folder passwords (name hidden until unlocked; folder gate blocks browse/upload/download; token scoped to the gating folder). Optional expiry 1h/1d/7d/30d/never.
- Admin console: account chip bottom-left → Login/Register/Account/Logout; ⭐ Admins-only 👥 Users button.
Key details
- Token payload:
{scope}.{expiry}.{hmac-sha256}withdata/secret.key(survives restarts). - Upload streams to disk in 1MB chunks (2GB cap via
MAX_UPLOAD_MB). - Frontend
api()wrapper attachesX-Auth-Token, auto-opens the Login modal on 403{"auth":"login_required"}, toasts on{"forbidden"}(not owner) /{"admin"}. - 101 automated tests (curl API + Playwright UI) all pass — see session notes for the suites.
Usage
- Start:
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.isaac.isaacdrop.plist(already installed) — or double-clickIsaacDrop-AutoStart.command/ stop withIsaacDrop-Stop.command. - Manual:
.venv/bin/python launcher.py(LAN) /launcher.py --public(tunnel). - Logs:
~/Library/Logs/IsaacDrop/{server,tunnel,agent,redirect}.log. - Register the first account on the page to become admin.