A CLI for publishing standard.site documents to ATProto
at test 93 lines 3.0 kB view raw view rendered
1# Sequoia Server 2 3Self-hostable AT Protocol OAuth and subscription server. Handles Bluesky login and manages `site.standard.graph.subscription` records on behalf of users. Built with Bun, Hono, and Redis. 4 5## Quickstart 6 7### Docker (recommended) 8 9```bash 10cp .env.example .env 11# Edit .env — at minimum set CLIENT_URL to your public URL 12docker compose up 13``` 14 15### Local development 16 17Requires [Bun](https://bun.sh) and a running Redis instance. 18 19```bash 20bun install 21CLIENT_URL=http://localhost:3000 bun run dev 22``` 23 24## How it works 25 261. A user visits `/subscribe?publicationUri=at://...` and enters their Bluesky handle 272. The server initiates an AT Protocol OAuth flow — the user authorizes on Bluesky 283. After callback, the server creates a `site.standard.graph.subscription` record in the user's repo 294. The [sequoia-subscribe](https://github.com/standard-schema/sequoia) web component can point to this server for the full flow 30 31### Routes 32 33| Route | Method | Description | 34|-------|--------|-------------| 35| `/api/health` | GET | Health check | 36| `/oauth/client-metadata.json` | GET | OAuth client metadata | 37| `/oauth/login?handle=` | GET | Start OAuth flow | 38| `/oauth/callback` | GET | OAuth callback | 39| `/oauth/logout` | POST | Revoke session | 40| `/oauth/status` | GET | Check auth status | 41| `/subscribe` | GET | Subscribe page (HTML) | 42| `/subscribe` | POST | Subscribe via API (JSON) | 43| `/subscribe/check` | GET | Check subscription status | 44| `/subscribe/login` | POST | Handle form submission | 45 46## Configuration 47 48| Variable | Required | Default | Description | 49|----------|----------|---------|-------------| 50| `CLIENT_URL` | Yes | — | Public URL of this server (used for OAuth redirects) | 51| `CLIENT_NAME` | No | `Sequoia` | Name shown on Bluesky OAuth consent screen | 52| `PORT` | No | `3000` | Server port | 53| `REDIS_URL` | No | `redis://localhost:6379` | Redis connection URL | 54 55### Theming 56 57The subscribe pages use CSS custom properties that can be overridden via environment variables: 58 59| Variable | Default | 60|----------|---------| 61| `THEME_ACCENT_COLOR` | `#3A5A40` | 62| `THEME_BG_COLOR` | `#F5F3EF` | 63| `THEME_FG_COLOR` | `#2C2C2C` | 64| `THEME_BORDER_COLOR` | `#D5D1C8` | 65| `THEME_ERROR_COLOR` | `#8B3A3A` | 66| `THEME_BORDER_RADIUS` | `6px` | 67| `THEME_FONT_FAMILY` | `system-ui, sans-serif` | 68| `THEME_DARK_BG_COLOR` | `#1A1A1A` | 69| `THEME_DARK_FG_COLOR` | `#E5E5E5` | 70| `THEME_DARK_BORDER_COLOR` | `#3A3A3A` | 71| `THEME_DARK_ERROR_COLOR` | `#E57373` | 72 73For full control, set `THEME_CSS_PATH` to a CSS file path (e.g. `/app/theme.css` mounted via Docker volume). It will be injected after the default styles. 74 75## Deployment 76 77The included `Dockerfile` produces a minimal image: 78 79```bash 80docker build -t sequoia-server . 81docker run -p 3000:3000 \ 82 -e CLIENT_URL=https://your-domain.com \ 83 -e REDIS_URL=redis://your-redis:6379 \ 84 sequoia-server 85``` 86 87Or use `docker-compose.yml` which bundles Redis: 88 89```bash 90docker compose up -d 91``` 92 93Place behind a reverse proxy (Caddy, nginx, Traefik) for TLS.