payload.secret != expected_secret short-circuits on the first
differing byte, which leaks timing information about how many
leading bytes of a guess are correct. Use subtle::ConstantTimeEq
instead.
db::ensure_dev_athlete was never called (main.rs had its own,
inferior copy, removed in the previous commit). Config::dev_sync_days
and Config::require_api_key were only used by the now-removed
/dev/sync handlers.
/dev/sync/{api_key} and /dev/sync/{api_key}/{athlete_id} took a
personal Intervals.icu API key as a URL path segment, which leaks
into server/proxy access logs (and tower_http's TraceLayer spans),
browser history, and Referer headers. There's no legitimate reason
to keep a credential-in-URL debug backdoor around outside local
development, so it's gone along with its handlers.
This also removes main.rs's local ensure_dev_athlete, which
duplicated db::ensure_dev_athlete but used a racy check-then-insert
instead of an upsert (TOCTOU on concurrent dev syncs for the same
athlete).
geo::crossings_between issued one DB round trip per consecutive GPS
sample pair (tens of thousands per multi-hour activity), even though
almost every segment stays inside a single county and produces no
crossing at all.
geo::crossings_for_track batches all segments of a track into a
single query via UNNEST ... WITH ORDINALITY. The per-segment geometry
logic (endpoint county lookup via the GiST index, boundary
intersection, ST_LineLocatePoint for the fractional position) is
unchanged, it now just runs once per activity instead of once per
segment.