The relay web client re-fetched every macro image through the relay->desktop
proxy on each render (tab switch, WS update) and revoked the object URL on
load, so nothing was reused and fetches were serial — slow to display.
- Client: cache image_path -> Promise<objectURL> and reuse across renders
(macro images are content-addressed by uuid, so immutable); fetch in
parallel and de-duplicate concurrent requests.
- Proxy: send Cache-Control: private, max-age=31536000, immutable on image
responses so the browser also disk-caches them across reloads.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Uniform auth responses remove the session-enumeration oracle: unknown
session and wrong password now return an identical 401 at the API layer and
an identical WS handshake/close; desktop-status and the 503 "not connected"
signal are only exposed after successful auth.
- Session-count cap re-checked after bcrypt.hash so concurrent creates can't
overshoot maxSessions.
- Relay web client reconnect backoff resets only after a successful auth
response (an accept-then-close server no longer defeats the backoff).
- idGenerator comment corrected to match the rejection-sampling; drop unused
recordFailure return value.
- DEPLOY.md: document ALLOWED_ORIGINS for reverse-proxy deployments.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses two Major findings from PR review:
- Auth lockout no longer griefable: the throttle key is namespaced per path
and includes the client IP (web:<session>:<ip> vs desktop:<session>:<ip>),
so a flood of bad web-client auths can neither lock other clients of the
same session nor block the desktop from (re)authenticating. Per-socket
failure close and brute-force lockout are preserved.
- Relay web client XSS eliminated: app.html tab/macro rendering rebuilt with
createElement/textContent (no macro/tab value reaches innerHTML); inline
scripts/handlers externalized to /static/app.js and /static/login.js so the
helmet CSP now uses script-src 'self' (dropped 'unsafe-inline' for scripts).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>