This repository has been archived on 2026-03-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Sienna Meridian Satterwhite 58237d9e44 Initial commit — Drive, an S3 file browser with WOPI editing
Lightweight replacement for the upstream La Suite Numérique drive
(Django/Celery/Next.js) built as a single Deno binary.

Server (Deno + Hono):
- S3 file operations via AWS SigV4 (no SDK) with pre-signed URLs
- WOPI host for Collabora Online (CheckFileInfo, GetFile, PutFile, locks)
- Ory Kratos session auth + CSRF protection
- Ory Keto permission model (OPL namespaces, not yet wired to routes)
- PostgreSQL metadata with recursive folder sizes
- S3 backfill API for registering files uploaded outside the UI
- OpenTelemetry tracing + metrics (opt-in via OTEL_ENABLED)

Frontend (React 19 + Cunningham v4 + react-aria):
- File browser with GridList, keyboard nav, multi-select
- Collabora editor iframe (full-screen, form POST, postMessage)
- Profile menu, waffle menu, drag-drop upload, asset type badges
- La Suite integration service theming (runtime CSS)

Testing (549 tests):
- 235 server unit tests (Deno) — 90%+ coverage
- 278 UI unit tests (Vitest) — 90%+ coverage
- 11 E2E tests (Playwright)
- 12 integration service tests (Playwright)
- 13 WOPI integration tests (Playwright + Docker Compose + Collabora)

MIT licensed.
2026-03-25 18:28:37 +00:00

Drive

An S3 file browser with WOPI-based document editing, built for La Suite Numérique. One Deno binary. No Django, no Celery, no Next.js — files, folders, and Collabora. That's the whole thing.

Built by Sunbeam Studios as a drop-in replacement for the upstream drive. The original is a Django/Celery/Next.js stack. This is a single binary that does the same job.

Status: Running in production. WOPI editing, pre-signed uploads, folder sizes, game asset hooks, full Ory integration — all shipping. We're replacing upstream drive one feature at a time.


What it does

Feature How it works
File browser Navigate folders, sort, search, multi-select. react-aria underneath for keyboard + screen reader support.
Document editing Double-click a .docx/.odt/.xlsx → Collabora Online opens via WOPI. Full-screen, no chrome.
Pre-signed uploads Browser uploads straight to S3. File bytes never touch the server. Multi-part for large files.
Game asset support Type detection for FBX, glTF, textures (DDS, KTX), audio, video. Icons + badges now, previews later.
Folder sizes Recursive PostgreSQL functions. Size updates propagate up the ancestor chain on every file change.
OIDC auth Ory Kratos sessions + Ory Hydra OAuth2. Same identity stack as every other La Suite app.
Permissions Ory Keto (Zanzibar-style). Hierarchical: bucket → folder → file, with group support.
Theming La Suite integration service provides runtime CSS. Dark mode, custom fonts, waffle menu — one URL.
S3 backfill Files dropped directly into SeaweedFS? Hit the backfill endpoint and they show up in the browser with correct metadata.

Architecture

Browser ──→ Deno/Hono Server ──→ SeaweedFS (S3)
                │                   PostgreSQL (metadata)
                │                   Valkey (WOPI locks)
                │                   Ory Keto (permissions)
                ├──→ Collabora Online (WOPI callbacks)
                └──→ Ory Kratos (session validation)

One Deno binary (~450KB JS + static UI). Hono routes requests, the UI is a Vite-built React SPA from ui/dist. deno compile packs it all into a single executable.


Quick start

# Prerequisites: Deno 2.x, Node 20+, PostgreSQL, SeaweedFS (or weed mini)

# Install UI deps + build
cd ui && npm install && npx vite build && cd ..

# Create database + run migrations
createdb driver_db
DATABASE_URL="postgres://localhost/driver_db" deno run -A server/migrate.ts

# Start
DATABASE_URL="postgres://localhost/driver_db" \
SEAWEEDFS_S3_URL="http://localhost:8333" \
deno run -A main.ts

Open http://localhost:3000. That's it.

For the full stack with Collabora editing, see docs/local-dev.md.


Project structure

