amal66 puts Mike's access controls under pressure

This fork adds direct testing of the boundaries that should keep one client's legal material out of another's hands.

securityinfrastructure

amal66 has separated the web service from the process that starts it, making it practical to test the service itself without changing how production runs. The result is a fast safety net around the routes handling legal workspaces and documents.

  • Tests block unauthenticated requests across core legal-work routes.
  • Ownership checks verify that one user cannot reach another user's resources.
  • Input and normal-use checks cover chat, projects, tabular work, user settings, uploads and service health.
  • Optional live checks exercise Supabase, a hosted database and authentication service, for tenant isolation and database access rules.

The work also identifies two remaining hardening gaps: uploads are checked by filename extension alone, and bulk downloads have no document-count limit.

So what Legal teams and product leaders handling privileged material should care because this turns access-control promises into repeatable checks before changes ship.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

6 commits from amal66/mike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
e7a09761 test(chapter-28): add HTTP integration tests around the Express app Amal 2026-05-24 ↗ GitHub
commit body
Chapter: 28 - Request-level testing.

Plain-English map:
Extract an app factory from process startup and add Supertest integration
tests that exercise the API through HTTP-style requests.

Why it matters:
Unit tests protect small functions. Integration tests catch mistakes in route
wiring, middleware order, and app startup assumptions.

Principle:
Test important boundaries at the level where users and clients hit them.

Precedent borrowed:
The fork report's testing leaders and downstream backend test coverage.

Upstream base: willchen96/mike@d39f580.
Original local commit: 9549258.
45a4f750 test: route-level integration tests + app/index split QA Runner 2026-07-20 ↗ GitHub
commit body
Ports the backend route-level integration suites from the amal66 fork
(index: Open-Legal-Products/mike#205), adapted from the fork's
apps/api modules/services layout to this repo's monolithic
backend/src/routes/*.ts layout.

app/index split (the only production change; mechanical, zero behavior
change): backend/src/index.ts previously built the express app and
called app.listen at the bottom. Everything except the listen call
moved verbatim into backend/src/app.ts, which now exports `app` (same
middleware order, same routes, same rate-limiter setup, dotenv/config
still imported first). index.ts is now a tiny entry that imports
{ app } and calls listen with the same log line. `npm run build` still
emits dist/index.js and the `start` script is unchanged.

New suites under backend/src/__tests__/integration/ (94 tests):
- health.test.ts (5): /health, requireAuth 401 paths, 404 fallthrough
- chat.routes.test.ts (6): POST /chat validation + SSE happy/error paths
- projects.routes.test.ts (18): overview/create/detail/patch/delete,
  sharing normalisation, ownership guards
- projectChat.routes.test.ts (3): project access guard + SSE paths
- tabular.routes.test.ts (31): review CRUD, access guards,
  document-access filtering, missing_api_key guards
- user.routes.test.ts (27): profile, API-key crypto boundary, MFA
  guards, export/deletion endpoints
- documentsUpload.routes.test.ts (4): upload validation + download-zip
  bounds/access
- access.supabase.test.ts (1) + stack.supabase.test.ts (4): gated on
  SUPABASE_TEST_URL / SUPABASE_TEST_SERVICE_ROLE_KEY (stack suite also
  needs SUPABASE_TEST_ANON_KEY); describe.skip otherwise
- scripts/test-stack.sh + `npm run test:stack`: reads a running
  `supabase status -o json` and runs the gated suites

Adds supertest + @types/supertest as devDependencies.

Dropped relative to the fork (subjects that do not exist in this repo):
- orgs.routes, credits.concurrency.supabase, dmsConnectors suites
  (fork-only features)
- all credit-reservation cases (429 CREDIT_LIMIT_EXCEEDED,
  reserve-then-refund) in chat/projectChat: no credit system here
- health /ready case: no /ready endpoint here
- org-membership project access case: no org model here
- upload magic-byte validation cases: this repo validates extension
  only (the fork adds content sniffing; replaced with a missing-file
  400 case)
- download-zip 50-document cap case: no cap here (replaced with a
  no-accessible-documents 404 case)
- stack.supabase PUBLIC_TABLES updated to this repo's schema; the
  fork's credit-RPC coverage is n/a

Verified locally: backend `npm test` -> 8 files passed, 2 skipped;
106 tests passed, 5 skipped (gated suites skip without env).
`npm run build` passes. The gated suites were additionally run against
a live local Supabase stack: 2 files, 5/5 tests passed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
6aed350a fix: repair JSON corrupted by the merge of main (package.json + lockfile) QA Runner 2026-07-22 ↗ GitHub
commit body
The "Merge branch 'main'" commit (71a7aba) auto-merged backend/package.json
and backend/package-lock.json without raising a conflict, but git's
line-level merge produced invalid JSON in both files: package.json lost the
comma after the new "test:stack" script, and package-lock.json lost the two
closing-brace lines of the supertest/cookie-signature entry. npm treats an
unparseable lockfile as absent, which is why CI failed with the misleading
"npm ci can only install with an existing package-lock.json".

package.json: restore the comma. package-lock.json: rebuilt from main's
known-good copy via `npm install --package-lock-only` against this branch's
package.json. Verified locally: npm ci, npm test (259 passed), npm run build.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
71a7aba3 Merge branch 'main' into olp-pr/backend-integration-tests Will Chen 2026-07-22 ↗ GitHub
9399fce8 fix stack test database initialization willchen96 2026-07-23 ↗ GitHub
b2dbb39c narrow service role schema grants willchen96 2026-07-23 ↗ GitHub

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-1336.md from inside the repo you want the changes in.

⬇ Download capture-thread-1336.md