Files
punktfunk/web/web.env.example
T
enricobuehler 1e2b956de6
ci / docs-drift (pull_request) Successful in 25s
ci / bun-nix (pull_request) Successful in 26s
ci / docs-site (pull_request) Successful in 1m11s
ci / web (pull_request) Successful in 1m14s
ci / rust-arm64 (pull_request) Successful in 1m52s
android / android (pull_request) Successful in 5m43s
ci / rust (pull_request) Successful in 5m43s
nix / flake (pull_request) Successful in 6m34s
fix(web,tray,host): review follow-ups — pair the halves, and stop two comments overclaiming
Review of the parent commit. One real defect, the rest accuracy.

The resolver could hand back a MISMATCHED pair, which is the one invariant its
own header promised it never would: `nativeCert` came from `dirname(cert)` and
`nativeKey` from `dirname(key)`, two independent directories, so
("/a/cert.pem", "/b/key.pem") resolved to /a/native-cert.pem + /b/native-key.pem
— two unrelated files presented as a pair. No shipped launcher splits them, but
the guard is one comparison and it is the whole point of the module.

Rewritten off a suffix test instead of `node:path`, which fixes two more things
in passing. `node:path` resolves per-RUNTIME, so a POSIX CI runner reads
`C:\ProgramData\punktfunk\cert.pem` as one long filename and never swaps — and
Windows, where windows/service.rs hands us exactly that, is the platform the CI
job can never exercise. The suffix test gives the same answer everywhere and is
now covered by a win32 case. It also leaves the prefix VERBATIM, where
`join(dirname(p), …)` normalised /a/b/../cert.pem into a different directory the
moment `b` was a symlink.

Existence is no longer enough: `pf_paths::write_secret_file` is
create+truncate+write rather than temp+rename, so a console starting mid-write
could adopt a 0-byte cert and leave `Bun.serve` throwing on every restart. Not
every launcher retries forever — the Steam Deck unit is `Restart=on-failure`
under the default rate limit, i.e. permanently dead. The check is now a
non-empty stat, mirroring the host's own `!c.trim().is_empty()`. Verified: with
native-cert.pem truncated to 0 bytes the console starts and serves the legacy
pair.

Two comments of mine overclaimed and are corrected rather than left to mislead:

  * serve() said "cert.pem existing implies the native pair does too". False on
    an upgraded host whose native clients pinned the legacy cert — load_or_adopt
    returns it and writes no native files at all. The ordering claim that IS
    true is narrower: whenever that call writes a native pair, it does so before
    cert.pem appears.
  * the tray said the console entry "always opens the same URL regardless of the
    probe". True of the menu entry, but win.rs gates the tray-icon single-click
    on console_up. Also notes that the Windows probe was never pinned to begin
    with (punktfunk_config_dir is None off Linux), so that half is a no-op.

Rest is doc drift the parent commit annotated in two launchers but not the other
four: web.env.example, README, web-run.cmd, and the ci.yml comment that still
said the web test step was "Scoped to server/".

18/18 web tests (was 14), biome and rustfmt clean, and the runtime check re-run
against a fresh build: both pairs -> P-256 with SANs; 0-byte native cert ->
legacy RSA, console still serving.
2026-08-24 22:45:47 +02:00

34 lines
2.0 KiB
Bash

# punktfunk web console — packaged config reference.
#
# On a `apt install punktfunk-web` install you DO NOT edit anything: the systemd --user units wire
# everything automatically —
# punktfunk-web.service sets PUNKTFUNK_MGMT_URL=https://127.0.0.1:47990,
# PORT=47992, HOST=0.0.0.0, the PUNKTFUNK_UI_TLS_* cert paths + PUNKTFUNK_UI_SECURE=1, and sources:
# ~/.config/punktfunk/mgmt-token (written by the host's `serve` — the shared bearer token)
# ~/.config/punktfunk/web-password (written by punktfunk-web-init — the console login password)
# ~/.config/punktfunk/{cert,key}.pem (the host identity — the console serves HTTPS with it)
#
# This file documents the variables for a MANUAL deploy (running `bun .output/server/index.mjs`
# yourself — the console runs on bun: `Bun.serve` is a Bun API, node can't run it). The mgmt API is
# HTTPS with the host's self-signed loopback cert; the proxy accepts it ONLY for that loopback hop,
# scoped in code (Bun per-request TLS) — so NODE_TLS_REJECT_UNAUTHORIZED is deliberately unset.
PUNKTFUNK_MGMT_URL=https://127.0.0.1:47990
PORT=47992
HOST=0.0.0.0
# Serve the console over HTTPS (HTTP/1.1 over TLS) with the host's own identity cert. BOTH paths
# set ⇒ HTTPS. (No HTTP/2 or HTTP/3: Bun.serve has no HTTP/2 server, and a browser won't speak
# HTTP/3/QUIC against a self-signed host cert — so HTTP/1.1 over TLS is what's offered.)
# Name the LEGACY pair below: the server prefers native-cert.pem/native-key.pem beside it when both
# exist (nitro-entry/tls-paths.mjs), and falls back to these on a host that never took the split.
PUNKTFUNK_UI_TLS_CERT=%h/.config/punktfunk/cert.pem
PUNKTFUNK_UI_TLS_KEY=%h/.config/punktfunk/key.pem
# Mark the session cookie Secure (required once served over TLS):
PUNKTFUNK_UI_SECURE=1
# Match the host's ~/.config/punktfunk/mgmt-token (auto-generated by the host if unset):
PUNKTFUNK_MGMT_TOKEN=
# Console login password (fails closed if unset on the built server):
PUNKTFUNK_UI_PASSWORD=