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.
This commit is contained in:
jubnl
2026-04-21 11:18:17 +02:00
parent ee31c78db8
commit 5eaf7492dc
21 changed files with 85 additions and 22 deletions
+2 -6
View File
@@ -77,15 +77,11 @@ const upload = multer({
// Routes
// ---------------------------------------------------------------------------
// Authenticated file download (supports Bearer header or ?token= query param)
// Authenticated file download (supports cookie, Bearer header, or ?token= query param)
router.get('/:id/download', (req: Request, res: Response) => {
const { tripId, id } = req.params;
const authHeader = req.headers['authorization'];
const bearerToken = authHeader && authHeader.split(' ')[1];
const queryToken = req.query.token as string | undefined;
const auth = authenticateDownload(bearerToken, queryToken);
const auth = authenticateDownload(req);
if ('error' in auth) return res.status(auth.status).json({ error: auth.error });
const trip = verifyTripAccess(tripId, auth.userId);