Harden client and WebSocket proxy

This commit is contained in:
2026-09-09 13:04:56 +02:00
parent f4f95ffff4
commit 8986f6270f
64 changed files with 4410 additions and 7313 deletions
+50 -105
View File
@@ -1,128 +1,73 @@
# SvelteMUD - A Modern MUD Client
# SvelteMUD
SvelteMUD is a feature-rich MUD (Multi-User Dungeon) client built with Svelte and SvelteKit, designed to provide a modern, accessible, and customizable interface for connecting to MUD servers.
SvelteMUD is an accessible, installable MUD client built with Svelte 5 and SvelteKit. It supports multiple simultaneous Telnet connections through a constrained WebSocket proxy, ANSI color, GMCP, triggers, profiles, and screen-reader-oriented navigation.
## Security model
- Browsers connect only to the same-origin `/mud-ws` endpoint. The proxy accepts a small JSON control protocol and carries Telnet data in binary WebSocket frames.
- The proxy rejects private, loopback, link-local, multicast, and otherwise special-use targets after DNS resolution. It pins the selected public address for the connection and verifies TLS certificates.
- Anonymous proxy use is rate-, connection-, bandwidth-, and buffer-limited. Resume tokens are random, single-tab credentials stored in `sessionStorage`, rotate after use, and expire after five minutes.
- Passwords are held in memory only. Existing passwords from older profile data are removed during migration, and backups never contain passwords.
- Server output is rendered as text, not HTML. Triggers cannot execute JavaScript. Trigger regular expressions are length- and complexity-limited.
- Server-requested remote media is disabled by default and must be enabled explicitly in Settings.
The proxy is intended for public MUD servers. It is not a general TCP tunnel and deliberately blocks access to private infrastructure and common mail ports.
## Features
### Core Functionality
- WebSocket to Telnet proxy for connecting to MUD servers
- Multiple simultaneous MUD connections via an MDI (Multiple Document Interface)
- ANSI color support
- Command history
- Configurable profiles for different MUD servers
- Auto-login functionality
- Progressive Web App (PWA) support for offline use and installation
- Multiple persistent connection tabs, including background output
- Incremental Telnet parsing and GMCP negotiation
- ANSI and 256-color output
- Plain-text and constrained regular-expression triggers
- Trigger highlighting, sounds, and command sending
- Per-profile command/output history
- High contrast, text-to-speech, font scaling, and keyboard navigation
- PWA installation and generated application icons
### GMCP Support
- Generic MUD Communication Protocol (GMCP) handling
- Support for common packages:
- Client.Media for sound playback
- Client.Keystroke for key capturing
- Easily extendable with custom GMCP packages
## Development
### Triggers System
- Pattern matching with plain text or regular expressions
- Actions:
- Sound playback on triggers
- Highlight matched text
- Send commands to the server
- Execute custom JavaScript code
### Accessibility Features
- Text-to-speech for incoming MUD text
- High contrast mode
- Configurable font size and family
- Keyboard navigation
- ARIA attributes for screen readers
## Installation
Requires Node.js 22 or newer.
```bash
# Clone the repository
git clone https://your-repo-url/svelte-mud.git
cd svelte-mud
# Install dependencies
npm install
# Start the development server
npm run dev
# Build for production
npm run build
npm ci
npm run dev:full
```
## Usage
`npm run dev:full` starts Vite and the WebSocket proxy. By default, development browser origins on localhost are accepted. Useful checks are:
1. **Creating a Profile**: Click "New Profile" to set up a connection to your MUD server. Configure host, port, and optional auto-login.
```bash
npm test
npm run check
npm run build
npm audit --omit=dev
```
2. **Connecting**: After creating a profile, click the connect button in the tab to establish a connection.
## Production configuration
3. **Setting Up Triggers**: Navigate to the Triggers tab and click "New Trigger" to create pattern matching triggers with various actions.
The supplied Docker Compose file runs the SvelteKit app and proxy as separate processes/containers. Caddy routes normal requests to the app and `/mud-ws` to the proxy.
4. **Customizing Settings**: Adjust appearance and accessibility options in the Settings tab.
Proxy environment variables:
## Project Structure
- `ALLOWED_ORIGINS`: comma-separated exact browser origins; required in production
- `TRUST_PROXY=1`: trust the first `X-Forwarded-For` address when deployed behind the configured reverse proxy
- `WS_PORT`: proxy listen port, default `3001`
- `src/lib/connection/` - MUD connection handling code
- `src/lib/gmcp/` - GMCP protocol handling
- `src/lib/triggers/` - Trigger system implementation
- `src/lib/accessibility/` - Accessibility features
- `src/lib/profiles/` - Profile management
- `src/lib/components/` - Svelte components
- `src/lib/stores/` - Svelte stores for state management
- `src/routes/api/` - Server endpoints for WebSocket proxying
- `static/sounds/` - Trigger sound files
- `static/icons/` - PWA icons in various sizes
- `static/manifest.json` - PWA manifest file
- `static/service-worker.js` - Service worker for offline capabilities
Set `ALLOWED_ORIGINS` to the deployed HTTPS origin and keep the proxy reachable only through a trusted reverse proxy. See [DOCKER-README.md](DOCKER-README.md).
## Configuration
## Data migration
The client can be configured through the UI, with settings stored in local browser storage:
- MUD server profiles
- Trigger patterns and actions
- UI preferences (dark mode, font size, etc.)
- Accessibility settings
Older local data is migrated on load. Stored profile passwords and trigger JavaScript actions are discarded. Backup import accepts only known settings, profile, and trigger keys, enforces a size limit, and sanitizes legacy data before applying it.
## WebSocket to Telnet Proxy
## Project layout
For security reasons, browser WebSockets cannot connect directly to telnet ports. SvelteMUD uses a server-side proxy to facilitate this connection. The proxy is implemented in the `src/routes/api/mud-connect` and `src/routes/api/mud-ws` endpoints.
## Progressive Web App (PWA) Support
SvelteMUD is configured as a Progressive Web App, allowing users to install it on their devices and use it offline:
### Features
- **Installable**: Add to home screen on mobile or desktop
- **Offline Support**: Basic functionality works without an internet connection
- **Automatic Updates**: Notifies users when a new version is available
- **Responsive Design**: Works on all screen sizes
### Installation
#### Mobile (iOS/Android)
1. Open SvelteMUD in your browser
2. Tap the Share button (iOS) or menu (Android)
3. Select "Add to Home Screen" or "Install App"
#### Desktop (Chrome, Edge, etc.)
1. Open SvelteMUD in your browser
2. Look for the install icon in the address bar
3. Click "Install" when prompted
### Customizing Icons
To replace the default PWA icons:
1. Replace the SVG template in `/static/icons/icon-512x512.svg`
2. Run the icon generator: `npm run generate-icons`
- `src/lib/connection/` — WebSocket control protocol and incremental Telnet parser
- `src/lib/gmcp/` — GMCP packages and routing
- `src/lib/triggers/` — trigger validation and execution
- `src/lib/profiles/` — profile storage and in-memory credentials
- `src/lib/stores/` — per-profile application state
- `src/websocket-server.js` — constrained WebSocket-to-Telnet proxy
- `static/icons/` — generated PWA icons
## License
This project is licensed under the [MIT License](LICENSE).
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
[MIT](LICENSE)