Skip to content

feat(payments): rate-limit GET /path-payment-quote/:id#732

Open
davedumto wants to merge 1 commit into
emdevelopa:mainfrom
davedumto:fix/path-payment-quote-rate-limit
Open

feat(payments): rate-limit GET /path-payment-quote/:id#732
davedumto wants to merge 1 commit into
emdevelopa:mainfrom
davedumto:fix/path-payment-quote-rate-limit

Conversation

@davedumto
Copy link
Copy Markdown

Summary

Adds a dedicated rate limiter to the GET /api/path-payment-quote/:id endpoint, the one entry to the Path Payment Service that previously had no abuse controls. Mirrors the structure of the existing createCreatePaymentRateLimit so the surface is consistent with the rest of the payments router.

closes #599

Changes

  • [Backend] Implement rate limiting for Path Payment Service #599 — Rate limiting for Path Payment Service:
    • New src/lib/path-payment-quote-rate-limit.js exporting createPathPaymentQuoteRateLimit plus the helpers getPathPaymentQuoteRateLimitConfig, getPathPaymentQuoteRateLimitKey, and getRetryAfterSeconds (same factored shape as create-payment-rate-limit.js).
    • The key generator scopes throttling per (paymentId, actor) pair, where actor precedence is: hashed x-api-key header → req.merchant.id → client IP (via express-rate-limit's ipKeyGenerator). Scoping by payment id stops one merchant/IP from monopolising quote requests for a specific payment, while the actor portion stops a leaked API key from fanning out across unrelated payments.
    • Defaults: 20 requests / 60s. Configurable via PATH_PAYMENT_QUOTE_RATE_LIMIT_MAX and PATH_PAYMENT_QUOTE_RATE_LIMIT_WINDOW_MS; invalid values fall back to defaults.
    • On block: 429 with { error: "Too many path payment quote requests, please try again later." }, plus Retry-After and standard X-RateLimit-* headers (legacy headers off, matching the rest of the codebase).
    • src/routes/payments.js: imports createPathPaymentQuoteRateLimit, instantiates it once at module load (alongside createPaymentRateLimit), and applies it as the first middleware on router.get("/path-payment-quote/:id", …), before validateUuidParam() / validateRequest so throttled requests don't pay validation cost.

Test plan

  • New src/lib/path-payment-quote-rate-limit.test.js (11 tests, all passing locally):
    • config defaults / env overrides / invalid-env fallback
    • key generator: hashed x-api-key, merchant id, IP fallback, unknown-payment marker
    • getRetryAfterSeconds rounding + window fallback
    • factory wiring (config flows through to the limiter factory)
    • handler returns 429 with Retry-After and the expected error body
  • Existing related tests still pass: src/lib/create-payment-rate-limit.test.js (10), src/lib/rate-limit.test.js (9), src/routes/payments-path-quote.test.js (3).
  • Run with npx vitest run src/lib/path-payment-quote-rate-limit.test.js (and the three above).

Scope notes / sibling issues

This PR intentionally addresses only #599. The three other Path Payment Service issues opened alongside it were inspected and not bundled in:

  • [Backend] Conduct security audit on Trustline Manager #598 — security audit on Trustline Manager: there is no "Trustline Manager" module in src/ (a repo-wide grep -i trustline src/ returns no hits). The audit has no concrete target until that module exists, so this needs scoping from the maintainers before a PR is appropriate.
  • [Backend] Add cryptographic signature verification to Path Payment Service #600 — cryptographic signature verification on Path Payment Service: /path-payment-quote/:id is a read-only GET that returns a quote — there is no client-signed transaction in the request to verify. The actual signature-verified path is verifyTransactionSignature on the confirm-payment flow, which already calls it. Needs clarification on which surface is meant.
  • [Backend] Optimize SQL queries in Path Payment Service #601 — optimize SQL queries in Path Payment Service: the quote endpoint issues a single .from("payments").select(...).eq("id", ...).is("deleted_at", null).maybeSingle() against an indexed PK — there's no measurable optimisation to make without a profile pointing at a specific slow query.

Happy to take any of those on once they're scoped concretely.


This contribution was authored with AI assistance (Claude Code).

Adds a per-payment-id rate limiter to GET /api/path-payment-quote/:id.
Each (paymentId, actor) pair is throttled independently (actor = API key
hash, merchant id, or client IP — same precedence as the create-payment
limiter), so a leaked API key cannot fan out across unrelated payment
ids and a single payment id cannot be flooded from one IP.

Defaults: 20 requests / 60s. Configurable via
PATH_PAYMENT_QUOTE_RATE_LIMIT_MAX and PATH_PAYMENT_QUOTE_RATE_LIMIT_WINDOW_MS.

Returns 429 with X-RateLimit-* / Retry-After headers when blocked.

Co-Authored-By: Claude <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 27, 2026

@davedumto is attempting to deploy a commit to the Emmanuel's projects Team on Vercel.

A member of the Team first needs to authorize it.

@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented May 27, 2026

@davedumto Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

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.

[Backend] Implement rate limiting for Path Payment Service

1 participant