Helmet adds HTTP security headers (HSTS, X-Frame-Options,
X-Content-Type-Options, etc.). CSP is disabled pending deployment-
specific tuning. Rate limiting (10 req / 15 min per IP) is applied
to POST /login and POST / (registration) to mitigate brute force
and credential stuffing attacks.
Sharing the JWT secret with express-session means a single leaked
secret compromises both auth mechanisms. SESSION_SECRET is now read
from its own env var, falling back to SECRET only if not set.
Wildcard CORS allowed any website to make authenticated cross-origin
requests on behalf of a victim. Origins are now read from the
ALLOWED_ORIGINS env var (comma-separated). No origins configured
means all cross-origin requests are rejected.
- Extract Express app creation into src/createApp.js to enable testing without starting the server
- Add Jest, Supertest, test helpers (createTestApp, auth token generator)
- Write 14 integration tests for skydive/jumps: auth protection, CRUD, ownership checks
Bugs caught and fixed by the test suite:
- MongoDB models: author field typed as Schema.Types.UUID (Mongoose 6 rejects string UUIDs) → changed to String
- Jump.toJSONFor: called toProfileJSONFor on a UUID string → guarded with typeof check
- exceptions.handler: used err.statusCode but express-jwt throws err.status → returns 500 on 401 errors
- Jump.count(query): deprecated Mongoose method was ignoring the filter → replaced with countDocuments
- jumps.routes GET /: $or query included non-schema field "title" stripped by strictQuery, leaving {} (match-all) → replaced with slug/lieu search
- $regex: was passing a JS RegExp object which serializes to {} in MongoDB → now passes raw string