Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions dev-docs/BROWSER_TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ synthetic provider.
checker's failure text is the review).
- Fixture names must stay free of route fragments: borrowed URLs are
namespaced `/<name><route>` and tests derive sibling URLs by substitution.
- Fixtures exercising host-local actions serve valid `/api/meta` data with
`localRequest: true`; non-local, missing and failed metadata retain their
fail-closed coverage in `host-only-controls.test.ts`.
- Tests that need stateful middleware (SSE feeds driven by the test, custom
Vite transform hooks, configs that diverge from the canonical daemon
config) keep their own server and live in the heavy tier.
Expand All @@ -92,6 +95,9 @@ synthetic provider.
explicitly. Mutation collectors match the exact HTTP method and path. Hold the
intended panel source independently of schedule reads, and await lifecycle
feedback settlement before asserting its final status.
- Mission selection helpers retain `data-mission-key` and resolve row/chevron
Locators at each action across retitling and panel remounts. Wait for the row's
visibility before distinguishing a leaf from an expandable row; use native clicks.
- Before pointer/keyboard selection in a Monaco diff, wait for its computed
diff decoration (`.line-insert` in the Git fixture), then locate the line.
Plain model text can paint before the worker result inserts deleted-code view
Expand Down
59 changes: 57 additions & 2 deletions dev-docs/REMOTE_CONTROL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,21 @@ browser ─TLS─▶ OpenTunnel relay (forwards ciphertext) ─▶ OpenTunnel SD
Every other upgrade gets 404.
- `request-origin.ts` is the only authority for local privileges:
`isLocalRequest()` requires a loopback peer **and** a non-ingress socket.
- The direct listener applies the shared host-only paths to every non-local
request, including encoded route targets and SideCar WebSocket upgrades.
Direct password login, its page and logout remain available to LAN clients.
`GET /api/remote-control/status` is available to authenticated clients and
returns `manageable: false` for non-local peers. SideCar registration APIs remain
available to authenticated clients; content and WebSockets require loopback.
Live preview capabilities retain their scoped admission. `/api/meta` reports
`localRequest` using that same transport authority; the UI hides password changes,
SideCar opening and remote-server management unless it is true.
- `gate.ts` runs before CORS, authentication and routing. It requires the exact
tunnel `Host` and the public `Origin` on mutations, and strips forwarding
tunnel `Host` and the public `Origin` on browser mutations, and strips forwarding
headers. It accepts origin-form targets only (no absolute-form, leading `//`
or fragment, which the router would reinterpret) and judges the path the
router routes (`server/routed-path.ts`). It denies host-only paths: login and token
bootstrap, Remote Control management, remote windows/proxy, SideCars,
bootstrap, Remote Control management, remote windows/proxy, SideCar content,
previews and the automation bridge. A live `/previews/<token>/…` capability
is admitted without a device cookie or public `Origin` (its sandboxed document
sends neither) while the host's **Web previews** switch is on, the default:
Expand All @@ -69,6 +78,9 @@ browser ─TLS─▶ OpenTunnel relay (forwards ciphertext) ─▶ OpenTunnel SD
Every other path requires a paired device. Refusals close the connection,
because an unread body would otherwise break the client's next keep-alive
request.
- Server-to-server `POST /api/remote-control/pair` accepts a valid one-use
code with no Origin, Referer or browser fetch metadata. Browser pairing
supplies the exact tunnel Origin. Other tunnel mutations require that Origin.
- A remote `/api/auth/status` without a valid device reports
`pairingRequired`. The recovery dialog then explains how to pair again
instead of offering password login, keeping the page and its drafts.
Expand All @@ -94,13 +106,56 @@ browser ─TLS─▶ OpenTunnel relay (forwards ciphertext) ─▶ OpenTunnel SD
It refuses URLs with user info or a fragment, so a pairing code or password
never travels on a command line; pair from Add server instead.

## Direct listener origins and password sessions

The direct listener grants credentialed CORS to its advertised local and remote
origins, reachable interface addresses and explicit `CODENOMAD_ALLOWED_ORIGINS`.
This environment variable is a comma-separated list of exact HTTP(S) origins,
for example `https://code.example.test,https://ui.example.test:8443`. Paths,
credentials, opaque origins and wildcards fail startup. Configure DNS aliases,
reverse-proxy public origins and separately hosted UIs here, then restart.
Forwarding headers grant neither origins nor local privileges; a proxy connected
over loopback has the privileges of its loopback transport and needs an enforcing
trusted perimeter. The configured UI development origin is admitted for local
requests. CORS for opaque preview documents is scoped to live preview capabilities.
Preview capability admission requires the matched route's `previewCapability`
configuration; a capability Host on an ordinary application route retains that
route's authentication, origin and host-only checks.

Direct state-changing requests check Origin first, then the origin of Referer
when Origin is absent. Non-local mutations require an allowed source; native
loopback calls may omit both. Read-only methods are GET, HEAD and OPTIONS.
Authentication and the host-only gate also apply with explicitly allowed origins;
`--dangerously-skip-auth` retains the origin and host-only gates.

SideCar WebSocket upgrades apply this same Origin/Referer policy before opening
an upstream connection, alongside their loopback transport and session checks.
Native loopback upgrades may omit both source headers. Preview WebSockets use
their scoped capability admission.

Password sessions expire after 24 hours without an authenticated request and
after seven days from creation. `CODENOMAD_SESSION_IDLE_SECONDS` and
`CODENOMAD_SESSION_ABSOLUTE_SECONDS` configure positive integer lifetimes in
seconds at startup. Logout revokes its current token; a successful persistent
password change revokes every session for that user, including the caller.
A failed password change preserves the existing sessions. Remote Control device
credentials follow their separate registry lifetime and revocation rules.

## Validation

- `remote-surface.test.ts` drives the real `createHttpServer` through the
ingress. It covers unpaired access, pairing, `Origin`/`Host` checks,
host-only paths including encoded ones, loopback privileges, spoofed headers,
upgrades, web previews and their switch, revocation of a live stream, skipped
local auth and tunnel failure.
- `direct-listener.test.ts` exercises the real application with LAN and loopback
peers, credentialed CORS, Origin/Referer checks and host-only routes.
`server/__tests__/sidecar-proxy.test.ts` covers SideCar upgrade source checks,
refusal before upstream contact, authenticated and skipped-auth exchanges,
native origin-less calls and logout revocation.
`session-manager.test.ts` covers idle/absolute deadlines, configuration and
revocation; `auth-responsiveness.test.ts` covers logout and password replacement
through real auth routes alongside concurrent credential checks.
- `manager.test.ts` covers resuming after a restart, Stop, never-started
installations, failed resumes and backends sharing a configuration;
`owner-lease.test.ts` the lease; `tests/browser/remote-control-settings.test.ts`
Expand Down
4 changes: 3 additions & 1 deletion docs/help/de/browser-sidecars.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ Registrierung ist von Clients geteilte Serverkonfiguration; sie installiert oder

Prüfen Sie bei Nichterreichbarkeit Prozess und Port auf dem Backend. Lädt HTML, aber scheitern Dateien/WebSockets, prüfen Sie Basispfad und Präfix-Modus des Werkzeugs. Erstellen Sie eine falsche Registrierung mit den vorgesehenen Einstellungen neu; geben Sie den Upstream nicht nur zum Umgehen eines Proxyfehlers öffentlich frei. SideCar-Anwendungen können Terminal oder Dateien mit der Autorität des Serverkontos freigeben; vertrauen Sie ihren Benutzern und ihrer Konfiguration.

Ein SideCar ist eine vertrauenswürdige Erweiterung von CodeNomad, keine Vorschau in einer Sandbox: Seine Seite läuft unter dem eigenen Origin von CodeNomad, sodass seine Skripte CodeNomad mit Ihrem angemeldeten Zugang nutzen können. Registrieren Sie nur Dienste, deren Code Sie vertrauen. CodeNomad leitet seine eigenen Anmelde-Cookies nicht an den Dienst weiter, während die eigenen Cookies des Dienstes erhalten bleiben. Fernsteuerung stellt keinen SideCar-Anwendungsproxyverkehr bereit; verwenden Sie den passenden Direktzugriffsweg unter [Fernzugriff](remote-access.md) und [Fernsteuerung](remote-control.md).
Ein SideCar ist eine vertrauenswürdige Erweiterung von CodeNomad, keine Vorschau in einer Sandbox: Seine Seite läuft unter dem eigenen Origin von CodeNomad, sodass seine Skripte CodeNomad mit Ihrem angemeldeten Zugang nutzen können. Registrieren Sie nur Dienste, deren Code Sie vertrauen. CodeNomad leitet seine eigenen Anmelde-Cookies nicht an den Dienst weiter, während die eigenen Cookies des Dienstes erhalten bleiben.

