update changelog

This commit is contained in:
Davide Scaini
2026-04-01 21:55:42 +02:00
parent bd5831c2fd
commit ef3bf12eb8
+41 -1
View File
@@ -1,6 +1,46 @@
# Changelog # Changelog
## [Unreleased] — 2026-03-31 ## [Unreleased] — 2026-04-01
### Security fixes (second-pass audit)
- **Sport value not validated before YAML write** (`edit/server.py`) — `sport` field now validated against `SPORTS` allowlist before being written to the sidecar
- **No image content-type validation** (`edit/server.py`) — arbitrary file uploads rejected; only `image/*` content types accepted
- **XSS via unescaped filename in `innerHTML`** (`edit/server.py`) — `escapeHtml()` applied to filenames in `renderImageList` before interpolation
- **No upload size limit** (`edit/server.py`) — 50 MB limit enforced before writing to disk; returns HTTP 413 on oversize uploads
- **Exception message leaks internal paths** (`edit/server.py`) — 422 response now returns `type(exc).__name__` only, not `str(exc)` which could expose filesystem paths
### Bug fixes — data (second-pass audit)
- **Disambiguated ID not written into JSON body** (`writer.py`) — collision suffix was added to the filename but `detail["id"]` still held the original ID; fixed to update `detail["id"]` after disambiguation
- **`write_activity` return value ignored** (`cli.py`) — caller was using the pre-collision ID to build the index summary; now captures the canonical return value from `write_activity`
- **TOCTOU race in collision guard** (`writer.py`, `cli.py`) — concurrent workers could both see no existing file and overwrite each other; workers now write to unique `.pending.json` files and the main process arbitrates by quality score via `finalize_pending()`
- **`athlete.yaml` merge has no field allowlist** (`render/merge.py`) — `merge_all()` now applies only `_ATHLETE_EDITABLE` keys (`max_hr`, `ftp_w`, `hr_zones`, `power_zones`, `seasons`, `gear`) from the sidecar
- **Timezone offsets without colon** (`parsers/tcx.py`) — regex updated to `[+-]\d{2}:?\d{2}` so `+0200` is handled alongside `+02:00`
- **Power data in GPX extensions not parsed** (`parsers/gpx.py`) — extension tags `pwr`, `power`, and `watts` now parsed; MMP no longer always `None` for GPX files with power meters
- **`speeds` array misaligned with `coordinates`** (`simplify.py`) — speeds array now uses the same lat/lon null filter as coordinates
### Bug fixes — frontend (second-pass audit)
- **Hardcoded nav links ignore `BASE_URL`** (`Base.astro`) — `/`, `/stats/`, `/athlete/` nav hrefs now use `baseUrl` from `import.meta.env.BASE_URL`
- **Undeclared `error` variable in `uploadImages`** (`EditDrawer.svelte`) — catch block now uses `saveStatus`/`saveOk` (existing error state) instead of undeclared `error`
- **`ResizeObserver` stale closure in MmpChart** (`MmpChart.svelte`) — reactive variables keep the closure current so resize re-renders with correct data after range selection changes
- **`resetTrim` guard always true** (`ActivityCharts.svelte`) — tracks `lastResetTab` to force trim reset on every tab switch regardless of whether min/max happen to match
- **No `onDestroy` cleanup in ActivityCharts** (`ActivityCharts.svelte`) — chart SVG now removed on component unmount to prevent memory leaks
- **Invalid URL `tab` parameter shows blank content** (`AthleteView.svelte`) — `tab` query param validated against `TABS` array; invalid values fall back to `'power'`
### Schema (second-pass audit)
- **`activity_summary` missing `custom` property** (`bas-v1.schema.json`) — `merge.py` always adds `custom` to summaries but it wasn't declared; added to schema
- **`skiing` missing from SCHEMA.md sport enum** — added alongside sub-sport enum updates
- **Summary fields table incomplete** (`SCHEMA.md`) — `sub_sport`, `mmp`, `best_efforts`, `best_climb_m`, `preview_coords` all added to the summary fields table
### Tests (second-pass audit)
- **`test_id_utc_conversion`** (`test_writer.py`) — verifies non-UTC timestamps are converted to UTC in generated IDs
- **`test_build_summary_required_fields`** (`test_writer.py`) — verifies all schema-required fields present in `build_summary` output
- **Skiing and swimming sport variants** (`test_sport.py`) — `test_skiing_variants` and `test_swimming_variants` added
- **Non-canonical IDs in test fixtures** (`test_merge.py`) — fixture IDs updated to canonical `2024-01-01T080000Z-morning-ride` format
### Security fixes ### Security fixes