-
Notifications
You must be signed in to change notification settings - Fork 0
Add expense tracker app with CodeRabbit review config #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,152 @@ | ||
| # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json | ||
|
|
||
| language: en-US | ||
| tone_instructions: > | ||
| Be thorough and professional. Provide actionable feedback with clear explanations | ||
| of why a change is recommended. When identifying security or performance issues, | ||
| include the potential impact and a suggested fix. Use a constructive, mentor-like tone. | ||
|
|
||
| early_access: true | ||
|
|
||
| reviews: | ||
| profile: assertive | ||
|
|
||
| # Summaries & visuals | ||
| high_level_summary: true | ||
| high_level_summary_instructions: > | ||
| Provide a concise executive summary covering: (1) what changed and why, | ||
| (2) architectural impact, (3) security or performance concerns, | ||
| and (4) any breaking changes. Include a risk assessment (low/medium/high). | ||
| high_level_summary_in_walkthrough: true | ||
| changed_files_summary: true | ||
| sequence_diagrams: true | ||
| collapse_walkthrough: false | ||
| review_status: true | ||
|
|
||
| # Effort & collaboration | ||
| estimate_code_review_effort: true | ||
| assess_linked_issues: true | ||
| related_issues: true | ||
| related_prs: true | ||
| suggested_labels: true | ||
| suggested_reviewers: true | ||
|
|
||
| # Disable fluff | ||
| poem: false | ||
| in_progress_fortune: false | ||
|
|
||
| # Auto-review settings | ||
| auto_review: | ||
| enabled: true | ||
| drafts: false | ||
| auto_incremental_review: true | ||
| base_branches: | ||
| - main | ||
| - develop | ||
| ignore_title_keywords: | ||
| - WIP | ||
| - DO NOT MERGE | ||
| - DRAFT | ||
|
|
||
| # Path filters — focus on source code | ||
| path_filters: | ||
| include: | ||
| - "backend/src/**" | ||
| - "frontend/src/**" | ||
| - "package.json" | ||
| - "tsconfig.json" | ||
| exclude: | ||
| - "node_modules/**" | ||
| - "dist/**" | ||
| - "build/**" | ||
| - "coverage/**" | ||
| - "*.min.js" | ||
| - "*.lock" | ||
| - "*.map" | ||
|
|
||
| # Path-specific review instructions | ||
| path_instructions: | ||
| - path: "backend/src/routes/**" | ||
| instructions: > | ||
| API routes: Verify input validation, proper HTTP status codes, | ||
| authentication/authorization checks, and SQL injection prevention. | ||
| Flag any raw SQL queries that don't use parameterized statements. | ||
| - path: "backend/src/middleware/**" | ||
| instructions: > | ||
| Middleware: Check JWT validation logic, error handling, and | ||
| ensure auth bypass is not possible. Verify token expiry handling. | ||
| - path: "backend/src/db.ts" | ||
| instructions: > | ||
| Database layer: Check for SQL injection, proper connection handling, | ||
| and data integrity constraints. Verify migrations are safe. | ||
| - path: "backend/src/utils/**" | ||
| instructions: > | ||
| Utility functions: Verify input sanitization, edge case handling, | ||
| and that validation logic is comprehensive and consistent. | ||
| - path: "frontend/src/pages/**" | ||
| instructions: > | ||
| Pages: Check for proper state management, error boundaries, | ||
| loading states, and accessibility (ARIA labels, keyboard navigation). | ||
| - path: "frontend/src/components/**" | ||
| instructions: > | ||
| Components: Verify React best practices — proper hook usage, | ||
| memoization where needed, prop validation, and XSS prevention. | ||
| - path: "frontend/src/api/**" | ||
| instructions: > | ||
| API client: Check error handling, request/response interceptors, | ||
| auth token attachment, and that sensitive data is not logged. | ||
|
|
||
| # Pre-merge quality gates | ||
| pre_merge_checks: | ||
| title: | ||
| mode: warning | ||
| requirements: "Use conventional commits format (feat:, fix:, refactor:, docs:, test:, chore:)" | ||
| description: | ||
| mode: warning | ||
| docstrings: | ||
| mode: warning | ||
| threshold: 70 | ||
| custom_checks: | ||
| - name: "Security" | ||
| mode: error | ||
| instructions: > | ||
| Check for hardcoded secrets, credentials, API keys, or tokens. | ||
| Verify no sensitive data is exposed in logs or error messages. | ||
| Flag any use of eval(), innerHTML, or dangerouslySetInnerHTML. | ||
| - name: "Performance" | ||
| mode: warning | ||
| instructions: > | ||
| Identify potential performance issues: N+1 queries, missing | ||
| database indexes, unbounded queries, memory leaks in React | ||
| components (missing cleanup in useEffect), and unnecessary re-renders. | ||
|
|
||
| # Finishing touches — automated improvements | ||
| finishing_touches: | ||
| docstrings: | ||
| enabled: true | ||
| unit_tests: | ||
| enabled: true | ||
|
|
||
| # Linting & analysis tools | ||
| tools: | ||
| eslint: | ||
| enabled: true | ||
| biome: | ||
| enabled: true | ||
| semgrep: | ||
| enabled: true | ||
| github-checks: | ||
| enabled: true | ||
| timeout_ms: 90000 | ||
|
|
||
| chat: | ||
| auto_reply: true | ||
|
|
||
| knowledge_base: | ||
| opt_out: false | ||
| web_search: | ||
| enabled: true | ||
| learnings: | ||
| scope: auto | ||
| issues: | ||
| scope: auto |
This file was deleted.
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| import Database from "better-sqlite3"; | ||
| import path from "path"; | ||
|
|
||
| const dbPath = path.join(__dirname, "..", "teamexpense.db"); | ||
| const db = new Database(dbPath); | ||
|
|
||
| db.pragma("journal_mode = WAL"); | ||
|
|
||
| db.exec(` | ||
| CREATE TABLE IF NOT EXISTS users ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| email TEXT UNIQUE NOT NULL, | ||
| password TEXT NOT NULL, | ||
| name TEXT NOT NULL, | ||
| role TEXT NOT NULL DEFAULT 'member' | ||
| ); | ||
|
|
||
| CREATE TABLE IF NOT EXISTS expenses ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| user_id INTEGER NOT NULL, | ||
| amount REAL NOT NULL, | ||
| description TEXT NOT NULL, | ||
| category TEXT NOT NULL, | ||
| status TEXT NOT NULL DEFAULT 'pending', | ||
| created_at TEXT NOT NULL DEFAULT (datetime('now')), | ||
| FOREIGN KEY (user_id) REFERENCES users(id) | ||
| ); | ||
| `); | ||
|
|
||
| export default db; |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,30 @@ | ||||||||||||||||||||
| import express from "express"; | ||||||||||||||||||||
| import cors from "cors"; | ||||||||||||||||||||
| import authRoutes from "./routes/auth"; | ||||||||||||||||||||
| import expenseRoutes from "./routes/expenses"; | ||||||||||||||||||||
| import reportRoutes from "./routes/reports"; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| const app = express(); | ||||||||||||||||||||
| const PORT = process.env.PORT || 3001; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // BUG: Wildcard CORS — allows any origin to make authenticated requests | ||||||||||||||||||||
| app.use(cors()); | ||||||||||||||||||||
| app.use(express.json()); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| app.use("/api/auth", authRoutes); | ||||||||||||||||||||
| app.use("/api/expenses", expenseRoutes); | ||||||||||||||||||||
| app.use("/api/reports", reportRoutes); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // BUG: No rate limiting on any endpoints — susceptible to brute-force attacks | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // BUG: Global error handler leaks stack traces to the client in production | ||||||||||||||||||||
| app.use((err: any, _req: express.Request, res: express.Response, _next: express.NextFunction) => { | ||||||||||||||||||||
| console.error(err); | ||||||||||||||||||||
| res.status(500).json({ error: err.message, stack: err.stack }); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
Comment on lines
+21
to
+24
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Medium: Stack traces exposed to clients in production The global error handler sends
Suggested change
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| app.listen(PORT, () => { | ||||||||||||||||||||
| console.log(`Server running on port ${PORT}`); | ||||||||||||||||||||
| }); | ||||||||||||||||||||
|
|
||||||||||||||||||||
| export default app; | ||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { Request, Response, NextFunction } from "express"; | ||
| import jwt from "jsonwebtoken"; | ||
|
|
||
| const JWT_SECRET = "supersecretkey123"; // BUG: Hardcoded JWT secret — should use environment variable | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Critical: Hardcoded JWT signing key in source control The JWT signing key is a short, static string committed directly to the repository. Anyone with read access can forge valid JWTs for any user or role. This is further worsened by the key being re-exported on line 36. Replace it with an environment variable and fail at startup if missing. The key should never be stored in code. |
||
|
|
||
| export interface AuthRequest extends Request { | ||
| user?: { id: number; email: string; role: string }; | ||
| } | ||
|
|
||
| export function authenticate(req: AuthRequest, res: Response, next: NextFunction) { | ||
| const header = req.headers.authorization; | ||
| if (!header) { | ||
| return res.status(401).json({ error: "No token provided" }); | ||
| } | ||
|
|
||
| // BUG: Does not validate "Bearer " prefix — any string with a valid JWT payload passes | ||
| const token = header.replace("Bearer ", ""); | ||
|
|
||
| try { | ||
| const payload = jwt.verify(token, JWT_SECRET) as any; | ||
| req.user = payload; | ||
| next(); | ||
| } catch { | ||
| return res.status(401).json({ error: "Invalid token" }); | ||
| } | ||
| } | ||
|
|
||
| export function requireAdmin(req: AuthRequest, res: Response, next: NextFunction) { | ||
| // BUG: Checks role from the JWT payload which the user controls — should verify role from DB | ||
| if (req.user?.role !== "admin") { | ||
| return res.status(403).json({ error: "Admin access required" }); | ||
| } | ||
| next(); | ||
|
Comment on lines
+4
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2. Insecure jwt auth JWT authentication is insecure: a hardcoded signing secret, non-expiring tokens, lax Authorization header parsing, and admin authorization based only on token claims enable token forgery and privilege escalation. Agent Prompt
Comment on lines
+28
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. High: Admin role authorization trusts JWT payload instead of database
Verify the current database role rather than relying solely on the token payload. |
||
| } | ||
|
|
||
| export { JWT_SECRET }; | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
9. Insecure server defaults
🐞 Bug⛨ SecurityAgent Prompt
ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools