queue-med/.env.example
Hermes 81c6bccf8a security: Phase 1 hardening - rate limit, helmet, CORS, JWT, session persistence
- express-rate-limit: 100/15min global, 5/15min on auth.login + auth.register,
  3/hour reserved for password-reset endpoints; trust proxy enabled.
- helmet: enabled with contentSecurityPolicy + crossOriginEmbedderPolicy off
  to keep Vite dev and the SPA bundle working.
- CORS: explicit allowlist (https://attente.cosmolan.fr in prod, localhost in
  dev), credentials true, restricted methods/headers; same allowlist applied
  to socket.io.
- JWT_SECRET: must be set and >= 32 chars; assertAuthEnv() called from the
  server bootstrap so the process refuses to start without one. The insecure
  "changeme-in-production" fallback in docker-compose.yml is removed.
- qm_auth cookie: maxAge reduced from 30d to 7d, JWT expiry matches.
- WhatsApp sessions: path now driven by WHATSAPP_SESSION_DIR and defaults to
  /app/data/whatsapp-sessions; docker-compose.yml mounts a named app_data
  volume so credentials survive container restarts.
- scripts/backup-db.sh: timestamped, gzipped mysqldump into /app/data/backups
  with rotation (keeps last 7); Dockerfile installs mysql-client and bundles
  the script.
- .env.example refreshed with documented placeholders for every required var
  (DATABASE_URL, JWT_SECRET, WHATSAPP_SESSION_DIR, MYSQL_*, BACKUP_*).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 13:06:51 +00:00

40 lines
2.4 KiB
Text

# ─── Database ───────────────────────────────────────────────────────────────
# Local dev (host MySQL):
# DATABASE_URL=mysql://queuemed:queuemed@localhost:3306/queuemed
# Docker compose (uses the "db" service):
# DATABASE_URL=mysql://queuemed:queuemed@db:3306/queuemed
DATABASE_URL=mysql://queuemed:queuemed@localhost:3306/queuemed
# ─── Auth ───────────────────────────────────────────────────────────────────
# REQUIRED. Must be at least 32 characters of high-entropy random data.
# Generate one with: openssl rand -hex 64
# The server refuses to start if this is missing or too short.
JWT_SECRET=replace_me_with_openssl_rand_hex_64_output
# ─── Server ─────────────────────────────────────────────────────────────────
PORT=5000
NODE_ENV=development
# Public URL used to build QR code links (e.g. https://queuemed.example.com).
# In production this should match the public origin allowed by CORS.
PUBLIC_BASE_URL=
# ─── WhatsApp (Baileys) ─────────────────────────────────────────────────────
# Persistent directory used to store Baileys auth credentials per clinic.
# Must live on a Docker volume in production so sessions survive restarts.
WHATSAPP_SESSION_DIR=/app/data/whatsapp-sessions
# ─── Docker compose only ────────────────────────────────────────────────────
MYSQL_ROOT_PASSWORD=replace_me_with_a_strong_password
MYSQL_DATABASE=queuemed
MYSQL_USER=queuemed
MYSQL_PASSWORD=replace_me_with_a_strong_password
MYSQL_PORT=3306
APP_PORT=5000
# ─── Backups (used by scripts/backup-db.sh) ─────────────────────────────────
# Inside the `app` container these point at the `db` service.
# Override only if running the script outside docker compose.
# MYSQL_HOST=db
# BACKUP_DIR=/app/data/backups
# BACKUP_KEEP=7