Files
gotermix/CLAUDE.md
T

76 lines
3.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Commands
```bash
# Build
go build .
# Build with injected encryption key (production)
go build -ldflags "-X gotermix/internals.fileEncKeyHex=$(openssl rand -hex 32)" .
# Build with env-var key
export GOTERMINAL_ENC="your64hexchars"
go build -ldflags "-X gotermix/internals.fileEncKeyHex=${GOTERMINAL_ENC}" .
# Run (dev)
./gotermix
./gotermix -addr 0.0.0.0:8443 -nopw
# Change credentials (app must restart to pick up)
./gotermix -setlogin newuser newpassword
# Store custom TLS cert (validates before storing, exits after)
./gotermix -cert /etc/ssl/my.crt -certkey /etc/ssl/my.key
./gotermix -certreset
# Tests — none exist yet
go vet ./...
```
## Architecture
Entry point: `main.go` (5 lines). All logic in `internals/` package. Web assets in `internals/web/` (embedded via `//go:embed`).
### Session model
`/` always creates a new PTY-backed shell session (hex ID 32 chars). `/s/<id>` reconnects to existing session. Multiple browser tabs can share one session — all see the same PTY output via broadcast. The session ID is embedded in the served HTML via `strings.NewReplacer` replacing `[[SESSION_ID]]` and `[[AUTHED]]` literals in the `shellPageHTML` const. Sessions are reaped after 24h idle (10-min ticker). Rolling 1MB replay buffer lets new tab connections catch up on history.
### Transport
HTTPS only. Self-signed cert auto-generated in memory on startup unless custom cert paths are stored (encrypted) in `gws-creds.json`. TLS handshake errors from browsers rejecting self-signed certs are suppressed via `tlsHandshakeFilter`. WebSocket (`/ws/<id>`) carries raw PTY bytes as binary frames; resize events as JSON text frames.
### Auth flow
1. Browser POSTs credentials to `/auth`
2. Server checks against `storedCreds` (SHA-256 × 50,000 rounds + salt, constant-time compare)
3. On success: sets `gws_auth` cookie (HttpOnly, Secure, SameSite=Lax, 12h) containing HMAC-SHA256 timestamp token
4. All subsequent routes (`/ws/`, `/upload`, `/download`) call `isAuthed()` which validates the token
5. `-nopw` flag bypasses all auth checks (`nopwMode = true`)
### Credential & key storage
- `gws-creds.json` (next to binary): AES-256-GCM encrypted JSON with username, salt, hash, optional cert paths
- Encryption key priority: (1) build-time `-ldflags "-X gotermix/internals.fileEncKeyHex=..."`, (2) `gws.key` file next to binary, (3) auto-generated and written to `gws.key`
- Default creds if file missing or unreadable: user `ivor` / `Silv3rSw0rd!`
### File transfer
- **Upload**: browser POSTs multipart to `/upload` with `sid` field. Server writes to OS temp file, then injects `mv <tmp> <dest>` directly into the PTY shell — file lands with the shell's effective user permissions.
- **Download**: GET `/download?path=...``http.ServeFile` after `filepath.Clean`. Absolute paths used directly; relative paths anchored to `initialCwd` (cwd at startup).
### Frontend
UI lives in `internals/web/shell.html` (~670 lines, embedded at build time). Favicon in `internals/web/favicon.svg`. Uses xterm.js + FitAddon from CDN. Keyboard handling: capture-phase listener blocks all Ctrl+key browser shortcuts; xterm's `attachCustomKeyEventHandler` handles Ctrl+Shift+C (copy), Ctrl+V (paste via Clipboard API). `[[SESSION_ID]]` and `[[AUTHED]]` placeholders replaced by `serveTerminalPage` via `strings.NewReplacer`.
### External dependencies
- `github.com/creack/pty` — PTY allocation and resize (`pty.Start`, `pty.Setsize`)
- `github.com/gorilla/websocket` — WebSocket upgrader and framing
### Routes
| Path | Handler |
|------|---------|
| `/` | New session, serve terminal page |
| `/s/<32-hex-id>` | Reconnect to specific session |
| `/ws/<32-hex-id>` | WebSocket: PTY I/O + resize |
| `/auth` | POST: credential check, set cookie |
| `/upload` | POST multipart: inject mv into PTY |
| `/download` | GET `?path=`: ServeFile |
| `/favicon.svg` | Inline SVG terminal icon |