- Escape player names rendered via innerHTML on the hand-over and game-over
score rows (defense-in-depth XSS; names are already capped at 16 chars)
- app.disable('x-powered-by') to stop advertising Express
- Add safe response headers: X-Content-Type-Options, X-Frame-Options,
Referrer-Policy (no CSP — inline SW script + socket.io would need unsafe-inline)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reorder the suit sort (hand + widow overlay) to alternate colours
(clubs, diamonds, spades, hearts) so hearts and diamonds no longer sit
next to each other.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phones stuck on stale service-worker caches (esp. iOS home-screen PWAs) could
show the new version string while still running old app.js/css. Tapping the
footer now unregisters the service worker, clears all caches, and reloads to
pull the latest build.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The mobile bid-history was capped at 110px, hiding the 4th player's bid behind
a scroll even though the panel had room. There are always exactly 4 players, so
show all four rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Server reads version from package.json and returns it from /api/config
- Client fetches it at boot and renders it in a lobby footer
- Bump service-worker cache to shelem-v3 so precache refreshes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>