fix(GRO-1036): secure stats endpoint + restore refund preconditions #385
Reference in New Issue
Block a user
Delete Branch "fix/GRO-1036-security-findings"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Fixes two security regressions introduced in PR #349 (GRO-693 E2E mock fixes):
CRITICAL — unauthenticated
/api/invoices/stats/summary: The handler was placed outside the authenticated router block, exposingrevenueThisMonth,outstanding,refundsThisMonth, andmethodBreakdownto anyone. AddedrequireRole('manager')middleware directly on the handler.HIGH — refund pre-condition removed + groomer role expansion: Two compounding issues:
requireRolefor refunds changed from"manager"to"manager", "groomer"— reverted to manager-only per CTO rulingstripePaymentIntentIdwas removed — restored, returns 422 when invoice has no Stripe payment intent (prevents manual refund abuse)manual_fallback refund branch since the pre-condition now guarantees a Stripe payment intent existsChanges
apps/api/src/routes/invoices.tsrequireRole('manager')auth middleware toGET /stats/summarystripePaymentIntentIdpre-condition check onPOST /:id/refund→ 422"groomer")processRefundimport to top-level imports sectionTesting
/api/invoices/stats/summaryneeds auth headers added — the mock intercept still applies since it runs in the browser; actual requests will now carry the auth cookie from the sessioncc @cpfarhood
QA review passed. All three security acceptance criteria verified:
/api/invoices/stats/summary—requireRole('manager')middleware added; endpoint is no longer unauthenticated.stripePaymentIntentIdguard — 422 early-return restored before the transaction; dead manual-refund fallback correctly removed.CI: Lint ✅ Typecheck ✅ Tests ✅ Build ✅ E2E ✅
Passing to CTO for final approval and merge.
CTO Review — APPROVED ✅
Diff reviewed. Both security findings correctly remediated:
requireRole("manager")added inline to/stats/summary. Unauthenticated access closed.stripePaymentIntentId422 early-return restored before the transaction; dead manual-refund fallback removed. Clean.Minimal, targeted fix. CI all green. QA approved. Merging to dev.
Deployed to groombook-dev
Images:
pr-385URL: https://dev.groombook.farh.net
Ready for UAT validation.