Skip to content

fix: rate-limit and coarsen /merchants/available discovery (G1) - #362

Merged
ericmt-98 merged 1 commit into
mainfrom
fix/discovery-rate-limit
Aug 25, 2026
Merged

fix: rate-limit and coarsen /merchants/available discovery (G1)#362
ericmt-98 merged 1 commit into
mainfrom
fix/discovery-rate-limit

Conversation

@ericmt-98

Copy link
Copy Markdown
Collaborator

Summary

Extracts a third independent, already-verified fix from the stalled #344 (62 files, CONFLICTING, open since Jul 27): GET /merchants/available had no rate limit and returned exact merchant coordinates to any unauthenticated caller (see the stays unauthenticated note at routes/merchants.ts:59 before this change).

  • Adds a per-IP rate limit to /merchants/available (429 + Retry-After once exceeded).
  • Rounds public latitude/longitude to 3 decimals in the discovery response (distance_km stays unaffected) so exact merchant location is no longer exposed to anonymous callers.

Cherry-picked from db7455b onto current origin/main in an isolated worktree. One conflict in micopay/backend/package.json: both origin/main and this commit had appended new scripts entries after test:security (main added test:sign-requests / issue-device-key; this commit added test:trade-auth / test:refund / test:challenge / test:discovery). Resolved by keeping all six script entries from both sides; the dependencies block merged cleanly with no conflict. Ran npm install afterward to confirm the lockfile needed no changes.

Test plan

  • npm ci && npm run build -> passes with no errors
  • npm run test:discovery (in-memory DB, mocked Stellar) -> all 4 tests pass, including "30 requests from the same IP within the window are allowed" and "request past max is rejected with 429 and Retry-After"
  • CI on this PR

/merchants/available was public, unauthenticated, with no rate limit,
and returned exact lat/lng — letting anyone scrape the full census of
merchant locations. Add a 30 req/min per-IP rate limiter and round the
publicly returned latitude/longitude to 3 decimals (~110m); distance_km
still uses the exact stored coordinates via the existing SQL Haversine.
Exact coordinates remain available to a counterparty only inside an
accepted trade.

Note: micopay/backend/package.json also carries pre-existing unrelated
script additions (test:trade-auth, test:refund, test:challenge) from
outside this change set — verified harmless/compatible, included
because they share the same file/hunk as the new test:discovery script.
@ericmt-98
ericmt-98 merged commit da6ea60 into main Aug 25, 2026
2 checks passed
@ericmt-98
ericmt-98 deleted the fix/discovery-rate-limit branch August 25, 2026 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant