Commit Graph

13 Commits

Author SHA1 Message Date
Ho Ngoc Hai
3be66f72df feat(listings): rate limit feature-listing via @nestjs/throttler (TEC-2930)
- Wire ThrottlerModule to a Redis-backed storage (shared across API
  instances) using @nest-lab/throttler-storage-redis.
- Add FeatureListingThrottlerGuard that tracks per-user when JWT is
  present, falling back to the real client IP behind the reverse proxy —
  keeps per-user and per-IP buckets independent.
- Apply @Throttle({ default: { limit: 10, ttl: 60_000 } }) + the guard
  to POST /listings/:id/feature and document 429 in Swagger.
- Integration test (feature-listing-throttle.integration.spec.ts)
  verifies: 10 reqs pass / 11th returns 429 with Retry-After, separate
  IPs keep their own quotas, and the tracker key logic.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-20 08:31:26 +07:00
Ho Ngoc Hai
329a821b4a feat(notifications): production-ready WebSocket gateway (TEC-2766)
- Add RedisIoAdapter (shared/infra) for multi-instance Socket.IO fan-out
  with graceful fallback to the in-memory IoAdapter when Redis is
  unreachable.
- Pin Socket.IO heartbeat (pingInterval/pingTimeout/connectTimeout)
  via env-tunable gateway options for reconnect stability.
- Expose Prometheus metrics on /notifications: goodgo_ws_connected_clients
  (Gauge) and goodgo_ws_messages_total (Counter) with namespace/event/
  direction labels. Wired through MetricsService and tracked across
  connect/disconnect + emits.
- Unit tests: RedisIoAdapter connect/fallback/close, new MetricsService
  WS helpers, and gateway metric increments/decrements on auth paths.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-18 15:06:25 +07:00
Ho Ngoc Hai
9e2bf9a4b5 fix: remaining lint auto-fixes and rate-limit guard test fixes
- Import ordering auto-fixes from `pnpm lint --fix` for remaining API modules
- Fix rate-limit guard test specs: override NODE_ENV to 'development'
  so guards don't skip rate limiting in test mode
- Unused import removal (UnauthorizedException in login-user handler)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-11 23:12:45 +07:00
Ho Ngoc Hai
d824d16760 feat(security): add per-endpoint API rate limiting with Redis sliding window
Implement @EndpointRateLimit() decorator and EndpointRateLimitGuard for
granular per-endpoint rate limiting using a Redis sorted-set sliding window.
This prevents brute force attacks on auth endpoints, replay attacks on
payment callbacks, and scraping on search endpoints.

Applied rate limits:
- /auth/login: 5 req/min per IP
- /auth/register: 3 req/min per IP
- /listings POST: 10 req/min per user
- /search: 30 req/min per user
- /payments/callback/*: 100 req/min per IP

Features:
- True sliding window (sorted set) for accurate rate measurement
- Configurable key strategy (IP or authenticated user)
- Admin bypass support (enabled by default)
- Fail-open on Redis errors
- Proper 429 response with Retry-After header
- Rate limit headers (X-RateLimit-Limit/Remaining/Reset)
- 22 unit tests covering all scenarios

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-11 00:36:35 +07:00
Ho Ngoc Hai
6ebacbc9bf fix: apply consistent-type-imports across API codebase (728 lint errors)
- Convert `import type { X }` to `import { type X }` (inline-type-imports style)
- Suppress consistent-type-imports for `typeof import()` in instrument.ts
- Includes uncommitted agent work: metrics module, redis caching, audit logs,
  saved searches, circuit breaker, rate limiting, and admin enhancements

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-10 23:22:21 +07:00
Ho Ngoc Hai
2611cfa867 feat(api): add @Cacheable decorator and plan list caching
- Create @Cacheable method decorator for declarative cache-aside pattern
  with configurable prefix, TTL, resource label, and key extraction
- Add PLAN_LIST (1h TTL) and REFERENCE_DATA (24h TTL) cache constants
- Add CachePrefix.PLAN_LIST and CachePrefix.REFERENCE entries
- Cache subscription plan queries in GetPlanHandler (single + list)
- Export Cacheable decorator from shared module barrel
- Add comprehensive tests for decorator and handler caching

The caching infrastructure (CacheService, Redis, Prometheus metrics,
event-driven invalidation) was already production-ready with 10+ hot
paths cached. This commit adds the missing declarative decorator and
plan list caching.

Resolves: TEC-1567

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 10:26:59 +07:00
Ho Ngoc Hai
45ebc6cf1d feat: API versioning, compound indexes, and new exports
- Add global /api/v1/ prefix with health/ready exclusions
- Add compound indexes on Property and Listing for query optimization
- Export CsrfMiddleware and UploadedFile type from shared infra
- New Prisma migration for compound indexes

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 01:27:17 +07:00
Ho Ngoc Hai
e89cd0ce84 fix(security): reject placeholder/weak JWT secrets at startup
The env-validation module previously only checked that JWT_SECRET and
JWT_REFRESH_SECRET were _present_ — it accepted any value, including
known placeholders like "CHANGE_ME". This meant a developer could copy
.env.example verbatim and run the app with predictable, forgeable tokens.

Changes:
- Add FORBIDDEN_SECRET_VALUES blocklist (case-insensitive) with 23 common
  placeholder strings (CHANGE_ME, secret, password, test, etc.)
- Enforce minimum 32-character length for JWT secrets (NIST HMAC guidance)
- Export validateJwtSecret() for direct testing and reuse
- Update .env.example: replace "CHANGE_ME" with generation instructions
- Add 14 unit tests covering placeholder rejection, length enforcement,
  missing-var errors, and production-mode validation

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-09 01:20:30 +07:00
Ho Ngoc Hai
e89c8f5810 fix(security): add production env validation and sanitize .env.example
- Add startup env validation that fails fast in production if critical vars
  (JWT_SECRET, JWT_REFRESH_SECRET, DATABASE_URL, CORS_ORIGINS, REDIS_HOST)
  are missing
- Fix CORS_ORIGINS to throw in production instead of defaulting to localhost
- Replace hardcoded dev passwords in .env.example with CHANGE_ME placeholders
- Add missing vars to .env.example (CORS_ORIGINS, SMTP_*, FIREBASE, LOG_LEVEL)
- Warn on missing optional payment/storage vars at startup

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 06:12:39 +07:00
Ho Ngoc Hai
2a392525a2 feat(cache): implement Redis caching layer for hot-read endpoints
Add cache-aside pattern for listing detail, search results, market
analytics (4 endpoints), and user profile queries. Cache invalidation
on all write mutations. Prometheus cache_hit_total/cache_miss_total
metrics with resource labels.

- CacheService: getOrSet, invalidate, invalidateByPrefix (SCAN-based)
- TTLs: listing 5m, search 1m, market 30m, profile 10m
- All 230 tests passing (13 new cache tests + 6 updated handler tests)

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 04:14:06 +07:00
Ho Ngoc Hai
f3081d92fc feat(security): add security hardening — Helmet, CORS, rate limiting, input sanitization
- Add Helmet with CSP, HSTS, referrer policy
- Configure CORS with environment-based origins
- Add global validation pipe with whitelist mode
- Add SanitizeInputMiddleware for XSS prevention
- Add ThrottlerBehindProxyGuard for rate limiting
- Add FileValidationPipe for upload security
- Set request body size limit to 1MB

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 02:04:13 +07:00
Ho Ngoc Hai
c981bff771 feat(shared): add error handling & structured logging strategy
- Global exception filter with consistent error response format
- Domain exceptions (NotFoundException, ValidationException, etc.)
- Error codes enum for domain-specific error identification
- Correlation ID middleware for request tracing
- Request/response logging middleware with structured JSON
- PII masking in logs (emails, phone numbers, sensitive fields)
- Enhanced LoggerService with pino formatters and ISO timestamps
- Tests for exception filter, domain exceptions, and PII masker

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 00:18:21 +07:00
Ho Ngoc Hai
1fb7bb39d2 feat(shared): add shared module with domain primitives, infrastructure services, and utils
Domain primitives: BaseEntity, AggregateRoot, ValueObject, DomainEvent, Result<T,E>
Infrastructure: PrismaService, RedisService, LoggerService (pino), EventBusService
Utils: Vietnam phone validator/normalizer, VND currency formatter, Vietnamese slug generator
Includes 45 unit tests covering all domain primitives, validators, and formatters.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-08 00:07:27 +07:00