Rebuild the hub on Bun: Elysia API, Better Auth, Drizzle, Next.js website
CI / test (push) Successful in 30s
CI / test (push) Successful in 30s
The hub becomes a Bun monorepo: apps/api (Elysia, Better Auth for accounts, roles, bans, proxy device sign-in and JWT keys; tagline linking, presence and the console as before), packages/db (Drizzle; Postgres in production, PGlite in development and tests), and the Next.js website from apps/web. Self-hostable with docker compose; the website deploys to Vercel-style hosts, the API to any that runs Bun or containers. The first version, in Go, is removed. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
64c552330b
commit
7a06ba49c3
59 files changed
+2640
-3523
No files matched your search
@@ -2,32 +2,48 @@
|
||||
|
||||
T5DE's hub: accounts linked to IMVU accounts, presence, and (to come) the registry of community products and
|
||||
catalogs, T5DE-hosted rooms, and the moderation console. Part of T5DE (git.t5de.dev/t5de). Design:
|
||||
[docs/design.md](docs/design.md); what a room needs from a server: [docs/imq-rooms.md](docs/imq-rooms.md).
|
||||
[docs/design.md](docs/design.md); the API: [docs/api.md](docs/api.md); what a room needs from a server:
|
||||
[docs/imq-rooms.md](docs/imq-rooms.md).
|
||||
|
||||
## What works
|
||||
|
||||
- **Accounts**: sign-up and sign-in (Argon2id passwords), sessions with CSRF protection. The first account is an
|
||||
admin.
|
||||
- **Accounts** (Better Auth): sign-up with email, username and password; sign-in by username. The first account is
|
||||
an admin; roles user, moderator, admin.
|
||||
- **Linking IMVU accounts**: the person puts a code in the account's tagline; the hub reads it from IMVU's public
|
||||
API. The most recent proof wins (an account linked elsewhere moves). Link caps per person (default 10).
|
||||
- **Age**: an account counts as adult if IMVU says it's age verified or has Access Pass, checked by the hub.
|
||||
- **Proxy sign-in**: OAuth 2.0 device codes (`t5de-proxy signin` shows a code to enter at `/device`); Ed25519 JWT
|
||||
access tokens (keys at `/.well-known/jwks.json`) and rotating refresh tokens.
|
||||
API. The most recent proof wins (an account linked elsewhere moves, with a new pairwise ID). Link caps per person
|
||||
(default 10).
|
||||
- **Age**: an IMVU account counts as adult if IMVU says it's age verified or has Access Pass, checked by the hub.
|
||||
- **Proxy sign-in**: OAuth 2.0 device authorization (`t5de-proxy signin` shows a code to enter at `/device`); the
|
||||
proxy then uses its session as a bearer token. JWTs with published keys (`/.well-known/jwks.json`) for catalogs.
|
||||
- **Presence**: signed-in proxies keep a WebSocket (`/api/v1/realtime`) telling the hub which IMVU account is in
|
||||
use and the community products it wears. `/online` shows accounts that opted in, with the opt-in T5DE badge.
|
||||
- **Console** (moderators): counts, who's online (live), people search, link caps, bans, roles, audit log.
|
||||
use and the community products it wears. `/online` shows those who opted in, live, with the opt-in T5DE badge.
|
||||
- **Console** (moderators): counts, who's online (live), people, link caps, bans, roles, the audit log.
|
||||
|
||||
## Layout
|
||||
|
||||
A Bun monorepo (workspaces, Turborepo):
|
||||
|
||||
| | |
|
||||
| --- | --- |
|
||||
| `apps/api` | The API: Elysia on Bun, Better Auth, the realtime WebSocket. Port 4101. |
|
||||
| `apps/web` | The website: Next.js 16 (React server components), Tailwind CSS 4, shadcn/ui. Port 4100. Calls the API through its own `/api` (rewrites), typed end to end with Eden. |
|
||||
| `packages/db` | Drizzle schema and migrations; Postgres in production, PGlite (in-process Postgres) for development and tests. |
|
||||
|
||||
## Development
|
||||
|
||||
Needs Bun (1.4) and Node (for Next.js).
|
||||
|
||||
bun install
|
||||
bun run dev # the API on :4101 (database in apps/api/data) and the website on :4100
|
||||
|
||||
`bun run test` tests the API against PGlite; `bun run check-types`, `bun run build`.
|
||||
|
||||
## Running it
|
||||
|
||||
go run ./cmd/t5de-hub -dev
|
||||
- **Self-hosted**: `AUTH_SECRET=$(openssl rand -base64 32) docker compose up -d` runs Postgres, the API and the
|
||||
website (see `docker-compose.yml` for the public addresses).
|
||||
- **Elsewhere**: the website deploys as is to Vercel and similar (`apps/web`, env `API_URL`); the API to any host
|
||||
that runs Bun or containers (Railway, Render, Fly.io, Heroku), with `DATABASE_URL`, `AUTH_SECRET`, `API_URL` (its
|
||||
public address) and `WEB_URL` (the website's).
|
||||
|
||||
runs the hub at http://127.0.0.1:8080 with its own Postgres (downloaded once, kept in `t5de-hub-data/`). In
|
||||
production: `t5de-hub -db postgres://... -public-url https://hub.t5de.dev -listen :8080 -data /var/lib/t5de-hub`
|
||||
(the data directory holds the token signing key).
|
||||
|
||||
To point a T5DE proxy at it: `t5de-proxy signin -hub http://127.0.0.1:8080`.
|
||||
|
||||
## Tests
|
||||
|
||||
`go test ./...` runs everything, the website and API against a real Postgres (embedded, downloaded on first run
|
||||
and cached; `T5DE_PG_CACHE` sets where), or the Postgres at `T5DE_TEST_DB` (as CI does), and a fake IMVU API.
|
||||
T5DE's proxies reach the API's address directly (sign-in and the WebSocket): `t5de-proxy signin -hub <API address>`.
|
||||
Reference in new issue
Block a user