Skip to content

fix(usage): coerce and validate topup amount_usd as a finite number#40

Merged
ralyodio merged 1 commit into
profullstack:masterfrom
AliaksandrNazaruk:fix/topup-amount-validation
Jul 2, 2026
Merged

fix(usage): coerce and validate topup amount_usd as a finite number#40
ralyodio merged 1 commit into
profullstack:masterfrom
AliaksandrNazaruk:fix/topup-amount-validation

Conversation

@AliaksandrNazaruk

Copy link
Copy Markdown
Contributor

Problem

POST /api/usage/topup read amount_usd raw from JSON and validated it with only !amount_usd and amount_usd < 1 || amount_usd > 10000. A non-numeric value like "abc" is truthy (passes the presence check) and both "abc" < 1 and "abc" > 10000 are false (NaN comparisons), so it slipped through and was forwarded to createCoinpayPayment and inserted into credit_deposits as a garbage amount. A numeric string like "50" was likewise stored as a string. (See #39.)

Fix

Coerce with Number() and guard with Number.isFinite, matching the existing pattern in funding/create-invoice/route.ts (L33–36). Downstream now always receives a real number.

const amount_usd = Number(body.amount_usd);
if (!Number.isFinite(amount_usd) || amount_usd < 1 || amount_usd > 10000) {
  return NextResponse.json({ error: "Amount must be between $1 and $10,000" }, { status: 400 });
}

Tests

Added usage/topup/__tests__/route.test.ts (mirroring the existing auth route-test style): non-numeric "abc" → 400 (and CoinPay/insert not called), out-of-range → 400, valid number → 200 with a numeric amount passed to CoinPay and the deposit row, and a numeric string coerced to a number.

Fixes #39.

/api/usage/topup read amount_usd raw from JSON and checked only
`!amount_usd` then `amount_usd < 1 || amount_usd > 10000`. A non-numeric
value like "abc" is truthy and both "abc" < 1 and "abc" > 10000 are false,
so it slipped through and was forwarded to CoinPay and inserted into
credit_deposits as a garbage amount (a numeric string like "50" was likewise
stored as a string).

Coerce with Number() and guard with Number.isFinite, matching the existing
pattern in funding/create-invoice/route.ts. Add tests covering non-numeric,
out-of-range, valid-number and numeric-string inputs.
@ralyodio ralyodio merged commit 84646c0 into profullstack:master Jul 2, 2026
9 checks passed
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.

usage/topup: amount_usd not coerced/validated as a finite number (accepts "abc")

2 participants