Add configurable per-route-group request body size limits - #689
Merged
Chucks1093 merged 1 commit intoJul 28, 2026
Merged
Conversation
…ayerorg#146) Adds a configurable request body size ceiling per route group instead of one hardcoded 10mb limit applied globally. auth/admin/creators routes can each override BODY_SIZE_LIMIT_DEFAULT via their own env var (BODY_SIZE_LIMIT_AUTH/_ADMIN/_CREATORS); every other group falls back to the default. Oversized requests get a structured 413 response (no raw body logged) via bodyParseErrorMiddleware. JSON parsing moves from a single global app.use() before the router to per-group instances mounted inside modules/index.ts, so bodyParseErrorMiddleware — which only catches errors from middleware registered after it — is relocated to just after the router mount. Documented in docs/body-size-limits.md alongside the existing rate-limiting docs.
|
@davedumto 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.
Summary
Replaces the single, hardcoded
express.json({ limit: '10mb' })applied globally with a configurable, per-route-group body size ceiling — so a route group that genuinely needs a tighter (or looser) limit than the rest of the API can be tuned independently via env vars, without touching every other route.closes #146
Changes
src/middlewares/body-size-limit.middleware.ts(new): exportsgetBodySizeLimit(group)— resolves a per-group override or falls back toBODY_SIZE_LIMIT_DEFAULT— androuteBodySizeLimit(group), which returns anexpress.json({ limit })instance for that group. Groups:auth,admin,creators,default.src/config.schema.ts: addsBODY_SIZE_LIMIT_DEFAULT(default'10mb') plus optionalBODY_SIZE_LIMIT_AUTH/_ADMIN/_CREATORSoverrides, validated the same way as the rest ofenvConfig(parsed once viaenvSchema.parse(process.env)at import time).src/modules/index.ts: everyrouter.use(...)call for a sub-router now also mountsrouteBodySizeLimit(<group>)ahead of it. Mapping:auth→auth,admin→admin, the threecreatorsrouters→creators, everything else (health, config, metrics, ledger, activity, ownership, wallets, alerts)→default.src/app.ts: removes the old globalapp.use(express.json({ limit: '10mb' }))+app.use(bodyParseErrorMiddleware)pair from before the router.bodyParseErrorMiddlewareis re-mounted immediately afterapp.use('/api/v1', router)instead — Express error-handling middleware only catches errors from points later in the stack than where it's registered, and since JSON parsing now happens inside the router (per group) rather than before it, the error handler has to move down to still catchentity.too.largeand other body-parse failures..env.example: documentsBODY_SIZE_LIMIT_DEFAULTand the three optional overrides.docs/body-size-limits.md(new): overview, the default/override table, a step-by-step guide for adding an override for a new route group, the exact 413 response shape and structured-logging behavior (no raw body ever logged), matching the style of the existingdocs/rate-limiting.md.No route currently needs a limit above the existing 10mb default (there's no base64 image upload anywhere in the codebase —
avatarUrletc. are plain URL strings) — onlyauth,admin, andcreatorsget dedicated override knobs since those are the groups most likely to need one later; every other group shares the single configurable default rather than getting its own unused env var.Test plan
src/middlewares/body-size-limit.middleware.test.ts(new, 7 tests): default resolution, fallback for unconfigured groups, group-specific override, multiple simultaneous overrides, non-defaultBODY_SIZE_LIMIT_DEFAULTpropagation,routeBodySizeLimitreturns a valid middleware function, distinct instances per call. Usesjest.resetModules()+jest.doMockper case sinceGROUP_OVERRIDESis captured once at module load (mirroring howenvConfigitself is a one-time snapshot).src/__tests__/integration/body-size-limit.integration.test.ts(new, 3 tests, real Expressapp+ supertest): an oversized payload toPOST /api/v1/auth/loginunder a tiny configuredBODY_SIZE_LIMIT_AUTHreturns exactly{ status: 413, body: { success: false, code: 'BAD_REQUEST', message: 'Request payload too large' } }; a normal-sized payload is not rejected for size (falls through to real controller logic);GET /api/v1/health(default group) is unaffected by an unrelated group's tiny override.jestsuite twice (once at full parallelism, once with--maxWorkers=2) — under heavy worker contention some unrelated suites intermittently time out, and one pre-existing suite (src/middlewares/deprecation.middleware.test.ts) fails to run because it has no actualit()/describe()blocks (confirmed pre-existing, no diff vsmain) — neither is caused by this change.npx tsc -bandnpx eslinton all touched files are clean.