# PON Fleet — web server A multi-user, browser-based front end for the same tooling as the Electron **PON Fleet Upgrader** (Dashboard / ONU firmware upgrades / OLT PON flooding mode). Built to sit behind a TLS-terminating reverse proxy so several operators can use it at once, **each with their own MCMS login**. ## How it relates to the Electron app It does **not** duplicate the app — it reuses it: - **Core logic** comes straight from `../src/` (`mcms-api.js`, `bank-strategy.js`, `dashboard.js`). One source of truth for every MCMS quirk. - **The UI is the same files.** The server serves `../renderer/app.js` and `../renderer/app.css` as-is and rewrites `../renderer/index.html` on the fly (adds a mobile viewport, swaps in the browser API shim + a small responsive overlay). So the Electron app and the web app never drift. - The only web-specific code is `server.js`, `public/api-web.js` (a `window.api` shim: Electron IPC → `fetch` + NDJSON streaming, Electron file dialogs → browser file pickers, CSV-to-Downloads → Blob download), and `public/web.css` (responsive overlay). Because of the `../` references this folder **must** live inside `pon-fleet-upgrader/` (it borrows the already-installed `tough-cookie` from `../node_modules`). No separate `npm install` is needed. ## Run ```bash cd pon-fleet-upgrader/web npm start # node server.js — listens on 127.0.0.1:8080 npm run check # node --check on server.js + api-web.js ``` Then browse to . Each browser logs in with its own MCMS host + credentials; the server keeps a separate `McmsClient` (separate cookie jar) per session. ### Configuration (env) | Var | Default | Meaning | |---|---|---| | `PORT` | `8080` | listen port | | `HOST` | `127.0.0.1` | bind address — keep on localhost behind a proxy | | `PFW_IDLE_MINUTES` | `30` | idle-session expiry (logs the MCMS session out) | | `PFW_SECURE_COOKIE` | off | force the `Secure` cookie flag (else inferred from `X-Forwarded-Proto: https`) | | `PFW_VERBOSE` | off | verbose MCMS request logging (very noisy with many users) | ## Reverse proxy Terminate TLS at the proxy and forward to `127.0.0.1:8080`. **Disable response buffering** so the NDJSON progress streams (bulk delete, FEC pre-flight, flood change, …) arrive live. Caddy: ``` mcms-tools.example.net { reverse_proxy 127.0.0.1:8080 { flush_interval -1 # don't buffer streamed responses } } ``` nginx: ```nginx location / { proxy_pass http://127.0.0.1:8080; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; # stream NDJSON progress live proxy_read_timeout 300s; # bulk ops can run a while } ``` ## Security notes - The server holds each logged-in user's **live MCMS session cookie in memory**. Run it behind HTTPS, keep `HOST=127.0.0.1`, and rely on the idle timeout. The session cookie is `HttpOnly`, `SameSite=Lax`, and `Secure` behind TLS. - "Accept self-signed TLS certificate" disables verification **to MCMS** for that session only (same as the desktop app). - There's no app-level user directory — anyone who can reach the page and has valid MCMS credentials can log in. Restrict network access at the proxy (mTLS / SSO / IP allow-list) if you need more than MCMS auth. - Several operators running bulk operations at once multiply load on MCMS; the page-size-100 / timeout mitigations from the main `CLAUDE.md` §5 still apply per session. ## What differs from the desktop app - **CSV files download through the browser** instead of auto-saving to `~/Downloads` (a server can't write to each user's machine). Same filenames, same BOM/CRLF/quoted format. - Firmware `.bin` and plan-CSV selection use the browser file picker. - Everything else — views, filters, FEC logic, flood-mode rules, the dashboard and its drill-downs — is the shared renderer code.