From 27c8cb50f8bd6798bbe06cd6169cfb08a4449720 Mon Sep 17 00:00:00 2001 From: Trezy Date: Sun, 22 Mar 2026 13:52:13 -0500 Subject: [PATCH] docs: add plugin docs --- docs/README.md | 2 + docs/guides/plugins.md | 170 ++++++++++++++++++ docs/plugins.md | 51 ------ sidebars.ts | 5 + .../app/dashboard/settings/plugins/page.tsx | 12 -- 5 files changed, 177 insertions(+), 63 deletions(-) create mode 100644 docs/guides/plugins.md delete mode 100644 docs/plugins.md diff --git a/docs/README.md b/docs/README.md index 7a22ced..147fb7a 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,7 @@ Building an AppView from scratch means wiring up firehose connections, record st - 🌐 **Network Lexicons**: Fetch lexicon schemas directly from the AT Protocol network via DNS authority resolution - ⚡ **Hot Reloading**: Upload or update lexicons at runtime, and new endpoints are available immediately with no restart - 🏷️ **Label Support**: Subscribe to external [labelers](guides/labelers.md) and surface content labels on records, with self-label detection and color-coded badges in the dashboard +- 🔌 **Plugin System**: Extend HappyView with WASM [plugins](guides/plugins.md) that integrate with external platforms like Steam, Xbox, and itch.io - 🛠️ **Admin Dashboard**: Manage lexicons, monitor record stats, and run backfill jobs through a built-in admin API ## Design Principles @@ -34,4 +35,5 @@ Building an AppView from scratch means wiring up firehose connections, record st - [Lua Scripting](guides/scripting.md): Write custom query and procedure logic - [Index Hooks](guides/index-hooks.md): React to record changes in real time - [Labelers](guides/labelers.md): Subscribe to external labelers and manage content labels +- [Plugins](guides/plugins.md): Integrate with external platforms using WASM plugins - [Event Logs](guides/event-logs.md): Monitor system activity, debug script errors, and audit admin actions diff --git a/docs/guides/plugins.md b/docs/guides/plugins.md new file mode 100644 index 0000000..8132c2f --- /dev/null +++ b/docs/guides/plugins.md @@ -0,0 +1,170 @@ +# Plugins + +HappyView uses WASM plugins to integrate with external platforms. Auth plugins enable users to link their accounts from platforms like Steam, Xbox, itch.io, and others, then sync data (like game libraries) to their AT Protocol identity. + +Official plugins for Steam, Xbox, itch.io, and other platforms are available in the [happyview-plugins](https://github.com/gamesgamesgamesgames/happyview-plugins) repository. + +## Installing Plugins + +### Via Dashboard + +1. Go to **Settings > Plugins** +2. Click **Add Plugin** +3. Enter the URL to a plugin's `manifest.json` or `.wasm` file +4. Review the plugin details and click **Install Plugin** +5. Configure any required secrets using the settings button + +### Via Environment Variables + +Set `PLUGIN_URLS` to load plugins at startup: + +``` +PLUGIN_URLS=steam|https://example.com/plugins/steam/manifest.json +``` + +Format: `id|url` or `id|url|sha256:hash` (comma-separated for multiple). + +### Via File System + +Place plugins in the `./plugins/` directory: + +``` +plugins/ + steam/ + manifest.json + plugin.wasm +``` + +## Plugin Configuration + +Plugins may require secrets (API keys, client credentials, etc.) to function. There are two ways to configure these: + +### Dashboard Configuration + +Click the settings icon next to a plugin to enter secrets. These are encrypted using AES-256-GCM and stored in the database. + +**Requires:** `TOKEN_ENCRYPTION_KEY` environment variable (base64-encoded 32-byte key). + +Generate one with: +```bash +openssl rand -base64 32 +``` + +### Environment Variables + +Set secrets as environment variables with the `PLUGIN__` prefix: + +```bash +PLUGIN_STEAM_API_KEY=your-api-key +PLUGIN_XBOX_CLIENT_ID=your-client-id +PLUGIN_XBOX_CLIENT_SECRET=your-client-secret +``` + +Dashboard-configured secrets take precedence over environment variables. + +## Plugin Manifest + +Each plugin has a `manifest.json` that describes its metadata: + +```json +{ + "id": "steam", + "name": "Steam", + "version": "1.0.0", + "api_version": "1", + "description": "Import your Steam game library and playtime data.", + "icon_url": "https://example.com/steam-icon.png", + "auth_type": "openid", + "wasm_file": "steam.wasm", + "required_secrets": [ + { + "key": "PLUGIN_STEAM_API_KEY", + "name": "Steam Web API Key", + "description": "Get your API key at steamcommunity.com/dev/apikey" + } + ] +} +``` + +| Field | Description | +|-------|-------------| +| `id` | Unique plugin identifier | +| `name` | Display name | +| `version` | Semantic version | +| `api_version` | Plugin API version (currently "1") | +| `description` | Brief description shown during install | +| `icon_url` | Optional icon URL | +| `auth_type` | Authentication type: `oauth2`, `openid`, or `api_key` | +| `wasm_file` | WASM binary filename (default: `plugin.wasm`) | +| `required_secrets` | Array of secrets the plugin needs | + +## API Endpoints + +### Public Endpoints + +| Endpoint | Description | +|----------|-------------| +| `GET /external-auth/providers` | List available auth providers | +| `GET /external-auth/accounts` | List user's linked accounts | +| `GET /external-auth/{plugin}/authorize` | Start OAuth flow | +| `GET /external-auth/{plugin}/callback` | OAuth callback handler | +| `POST /external-auth/{plugin}/sync` | Sync data from linked account | +| `POST /external-auth/{plugin}/unlink` | Unlink account | +| `POST /external-auth/{plugin}/connect` | Connect with API key (for `api_key` auth type) | + +### Admin Endpoints + +| Endpoint | Description | +|----------|-------------| +| `GET /admin/plugins` | List installed plugins | +| `POST /admin/plugins` | Install a plugin | +| `POST /admin/plugins/preview` | Preview plugin before installing | +| `DELETE /admin/plugins/{id}` | Remove a plugin | +| `POST /admin/plugins/{id}/reload` | Reload plugin from source | +| `GET /admin/plugins/{id}/secrets` | Get configured secrets (masked) | +| `PUT /admin/plugins/{id}/secrets` | Update plugin secrets | + +## Security + +- **Sandboxed execution**: Plugins run in isolated WASM environments +- **Limited host access**: Plugins can only call approved host functions (HTTP requests, KV storage, secrets, logging) +- **Encrypted storage**: OAuth tokens and secrets are encrypted at rest using AES-256-GCM +- **Scoped storage**: Plugin KV storage is isolated per-plugin and per-user +- **No filesystem access**: Plugins cannot access the host filesystem + +## Developing Plugins + +See the [happyview-plugins](https://github.com/gamesgamesgamesgames/happyview-plugins) repository for examples and the plugin SDK. + +### Plugin Exports + +Plugins must export these functions: + +| Export | Signature | Description | +|--------|-----------|-------------| +| `alloc` | `(size: u32) -> u32` | Allocate memory | +| `dealloc` | `(ptr: u32, size: u32)` | Deallocate memory | +| `get_authorize_url` | `(ptr: u32, len: u32) -> i64` | Generate OAuth authorize URL | +| `handle_callback` | `(ptr: u32, len: u32) -> i64` | Handle OAuth callback | +| `refresh_tokens` | `(ptr: u32, len: u32) -> i64` | Refresh expired tokens | +| `get_profile` | `(ptr: u32, len: u32) -> i64` | Get external profile info | +| `sync_account` | `(ptr: u32, len: u32) -> i64` | Sync data and return records | + +### Host Functions + +Plugins can import these host functions: + +| Import | Description | +|--------|-------------| +| `host_http_request` | Make HTTP requests | +| `host_get_secret` | Read configured secrets | +| `host_log` | Write to server logs | +| `host_kv_get` | Read from KV storage | +| `host_kv_set` | Write to KV storage | +| `host_kv_delete` | Delete from KV storage | + +## Next steps + +- [Official plugins repository](https://github.com/gamesgamesgamesgames/happyview-plugins) — ready-to-use plugins for Steam, Xbox, itch.io, and more +- [API Keys](api-keys.md) — authenticate programmatic access to admin endpoints +- [Permissions](permissions.md) — configure user access to plugin management diff --git a/docs/plugins.md b/docs/plugins.md deleted file mode 100644 index 095fd17..0000000 --- a/docs/plugins.md +++ /dev/null @@ -1,51 +0,0 @@ -# HappyView Plugin System - -HappyView supports WASM plugins for extending functionality. The first plugin type is external auth providers (Steam, GOG, Epic, etc.). - -## Configuration - -### Environment Variables - -- `TOKEN_ENCRYPTION_KEY`: Base64-encoded 32-byte key for encrypting OAuth tokens (required for external auth) -- `PLUGIN_URLS`: Comma-separated list of plugins to load from URLs - -### PLUGIN_URLS Format - -``` -id|url|sha256:hash,id|url|sha256:hash -``` - -Example: -``` -PLUGIN_URLS=steam|https://github.com/org/plugins/releases/download/v1.0.0/steam.wasm|sha256:abc123 -``` - -### File-based Plugins - -Place plugins in the `./plugins/` directory: - -``` -plugins/ - steam/ - plugin.wasm - plugin.toml -``` - -## API Endpoints - -- `GET /external-auth/providers` - List available auth providers -- `GET /external-auth/{plugin_id}/authorize?redirect_uri=...` - Start auth flow -- `GET /external-auth/{plugin_id}/callback` - OAuth callback -- `POST /external-auth/{plugin_id}/sync` - Sync account data -- `POST /external-auth/{plugin_id}/unlink` - Unlink account - -## Plugin Development - -See the [Plugin Development Guide](./plugin-development.md) for creating custom plugins. - -## Security - -- OAuth tokens are encrypted at rest using AES-256-GCM -- Plugins run in a sandboxed WASM environment -- Plugins can only access host functions (HTTP, KV, secrets, logging) -- KV storage is scoped per-plugin and per-user diff --git a/sidebars.ts b/sidebars.ts index cad4372..395a411 100644 --- a/sidebars.ts +++ b/sidebars.ts @@ -94,6 +94,11 @@ const sidebars: SidebarsConfig = { id: "guides/event-logs", label: "Event Logs", }, + { + type: "doc", + id: "guides/plugins", + label: "Plugins", + }, ], }, { diff --git a/web/src/app/dashboard/settings/plugins/page.tsx b/web/src/app/dashboard/settings/plugins/page.tsx index d0cdcfa..054a759 100644 --- a/web/src/app/dashboard/settings/plugins/page.tsx +++ b/web/src/app/dashboard/settings/plugins/page.tsx @@ -465,18 +465,6 @@ export default function PluginsPage() { )} -
-

Plugin Configuration

-

- Configure plugin secrets using the button. - Alternatively, set environment variables like{" "} - PLUGIN_STEAM_API_KEY. -

-

- Dashboard-configured secrets take precedence over environment variables. -

-
- {/* Configure Secrets Dialog */} -- 2.51.2