amal66 puts Mike's API access controls under a microscope

A new test suite is designed to catch the kinds of access failures that matter most when legal documents sit behind an API.

securityworkflow

amal66 has added route-level checks across the parts of Mike that handle conversations, projects, tables, user accounts, document uploads and basic service availability. The focus is not just whether requests work, but whether the wrong person is blocked quickly and consistently.

  • Unauthenticated access: confirms protected actions reject people who have not signed in.
  • Ownership boundaries: checks one user cannot access another user's projects or related material.
  • Input validation: tests that malformed requests are refused rather than processed.
  • Live database checks: optional tests can verify authentication, tenant separation and database-level deny-by-default rules against a real Supabase setup.

The work also makes the application easier to test without changing how it runs in production. Two hardening gaps remain flagged: upload checks rely on file extensions, and bulk ZIP downloads have no document-count ceiling.

So what Legal product teams handling confidential matter files should care because this adds repeatable proof that core access boundaries hold before a release.

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