Skip to content

security: Replace X-User-Id placeholder auth with real JWT authentication (api/src/common/guards/)Β #138

Description

@Xhristin3

πŸ”΄ Where to work

Primary files to edit:

  • api/src/common/guards/auth.guard.ts [REWRITE] β€” currently reads X-User-Id header (line 28). Rewrite to verify JWT from Authorization: Bearer header using Passport strategy.
  • api/src/common/guards/stream-ownership.guard.ts [EDIT] β€” same X-User-Id pattern (line 30). Update to extract user from validated JWT.

New files to create:

  • api/src/auth/jwt.strategy.ts [NEW] β€” Passport JWT strategy extending PassportStrategy(Strategy)
  • api/src/auth/jwt-auth.guard.ts [NEW] β€” guard extending AuthGuard('jwt')

Files to update:

  • api/src/auth/auth.module.ts [EDIT] β€” add PassportModule import
  • api/src/streams/streams.module.ts [EDIT] β€” update guard imports to JWT versions
  • api/src/tags/tags.module.ts [EDIT] β€” update guard imports to JWT versions
  • api/src/gateways/streams.gateway.ts [VERIFY] β€” already does JWT verification independently, ensure uses same strategy

Reference patterns:

  • api/src/auth/auth.service.ts β€” JwtService.sign() already creates valid tokens
  • api/src/auth/auth.module.ts β€” JwtModule already registered

Problem Statement

The AuthGuard at api/src/common/guards/auth.guard.ts:28 reads user identity from X-User-Id header with zero verification: const rawUserId = (req.header("x-user-id") ?? "").trim(). Any caller can impersonate any user. Exploit: curl -H "X-User-Id: 1" http://localhost:3001/streams.

Acceptance Criteria

  • POST /auth/login returns JWT accepted by new AuthGuard
  • Requests without Authorization header β†’ 401
  • Requests with expired tokens β†’ 401
  • X-User-Id header completely ignored by all auth guards
  • StreamsGateway WebSocket uses same JWT verification
  • All existing auth tests pass (may need updates for new guard)

Testing Strategy

  • Unit: Test JwtStrategy.validate() with valid/invalid/expired tokens
  • Unit: Test JwtAuthGuard.canActivate() with valid/missing/malformed headers
  • Integration: Full POST /auth/login β†’ GET /streams flow
  • Negative: Expired token, wrong secret, missing header, malformed token

Security Considerations

Primary security fix. Follow OWASP authentication best practices. JWT secret from environment only. Token expiry enforced. Use sub claim as user identifier.

Metadata

Metadata

Assignees

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions