eba5a2a38e
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>
2.8 KiB
2.8 KiB
MacroPad Relay Server - Deployment Guide
Cloud Node Container Deployment
For AnHonestHost cloud-node-container deployment:
1. Build Locally
cd /home/jknapp/code/macropad/macropad-relay
npm install
npm run build # required: the build is no longer triggered automatically on install
Note: the
postinstallbuild hook was removed. Always runnpm run buildexplicitly (locally or in CI) afternpm installto producedist/.
2. Prepare Deployment Package
The build outputs to dist/ with public files copied. Upload:
# Upload built files to your node container app directory
rsync -avz --exclude 'node_modules' --exclude 'src' --exclude '.git' \
dist/ package.json public/ \
user@YOUR_SERVER:/path/to/app/
3. On Server
The cloud-node-container will automatically:
- Install dependencies from package.json
- Start the app using PM2
- Configure the process from package.json settings
4. Create Data Directory
mkdir -p /path/to/app/data
Directory Structure on Server
app/
├── index.js # Main entry (compiled)
├── config.js
├── server.js
├── services/
├── handlers/
├── utils/
├── public/
│ ├── login.html
│ └── app.html
├── data/
│ └── sessions.json # Created automatically
└── package.json
Update After Code Changes
# On local machine:
cd /home/jknapp/code/macropad/macropad-relay
npm run build
rsync -avz --exclude 'node_modules' --exclude 'src' --exclude '.git' --exclude 'data' \
dist/ package.json public/ \
user@YOUR_SERVER:/path/to/app/
# On server - restart via your container's control panel or:
pm2 restart macropad-relay
Environment Variables
Set these in your container configuration:
PORT- Server port (default: 3000)DATA_DIR- Data storage path (default: ./data)NODE_ENV- production or developmentLOG_LEVEL- info, debug, error
Test It Works
# Test health endpoint
curl http://localhost:3000/health
# Should return (counts only - no session ids are exposed):
# {"status":"ok","desktops":0,"webClients":0,"uptime":1.23}
Nginx/Reverse Proxy (for HTTPS)
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket timeout (24 hours)
proxy_read_timeout 86400;
}
Troubleshooting
Check logs:
pm2 logs macropad-relay
Check sessions:
cat /path/to/app/data/sessions.json
Port in use:
lsof -i :3000