Force patched versions of two vulnerable transitive dev-tooling deps
flagged by Dependabot. Both are dev-only (pulled in transitively by
wrangler / @usebruno/cli) and are not part of the Go/Wasm Worker:
- form-data 4.0.4 -> 4.0.6 (HIGH, CRLF injection; vuln >=4.0.0 <4.0.6)
- uuid 10.0.0 -> 14.0.1 (MEDIUM, buffer bounds; vuln <11.1.1)
The pnpm overrides live in pnpm-workspace.yaml (the `overrides:` key)
rather than package.json's `pnpm.overrides` because pnpm 11 no longer
reads the "pnpm" field in package.json (it warns and ignores it). This
sits alongside the existing allowBuilds config in the same file. The
lockfile was regenerated so form-data resolves to a single 4.0.6 and
uuid to 14.0.1 (the >=11.1.1 override resolves to the latest published
uuid, which is well above the vulnerable <11.1.1 range).
Verified locally:
- pnpm install and pnpm install --frozen-lockfile exit 0
- pnpm run test:api (Bruno suite) passes 8/8 against go devserver
- pnpm exec wrangler --version -> 4.106.0
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add internal/ingest implementing POST /v1/reports, wired into the core
build-tag-free handler so the same route serves on the dev server and the
Cloudflare Worker.
Response contract (ADR #6 §2.4):
- 202 Accepted for valid JSON within the 256 KiB cap ({"status":"accepted"})
- 413 for oversized bodies (Content-Length fast path AND a MaxBytesReader
hard cap, so a missing/lying Content-Length cannot bypass the limit)
- 415 when Content-Type is not application/json
- 400 for malformed JSON or failed schema validation (generic error body,
never echoes request content)
- 405 with Allow: POST for any non-POST method
- 503 when the storage Sink fails
Storage is decoupled behind a small Sink interface (Store(ctx, raw)) with a
NopSink default and a MemorySink for tests, so PII scrubbing (#8) and
encrypted R2 storage (#9) can slot in without touching the HTTP contract.
Rate limiting (429) and volumetric shedding stay a Cloudflare-edge/Pulumi
concern per #2 and are intentionally not implemented in the Worker.
Tests:
- Go unit tests (net/http/httptest) for every response code, including 413
via both Content-Length and an oversized streamed body, plus boundary,
storage-failure, and no-content-echo cases.
- Bruno API tests in OpenCollection YAML format under api-tests/, asserting
the full contract against the local dev server via @usebruno/cli.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Initialize the Go module and the Go -> Cloudflare Workers (TinyGo/Wasm) build
path, structured so `go test` and a local dev server run on plain Go without
TinyGo, while the real Wasm entrypoint is isolated behind build tags.
- go.mod/go.sum: module github.com/JMR-dev/LibreMail-Bug-Report-Ingest (Go 1.26),
requiring github.com/syumai/workers.
- internal/handler: build-tag-free core http.Handler (GET / and GET /healthz,
JSON responses, 404/405 handling) with net/http/httptest unit tests.
- cmd/devserver: plain net/http server mounting the core handler for local dev
without TinyGo (listens on :8787, override with ADDR).
- worker/main.go: Cloudflare Workers (Wasm) entrypoint behind
//go:build js && wasm, wiring the same handler via github.com/syumai/workers;
excluded from host builds/tests.
- package.json + pnpm-lock.yaml + pnpm-workspace.yaml: wrangler dev dependency
managed with pnpm, with toolchain build scripts approved.
- wrangler.jsonc: name=libremail-bug-report-ingest, main=./build/worker.mjs,
build via `pnpm run build` (TinyGo).
- README: "Build & run locally" section with exact commands and the rationale
for the TinyGo + syumai/workers path.
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>