The place-photo cache (uploads/photos/google) grew unbounded: a Wikimedia
geosearch path cached full-res originals despite requesting a 400px thumb,
the writer applied no size guard, nothing reclaimed orphaned files, and
backups archived the whole re-derivable cache verbatim.
- Prefer the scaled `thumburl` over the full-res `info.url` in the Commons
geosearch fallback.
- Downscale any cached image to <=800px JPEG via the existing jimp dep,
with a safe fallback to the original bytes on decode failure.
- Add sweepOrphans() (orphaned meta rows + stray files) wired into the
scheduler (startup + nightly), and removeIfUnreferenced() called on
place delete for prompt reclamation.
- Exclude the re-derivable photo/trek caches from backups; restores
self-heal as the cache dirs are recreated at startup.
Fixes#773: isValidBackupFilename regex anchored to ^backup- rejected all
auto-backup-* filenames, causing 400 on download/restore/delete. Broadened
to ^(?:auto-)?backup-.
Fixes#774: three regressions in the trip Files tab —
- openFile import shadowed by a local function of the same name inside
FileManager; PDF preview modal was calling the local with a URL string,
corrupting state and crashing on the second click (mime_type read on
undefined). Fixed by aliasing the import as openFileUrl.
- GET /:id/download used a bespoke authenticateDownload that checked only
Bearer header and ?token= query param, ignoring the trek_session cookie.
After the JWT-to-cookie migration the client sends cookies only, so every
download silently 401-ed. Extended authenticateDownload to accept req and
check cookie → Bearer → query token in priority order.
- files.download and files.openError translation keys were missing from all
15 locale files; t() was returning the raw key as a truthy string,
defeating the || 'Download' fallback.
- testSmtp now surfaces real nodemailer error instead of generic 'SMTP not configured' on send failure
- admin webhook test button uses correct i18n key (was showing 'Test-E-Mail senden' in all languages)
- backup created_at uses stat.mtime instead of unreliable stat.birthtime on Linux