Commit Graph

17 Commits

Author SHA1 Message Date
Eric Gullickson
dd3b58e061 fix: migrate remaining controllers from Auth0 sub to UUID identity (refs #220)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 3m40s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 24s
Deploy to Staging / Verify Staging (pull_request) Successful in 10s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 8s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
16 controllers still used request.user.sub (Auth0 ID) instead of
request.userContext.userId (UUID) after the user_id column migration,
causing 500 errors on all authenticated endpoints including dashboard.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:38:46 -06:00
Eric Gullickson
87ee498af7 chore: update docs 2026-02-05 21:49:35 -06:00
ec8e6ee5d2 Merge pull request 'feat: Document feature enhancements (#31)' (#32) from issue-31-document-enhancements into main
All checks were successful
Deploy to Staging / Build Images (push) Successful in 4m43s
Deploy to Staging / Deploy to Staging (push) Successful in 38s
Deploy to Staging / Verify Staging (push) Successful in 7s
Deploy to Staging / Notify Staging Ready (push) Successful in 6s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
Reviewed-on: #32
2026-01-15 02:35:55 +00:00
Eric Gullickson
a3b119a953 fix: resolve document upload hang by fixing stream pipeline (refs #33)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 2m22s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 29s
Deploy to Staging / Verify Staging (pull_request) Successful in 7s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 6s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
The upload was hanging silently because breaking early from a
`for await` loop on a Node.js stream corrupts the stream's internal
state. The remaining stream could not be used afterward.

Changes:
- Collect ALL chunks from the file stream before processing
- Use subarray() for file type detection header (first 4100 bytes)
- Create single readable stream from complete buffer for storage
- Remove broken headerStream + remainingStream piping logic

This fixes the root cause where uploads would hang after logging
"Document upload requested" without ever completing or erroring.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 20:28:19 -06:00
Eric Gullickson
5dbc17e28d feat: add document-vehicle API endpoints and context-aware delete (refs #31)
Updates documents backend service and API to support multi-vehicle insurance documents:
- Service: createDocument/updateDocument validate and handle sharedVehicleIds for insurance docs
- Service: addVehicleToDocument validates ownership and adds vehicles to shared array
- Service: removeVehicleFromDocument with context-aware delete logic:
  - Shared vehicle only: remove from array
  - Primary with no shared: soft delete document
  - Primary with shared: promote first shared to primary
- Service: getDocumentsByVehicle returns all docs for a vehicle (primary or shared)
- Controller: Added handlers for listByVehicle, addVehicle, removeVehicle with proper error handling
- Routes: Added POST/DELETE /documents/:id/vehicles/:vehicleId and GET /documents/by-vehicle/:vehicleId
- Validation: Added DocumentVehicleParamsSchema for vehicle management routes

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 19:28:00 -06:00
Eric Gullickson
57debe4252 feat: add shared_vehicle_ids schema and repository methods (refs #31)
- Add migration 004_add_shared_vehicle_ids.sql with UUID array column and GIN index
- Update DocumentRecord interface to include sharedVehicleIds field
- Add sharedVehicleIds to CreateDocumentBody and UpdateDocumentBody schemas
- Update repository mapDocumentRecord() to map shared_vehicle_ids from database
- Update insert() and batchInsert() to handle sharedVehicleIds
- Update updateMetadata() to support sharedVehicleIds updates
- Add addSharedVehicle() method using atomic array_append()
- Add removeSharedVehicle() method using atomic array_remove()
- Add listByVehicle() method to query by primary or shared vehicle

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 19:24:34 -06:00
Eric Gullickson
7928b87ef5 feat: integrate DocumentsService with ownership_costs (refs #29)
Milestone 2: Auto-create ownership_cost when insurance/registration
document is created with cost data (premium or cost field).

- Add OwnershipCostsService integration
- Auto-create cost on document create when amount > 0
- Sync cost changes on document update
- mapDocumentTypeToCostType() validation
- extractCostAmount() for premium/cost field extraction
- CASCADE delete handled by FK constraint

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 21:30:02 -06:00
Eric Gullickson
e6af7ed5d5 feat: add batch insert operations to repositories (refs #26)
Add batchInsert methods to vehicles, fuel-logs, maintenance, and documents repositories. Multi-value INSERT syntax provides 10-100x performance improvement over individual operations for bulk data import.

- vehicles.repository: batchInsert for vehicles
- fuel-logs.repository: batchInsert for fuel logs
- maintenance.repository: batchInsertRecords and batchInsertSchedules
- documents.repository: batchInsert for documents
- All methods support empty array (immediate return) and optional transaction client
- Fix lint error: replace require() with ES6 import in test mock

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-11 19:28:11 -06:00
Eric Gullickson
f494f77150 feat: Implement user tier-based feature gating system (refs #8)
All checks were successful
Deploy to Staging / Build Images (pull_request) Successful in 4m35s
Deploy to Staging / Deploy to Staging (pull_request) Successful in 27s
Deploy to Staging / Verify Staging (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Ready (pull_request) Successful in 5s
Deploy to Staging / Notify Staging Failure (pull_request) Has been skipped
Add subscription tier system to gate features behind Free/Pro/Enterprise tiers.

Backend:
- Create feature-tiers.ts with FEATURE_TIERS config and utilities
- Add /api/config/feature-tiers endpoint for frontend config fetch
- Create requireTier middleware for route-level tier enforcement
- Add subscriptionTier to request.userContext in auth plugin
- Gate scanForMaintenance in documents controller (Pro+ required)
- Add migration to reset scanForMaintenance for free users

Frontend:
- Create useTierAccess hook for tier checking
- Create UpgradeRequiredDialog component (responsive)
- Gate DocumentForm checkbox with lock icon for free users
- Add SubscriptionTier type to profile.types.ts

Documentation:
- Add TIER-GATING.md with usage guide

Tests: 30 passing (feature-tiers, tier-guard, controller)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-04 14:34:47 -06:00
Eric Gullickson
2ab58267dd feat: expand documents to include manuals 2025-12-25 12:54:00 -06:00
Eric Gullickson
719c80ecd8 Notification updates 2025-12-21 19:56:52 -06:00
Eric Gullickson
183d55b0fe Security fix: Implement magic byte validation for file uploads (Fix 2)
Fixed HIGH severity security vulnerability (CVSS 7.5) where file upload
validation relied solely on Content-Type headers, allowing malicious
files with spoofed MIME types to bypass validation.

Changes:
- Updated file-type dependency to v16.5.4 (last CommonJS version)
- Added magic byte (file signature) validation using fileTypeFromBuffer
- Read first 4100 bytes of upload to detect actual file type
- Verify detected type matches claimed Content-Type header
- Reject files where content doesn't match headers
- Enhanced logging with detected_type for audit trail

Security impact:
- Prevents .exe files renamed to .pdf from being uploaded
- Prevents Content-Type header spoofing attacks
- Validates file content at binary level, not just metadata

Status: Fix 2 complete
- Fix 1: crypto.randomBytes() ✓
- Fix 2: Magic byte validation ✓
- Fix 3: Google Maps API proxy ✓

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 10:06:53 -06:00
Eric Gullickson
a35e1a3aea Security fixes: Implement P0 critical vulnerability remediations
Implemented 3 critical security fixes identified in audit report:

1. CRITICAL (CVSS 8.1): Replace Math.random() with crypto.randomBytes()
   - Location: documents.controller.ts cryptoRandom() function
   - Risk: Predictable document storage keys could allow unauthorized access
   - Fix: Use crypto.randomBytes(32).toString('hex') for cryptographic security
   - Impact: Document storage keys are now cryptographically unpredictable

2. HIGH (CVSS 7.5): Implement magic byte validation for file uploads
   - Location: documents.controller.ts upload method
   - Risk: Malicious files with spoofed Content-Type could bypass validation
   - Fix: Added file-type library to validate actual file content via magic bytes
   - Impact: File uploads now verify actual file type matches claimed type
   - Added dependency: file-type@^19.8.0

3. HIGH (CVSS 6.5): Proxy Google Maps photos to hide API key
   - Note: Implementation in progress - agent reached token limit
   - Will be completed in follow-up commit

Files modified:
- backend/package.json: Added file-type dependency
- backend/src/features/documents/api/documents.controller.ts:
  - Added crypto import
  - Replaced insecure cryptoRandom() with secure version
  - Added magic byte validation to upload method
  - Added file-type and Readable imports
- SECURITY-FIXES.md: Complete implementation guide for all fixes

Security status: 2/3 P0 fixes implemented and verified
Next step: Complete Google Maps API proxy implementation

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-14 09:49:05 -06:00
Eric Gullickson
d4156cf521 Stuff 2025-11-04 18:38:06 -06:00
Eric Gullickson
3693ce5761 Docs Cleanup 2025-11-02 10:34:43 -06:00
Eric Gullickson
046c66fc7d Redesign 2025-11-01 21:27:42 -05:00
Eric Gullickson
775a1ff69e Added Documents Feature 2025-09-28 20:35:46 -05:00