Commit Graph

11 Commits

Author SHA1 Message Date
shadowdao 2bbbc5e283 perf(relay): cache macro images instead of re-fetching every render
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>
2026-07-17 23:22:04 -07:00
shadowdao b5e5bed7dd security(relay): minor hardening follow-ups from PR review
- 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>
2026-07-17 18:13:33 -07:00
shadowdao d07005bde3 security(relay): fix lockout DoS and DOM XSS in web client
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>
2026-07-17 18:07:48 -07:00
shadowdao eba5a2a38e security(relay): harden internet-facing relay server
Closes the account-takeover chain and related issues found in audit:

- WS auth brute-force protection: per-session lockout (authThrottle) + per-
  socket failure cap that closes the socket (1008); applied to both web-client
  and desktop auth. Failed auth no longer leaves the socket open for unlimited
  guesses.
- WS upgrades now pass an IP-based rate limiter and Origin allowlist before
  handleUpgrade (previously bypassed all HTTP middleware); trust proxy set so
  limiting keys on the real client IP.
- /health no longer leaks live session IDs (counts only).
- .env.example rate-limit fixed (900000ms / 300) from the accidental ~11k rps.
- Credentials moved out of URLs into the X-MacroPad-Password header; images
  fetched via header + blob URLs; login stores creds in sessionStorage.
- Session creation bounded (max sessions, min password length) and TTL-pruned;
  session store writes are now atomic (temp+rename) and debounced.
- Session IDs lengthened to 12 chars with rejection sampling (no modulo bias).
- Enable helmet CSP; restrict CORS to configured origins.
- Request IDs use crypto.randomUUID; drop postinstall build hook and uuid dep.
- Uniform response for unknown session IDs (removes enumeration oracle).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-17 10:15:23 -07:00
shadowdao 6f3823eccf Add PWA, wake lock, and fullscreen to relay app
- Add wake lock (keep screen awake) functionality
- Add fullscreen toggle button
- Add dynamic PWA manifest generation
- Add favicon and icons for all relay pages
- Copy icons from main web folder

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 21:04:03 -08:00
shadowdao 5b6eb33bad Fix image authentication in relay app.html
Add password query parameter to image URLs in the relay server's
app.html - this file has its own inline JavaScript separate from
the main web/js/app.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 20:51:37 -08:00
shadowdao 7d95d47c73 Update relay server defaults and repo links
- Update index.html links to repo.anhonesthost.net
- Adjust rate limit defaults in .env.example

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 20:47:32 -08:00
shadowdao 5aed19564c Add index landing page for relay server
- Add index.html explaining what MacroPad Relay is
- Add /ping endpoint for container health checks
- Add route for index page

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 20:33:03 -08:00
shadowdao 6e76d469c8 Add .env.example for relay server configuration
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 20:27:06 -08:00
shadowdao ff3c7b990c Fix relay server for cloud-node-container deployment
- Add postinstall script to build TypeScript automatically
- Move typescript to dependencies (needed during npm install)
- Update main and start to point to dist/index.js

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 20:23:31 -08:00
shadowdao 1d7f18018d Add relay server for remote HTTPS access
Node.js/TypeScript relay server that enables remote access to MacroPad:
- WebSocket-based communication between desktop and relay
- Password authentication with bcrypt hashing
- Session management with consistent IDs
- REST API proxying to desktop app
- Web client WebSocket relay
- Login page and PWA-ready app page
- Designed for cloud-node-container deployment

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 19:46:33 -08:00