fix mid level issues. updated changelog

This commit is contained in:
Davide Scaini
2026-03-31 23:00:39 +02:00
parent f8abab2c23
commit 8f91503cf7
7 changed files with 119 additions and 33 deletions
+33 -1
View File
@@ -1,6 +1,38 @@
# Changelog
## [Unreleased] — 2026-03-30
## [Unreleased] — 2026-03-31
### Security fixes
- **Path traversal prevention** (`edit/server.py`) — all routes now validate `activity_id` against `[a-zA-Z0-9\-]+` regex via `_check_id()`; invalid IDs return 400
- **Path traversal in `delete_image`** — `filename` parameter now stripped to basename via `Path(filename).name` before use in filesystem paths
- **Path traversal in `upload_activity`** — uploaded `file.filename` stripped to basename via `Path(file.filename).name`
- **XSS in activity description** (`ActivityDetail.svelte`) — `marked()` output now wrapped in `DOMPurify.sanitize()` before `{@html}` rendering
- **CORS restricted** (`edit/server.py`) — `allow_origins=["*"]` replaced with `allow_origin_regex` matching `localhost` origins only
- **YAML injection in `hide_stats`** — values filtered against a `STAT_PANELS` allowlist before writing to YAML frontmatter
- **Regex injection in `deleteImage`** (`EditDrawer.svelte`) — filename special characters escaped before `RegExp` construction
### Bug fixes — data
- **MMP sliding window on non-contiguous data** (`metrics.py`) — power series now built as a dense 1 Hz array with gaps zero-filled (standard GoldenCheetah/WKO approach); recording pauses no longer inflate MMP values
- **Best-effort times on non-contiguous data** (`metrics.py`) — speed series uses same zero-fill; pauses count as 0 km/h so windows cannot span them silently
- **Activity ID collision** (`writer.py`) — when two activities share the same start-time + title, the second is disambiguated with a 6-character source hash suffix; re-extracting the same file is idempotent
- **Misaligned lat/lon arrays** (`ActivityMap.svelte`) — lat and lon were filtered for nulls independently; now filtered as pairs so indices always stay aligned
- **Falsy `0.0` speed check** (`metrics.py:89-90`, `parsers/fit.py:89`) — `if avg_speed_kmh` / `if speed_raw` replaced with `is not None`; 0.0 is no longer silently dropped
- **TCX timestamps with numeric timezone offsets** (`parsers/tcx.py`) — `+02:00`-style offsets now parsed correctly and converted to UTC; previously crashed with `ValueError`
### Bug fixes — frontend
- **Backdrop dismiss fires `saved` event** (`EditDrawer.svelte`) — backdrop click and ×-button now dispatch `close` instead of `saved`, preventing unsaved data from overwriting the displayed title/description
- **No error handling in `uploadImages`** (`EditDrawer.svelte`) — wrapped upload loop in try/catch/finally so a network error clears the `uploading` spinner and surfaces an error message instead of locking the UI
- **Stats page pagination** (`StatsView.svelte`) — heatmap now shows 4 years per page with ← Newer / Older → controls; `?page=` persisted in URL
### Schema
- **Writer output now matches schema** (`bas-v1.schema.json`) — `mmp`, `best_efforts`, `best_climb_m`, `preview_coords`, and `custom` are all declared in the schema; previously `additionalProperties: false` caused validation failures
- **`skiing` added to sport enum** — was produced by the extractor but missing from the schema definition
- **Sub-sport enum extended** — `nordic`, `alpine`, `open_water`, `pool` added to schema
- **Activity ID format corrected in SCHEMA.md** — examples updated from `+0200` offset to `Z` UTC suffix (matching actual code behaviour since v0.1.0)
### Navigation