SideCar-Inhalte (`/sidecars/`) und SideCar-WebSockets erfordern eine Loopback-Verbindung auf dem Host. Die Registrierung über `/api/sidecars` ist für gekoppelte Geräte und authentifizierte direkte LAN-Clients verfügbar. Inhalte aktiver Vorschauen (`/previews/`) sind mit einem gültigen Berechtigungstoken über direkten LAN-Zugriff verfügbar; Web-Vorschauen der [Fernsteuerung](remote-control.md#remote-surface) bleiben mit ihrem Berechtigungstoken verfügbar, solange sie aktiviert sind. Anforderungen für den Direktzugriff stehen unter [Aktualisieren](remote-access.md#upgrading).

## OpenVSCode-Server-Rezept {#openvscode}

Expand Down
8 changes: 8 additions & 0 deletions docs/help/de/remote-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ codenomad --host 127.0.0.1 --https=false --http=true

Setzen Sie Port 9898 oder 9899 nicht voraus: Nicht angegebene Ports können bei Belegung ausweichen. Ein expliziter von null verschiedener `--https-port` oder ein `--http-port` bei aktiviertem HTTP legt den Port fest und schlägt bei fehlgeschlagener Bindung fehl; `0` fordert eine OS-Zuweisung an. Die ausgegebenen **Local Connection URL** und **Remote Connection URL** sowie aktualisierte **Erreichbare Adressen** sind für diesen Lauf maßgeblich. Siehe die vollständige [Server-CLI-Referenz](server.md).

## Aktualisieren {#upgrading}

Melden Sie sich nach der Aktualisierung erneut an. Setzen Sie für einen Hostnamen-Alias, Reverse-Proxy oder eine separat gehostete Oberfläche `CODENOMAD_ALLOWED_ORIGINS` im Backend auf die vertrauenswürdigen Origins der Oberfläche (Schema, Hostname und Port). Native LAN-Clients müssen bei schreibenden Anfragen einen erlaubten `Origin`-Header mitsenden.

Verwenden Sie eine Loopback-Verbindung für dem Host vorbehaltene Vorgänge: SideCar-Inhalte (`/sidecars/`) und WebSockets, Fernsteuerungsverwaltung (`/api/remote-control/`), Plugin-Brücke (`/api/opencode-plugin/`), Remote-Proxys (`/api/remote-proxy/`), Verwaltung gespeicherter Server (`/api/remote-servers/`), Passwortänderungen und Token-Ersteinrichtung. Diese Vorgänge erfordern auch bei angemeldetem direktem LAN-Zugriff Loopback. Inhalte aktiver Vorschauen (`/previews/`) sind mit einem gültigen Berechtigungstoken über direkten LAN-Zugriff verfügbar.

Die Registrierungs-APIs `/api/sidecars` bleiben für authentifizierte direkte LAN-Clients und gekoppelte Geräte verfügbar. Web-Vorschauen der Fernsteuerung bleiben mit ihrem Berechtigungstoken verfügbar, solange sie auf dem Host aktiviert sind.

## Vertrauenswürdiges TLS konfigurieren {#tls}

### Eigenes Zertifikat bereitstellen {#custom-certificates}
Expand Down
4 changes: 2 additions & 2 deletions docs/help/de/remote-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,12 @@ Gekoppelte Geräte können normale Projekt-/Unterhaltungs-APIs verwenden, Prompt
| Passwortanmeldung/-abmeldung, Passwortänderungen, lokale Token-Ersteinrichtung | Nicht verfügbar; Gerätezugangsdaten sind auch bei deaktivierter direkter Authentifizierung nötig. |
| Fernsteuerungsstatus | Für gekoppelte Geräte lesbar; Verwaltung nicht verfügbar. Start/Stop, Kopplungserstellung, Geräteliste und Widerruf bleiben auf dem Host-Zugriffsweg. |
| Desktop-Remote-Fenster-/Serververwaltung und Proxy-Routen | Nicht verfügbar (`/api/remote-servers/`, `/api/remote-proxy/`). |
| SideCar-**Inhaltsproxy** | Nicht verfügbar (`/sidecars/`). Dies bedeutet **nicht**, dass alle SideCar-APIs blockiert sind: Gekoppelte Clients können weiterhin die Registrierungs-APIs `/api/sidecars` nutzen. |
| SideCar-**Inhaltsproxy** | Erfordert Loopback (`/sidecars/`), ebenso wie SideCar-WebSockets. Die Registrierungs-APIs `/api/sidecars` sind für gekoppelte Geräte und authentifizierte direkte LAN-Clients verfügbar. |
| Inhalt der Web-Vorschau | Verfügbar, solange **Web-Vorschauen** (Standard) unter **Einstellungen → Remote-Zugriff → Fernsteuerung** auf dem Host eingeschaltet ist. Jede Vorschauadresse öffnet ihre Seite ohne Kopplung; halten Sie sie privat. Das Ausschalten beendet ausgelieferte Vorschauen und ihre WebSockets; gekoppelte Geräte blenden **Web-Vorschau öffnen** nach dem Neuladen aus. |
| Automatisierungsbrücke | Nicht verfügbar (`/api/opencode-plugin/`). Native Desktop-Fähigkeiten werden nicht zu Browserfähigkeiten. |
| WebSocket-Upgrades | Nur für Web-Vorschauen verfügbar. |

Verwenden Sie eine entsprechend geschützte [Direktverbindung](remote-access.md), wenn ein Ablauf eine blockierte Proxy-/WebSocket-Oberfläche benötigt. Fernsteuerung wechselt nicht automatisch dorthin.
Verwenden Sie eine Loopback-Verbindung auf dem Host für hostgebundene Proxy-/WebSocket-Funktionen und die Fernsteuerungsverwaltung (`/api/remote-control/`). Auch direkter LAN-Zugriff erfordert dafür Loopback; siehe [Aktualisieren](remote-access.md#upgrading). Web-Vorschauen der Fernsteuerung verwenden ein Berechtigungstoken in ihrer Adresse und bleiben verfügbar, solange sie auf dem Host aktiviert sind; halten Sie diese Adresse privat.

## Relay und Datenschutz {#relay-privacy}

Expand Down
6 changes: 5 additions & 1 deletion docs/help/de/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ Ersteinrichtung wird nur vom eigenen Loopback-Listener des Hosts angenommen, nic

Direkte Anmeldung erzeugt eine undurchsichtige Backend-Sitzung im Arbeitsspeicher und ein `codenomad_session`-Cookie (oder den konfigurierten Cookie-Namen). Cookies sind `HttpOnly`, `SameSite=Lax`, auf `/` begrenzt und bei Ausgabe über HTTPS als `Secure` markiert. Es sind Browsersitzungs-Cookies; ein Backend-Neustart macht die Sitzungen im Speicher ungültig. Authentifizieren Sie sich bei Aufforderung an Ort und Stelle neu, statt fehlgeschlagene Änderungen erneut zu senden.

Ein Passwortwechsel ändert spätere Zugangsdatenprüfungen; er macht bereits ausgegebene Direkt-Sitzungen oder Fernsteuerungsgeräte **nicht** ungültig. Bei Kompromittierungsverdacht:
Abmelden widerruft die aktuelle direkte Sitzung. Ein erfolgreicher Passwortwechsel auf dem Host widerruft alle direkten Sitzungen dieses Benutzers einschließlich der aufrufenden Sitzung; melden Sie sich erneut an. Sitzungen laufen nach 24 Stunden ohne authentifizierte Anfrage oder sieben Tagen seit Erstellung ab. Passen Sie diese Grenzen vor dem Backend-Start mit `CODENOMAD_SESSION_IDLE_SECONDS` und `CODENOMAD_SESSION_ABSOLUTE_SECONDS` als positive ganze Sekunden an. Fernsteuerungsgeräte werden separat widerrufen.

LAN-Clients können sich an- und abmelden und Projekte nutzen. Passwortänderungen, Fernsteuerungsverwaltung, Remote-Server-/Proxy-Werkzeuge und SideCars werden auf dem Loopback-Host verwaltet. Browseränderungen benötigen einen erlaubten Origin oder ersatzweise Referer. Die veröffentlichten Server-Ursprünge sind erlaubt; für DNS-Aliasse, Reverse-Proxys oder eine separat gehostete Oberfläche setzen Sie `CODENOMAD_ALLOWED_ORIGINS` auf kommagetrennte exakte HTTP(S)-Ursprünge, etwa `https://code.example.test,https://ui.example.test:8443`, und starten neu. Verwenden Sie keine Pfade oder Platzhalter. Dies gewährt Browserzugriff, keine Host-Rechte. Native LAN-Clients müssen bei Änderungen ebenfalls einen erlaubten Origin senden. Ein vertrauenswürdiger Proxy über Loopback hat Host-Rechte und benötigt eigene Zugriffskontrollen.

Bei Kompromittierungsverdacht:

1. Begrenzen Sie die Netzwerkfreigabe und setzen Sie auf dem Host ein neues Passwort oder ändern Sie Ihr Laufzeitgeheimnis und starten neu.
2. Starten Sie das Backend neu, um vorhandene Direkt-Sitzungen ungültig zu machen.
Expand Down
4 changes: 3 additions & 1 deletion docs/help/en/browser-sidecars.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,9 @@ Registration is server configuration, shared by its clients; it neither installs

If unreachable, check the process and port on the backend. If HTML loads but assets/WebSockets fail, check the tool's base path and prefix mode. Recreate a wrong registration with the intended settings; do not expose the upstream publicly just to work around a proxy error. SideCar applications can expose a terminal or files with the server account's authority; trust their users and configuration.

A SideCar is a trusted extension of CodeNomad, not a sandboxed preview: its page runs with CodeNomad's own origin, so its scripts can use CodeNomad with your signed-in access. Register only services whose code you trust. CodeNomad does not forward its own sign-in cookies to the service, while the service's own cookies are kept. Remote Control does not expose SideCar application proxy traffic; use the appropriate direct-access path described in [Remote access](remote-access.md) and [Remote Control](remote-control.md).
A SideCar is a trusted extension of CodeNomad, not a sandboxed preview: its page runs with CodeNomad's own origin, so its scripts can use CodeNomad with your signed-in access. Register only services whose code you trust. CodeNomad does not forward its own sign-in cookies to the service, while the service's own cookies are kept.

SideCar content (`/sidecars/`) and SideCar WebSockets require a loopback connection on the host. Registration through `/api/sidecars` is available to paired devices and authenticated direct LAN clients. Live preview content (`/previews/`) is available over direct LAN access with a valid capability token; [Remote Control](remote-control.md#remote-surface) web previews remain available with their capability token while enabled. See [Upgrading](remote-access.md#upgrading) for direct-access requirements.

## OpenVSCode Server recipe {#openvscode}

Expand Down
8 changes: 8 additions & 0 deletions docs/help/en/remote-access.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,14 @@ codenomad --host 127.0.0.1 --https=false --http=true

Do not assume port 9898 or 9899: omitted ports can fall back when busy. An explicit nonzero `--https-port`, or `--http-port` with HTTP enabled, pins the port and fails if it cannot bind; `0` asks the OS to assign one. The printed **Local Connection URL** and **Remote Connection URL**, and refreshed **Reachable addresses**, are authoritative for that run. See the complete [server CLI reference](server.md).

## Upgrading {#upgrading}

Sign in again after upgrading. For a hostname alias, reverse proxy or separately hosted UI, set `CODENOMAD_ALLOWED_ORIGINS` on the backend to the trusted UI origins (scheme, hostname and port). Native LAN clients must supply an allowed `Origin` header for mutations.

Use a loopback connection for host-only operations: SideCar content (`/sidecars/`) and WebSockets, Remote Control management (`/api/remote-control/`), the plugin bridge (`/api/opencode-plugin/`), remote proxies (`/api/remote-proxy/`), saved-server management (`/api/remote-servers/`), password changes and token bootstrap. These require loopback even when signed in through direct LAN access. Live preview content (`/previews/`) is available over direct LAN access with a valid capability token.

The `/api/sidecars` registration APIs remain available to authenticated direct LAN clients and paired devices. Remote Control web previews remain available with their capability token while enabled on the host.

## Configure trusted TLS {#tls}

### Supply your own certificate {#custom-certificates}
Expand Down
Loading
Loading