feat: add rate limiting, OpenAPI documentation, query middleware and audit logging - #171
Open
arandomogg wants to merge 1 commit into
Open
Conversation
…ging Implements four related backend concerns on top of the existing Express and Mongoose skeleton, together with the domain layer they operate on. Rate limiting and brute force protection - Add src/middlewares/rateLimiter.ts exposing five configurable limiters. - Key auth attempts by source IP and the targeted account so that a distributed attack against one account is still throttled. - Skip successful logins so legitimate users are never locked out. - Apply strict limits to auth, registration, escrow and escrow settlement. OpenAPI 3.0 documentation - Add src/docs with the assembled specification and serve Swagger UI at /api-docs and the raw document at /api-docs.json. - Derive enumerations from the Mongoose models so the published docs cannot drift from what the API accepts. Pagination, sorting and filtering - Add src/middlewares/queryMiddleware.ts parsing page, limit, sort, search and whitelisted filters into normalized options. - Support the comparison operators eq, ne, gt, gte, lt, lte, in and nin, and reject fields a route does not expose. - Return total item and page counts on every paginated response. Audit logging - Add the AuditLog model recording admin, action, target, timestamp and a field level before/after snapshot. - Block updates and deletes so the trail stays append only. - Write the entry before the privileged change is persisted, so no audited action can land unrecorded. Supporting changes - Add User, Delivery and Escrow models with the controllers, services, validators and versioned routes under /api/v1. - Extend the error handler to translate ApiError and Mongoose errors while masking internal details on 5xx responses. - Add .gitattributes normalizing line endings to LF, which prevents Windows checkouts from reporting whole files as modified. - Add 85 tests covering all four features against an in-memory MongoDB.
|
@arandomogg Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
closes #106
closes #107
closes #108
closes #109
Summary
Implements four related backend concerns on top of the existing Express and
Mongoose skeleton, along with the domain layer they operate on.
Rate limiting and brute force protection (#106)
Adds
src/middlewares/rateLimiter.tsexposing five limiters, each configurablethrough environment variables documented in
.env.example.POST /auth/loginPOST /auth/registerTwo decisions worth calling out:
IP alone lets an attacker rotate addresses to brute force a single account.
correctly is never locked out; only failed attempts count.
TRUST_PROXYis honoured so the real client IP is used behind a load balancerrather than the proxy's address.
OpenAPI 3.0 documentation (#107)
Adds
src/docs/and serves Swagger UI at/api-docs, with the raw document at/api-docs.jsonfor client generators and contract tests.All 15 endpoints are documented with request/response schemas, auth
requirements, rate limit responses and pagination parameters. Enumerations are
derived from the Mongoose models rather than restated, so the published
documentation cannot drift from what the API actually accepts. The spec is
validated by
@apidevtools/swagger-parserin the test suite, so a broken$reffails the build instead of surfacing as a broken docs page.
Pagination, sorting and filtering (#108)
Adds
src/middlewares/queryMiddleware.ts, which parsespage,limit,sort,searchand filters into normalized options onreq.queryOptions. Applied toDeliveries and Users as required, and also to Escrows and Audit Logs.
Filters support
eq,ne,gt,gte,lt,lte,inandninin bracketnotation:
Each route declares which fields it exposes; anything else is ignored or
rejected, which keeps unindexed and sensitive fields out of client-controlled
queries. Search terms are regex-escaped to prevent catastrophic backtracking.
Every paginated response returns
totalItems,totalPages,currentPage,limitand navigation flags.Audit logging (#109)
Adds
src/models/AuditLog.tsrecording the acting admin, action type, targettype and id, timestamp, and a field-level before/after snapshot, plus IP and
user agent for forensics.
the audit write fails the action is abandoned, which guarantees no audited
action can land unrecorded.
escrow refund/release.
Supporting changes
mainhad no models, controllers or services, so these were added to satisfythe "response data must come from the database" requirement:
User,DeliveryandEscrowmodels with controllers, services, validatorsand versioned routes under
/api/v1.ApiErrorand Mongoose validation,cast and duplicate-key errors, while masking internal details on 5xx.
src/middleware/intosrc/middlewares/to match the structuredocumented in the README.
.gitattributesnormalizing line endings to LF. Without it a Windowscheckout rewrites files to CRLF and Prettier reports whole untouched files as
changed.
Testing
85 tests across 6 suites, all passing. Integration tests run against an
in-memory MongoDB (
mongodb-memory-server), exercising real Mongoose queries,indexes and validation rather than mocked data access.
Coverage includes: rate limit enforcement and header behaviour, per-account
keying, pagination/sorting/filter coercion and rejection paths, audit log
immutability, OpenAPI spec validation, and end-to-end API flows including
authorization and error cases.
pnpm build,pnpm lintandpnpm testall pass clean.Notes for reviewers
backend/src/..., but this repository's root is thebackend (
src/at root, per the README structure), so files are placedaccordingly.
NODE_ENV=testso integration suites are notthrottled by earlier cases in the same run.