The Security Audit job failed because new advisories dropped against existing
deps and `npm audit --audit-level=high` audits the whole tree (incl. dev/build
tooling that isn't shipped).
- Switch both audit steps to `audit-ci --high --skip-dev`, so the gate reflects
what's actually deployed (backend ships --omit=dev; frontend ships a static
build) while still failing on real high/critical production advisories.
- Allowlist GHSA-qwww-vcr4-c8h2 (React Router "RSC Mode CSRF") for the frontend:
this is a client-side SPA using BrowserRouter — RSC mode is not used — and
there is no forward-compatible fix for react-router-dom 7.x (only a downgrade).
- `npm audit fix` on both lockfiles to patch non-breaking transitive dev
advisories (js-yaml, postcss, brace-expansion, minimatch). No direct/prod
dependency versions changed; app runtime is unchanged.
Verified: backend 114 tests pass, frontend builds, and audit-ci passes for both
projects locally.
Address the open CodeQL code-scanning alerts:
- guestWifi voucher codes now use rejection sampling so the character
distribution is uniform (fixes js/biased-cryptographic-random).
- Scheduled-report recipient validation replaced the backtracking email regex
with a linear split-based check (fixes js/polynomial-redos).
- Add .github/codeql/codeql-config.yml excluding js/missing-rate-limiting:
rate limiting is applied globally via app.use('/api', rateLimitRedis) plus
per-route limiters, which CodeQL can't attribute to individual handlers, so
that rule fired ~38 false positives.
Remaining alerts are dismissed as accepted/false-positive (RouterOS MD5 API
login and self-signed cert acceptance are protocol-mandated; log sites already
strip CRLF).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add docker/setup-qemu-action and platforms: linux/amd64,linux/arm64 to
both the backend and nginx build-push steps so GHCR images run natively
on arm64 (ARMv8) hosts instead of amd64-only. Refs #56.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
docker/build-push-action@v6 renamed the parameter from 'dockerfile' to
'file'. The backend succeeded by luck (default Dockerfile matched), but
nginx failed because the Dockerfile isn't in the root context directory.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a GitHub Actions workflow that builds and pushes backend and nginx
images to GitHub Container Registry on every merge to main and on
releases. Adds docker-compose.ghcr.yml for end users who want to deploy
without cloning the repo, and updates the README with Quick Deploy
instructions alongside the existing build-from-source guide.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SECURITY.md with vulnerability disclosure policy and self-hosting guidance
- Dependabot config for weekly dependency updates (npm, Docker, Actions)
- ESLint v9 flat config for frontend and backend, with eslint-plugin-security
- GitHub Actions CI: lint, typecheck, build, and npm audit on every push/PR
- CodeQL workflow for automated security scanning (runs on push and weekly)