v0.18.0 - API keys, fasting+water intake+bowl movement tracking in health, Strava bulk import, activity map thumbnails, Redis-backed security storage, and security hardening
⚠️ Warning:
- The DB has schema changes. Backup your DB before applying the update.
- Docker deployments using custom compose files should add Redis and configure
RATE_LIMIT_STORAGE_URIandAUTH_SECURITY_STORAGE_URI. Process-local memory is still available, but rate-limit counters, login lockout state, and pending MFA state are not shared across multiple backend instances without Redis. - Garmin Connect token storage was migrated. If you receive the new Garmin token-expired notification, reconnect Garmin Connect.
- You may need to relogin on upgrade and clear cookies.
- First startup after migration can be long. DB migration is large and activities thumbnails will be created.
Backend:
- Added user API keys with scoped access, expiration, revocation, upload authentication support, and backend tests.
- Added step-up verification for sensitive actions such as API key creation, MFA setup, and IdP unlinking.
- Added Redis-backed storage support for rate limiting and authentication security state.
- Added health fasting, water, and poop tracking APIs, plus new health target fields.
- Added activity map thumbnail generation, missing-thumbnail backfill, and thumbnail regeneration when tile server settings change #380.
- Improved Strava bulk import support, including metadata parsing, activity media import, bikes/shoes import, multi-file handling, progress logs, and clearer validation #351.
- Added Strava API rate-limit handling and additional import guards #436, #517.
- Refactored activity file import logic into shared GPX, TCX, and FIT utilities with improved parsing state, cleanup on failure, and extra tests.
- Refactored activities, activity laps, streams, summaries, workout steps, gears, followers, notifications, sign-up tokens, password-reset tokens, and user modules for cleaner structure and typed SQLAlchemy models.
- Migrated Garmin Connect OAuth token storage to a single JSON token column and added token-expiration handling.
- Added request ID middleware for better log correlation.
- Added SSRF protection and safer file-serving/upload utilities.
- Added proxy-aware client IP helpers and environment-aware trusted proxy defaults.
- Added database SSL configuration support and improved DB error handling.
- Added i18n logic for email generation.
- Add temperature tracking and graph for .fit files #544
- Add support for parsing opentracks gpx export power of cycling #601
- Migrated backend dependency management from Poetry to uv.
- Updated backend dependencies.
Frontend:
- Added API key management UI in user security settings, including key creation and one-time reveal modals.
- Added fasting, water, and poop health tracking screens, charts, lists, and dashboard cards.
- Improved health dashboard loading states, placeholder components, interval filtering, and time formatting.
- Added activity map thumbnail support in activity views.
- Added Strava bulk import UI/status improvements and moved import actions into the Settings import zone.
- Improved gear pages with pagination, filters, placeholders, and component editing by body id.
- Added Garmin token-expired notification UI and translations.
- Updated the login image and kept previous login images as versioned assets.
- Add temperature tracking and graph for .fit files #544
- Updated frontend dependencies, including Vite 8, TypeScript 6, vue-router 5, lodash, and serialize-javascript override.
Fixes:
- Fix password reset leaving sibling reset tokens valid and consuming tokens non-atomically.
- Fix password reset not invalidating user sessions.
- Fix MFA backup-code
expires_atnot being enforced. - Fix wrong TOTP during MFA enable burning the pending secret.
- Fix API keys remaining valid for inactive users.
- Fix SSO token minting for inactive or pending users.
- Fix IdP linking and unlinking missing step-up protection.
- Fix IdP link tokens being stored as plaintext primary keys.
- Fix admin force-password-change not invalidating target user sessions.
- Fix OAuth state replay claim not being enforced after atomic update.
- Fix SSO token exchange trusting client-declared
client_typeover OAuth state. - Fix secure-cookie rule mismatch between SSO token exchange and password login.
- Fix username enumeration via login timing and per-username lockout bypass via case/whitespace variants.
- Fix JWT decoding to explicitly pin allowed algorithms.
- Fix advertised API scopes that were not enforced.
- Fix path traversal sequences bypassing
photo_pathprefix checks. - Fix imperial weight target handling #545.
- Fix water unit conversion when setting health targets.
- Fix right-aligned dropdowns and Strava import paths.
- Fix import of tcx for indoor activity from "a Training Tracker" app on Android fails #567
- Add alt text to activity icons #543
- Fix update user handling in edit user form to ensure correct profile data is used
- Fix activity display unit mismatches across several sports #600
Docs and development:
- Added API key authentication documentation.
- Added Strava bulk import and importing documentation.
- Added reference docs for activity streams, summaries, workout steps, gears, gear components, GPX, TCX, health water, health poop, migrations, notifications, password reset tokens, sign-up tokens, server settings, and user API keys.
- Added Copilot agents and updated backend development instructions.
- Updated Docker examples with Redis and adjusted Docker build/runtime behavior.
New contributors:
- GitHub user F-Stop
- GitHub user Saif-Ahh
- GitHub user julienheinen
- GitHub user joaquinhuigomez
- GitHub user swenske
- @DanyPM
- @HangryCB