Skip to content

fix: cap POST /download-zip at 50 documents#111

Open
bmersereau wants to merge 2 commits into
willchen96:mainfrom
bmersereau:fix/99-download-zip-limit
Open

fix: cap POST /download-zip at 50 documents#111
bmersereau wants to merge 2 commits into
willchen96:mainfrom
bmersereau:fix/99-download-zip-limit

Conversation

@bmersereau
Copy link
Copy Markdown

@bmersereau bmersereau commented May 13, 2026

Summary

  • Adds a MAX_ZIP_DOCUMENTS = 50 constant and a 400 guard to POST /single-documents/download-zip
  • Prevents an authenticated user from triggering simultaneous in-memory loading of an unbounded number of large files

Closes #99
Closes #114

Changes

  • backend/src/routes/documents.tsMAX_ZIP_DOCUMENTS constant + length check returning 400
  • backend/src/lib/__tests__/downloadZipLimit.test.ts — static analysis test verifying the limit exists
  • backend/vitest.config.ts — vitest config scoping tests to src/ (excludes compiled dist/)
  • backend/package.json"test": "vitest run" script added

Test plan

  • Unit tests added and passing
  • Backend build passes

Copy link
Copy Markdown
Author

@bmersereau bmersereau left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review

Summary

Adds MAX_ZIP_DOCUMENTS = 50 guard to POST /single-documents/download-zip, returning 400 with a clear message when the request exceeds the limit. Simple, correct, and exactly scoped to the issue.

Findings

  • [severity:praise] Named constant MAX_ZIP_DOCUMENTS makes the limit self-documenting and easy to tune
  • [severity:praise] Error message includes the actual limit value (Cannot download more than ${MAX_ZIP_DOCUMENTS} documents at once) — good UX
  • [severity:nit] Static test uses readFileSync — verifies pattern is present but not that the HTTP response is actually 400. Acceptable given the simplicity of the change

Specific checks

  • "test": "vitest run" in package.json ✓
  • vitest.config.ts include filter present ✓
  • Tests pass: 2/2 ✓
  • documents.ts unchanged from origin/main (aside from this fix) ✓

Verdict

Approve — clean.

Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
- Add RLS to all public tables with deny-all default policy and
  auto-enable event trigger for future tables. PostgREST anon role
  can no longer read any data. Prisma service-role bypasses RLS (PR willchen96#145)
- Wrap runLLMStream() in Promise.race with 180s configurable timeout;
  sends SSE error event on timeout and closes connection (PR willchen96#112)
- Cap download-zip document_ids array at 50 to prevent memory
  exhaustion from unbounded batch downloads (PR willchen96#111)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Dshamir added a commit to Dshamir/AI-Legal that referenced this pull request May 24, 2026
…tegration

- CHANGELOG: add security hardening and feature entries for PRs willchen96#158,
  willchen96#81, willchen96#76, willchen96#79, willchen96#145, willchen96#112, willchen96#111, willchen96#110, willchen96#155, willchen96#157, willchen96#59
- ROADMAP: mark 12 new items as completed
- CLAUDE.md: add sanitize.ts, streamTimeout.ts, credits.ts to lib index,
  update test count to 40
- README: update API endpoints table (chat pagination, workflow export),
  security row (HKDF, RLS, prompt defense), encryption row

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant