Files
motovaultpro/backend
Eric Gullickson bcb1cea311 Security fix: Implement Google Maps API photo proxy (Fix 3)
Completed HIGH severity security fix (CVSS 6.5) to prevent Google Maps
API key exposure to frontend clients.

Issue: API key was embedded in photo URLs sent to frontend, allowing
potential abuse and quota exhaustion.

Solution: Implemented backend proxy endpoint for photos.

Backend Changes:
- google-maps.client.ts: Changed photoUrl to photoReference, added fetchPhoto()
- stations.types.ts: Updated type definition (photoUrl → photoReference)
- stations.controller.ts: Added getStationPhoto() proxy method
- stations.routes.ts: Added GET /api/stations/photo/:reference route
- stations.service.ts: Updated to use photoReference
- stations.repository.ts: Updated database queries and mappings
- admin controllers/services: Updated for consistency
- Created migration 003 to rename photo_url column

Frontend Changes:
- stations.types.ts: Updated type definition (photoUrl → photoReference)
- photo-utils.ts: NEW - Helper to generate proxy URLs
- StationCard.tsx: Use photoReference with helper function

Tests & Docs:
- Updated mock data to use photoReference
- Updated test expectations for proxy URLs
- Updated API.md and TESTING.md documentation

Database Migration:
- 003_rename_photo_url_to_photo_reference.sql: Renames column in station_cache

Security Benefits:
- API key never sent to frontend
- All photo requests proxied through authenticated endpoint
- Photos cached for 24 hours (Cache-Control header)
- No client-side API key exposure

Files modified: 16 files
New files: 2 (photo-utils.ts, migration 003)

Status: All 3 P0 security fixes now complete
- Fix 1: crypto.randomBytes() ✓
- Fix 2: Magic byte validation ✓
- Fix 3: API key proxy ✓

Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 09:56:33 -06:00
..
2025-09-17 16:09:15 -05:00
2025-08-09 12:47:15 -05:00
2025-11-04 18:38:06 -06:00

MotoVaultPro Backend

Modified Feature Capsule Architecture

Each feature is 100% self-contained in src/features/[name]/:

  • api/ - HTTP endpoints and routing
  • domain/ - Business logic and types
  • data/ - Database operations
  • migrations/ - Feature-specific schema
  • external/ - External API integrations
  • tests/ - All feature tests
  • docs/ - Feature documentation

Quick Start (Containerized)

# From project root directory
# Ensure a valid .env exists at project root (production values provided by your team)

# Build and start all services (including backend)
make setup

# View logs
make logs-backend

# Run migrations
make migrate

Available Commands (Containerized)

From project root:

  • make start - Build and start all services (production)
  • make migrate - Run database migrations
  • make logs-backend - View backend logs
  • make shell-backend - Open shell in backend container

Inside container (via make shell-backend):

  • npm run build - Build for production
  • npm start - Run production build
  • npm test - Run all tests
  • npm test -- features/vehicles - Test specific feature
  • npm test -- features/vehicles/tests/unit - Test specific test type
  • npm run test:watch - Run tests in watch mode
  • npm run schema:generate - Generate combined schema

Core Modules

Configuration (src/core/config/)

  • config-loader.ts - Environment variable loading and validation
  • database.ts - PostgreSQL connection pool
  • redis.ts - Redis client and cache service
  • user-context.ts - User context extraction utilities

Security (Fastify Plugins)

  • src/core/plugins/auth.plugin.ts - Auth0 JWT via JWKS (@fastify/jwt + get-jwks)
  • src/core/plugins/error.plugin.ts - Error handling
  • src/core/plugins/logging.plugin.ts - Request logging

Logging (src/core/logging/)

  • logger.ts - Structured logging with Winston

Middleware

  • src/core/middleware/user-context.ts - User ID extraction from JWT

Storage

  • src/core/storage/ - Storage abstractions
  • src/core/storage/adapters/minio.adapter.ts - MinIO S3-compatible adapter

Feature Development

To create a new feature capsule:

../scripts/generate-feature-capsule.sh feature-name

This creates the complete capsule structure with all necessary files.

Testing

Tests mirror the source structure:

features/vehicles/
├── domain/
│   └── vehicles.service.ts
└── tests/
    └── unit/
        └── vehicles.service.test.ts

Run tests (inside container via make shell-backend):

# All tests
npm test

# Specific feature
npm test -- features/vehicles

# Unit tests for specific feature
npm test -- features/vehicles/tests/unit

# Integration tests for specific feature
npm test -- features/vehicles/tests/integration

# Watch mode
npm run test:watch

# With coverage
npm test -- features/vehicles --coverage

Environment Variables

Ensure .env includes these key variables:

  • Database connection (DB_*)
  • Redis connection (REDIS_*)
  • Auth0 configuration (AUTH0_*) — backend validates JWTs via Auth0 JWKS (@fastify/jwt + get-jwks)
  • External API keys