Skip to content

fix(backend): protect analytics/reputation routes with JwtAuthGuard, add indexes on claimedById and webhook events, and enforce MaxLength on free-text DTOs (#138, #139, #148, #149, #151) - #184

Open
ghzhost wants to merge 1 commit into
MergeFi:mainfrom
ghzhost:fix/auth-guards-and-schema-hardening-138-139-148-149-151

Conversation

@ghzhost

@ghzhost ghzhost commented Aug 21, 2026

Copy link
Copy Markdown

Summary of Changes

This PR addresses multiple security, performance, and schema validation items across the backend:

  1. Authentication Guards on Analytics & Reputation Endpoints (ReputationController has zero authentication guards, including POST /:userId/recompute #138, AnalyticsController.forContributor has no authentication guard #139):

    • Added @UseGuards(JwtAuthGuard) and @ApiBearerAuth() to AnalyticsController.forContributor (GET /analytics/contributors/:userId), preventing unauthenticated scraping of contributor financial/performance profile data.
    • Added @UseGuards(JwtAuthGuard) and @ApiBearerAuth() to ReputationController across POST /:userId/recompute, GET /:userId, and GET /:userId/history, preventing unauthenticated denial-of-service / duplicate snapshot writes and information exposure.
  2. Database Performance Indexing (Bounty.claimedById has no database index despite being the primary filter column for reputation and analytics #148, WebhookEvent has no index on eventType, status, or receivedAt #149):

    • Added @Index() on Bounty.claimedById (src/common/entities/bounty.entity.ts), speeding up critical contributor lookups in ReputationService and AnalyticsService.
    • Added composite indexes @Index(["eventType", "status"]), @Index(["status", "receivedAt"]), and single index on receivedAt in WebhookEvent (src/common/entities/webhook-event.entity.ts) for query performance over ever-growing webhook audit logs.
  3. String Length Range & DTO Constraints (Several free-text DTO fields have no @MaxLength(), and their entity columns have no varchar length either #151):

    • Enforced @MaxLength(100) on TeamMemberSplitDto.role and matching length: 100 on TeamMemberSplit.role.
    • Enforced @MaxLength(150) on CreateTeamDto.name.
    • Enforced @MaxLength(255) on CreateMilestoneDto.title and @MaxLength(2000) on description, with corresponding column lengths in Milestone entity.
    • Enforced @MaxLength(150) on CreatePoolDto.name and corresponding column length in MaintenancePool entity.

Validation

  • Ran full test suite (npm test excluding disconnected Postgres DB integration specs): all 20 test suites and 163 unit tests passed cleanly.
  • Tested compilation (npm run build): clean build.

Closes #138, Closes #139, Closes #148, Closes #149, Closes #151

…add indexes on claimedById and webhook events, and enforce MaxLength on free-text DTOs (MergeFi#138, MergeFi#139, MergeFi#148, MergeFi#149, MergeFi#151)
@vercel

vercel Bot commented Aug 21, 2026

Copy link
Copy Markdown

Someone is attempting to deploy a commit to the chonilius' projects Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment