MyGarage
Self-hosted vehicle maintenance tracking application
What is MyGarage?
MyGarage is a self-hosted vehicle maintenance tracker. Add your cars, log services, track fuel economy, and get reminders when maintenance is due. It decodes VINs automatically, checks for recalls, and keeps all your receipts and documents in one place.
The app supports multiple users with OIDC/SSO integration (works with Authentik, Keycloak, etc.) so your whole household can manage their vehicles. Fleet analytics show spending trends across all vehicles, while individual dashboards break down costs per car.
Everything runs on your own hardwareβno subscriptions, no cloud accounts, your data stays yours. Take a photo of a receipt and OCR extracts the details. Export reports as PDF or CSV when you need them.
Technology Stack
Backend
- β Python 3.14+ with FastAPI 0.121.3 and Granian 2.6.0 ASGI server
- β SQLAlchemy 2.0.44 + SQLite (WAL mode) via aiosqlite 0.21.0
- β Pydantic 2.12.4 for data validation and settings management
- β JWT auth with Argon2id hashing and OIDC/SSO (authlib 1.6.5)
- β NHTSA API for VIN decoding and recall checks (httpx 0.28.1)
- β Tesseract OCR for receipt scanning (PyMuPDF 1.26.6)
- β ReportLab 4.4.5 for PDF generation and analytics export
- β Multi-service notifications via aiosmtplib 3.0+ for email delivery
Frontend
- β React 19.2.0 + TypeScript 5.9.3 with Vite 7.2.4
- β Tailwind CSS 4.1.17 with custom garage theme and light/dark mode
- β React Router 7.9.6 for client-side navigation
- β Recharts 3.5.0 for interactive analytics charts
- β react-big-calendar 1.19.4 for comprehensive calendar UI
- β date-fns 4.1.0 for date manipulation and formatting
- β Zod 4.1.12 + React Hook Form 7.66.1 for form validation
- β Lucide React 0.554.0 iconography and Sonner 2.0.7 for toasts
Project Statistics
Version History
Track the evolution of MyGarage through its version releases. Each release includes new features, improvements, and bug fixes.
v2.14.2 2025-12-04
π Security
- β’ **[CRITICAL] Fixed Server-Side Request Forgery (SSRF) vulnerabilities (CWE-918)** β Created comprehensive URL validation utility (`backend/app/utils/url_validation.py`) β Fixed SSRF in OIDC service (`backend/app/services/oidc.py:100`) - prevents access to internal services β Fixed SSRF in NHTSA service (`backend/app/services/nhtsa.py:48`) - validates API URLs β Protection includes: blocks private IPs (RFC 1918, RFC 4193), loopback, link-local, AWS metadata endpoint β DNS rebinding protection and domain allowlisting support β All HTTP requests to external services now validated
- β’ **[HIGH] Fixed Log Injection vulnerabilities (CWE-117) - 200+ instances across 44 files** β Converted all f-string logging to parameterized logging format β Prevents log forgery attacks via newline injection β Created automated remediation tool (`fix_log_injection.py`) β Affected files: all routes/, services/, utils/, migrations/, and core modules
- β’ **[HIGH] Fixed Secret Exposure in Logs** β Created `mask_secret()` function to safely log sensitive values β Fixed 4 instances of OIDC client secret exposure in logs β Secrets now show only first/last 4 chars (e.g., `oidc_****...****_abcd`)
- β’ **[HIGH] Fixed Path Injection vulnerabilities (CWE-22)** β Added defense-in-depth path validation in photo deletion (`backend/app/routes/photos.py:250,259`) β Validates resolved paths are within PHOTO_DIR to prevent traversal attacks β Enhanced with `validate_path_within_base()` security checks
- β’ **[MEDIUM] Fixed postMessage Origin Validation (CWE-20291)** β Added strict same-origin validation in service worker (`frontend/public/sw.js:147`) β Prevents XSS and message spoofing from unauthorized origins β Rejects messages with console warning for security monitoring
π Changed
- β’ **Exception Handling** - Verified stack trace exposure properly handled β Production mode (default): Generic error messages only, no internal details β Debug mode: Detailed traces for development only β Error handlers in `backend/app/utils/error_handlers.py` provide secure responses
β¨ Added
- β’ **New Security Utilities** β `backend/app/utils/url_validation.py` - Comprehensive SSRF protection (447 lines) β `backend/app/exceptions.py` - Added `SSRFProtectionError` exception class β `fix_log_injection.py` - Automated log injection remediation script
π Fixed
- β’ **Code Quality Improvements** - Resolved 101 CodeQL NOTE-level alerts β Removed 59 unused imports from 39 Python files (automated) β Added explanatory comments to 8 empty except blocks (optional dependency checks) β Renamed 9 unused local variables to `_` for intentionally unused values β Fixed useless comparison in frontend user count display β Documented 3 Pydantic validator false positives (require `cls` parameter) β Documented 3 pytest.skip false positives (raises exception, never returns None)
π Documentation
- β’ **SECURITY.md** - Added comprehensive CodeQL Security Analysis section β Documented all 140 fixed vulnerabilities (2 CRITICAL, 119 HIGH, 1 MEDIUM) β Documented 17 false positives with justification β Listed 136 deferred code quality items (NOTE level) β Updated security changelog for v2.14.2
- β’ **Cyclic Imports** - Documented 47 cyclic import alerts for future architectural refactoring β Saved to `/srv/raid0/docker/documents/history/mygarage/2025-12-04-cyclic-imports-deferred.txt` β Includes recommended fixes (TYPE_CHECKING, dependency injection, lazy imports)
π Technical Notes
- β’ All security and code quality fixes are backward compatible
- β’ No API changes or breaking changes
- β’ Total files modified: 86 (47 security + 39 code quality)
- β’ CodeQL analysis: 241/272 alerts resolved (140 security + 101 code quality)
- β’ Remaining 47 alerts are cyclic imports (architectural issue, deferred to refactoring sprint)
v2.14.1 2025-12-03
β¨ Added
- β’ **Single-Source-of-Truth Version Management** β Backend now reads version from `pyproject.toml` automatically at runtime β Added `get_version()` function using Python's built-in `tomllib` parser β Version bumps now only require updating 2 files instead of 3 β Eliminates version drift between config.py and pyproject.toml β Updated Dockerfile to copy `pyproject.toml` into production image
π Changed
- β’ **Zod v4 API Migration** - Updated all validation schemas to use Zod v4 API patterns β Removed deprecated `required_error` and `invalid_type_error` parameters from schemas β Simplified error messages using single `message` parameter β Updated z.enum `errorMap` syntax to new `message` format β Removed unnecessary `z.preprocess()` wrappers that were causing type inference issues β React Hook Form's zodResolver automatically handles empty string β undefined conversion
- β’ **Form Type Safety Improvements** β Fixed defaultValues type mismatches across 15+ form components β Changed numeric field defaults from `.toString() || ''` to `?? undefined` pattern β Fixed boolean field defaults using `??` instead of `||` to preserve explicit false values β Improved type inference for all form schemas (now return proper types instead of `unknown`)
- β’ **Test Infrastructure Updates** β Changed `global` to `globalThis` for Node.js/browser compatibility in test setup β Removed unused imports and variables across test files
π Fixed
- β’ **TypeScript Compilation Errors** - Resolved 100+ TypeScript errors caused by Zod v4 API changes β Fixed all schema validation patterns to match Zod v4 requirements β Fixed form component type mismatches for numeric and boolean fields β Fixed null safety issues in title length checks and property access β Removed unused imports and watch variables flagged by TypeScript strict mode
π Dependencies
- β’ **Frontend**: Updated jsdom from 25.0.1 to 27.2.0 (Dependabot security update)
π Technical Notes
- β’ All changes are backward compatible - no validation rules or API contracts changed
- β’ Build passes successfully with Vite
- β’ All 28 unit tests passing
- β’ 49 non-blocking TypeScript warnings remain (type inference cascades from resolver types)
v2.14.0 2025-12-01
β¨ Added
- β’ **Multi-User Management System** β Database setting `multi_user_enabled` to control user creation (default: false) β Backend enforcement: blocks user creation when multi-user mode is disabled β Admin password reset endpoint (`PUT /auth/users/{id}/password`) for local auth users only β Multi-User Management card in Settings > System (admin-only, local auth only) β Toggle switch to enable/disable multi-user mode β User preview showing first 3 users with avatars β "Add User" button to create new accounts β "Manage All Users" button to access full user management interface β User Management modal with: β Searchable user table (by username, email, or full name) β Role badges (Admin/User) β Status badges (Active/Inactive) β Auth method badges (OIDC/Local) β Edit user details β Reset password (local users only) β Enable/disable user accounts β Delete users (cannot delete yourself) β Add/Edit User modal with: β Username field (disabled in edit mode) β Email field (required) β Full name field (optional) β Password fields with strength indicator β Password visibility toggles β Role selector (Admin/User) β Active status checkbox β OIDC user badge (when applicable) β Delete User modal with: β User information display β Data impact warnings (vehicles, service records, fuel records) β Type "DELETE" confirmation requirement β Admin badge warning for admin users β Security safeguards: β Last admin protection: cannot disable the only active admin β Last admin protection: cannot change role of the only active admin β Self-deletion prevention: users cannot delete their own account β Warning tooltips for disabled actions β Confirmation dialogs for destructive operations
π Changed
- β’ Settings > System page now uses two-column CSS Grid layout: β Left column: System Configuration + Multi-User Management β Right column: Authentication Mode + Change Password
π Fixed
- β’ Button styling consistency across multi-user management components: β Change Password button now uses correct theme (`bg-gray-700 border border-gray-600`) β Create/Update button in Add/Edit User modal now uses correct theme β All buttons now match the application's standard gray button style
v2.13.0 2025-12-01
β¨ Added
- β’ **OIDC Username-Based Account Linking with Password Verification** β Prevents duplicate account creation (username1, username2, etc.) during OIDC login β When username matches but email differs, users are prompted to verify their password β New database table `oidc_pending_links` for temporary link tokens (migration 015) β New frontend page `/auth/link-account` for password verification β Security features: β Token expiration: 5 minutes (configurable via `oidc_link_token_expire_minutes`) β Max password attempts: 3 (configurable via `oidc_link_max_password_attempts`) β Rate limiting: 5 requests/minute on link endpoint β One-time use tokens (deleted after successful link) β Comprehensive audit logging (success and failure) β Edge case handling: β Token expiration with user-friendly error messages β Maximum attempt lockout β OIDC-only user detection (no password) β Conflict prevention (already linked to different provider) β Inactive user checks β Backward compatible with existing OIDC flows (email-based linking still works) β Files added: β `backend/app/exceptions.py` - PendingLinkRequiredException β `backend/app/models/oidc_pending_link.py` - Pending link model β `backend/app/migrations/015_add_oidc_pending_links.py` - Database migration β `frontend/src/pages/LinkAccount.tsx` - Password verification UI β Files modified: β `backend/app/services/settings_init.py` - Added 2 new settings β `backend/app/services/oidc.py` - Added 3 helper functions, modified user creation logic β `backend/app/routes/oidc.py` - Modified callback handler, added `/link-account` endpoint β `frontend/src/App.tsx` - Added route for link account page
v2.13.0 2025-11-30
β¨ Added
- β’ **Code Quality Refactoring (Phase 2)** β Complete service layer architecture for business logic separation β `VehicleService` (226 lines) - Vehicle CRUD operations with integrated authorization β `ServiceRecordService` (366 lines) - Service record management with N+1 query optimization β `FuelRecordService` (486 lines) - Fuel tracking with MPG calculations and caching β `PhotoService` (179 lines) - Photo management and thumbnail generation β Photo management extracted to dedicated router (`/app/routes/photos.py`, 448 lines, 7 endpoints) β Average MPG calculation now cached (5-minute TTL) for performance β Legacy photo hydration moved to one-time migration script (removed from request hot path) β Database migration 014: `014_hydrate_legacy_photos.py` for one-time photo metadata population
- β’ **Authentication Mode 'None' Implementation** β Support for running application without authentication in development environments β Frontend centralized auth_mode state in AuthContext (single API call to `/settings/public`) β Smart authentication dependencies check `auth_mode` setting before enforcing β `auth_mode='none'` allows guest access (user = None) with full permissions β Settings UI allows changing Authentication Mode to "None" with security warnings β Frontend ProtectedRoute respects `auth_mode` from context (no duplicate API calls)
π Changed
- β’ **Massive Code Reduction and Organization (Phase 2)** β `vehicles.py`: 1,002 β 316 lines (69% reduction) β `service.py`: 404 β 185 lines (54% reduction) β `fuel.py`: 487 β 165 lines (66% reduction) β Total: 1,227 lines removed from route files (average 63% reduction) β Route handlers now focused purely on HTTP concerns, business logic in service layer β Removed redundant `_sanitize_filename` function (using centralized utils version with better validation) β Consolidated duplicate VIN decode endpoints with shared `_decode_vin_helper()` function β All photo endpoints maintain backward compatibility with authorization checks in place
- β’ **Authentication Architecture Updates** β `require_auth()` now checks `auth_mode` setting: returns None when disabled, enforces when enabled β `get_current_admin_user()` checks `auth_mode` first: returns None when disabled (allows all access) β All helper functions accept `Optional[User]` for type safety with null checks β `get_vehicle_or_403()` and `check_vehicle_ownership()` handle None users (grant full access) β Vehicle/Service/Fuel service layers accept `Optional[User]`, show all data when user is None β Settings endpoints split: `/api/settings/public` (no auth) vs `/api/settings` (admin only) β All 100+ endpoints now work seamlessly with `auth_mode='none'`
π Fixed
- β’ **Code Quality Improvements (Phase 3 - 71% reduction in linting issues)** β Fixed F821 (undefined name): Added missing `Document` import in [vehicle.py:187](backend/app/models/vehicle.py#L187) β Fixed E722 (bare except): Replaced with specific `ValueError` in [insurance.py:129](backend/app/services/document_parsers/insurance.py#L129) β Auto-fixed 128 actionable issues via ruff (unused imports, empty f-strings, boolean comparisons, unused variables) β Reduced total ruff issues from 181 β 53 (71% reduction) β Remaining 53 issues are intentional design patterns (documented in `pyproject.toml`) β E402 (46 issues): Imports after code for FastAPI initialization order and circular dependency resolution β F401 (7 issues): Unused imports in try/except blocks for optional dependency checks β Added comprehensive ruff configuration with per-file ignores
- β’ **Authentication Flow Improvements** β Fixed CSRF token endpoint to work without authentication when `auth_mode='none'` β Fixed ProtectedRoute and Layout to use `/settings/public` instead of admin-only endpoint β Eliminated ERROR logs ("No credentials provided") on page load before authentication β CSRF endpoint now uses `optional_auth` dependency, returns `{"csrf_token": None}` when disabled β Frontend no longer makes duplicate API calls to check auth_mode (centralized in AuthContext) β Resolved infinite loop issue (3 components independently calling `/settings/public` β 200+ requests)
- β’ **Frontend Validation Error Serialization** β Fixed `TypeError: Object of type ValueError is not JSON serializable` in error handlers β Validation errors now properly converted to JSON-serializable format before response
- β’ **Auth Mode 'None' Backend Validation** β Removed overly restrictive validation blocking `auth_mode='none'` changes (kept warning logs only) β Fixed AttributeError crashes from None user references in authorization helpers β Fixed 500 errors when accessing endpoints with `auth_mode='none'` enabled β Settings page now accessible without authentication when auth is disabled
π Security
- β’ **CRITICAL: Authentication & Authorization Hardening (Phase 1)** β All vehicle data endpoints now require authentication via `require_auth` dependency β Implemented per-vehicle authorization - users can only access their own vehicles β Added `user_id` column to vehicles table with foreign key to users (database migration 013) β Admin users retain access to all vehicles for support purposes β Production safeguard: `auth_mode='none'` blocked in production without explicit `MYGARAGE_ALLOW_AUTH_NONE=true` flag β Startup warning displayed when `auth_mode='none'` is active β Authentication dependencies: `require_auth()` (smart enforcement) vs `optional_auth()` (never enforces) β Authorization helpers: `get_vehicle_or_403()`, `check_vehicle_ownership()` with None user support β 24+ endpoints hardened: vehicles, service records, fuel records, photos, settings β Public settings endpoint (`/api/settings/public`) works without authentication for frontend initialization β Prevents unauthenticated data access and cross-user data leakage in production β Allows development without authentication when explicitly configured
- β’ **Dependency Security Validation (Phase 3)** β Zero vulnerabilities found in 79 scanned packages (Safety v3.7.0) β All dependencies up-to-date with no known CVEs β Key packages verified: fastapi 0.123.0, sqlalchemy 2.0.29, pillow 12.0.0, argon2-cffi 25.1.0
- β’ **Code Security Validation (Phase 3)** β Bandit scan: Only 2 findings, both acceptable design choices β 0.0.0.0 binding (required for Docker container networking) β MD5 for cache keys (non-cryptographic use case with `usedforsecurity=False`) β No actual security vulnerabilities detected in 41,554 lines of code β Strong security posture validated by automated scanning
β‘ Performance
- β’ **Service Layer Optimizations** β MPG calculation now cached with 5-minute TTL (automatic invalidation on data changes) β Photo hydration removed from request hot path (one-time migration instead) β N+1 query optimizations in ServiceRecordService (pre-fetches attachment counts via JOIN) β Reduced code size improves application load time and memory footprint
- β’ **Authentication Flow Optimization** β Single API call to check `auth_mode` instead of 3 duplicate calls β Resolved rate limit issues (200+ requests to `/settings/public` β 1 request) β Centralized state management prevents redundant network requests
π Technical Notes
- β’ **Service Layer Architecture**: Implements dependency injection, integrated authorization, complete business logic separation from HTTP layer
- β’ **Type Safety**: All functions use `Optional[User]` to force explicit null handling throughout codebase
- β’ **Smart Authentication**: Functions check `auth_mode` setting dynamically - no hardcoded auth bypass logic
- β’ **Graceful Degradation**: None users represent guest access with full permissions when auth is disabled
- β’ **Code Quality**: 71% reduction in linting issues, 69% reduction in main route file, production-ready code
- β’ **Backward Compatibility**: All API contracts maintained, photo endpoints work identically after extraction
- β’ Database migrations: 013 (user_id for multi-user support), 014 (legacy photo hydration)
v2.12.0 2025-11-28
β¨ Added
- β’ **Multi-Service Notification System** - Expanded from ntfy-only to 7 notification providers β **ntfy** - Self-hosted push notifications with optional token authentication β **Gotify** - Self-hosted push notification server β **Pushover** - iOS/Android push notifications β **Slack** - Team channel notifications via webhooks β **Discord** - Discord channel notifications via webhooks β **Telegram** - Bot-based notifications β **Email** - SMTP-based email notifications (with STARTTLS support) β Unified NotificationDispatcher with priority-based retry logic β Per-service test endpoints (`/api/notifications/test/{service}`) β Configurable retry attempts and delays with service-specific multipliers β Event-type toggles: recalls, service due/overdue, insurance/warranty expiring, milestones
- β’ **Frontend Notification Configuration UI** β Sub-tab navigation for switching between notification providers β Individual configuration forms for each service with enable toggle, credentials, and test button β Green dot indicators showing which services are enabled β Unified Event Notifications card with expandable sections β Advance warning day configuration for insurance, warranty, and service reminders β Two-column responsive layout (service config + event settings)
π Changed
- β’ Backend notification architecture refactored to abstract base class pattern
- β’ Settings system expanded with 24 new notification-related keys
- β’ Notification services use async HTTP (httpx) and async SMTP (aiosmtplib)
v2.11.0 2025-11-26
β¨ Added
- β’ **Frontend HTTP Error Handler** - New utility for consistent error message handling β `httpErrorHandler.ts` maps HTTP status codes to user-friendly messages β `parseApiError()` - Full error parsing with status, message, retry hints β `getErrorMessage()` - Simple error message extraction β `getActionErrorMessage()` - Context-aware messages ("Failed to save...") β Re-exported from `api.ts` for convenient access throughout frontend
π Changed
- β’ **Error Handling Standardization** - Refactored generic exception handlers to use specific exception types β Reduced generic `except Exception as e:` handlers from ~120 to ~71 (40% reduction) β API routes now use specific exceptions: `IntegrityError`, `OperationalError`, `httpx.*`, `FileNotFoundError`, etc. β Improved HTTP status codes: 409 for conflicts, 503 for database unavailable, 504 for timeouts β Better error messages that don't expose internal details β Remaining generic handlers are intentional fallbacks (CSV import rows, OCR, migrations)
π Fixed
- β’ **Backup Creation Logout Bug** - Fixed issue where creating backups would log users out β Exempted `/api/backup/*` routes from CSRF protection (already protected by JWT authentication) β Backup endpoints are idempotent with no user input, making CSRF protection redundant β Added CSRF token storage validation to catch sessionStorage failures early β Added console warnings when CSRF tokens are missing on state-changing requests β Removed duplicate CSRF token cleanup from middleware (performance optimization)
v2.10.0 2025-11-23
π Security
- β’ **CRITICAL: CSRF Protection** - Implemented synchronizer token pattern for cross-site request forgery protection β Added `csrf_tokens` database table with 24-hour token expiration β CSRF tokens automatically generated on login (both local and OIDC) β Middleware validates CSRF tokens on all state-changing operations (POST/PUT/PATCH/DELETE) β Tokens returned in login response for frontend integration β Automatic cleanup of expired tokens on logout and login
- β’ **CRITICAL: Settings Endpoint Security** - Fixed privilege escalation vulnerability β **BREAKING**: Split settings endpoints - `/api/settings/public` (no auth) for initialization, `/api/settings` (admin-only) for management β All settings CRUD operations now require admin privileges (`get_current_admin_user`) β Public endpoint returns only whitelisted settings: `auth_mode`, `app_name`, `theme` β Prevents unauthorized users from reading/modifying sensitive configuration (OIDC secrets, SMTP credentials, etc.)
- β’ **HIGH: JWT Cookie Security** - Auto-detect secure cookie flag based on environment β `jwt_cookie_secure` now auto-detects: `Secure=true` in production (`debug=false`), `Secure=false` in development β Prevents session token exposure over unencrypted HTTP in production β Explicit override available via `JWT_COOKIE_SECURE` environment variable β Default changed from `false` to environment-aware
- β’ **MEDIUM: OIDC State Persistence** - Database-backed state storage for multi-worker reliability β Added `oidc_states` database table with 10-minute expiration β Replaces in-memory dictionary storage β Supports multi-worker deployments and container restarts during authentication flows β State validation and one-time-use enforcement via database
- β’ **LOW: SQLite Pool Configuration** - Conditional pool settings for database compatibility β Pool configuration now only applied to PostgreSQL/MySQL β SQLite uses appropriate NullPool automatically β Prevents future SQLAlchemy compatibility issues
π Changed
- β’ **Database Migration 012**: Added `csrf_tokens` and `oidc_states` tables with indexes
- β’ CORS middleware now allows `X-CSRF-Token` header
- β’ Login and logout endpoints updated to manage CSRF tokens
- β’ OIDC callback endpoint updated to generate CSRF tokens
- β’ Settings routes refactored for public/admin separation
π Technical Notes
- β’ Frontend integration required: Store CSRF token from login response, send in `X-CSRF-Token` header for mutations
- β’ Addresses Codex security audit findings: HIGH and MEDIUM risk items resolved
- β’ Version bump: 2.8.0 β 2.10.0 (skipped 2.9.0 to align with frontend)
v2.8.0 2025-11-23
β¨ Added
- β’ **Fleet Analytics Enhancements** β CSV export functionality for fleet-wide data analysis β PDF export with professional fleet report generation β Fleet Analytics Help Modal with comprehensive feature documentation β Rolling average trend lines (3-month and 6-month) on monthly spending chart β Visual spending trend analysis with smooth overlay indicators
- β’ **Individual Vehicle Analytics Enhancements** β CSV export for vehicle-specific analytics data β PDF export with detailed vehicle reports β Export functionality mirrors fleet analytics capabilities β Consistent export button styling across both analytics pages
π Changed
- β’ Standardized export button UI across Fleet and Vehicle Analytics pages
- β’ Updated button styling to use garage theme colors for consistency
- β’ Removed "Export" prefix from button labels (now just "CSV" and "PDF")
π Technical Notes
- β’ Added `garage-primary`, `garage-primary-dark`, `success`, and `danger` color classes to Tailwind theme
- β’ Frontend analytics pages now fully support data export workflows
- β’ Export buttons use consistent `bg-garage-surface` styling with theme-aware hover states
v2.7.0 2025-11-23
β¨ Added
- β’ **OpenID Connect (OIDC) / SSO Authentication** β Complete OIDC authentication integration with support for external identity providers (Authentik, Keycloak, etc.) β "Sign in with SSO" button on login page with dynamic provider name display β OIDC callback success page with automatic token handling and redirect β Email-based account linking - automatically links OIDC accounts to existing local accounts via verified email β Dual authentication support - users can login with either password OR OIDC after linking β Admin UI for OIDC configuration in Settings β System β OIDC tab β Provider configuration: Issuer URL, Client ID/Secret, Scopes β Auto-generated redirect URI display β Test connection functionality with detailed result feedback β Claim mapping configuration (username, email, full name) β Group-based admin role mapping β Authentik setup guide with step-by-step instructions β Database schema additions: `oidc_subject`, `oidc_provider`, `auth_method` fields on User model β 12 new OIDC settings with defaults and validation β `/api/auth/oidc/config` - Public OIDC configuration endpoint β `/api/auth/oidc/login` - OIDC flow initiation endpoint β `/api/auth/oidc/callback` - Provider callback handler β `/api/auth/oidc/test` - Admin-only connection testing endpoint
π Security
- β’ **OIDC Security Features** β CSRF protection via state parameter validation (10-minute expiration) β Replay attack protection via nonce validation in ID tokens β JWT signature verification using provider's JWKS public keys β Issuer claim validation (prevents token reuse from other providers) β Audience claim validation (ensures tokens issued for MyGarage) β Expiration validation on all tokens β NULL password protection - OIDC-only users cannot authenticate via password login β Made `hashed_password` column nullable to support OIDC-only users (migration 011)
π Changed
- β’ Authentication system now supports multiple auth methods (local password + OIDC)
- β’ User model `hashed_password` field is now nullable (OIDC-only users have NULL password)
- β’ Login page conditionally displays SSO button based on OIDC configuration
π Dependencies
- β’ **Backend**: Added `authlib>=1.6.5` for OIDC/OAuth2 authentication
π Technical Notes
- β’ Backend implementation: 532-line OIDC service with complete OAuth2 flow
- β’ Frontend implementation: OIDC success page, login page SSO integration, settings UI
- β’ Database migration 011 applied to support OIDC fields
v2.6.0 2025-11-22
β¨ Added
- β’ **Light/Dark Theme System** β User-selectable theme toggle in Settings β System tab β Comprehensive light theme for all pages and components β React Big Calendar fully themed for both light and dark modes β Theme preference persisted in both localStorage (instant) and database (cross-device sync) β ThemeContext provider for global theme state management β Sun/Moon icon toggle UI with visual active state indication β Default theme remains dark mode for existing users β Tailwind v4 CSS variable architecture for clean theme switching β Refactored 48+ components to use semantic theme-aware classes β Light mode color palette: white cards (#ffffff) on light gray background (#f3f4f6) β Dark mode color palette: slate cards (#1a1f28) on dark background (#0a0e14)
π Fixed
- β’ **Light Mode Styling Issues** β Removed 200+ hardcoded dark gray button styles (`bg-gray-700`) across all components β Replaced with semantic `.btn-primary` class that adapts to both themes β Fixed modal overlays being too harsh in light mode (50% β 30% opacity) β Fixed badge colors not adapting to light mode background β Fixed text contrast issues with hardcoded gray colors β Corrected CSS architecture to properly use Tailwind v4 `@theme` directive β Eliminated redundant CSS variable overrides β Removed all `!important` hacks - proper specificity through CSS layers
π Security
- β’ **Password Hashing Migration: Bcrypt β Argon2** β Migrated from bcrypt 5.0.0 to Argon2id (argon2-cffi 25.1.0) β Argon2id is the current OWASP recommended password hashing algorithm β Hybrid verification system supports both legacy bcrypt and new Argon2 hashes β Auto-rehashing: User passwords transparently upgraded to Argon2 on next login β No password resets required - zero downtime migration β Removed 72-byte password length limitation (bcrypt restriction) β Argon2 parameters: time_cost=2, memory_cost=102400 (100MB), parallelism=8 β Migration tracking via automated database migration system (migration 010) β bcrypt temporarily retained for gradual migration support
π Changed
- β’ Tailwind CSS dark mode enabled via class-based switching
- β’ Theme preference stored in global settings table with category 'general'
- β’ CSS architecture updated to support dynamic theme switching via CSS variables
v2.5.2 2025-11-22
π Changed
- β’ **Automated Database Migration System** β Migrations now run automatically on container startup β Added `schema_migrations` tracking table β Renamed migration files with numeric prefixes for ordering β Extracted inline migrations from database.py to standalone files β Prevents schema drift between development and production β No manual migration execution required after deployments
π Fixed
- β’ Database migration system now prevents schema mismatch issues
- β’ Migration tracking persists across container restarts
v2.5.1 2025-11-22
π Security
- β’ **CRITICAL: Fixed default authentication mode** β Changed default `auth_mode` from `none` to `local` to require authentication by default β Previously, all endpoints were publicly accessible out-of-the-box until manually configured β New instances now require authentication immediately after first admin setup
- β’ **CRITICAL: Fixed rate limiting enforcement** β Wired up SlowAPI middleware to actually enforce rate limits β Previously, rate limit decorators were no-ops due to missing middleware β Auth endpoints now properly rate-limited at 5 requests/minute to prevent brute-force attacks β Upload endpoints now properly rate-limited at 20 requests/minute to prevent DoS β Default global rate limit of 200 requests/minute now enforced
- β’ **CRITICAL: Fixed open user registration** β Registration endpoint now restricted to first user only β After first admin is created, public registration is disabled β Added new admin-only `/api/auth/users` POST endpoint for admins to create accounts β New users created by admins default to inactive and non-admin status β Prevents unauthorized account creation on public instances
π Changed
- β’ User registration flow: Only first user can self-register (becomes admin)
- β’ Subsequent users must be created by administrators through user management UI
- β’ New users require admin activation before they can log in
v2.5.0 2025-11-22
β¨ Added
- β’ **Zod + React-Hook-Form Integration** β Implemented declarative form validation using Zod v4 schemas β Created reusable schema infrastructure in `/frontend/src/schemas/` β `shared.ts`: Common validators (mileage, currency, dates, etc.) β `auth.ts`: Authentication forms with password strength validation β `fuel.ts`: Fuel record validation β `service.ts`: Service record validation with type enum β `reminder.ts`: Conditional validation (date OR mileage required) β Added `FormError` component for field-level error display β Migrated Register and Login forms to use react-hook-form with zodResolver β Real-time validation with field-specific error messages β Password strength indicator in registration form
π Changed
- β’ **Dependency Updates** β Updated zod: 3.24.0 β 4.1.12 β Updated @hookform/resolvers: 3.9.0 β 5.2.2 β Updated react-hook-form: 7.54.0 β 7.61.1 β Updated axios: 1.7.0 β 1.13.2 β Updated lucide-react: 0.553.0 β 0.554.0 β Updated @types/react: 19.0.6 β 19.2.6 β Updated @types/react-big-calendar: 1.8.12 β 1.16.3 β Updated @types/react-dom: 19.0.2 β 19.2.3 β Updated @typescript-eslint packages: 8.46.4 β 8.47.0 β Updated vite: 7.2.2 β 7.2.4
π Fixed
- β’ **Critical: Password Validation Mismatch** β Fixed frontend password validation to match backend requirements β Frontend now validates: uppercase, lowercase, digit, special character (!@#$...) β Previously only checked length β₯ 8, causing confusing backend rejection errors β Users now get immediate, clear feedback about password requirements
v2.4.0 2025-11-21
β¨ Added
- β’ **Unified Document Scanner with Multi-Provider Insurance Support** β Consolidated PDF/image scanning architecture for all document types β Insurance documents now use same OCR engine as window stickers (PaddleOCR + Tesseract) β Auto-detection of insurance providers from document content β Provider-specific parsers: Progressive, State Farm, GEICO, Allstate β Generic fallback parser for unknown providers β Image upload support for insurance documents (jpg, png) in addition to PDF β New `/api/insurance/parsers` endpoint to list available parsers and OCR status β New `/api/vehicles/{vin}/insurance/test-parse` endpoint for debugging extraction β Confidence scoring (0-100%) for insurance extraction β Per-field confidence levels (high/medium/low) β Optional `provider` query parameter to hint parser selection
- β’ **Window Sticker OCR Display Enhancement** β Added display of all OCR-extracted fields that were previously stored but not shown β New Standard Equipment card (collapsible) showing categorized standard features β New Optional Equipment card (collapsible) with pricing from `window_sticker_options_detail` β New Packages card showing package groupings with prices β OCR metadata display (parser used, confidence score, VIN verification) β Drivetrain field now displayed in Powertrain card
ποΈ Removed
- β’ **pdfplumber dependency** β Removed unused pdfplumber library (PyMuPDF handles all PDF operations) β Reduces container size and maintenance burden
π Fixed
- β’ **Window Sticker Data Display Gap** β Fixed 8 OCR-extracted fields not being rendered in frontend despite being stored in database β Fields now displayed: `standard_equipment`, `optional_equipment`, `window_sticker_options_detail`, `window_sticker_packages`, `sticker_drivetrain`, `window_sticker_parser_used`, `window_sticker_confidence_score`, `window_sticker_extracted_vin`
- β’ **Stellantis OCR Parser Fixes** β Fixed environmental ratings extraction (GHG/Smog) - now correctly identifies actual ratings vs scale markers β Fixed equipment categorization - optional package items no longer appear under standard equipment β Fixed confidence score display (was showing 9500% instead of 95%)
v2.3.1 2025-11-19
π Changed
- β’ **Frontend JWT Authentication Migration** β Migrated 35 components from direct `fetch()` calls to centralized axios API client β All API requests now automatically include `Authorization: Bearer <token>` header β Consistent error handling with automatic logout/redirect on 401 errors β Improved type safety and code maintainability
π Fixed
- β’ **Authentication consistency** β Eliminated "No credentials provided" errors from components bypassing auth β Fixed JWT token not being sent with dashboard, settings, form, and page requests β Corrected authentication flow in backup/restore operations β Fixed file upload/download endpoints to properly use axios with FormData and blob responses β Fixed vehicle import/export JSON functionality
π Technical Details
- β’ Updated components (35 total): β Pages: Dashboard, Register, VehicleDetail, VehicleEdit β Settings tabs: System, Files, Integrations, Notifications, Backup, AddressBook β Forms: ServiceRecord, TollTag, TollTransaction, TaxRecord, SpotRental β Uploads: PhotoUpload, WindowStickerUpload β Lists: TollTagList, TollTransactionList, TaxRecordList, SpotRentalList β Tabs: TollsTab β Utilities: AddressBookSelect, AddressBookAutocomplete, ReportsPanel, ProtectedRoute β Hooks: useAppVersion
- β’ All file downloads now use `responseType: 'blob'` with axios
- β’ FormData uploads work seamlessly without additional configuration
- β’ Updated fallback version in useAppVersion to 2.3.1
v2.3.0 2025-11-15
β¨ Added
- β’ **Propane tracking for fifth wheel vehicles** β Added `propane_gallons` field to fuel records (Numeric 8,3 precision) β New propane input field in fuel record form β Propane column in fuel record list view β Automatic database migration on startup β Input validation (0-999.999 gallons, 3 decimal places)
- β’ **Security improvements** (10 major fixes) β Path traversal protection for document uploads β VIN pattern validation (17-character alphanumeric) β SQL injection prevention via parameterized queries β MIME type validation for file uploads (PDF, images) β File size limits (10MB for images, 50MB for PDFs) β Password length limits (72 bytes for bcrypt compatibility) β Email format validation (max 254 characters) β User input sanitization across all endpoints β Rate limiting headers exposed in CORS configuration β Comprehensive error handling with proper HTTP status codes
π Fixed
- β’ **Critical:** Fixed fifth wheel fuel tab access β Corrected boolean operator precedence in vehicle type check β Fifth wheels can now properly access fuel tracking features
- β’ **Security:** Prevented path traversal in document downloads β Added strict filename validation β Restricted access to user-owned documents only
- β’ **Security:** Added MIME type validation for uploads β Prevents execution of malicious files β Validates against allowed types (PDF, JPG, PNG, HEIC, etc.)
- β’ **Security:** Implemented file size limits β Images: 10MB maximum β PDFs: 50MB maximum β Prevents DoS attacks via large file uploads
- β’ Input validation edge cases across multiple endpoints β Maintenance records: validated mileage, date ranges β Fuel records: validated amounts, prices, odometer readings β Documents: validated descriptions, file metadata β Settings: validated configuration values
π Changed
- β’ Updated version to 2.3.0 (MINOR bump for propane feature)
- β’ Enhanced fuel record form layout (3-column grid)
- β’ Improved About page organization and statistics
v2.2.1 2025-11-15
π Fixed
- β’ **Critical:** Removed non-functional token refresh logic β Eliminated dead code calling non-existent `/api/auth/refresh` endpoint β Simplified authentication flow β Reduced unnecessary API calls
- β’ **Critical:** Fixed React hooks compliance violations β Added proper `useCallback` wrappers in AuthContext β Fixed PhotoGallery dependencies β Corrected Calendar.tsx hook dependencies β Removed all `eslint-disable` comments for hooks
- β’ Removed 11 production console.log statements β Kept only PWA-related debug logs β Cleaner console output
β‘ Performance
- β’ **Added React.memo to 17 expensive components** β VehicleCard, PhotoGallery, ReminderCard, MaintenanceRecordItem β DocumentCard, FuelCard, FuelRecordList, MaintenanceRecordList β DocumentList, ReminderList, VehicleList, TabContent components β Analytics charts and reports components β Reduces unnecessary re-renders β Improved list/grid rendering performance
- β’ Optimized component re-rendering patterns
π Improved
- β’ **Code quality** - Better React patterns and hooks compliance
- β’ **Developer experience** - No more lint warnings
- β’ **Production logs** - Reduced noise, better signal
v2.2.0 2025-11-15
π Changed
- β’ **MAJOR:** Migrated from Uvicorn to Granian ASGI server β **+11% requests/sec** (45,000 β 50,000) β **-25% memory usage** (20MB β 15MB per worker) β More consistent latency (2.8x max/avg vs 6.8x) β Single worker mode for APScheduler compatibility
- β’ **MAJOR:** Removed deprecated libraries β Removed moment.js (~232KB), replaced with date-fns (~78KB) - **-154KB** β Removed unused chart.js and react-chartjs-2 - **-200KB** β Total bundle savings: **~350KB**
- β’ **MAJOR:** Implemented frontend code splitting β Route-based lazy loading for all pages β Manual chunk configuration (react-vendor, charts, calendar, ui, forms, utils) β **-78% initial bundle size** (~900KB β ~200KB) β **-60% time to interactive** (~2.5s β <1s)
- β’ **MAJOR:** Migrated to @vitejs/plugin-react-swc β Faster builds using SWC instead of Babel β Better development experience
- β’ Fixed Tailwind v4 PostCSS configuration β Created `postcss.config.js` with @tailwindcss/postcss plugin β Added autoprefixer support β Simplified tailwind.config.js (theme moved to CSS)
β¨ Added
- β’ Created `pyproject.toml` for modern Python packaging β Version management in single source of truth β Dev dependencies separated (pytest, ruff) β Better tooling support
- β’ **Health check logging filter** β Suppresses Docker health check logs from access logger β Reduces log noise while preserving API request visibility β Applied to Granian access logger
π Security
- β’ **bcrypt v5.0 password validation** β Added password length checks (max 72 bytes) β Prevents silent truncation vulnerability β Returns clear error for invalid passwords
π Updated
- β’ **Backend dependencies:** β FastAPI: 0.121.0 β 0.121.1 β APScheduler: 3.10.4 β 3.11.1 β Pydantic: 2.12.0 β 2.12.3 β Pillow: 11.0.0 β 12.0.0 (Python 3.14 support) β Added Granian: 2.5.7
- β’ **Frontend dependencies:** β lucide-react: 0.468.0 β 0.553.0 β react-router-dom: 7.1.1 β 7.9.6 β recharts: 3.3.0 β 3.4.1 β TypeScript: 5.6.2 β 5.9.3 β @types/react: 19.0.0 β 19.0.6 β @types/react-dom: 19.0.0 β 19.0.2 β Added date-fns: 4.1.0 β Added @tailwindcss/postcss: 4.1.17 β Added autoprefixer: 10.4.20
- β’ **v2.1.0:** Authentication UI redesign, dependency updates (Tailwind v4, Vite 7), security improvements, zero-config
- β’ **v2.0.0:** Backup system, service consolidation, enhanced features
- β’ **v1.x:** Initial development phases (7 major phases + 12 feature phases)
Key Features
Vehicle Profiles
Add vehicles by VIN and get automatic decoding via NHTSA. Stores make, model, year, engine, transmission, and more.
Service Records
Log oil changes, repairs, tire rotationsβanything. Attach receipts, set the mileage, track costs. Full history per vehicle.
Fuel Tracking
Log fill-ups and get automatic MPG calculations. Separate tracking for towing/hauling to see how loads affect efficiency.
Multi-Service Notifications
7 notification providers: ntfy, Gotify, Pushover, Slack, Discord, Telegram, and Email. Get alerts for maintenance, recalls, and expirations.
Recall Checking
Automatic NHTSA recall lookup by VIN. See active recalls, completion status, and links to CarComplaints for known issues.
OCR Receipt Scanning
Upload a photo of a receipt and Tesseract OCR extracts the vendor, date, amount, and line items automatically.
Analytics Dashboards
Fleet analytics for spending trends across all vehicles. Individual dashboards show cost breakdown per car with charts.
Calendar View
See upcoming maintenance and past services on a calendar. Visual timeline of everything that's happened and what's coming.
OIDC/SSO Auth
Works with Authentik, Keycloak, or any OIDC provider. Multiple users with admin/regular roles. Or just use local accounts.
PDF & CSV Exports
Export service history, fuel logs, and analytics as PDF reports or CSV files. Good for insurance claims or selling a vehicle.
Address Book
Keep track of mechanics, dealerships, and parts stores. Link service records to providers for quick reference.
Light/Dark Theme
Toggle between light and dark themes. Your preference is saved and syncs across devices.
Why Self-Host?
Your data stays with you
No cloud accounts, no subscriptions, no third parties seeing your maintenance records or vehicle info.
Works offline
Once deployed, everything works on your local network. No internet needed to log a service or check your history.
Multiple users
Household members can each have their own account and vehicles. Admin users manage settings and user access.
Full backups
Built-in backup/restore. Download your entire database and uploads as a zip file whenever you want.
Screenshots
Login
Clean login page with support for local accounts and OIDC/SSO providers like Authentik or Keycloak.
Dashboard
Overview of all your vehicles with quick stats, recent activity, and upcoming maintenance reminders at a glance.
Analytics
Fleet-wide analytics showing spending trends, fuel economy, and cost breakdowns across all vehicles with interactive charts.
Vehicle Overview
Individual vehicle page with VIN-decoded specs, photo gallery, and quick access to all maintenance records.
Service History
Complete service log with dates, mileage, costs, and vendors. Attach receipts and documents to any service record.
Fuel History
Track fill-ups with automatic MPG calculations. Separate tracking for normal driving vs. towing/hauling to see efficiency impact.
Odometer Tracking
Visual timeline of mileage over time with automatic syncing from service and fuel records.
Recall Checking
Automatic NHTSA recall lookup by VIN. See active recalls, descriptions, and remedies with links to CarComplaints for known issues.
Maintenance Reminders
Set reminders by date or mileage. Supports recurring schedules and push notifications when maintenance is due.