drive/
├── main.ts                 Hono app entry — all routes
├── deno.json               Tasks, imports
├── compose.yaml            Docker Compose for WOPI integration testing
├── server/
│   ├── auth.ts             Kratos session middleware
│   ├── csrf.ts             CSRF protection (HMAC double-submit)
│   ├── telemetry.ts        OpenTelemetry tracing + metrics middleware
│   ├── db.ts               PostgreSQL client
│   ├── migrate.ts          Schema migrations
│   ├── s3.ts               S3 client (AWS SigV4, no SDK)
│   ├── s3-presign.ts       Pre-signed URL generation
│   ├── files.ts            File CRUD + user state handlers
│   ├── folders.ts          Folder operations
│   ├── keto.ts             Ory Keto HTTP client
│   ├── permissions.ts      Permission middleware + tuple lifecycle
│   ├── backfill.ts         S3 → DB backfill API
│   └── wopi/
│       ├── handler.ts      WOPI endpoints (CheckFileInfo, GetFile, PutFile, locks)
│       ├── token.ts        JWT access tokens for WOPI
│       ├── lock.ts         Valkey-backed lock service
│       └── discovery.ts    Collabora discovery XML cache
├── ui/
│   ├── src/
│   │   ├── main.tsx        Vite entry point
│   │   ├── App.tsx         CunninghamProvider + Router
│   │   ├── layouts/        AppLayout (header + sidebar + main)
│   │   ├── pages/          Explorer, Recent, Favorites, Trash, Editor
│   │   ├── components/     FileBrowser, FileUpload, CollaboraEditor, ProfileMenu, etc.
│   │   ├── api/            React Query hooks + fetch client
│   │   ├── stores/         Zustand (selection, upload queue)
│   │   ├── hooks/          Asset type detection, preview capabilities
│   │   └── cunningham/     Cunningham theme integration
│   └── e2e/                Playwright tests (driver, wopi, integration-service)
├── keto/
│   └── namespaces.ts       OPL permission model
└── tests/
    └── server/             Deno test files (10 files)

Stack

Layer Technology
Server Deno + Hono
Frontend React 19 + Cunningham v4 + react-aria
Storage SeaweedFS (S3-compatible)
Database PostgreSQL (file registry, folder sizes)
Cache Valkey (WOPI locks with TTL)
Auth Ory Kratos (identity) + Ory Hydra (OAuth2/OIDC)
Permissions Ory Keto (Zanzibar-style ReBAC)
Document editing Collabora Online via WOPI
Theming La Suite integration service
Build deno compile → single binary

Testing

# Server unit tests (Deno)
deno task test

# UI unit tests (Vitest)
cd ui && npx vitest run

# UI unit tests with coverage
cd ui && npx vitest run --coverage

# E2E tests (Playwright — needs running server + weed mini + PostgreSQL)
cd ui && npx playwright test e2e/driver.spec.ts

# Integration service tests (Playwright — hits production integration.sunbeam.pt)
cd ui && INTEGRATION_URL=https://integration.sunbeam.pt npx playwright test e2e/integration-service.spec.ts

# WOPI integration tests (Playwright — needs docker compose stack)
docker compose up -d
# start server pointed at compose services, then:
cd ui && DRIVER_URL=http://localhost:3200 npx playwright test e2e/wopi.spec.ts

90%+ line coverage on both server and UI. See docs/testing.md for the full breakdown.


Environment variables

Variable Default Description
PORT 3000 Server listen port
PUBLIC_URL http://localhost:3000 Public-facing URL (used in WOPI callbacks + redirects)
DATABASE_URL postgres://driver:driver@localhost:5432/driver_db PostgreSQL connection string
SEAWEEDFS_S3_URL http://seaweedfs-filer.storage.svc.cluster.local:8333 S3 endpoint
SEAWEEDFS_ACCESS_KEY (empty) S3 access key
SEAWEEDFS_SECRET_KEY (empty) S3 secret key
S3_BUCKET sunbeam-driver S3 bucket name
S3_REGION us-east-1 S3 region for signing
VALKEY_URL redis://localhost:6379/2 Valkey/Redis URL for WOPI locks (falls back to in-memory if unavailable)
KRATOS_PUBLIC_URL http://kratos-public.ory.svc.cluster.local:80 Kratos public API
KETO_READ_URL http://keto-read.ory.svc.cluster.local:4466 Keto read API
KETO_WRITE_URL http://keto-write.ory.svc.cluster.local:4467 Keto write API
COLLABORA_URL http://collabora.lasuite.svc.cluster.local:9980 Collabora Online
WOPI_JWT_SECRET dev-wopi-secret-change-in-production HMAC secret for WOPI access tokens
CSRF_COOKIE_SECRET dev-secret-change-in-production HMAC secret for CSRF tokens
DRIVER_TEST_MODE (unset) Set to 1 to bypass auth (E2E testing only)

Docs

Doc What's in it
Architecture How the pieces fit together and why there aren't many of them
WOPI Collabora integration — discovery, tokens, locks, the iframe dance
Permissions Keto OPL model — Zanzibar-style, hierarchical traversal
S3 Layout Human-readable keys, backfill, the metadata layer
Testing Five test suites, coverage targets, Docker Compose for WOPI
Local Dev Zero to running in 2 minutes
Deployment Kubernetes, Collabora config, deployment checklist

License

MIT — do whatever you want with it.

Questions? hello@sunbeam.pt

Description
No description provided
Readme 308 KiB
Languages
TypeScript 99.9%