Files
KoalaSync/docs/internal/host-control-mode-TESTING.md
T
Skrockle 463f871958 feat: Add protocol spec, rate limiting, vitest framework, and documentation
## Added
- **WebSocket Protocol Specification** (docs/PROTOCOL.md) - Complete reference
  for all 20+ events with payload schemas, rate limits, and edge cases
- **LEAVE_ROOM Rate Limiting** - 10 requests/socket/minute to prevent abuse
- **Vitest Testing Framework** - Modern test setup with coverage reporting
- **Host Control Mode Documentation** - Consolidated EN documentation
  (docs/host-control-mode.md) with references to internal implementation

## Changed
- **Graceful Shutdown** - Socket.IO clients properly disconnected during
  server shutdown (server/index.js)
- **CI Workflow** - Added test step with continue-on-error for gradual rollout
- **README** - Added protocol documentation link
- **CHANGELOG** - Updated with all new features and improvements

## Moved
- Internal documentation moved to docs/internal/ for better organization
- Host Control Mode docs consolidated from 4 files to 1 comprehensive guide

## Technical Details
- Protocol spec: 495 lines, covers all events from shared/constants.js
- Rate limiter: Follows existing pattern (checkAuthRate, checkEventRate)
- Vitest: 6 tests for rate limiter, all passing
- Documentation: Host Control Mode doc includes edge cases, testing checklist,
  architecture decisions
2026-07-01 23:27:30 +02:00

3.8 KiB

Host Control Mode — Beta Testing Guide

Temporary doc for branch feature/host-control-mode. Remove before merge. The feature needs the server half too — the official relay (wss://syncserver.koalastuff.net) doesn't run it yet, so test against a beta server first.

1. Run the beta relay (Docker)

The branch publishes the server image to GHCR under non-production tags (:beta = newest branch build, :sha-<commit> = immutable pin). :latest is never touched.

# Log in (the package is private → PAT with read:packages)
echo "$GHCR_PAT" | docker login ghcr.io -u <your-gh-user> --password-stdin

# Pull + (re)create — NOTE: `docker restart` does NOT pick up a new image,
# you must remove and re-run (or use compose / Watchtower).
docker pull ghcr.io/shik3i/koalasync:beta
docker rm -f koala-beta 2>/dev/null || true
docker run -d --name koala-beta -p 3000:3000 \
  -e SERVER_SALT='choose-your-own-salt' \
  ghcr.io/shik3i/koalasync:beta

To always run the newest beta automatically, point Watchtower at the container — it does the pull → recreate whenever :beta moves.

The OFFICIAL_SERVER_TOKEN is baked into shared/constants.js, so no token env is needed. Set SERVER_SALT (used for room-password hashing).

2. Connect the extension to it

⚠️ The client force-upgrades ws:// to wss:// for any non-localhost host (see background.js "Upgraded to wss:// for remote host"). So a bare ws://your-server:3000 will fail without TLS. Two options:

  • Quick (no TLS): SSH-tunnel the port so it counts as local:
    ssh -L 3000:localhost:3000 your-beta-server
    
    then in the popup → Manual Connect / Advanced → Custom → ws://localhost:3000.
  • Proper: put the container behind a TLS reverse proxy (Caddy does automatic HTTPS) → wss://beta.yourdomain.

Then create/join a room.

3. ⚠️ Use two new clients

Test with two browser profiles both running this branch build (load unpacked from extension/, or install the built zip). A stock release client as a guest will be correctly gated by the server but has none of the content-side code, so it silently desyncs with no dialog/snap-back — that's expected degradation, not a bug, but it looks like one during testing.

4. Verification checklist

# Step Expect
1 Create a room (host) Host Control card shows Host + the toggle
2 Second profile joins Guest sees no card while mode is "everyone"
3 Host enables "Only I can control" Guest's Play/Pause/SYNC buttons lock; card shows Guest
4 Guest presses pause/space on the video Brief flicker, snaps back to host position
5 Guest pauses again Dialog: "Stay in sync" / "Watch on my own"
6 Guest → "Watch on my own" Persistent "Solo" badge; host's peer list shows Solo
7 Guest → "Resync" Snaps back to host; Solo badge clears on both sides
8 Guest tries Force-Sync / seek spam Nothing propagates to the room
9 Host disables host-only Card hides for guest; controls unlock
10 Host leaves the room Room falls back to "everyone"; a remaining peer becomes host
11 Reload the guest's page while desynced Still shows Solo (state survives reload)
12 Switch the popup language Dialog/badge text is localized

5. Capability detection

The relay advertises capabilities: ['host-control'] in ROOM_DATA. The client only enables the feature when that flag is present, so:

  • against this beta server → feature on;
  • against the old official server → feature cleanly hidden (no errors).

This is the extensible hook for the planned co-host feature (owner promotes guests to additional controllers) — it'll add a 'co-host' capability + events without breaking older relays/clients.