Commit Graph

6 Commits

Author SHA1 Message Date
jubnl 910631c1ff fix(backup): restore from Docker, fail-fast on shadowed /app, bundle encryption key (#1193) (#1197)
* fix(backup): restore uploads through symlinked dir and bundle encryption key (#1193)

Restoring a backup inside Docker threw ERR_FS_CP_DIR_TO_NON_DIR because
/app/server/uploads is a symlink to the mounted /app/uploads volume and
cpSync (dereference:false) refuses to overwrite the symlink node with a
directory. The DB was swapped before this failing copy, so users saw
restored data but missing upload files (trip covers). Resolve the symlink
with realpathSync before copying so the merge targets the real directory;
no-op on a plain dir, so non-Docker behavior is unchanged.

Also bundle the at-rest encryption key (data/.encryption_key) into the
backup so a restore onto a different install can decrypt stored secrets
(API keys, MFA, SMTP/OIDC). Skipped when ENCRYPTION_KEY is provided via
env (the file is not the source of truth then). On restore the key is
swapped back if the archive carries one; a restart is required for the
in-memory key to take effect.

* fix(docker): fail fast when a volume shadows /app (#1193)

Mounting an old volume at /app hides the image's node_modules and dist,
so startup crashed with a cryptic "Cannot find module
'tsconfig-paths/register'". Add a CMD preflight that detects the missing
app files and exits with actionable guidance. Document in the README that
only /app/data and /app/uploads should be mounted, never /app.

* fix: ssrf test
2026-06-16 07:43:00 +02:00
jubnl 8077ffab34 fix(maps): bound place-photo cache growth (Wikimedia + Google) (#1174)
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.
2026-06-14 23:31:02 +02:00
Maurice 093e069ccc Backend/frontend hardening & consistency cleanups (#1113)
* refactor(auth): session token validation and password-change consistency

* refactor(journey): entry field allow-list and public share-link consistency

* refactor(mcp): align tool authorization with the REST permission checks

* chore: input validation and sanitisation touch-ups (uploads, pdf, maps, backup, csp)
2026-06-06 16:37:03 +02:00
jubnl 5eaf7492dc fix(backups,files): auto-backups rejected by validator; trip file download broken after cookie migration
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.
2026-04-21 11:18:17 +02:00
jubnl 6a23118342 fix(notifications): fix SMTP error surfacing, webhook button label, backup timestamp
- 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
2026-04-14 16:20:52 +02:00
jubnl b4922322ae test: expand test suite to 87.3% backend coverage
Add new integration test files covering previously untested routes:
- categories.test.ts — GET /api/categories
- oidc.test.ts — full OIDC login flow (callback, state, errors)
- settings.test.ts — GET/PUT /api/settings, bulk save
- tags.test.ts — CRUD for trip tags
- todo.test.ts — todo items CRUD and reorder

Add new unit test files covering service-layer logic:
- adminService.test.ts — user/invite management, packing templates, OIDC settings
- atlasService.test.ts — atlas search and place enrichment
- authServiceDb.test.ts — DB-backed auth helpers (login, register, MFA)
- backupService.test.ts — export/import/restore logic
- categoryService.test.ts — category CRUD
- dayService.test.ts — day management and accommodation helpers
- mapsService.test.ts — route/directions helpers
- oidcService.test.ts — OIDC state, auth code, role resolution, user upsert
- packingService.test.ts — packing item/bag/template operations
- placeService.test.ts — place CRUD and tag attachment
- settingsService.test.ts — settings get/set/bulk
- tagService.test.ts — tag CRUD
- todoService.test.ts — todo CRUD and reorder
- tripService.test.ts — trip CRUD, member management, archiving
- vacayService.test.ts — vacay integration helpers
- tripAccess.test.ts (middleware) — requireTripAccess middleware

Expand existing integration and unit test files with additional cases
across admin, atlas, auth, backup, collab, days, files, maps, memories
(Immich/Synology), notifications, places, reservations, share, vacay,
weather, auth middleware, ephemeral tokens, notification preferences,
permissions, SSRF guard, and WebSocket connection tests.

Update test helpers (factories.ts, test-db.ts) with new factory
functions and seed data required by the expanded suite.

Fix minor issues in server/src/routes/reservations.ts and
server/src/services/atlasService.ts surfaced by new test coverage.

Update sonar-project.properties to reflect new coverage thresholds.
2026-04-06 20:08:30 +02:00