Repository navigation
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🤖 CodeLens AI Review🔍 Code Review - api/razorpay.tsIssues Found:
|
📝 WalkthroughWalkthrough
ChangesRazorpay createOrder protection
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant createOrder
participant Firestore
participant Razorpay
Client->>createOrder: Submit createOrder request
createOrder->>Firestore: Validate billing and update rate-limit state
Firestore-->>createOrder: Allow request or return retry delay
alt Request allowed
createOrder->>Razorpay: Create order
Razorpay-->>createOrder: Return order details
createOrder-->>Client: Return order response
else Request limited
createOrder-->>Client: Return HTTP 429 with Retry-After
end
Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Visit the preview URL for this PR (updated for commit 8b6e910): https://servio-0--pr367-fix-253-api-rate-lim-8205mbg4.web.app (expires Sat, 15 Aug 2026 17:03:37 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 15915abb5951eb298a844eda460b24f444d93a69 |
🤖 CodeLens AI Review🔍 Code Review - api/razorpay.tsIssues Found:
|
🤖 CodeLens AI Review |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@api/razorpay.ts`:
- Around line 101-112: Update createOrder’s rate-limit setup to require
RATE_LIMIT_HASH_SECRET, returning a server error before order creation when it
is missing; pass that secret to checkRateLimit instead of razorpayKeySecret, and
change its catch path to return a 503 response rather than continuing with
payment creation.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
| // Use the already-required server-side Razorpay secret to hash the IP. | ||
| // No additional environment variable is needed. Rate-limit persistence is | ||
| // best-effort; only an actual limit violation blocks order creation. | ||
| try { | ||
| const verdict = await checkRateLimit(callerIp(req), razorpayKeySecret, Date.now()); | ||
| if (!verdict.allowed) { | ||
| res.setHeader("Retry-After", String(Math.ceil(verdict.retryAfterMs / 1000))); | ||
| return res.status(429).json({ error: "Too many order requests. Please try again later.", retryAfterMs: verdict.retryAfterMs }); | ||
| } | ||
| } catch (error) { | ||
| console.error("Razorpay rate-limit check failed; continuing with payment creation:", error); | ||
| } |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Fail closed when rate limiting is unavailable.
Lines 101-112 use RAZORPAY_KEY_SECRET instead of RATE_LIMIT_HASH_SECRET. They also continue order creation when checkRateLimit fails. An attacker can bypass the protection during Firestore failures, so this does not meet the required fail-closed behavior.
Require RATE_LIMIT_HASH_SECRET for createOrder. Return a server error when it is missing. Return a 503 when the rate-limit transaction fails.
Proposed fix
- // Use the already-required server-side Razorpay secret to hash the IP.
- // No additional environment variable is needed. Rate-limit persistence is
- // best-effort; only an actual limit violation blocks order creation.
+ const rateLimitHashSecret = process.env.RATE_LIMIT_HASH_SECRET;
+ if (!rateLimitHashSecret) {
+ return res.status(500).json({ error: "Rate limiting is not configured. Please try again later." });
+ }
try {
- const verdict = await checkRateLimit(callerIp(req), razorpayKeySecret, Date.now());
+ const verdict = await checkRateLimit(callerIp(req), rateLimitHashSecret, Date.now());
if (!verdict.allowed) {
res.setHeader("Retry-After", String(Math.ceil(verdict.retryAfterMs / 1000)));
return res.status(429).json({ error: "Too many order requests. Please try again later.", retryAfterMs: verdict.retryAfterMs });
}
} catch (error) {
- console.error("Razorpay rate-limit check failed; continuing with payment creation:", error);
+ console.error("Razorpay rate-limit check failed:", error);
+ return res.status(503).json({ error: "Please try again later." });
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Use the already-required server-side Razorpay secret to hash the IP. | |
| // No additional environment variable is needed. Rate-limit persistence is | |
| // best-effort; only an actual limit violation blocks order creation. | |
| try { | |
| const verdict = await checkRateLimit(callerIp(req), razorpayKeySecret, Date.now()); | |
| if (!verdict.allowed) { | |
| res.setHeader("Retry-After", String(Math.ceil(verdict.retryAfterMs / 1000))); | |
| return res.status(429).json({ error: "Too many order requests. Please try again later.", retryAfterMs: verdict.retryAfterMs }); | |
| } | |
| } catch (error) { | |
| console.error("Razorpay rate-limit check failed; continuing with payment creation:", error); | |
| } | |
| const rateLimitHashSecret = process.env.RATE_LIMIT_HASH_SECRET; | |
| if (!rateLimitHashSecret) { | |
| return res.status(500).json({ error: "Rate limiting is not configured. Please try again later." }); | |
| } | |
| try { | |
| const verdict = await checkRateLimit(callerIp(req), rateLimitHashSecret, Date.now()); | |
| if (!verdict.allowed) { | |
| res.setHeader("Retry-After", String(Math.ceil(verdict.retryAfterMs / 1000))); | |
| return res.status(429).json({ error: "Too many order requests. Please try again later.", retryAfterMs: verdict.retryAfterMs }); | |
| } | |
| } catch (error) { | |
| console.error("Razorpay rate-limit check failed:", error); | |
| return res.status(503).json({ error: "Please try again later." }); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@api/razorpay.ts` around lines 101 - 112, Update createOrder’s rate-limit
setup to require RATE_LIMIT_HASH_SECRET, returning a server error before order
creation when it is missing; pass that secret to checkRateLimit instead of
razorpayKeySecret, and change its catch path to return a 503 response rather
than continuing with payment creation.
Summary
createOrderendpointRATE_LIMIT_HASH_SECRETbefore storing rate-limit state429withRetry-Afterwhen a caller exceeds the order-creation limitThis prevents unauthenticated callers from repeatedly invoking the paid Gemini/Razorpay operations described in #253.
Closes #253
Summary by CodeRabbit