Skip to content

fix(api): store backup archive filename instead of absolute path - #331

Open
bfs2021 wants to merge 1 commit into
Open-Glassbeetle:mainfrom
bfs2021:fix/backup-relative-archive-path
Open

bfs2021 wants to merge 1 commit into
Open-Glassbeetle:mainfrom
bfs2021:fix/backup-relative-archive-path

Conversation

@bfs2021

@bfs2021 bfs2021 commented Nov 15, 2026

Copy link
Copy Markdown
Contributor

Problem

backups.file_path stores the absolute archive path
(…/backups/backup-<id>.tar.gz), while every other stored file reference in the
database is a relative one (pictures/…, project-images/…) as required by the
FileStorageService contract. Restoring a backup archive on another machine
leaves every historical row pointing into the old user's home directory, and the
row leaks the local filesystem layout.

Root cause

createBackup inserts finalArchivePath — built from resolveTargetDirectory()
— into backups.file_path, and deleteBackup plus mapRowToResponse's
existsSync probe read that column back as an absolute path.

Fix

  • Store only backup-${id}.tar.gz in file_path.
  • Add one private archivePathFor(row) that joins resolveTargetDirectory()
    with path.basename(row.file_path), and use it in deleteBackup and in
    mapRowToResponse's existsSync probe.
  • Applying path.basename on read means rows written by the previous code keep
    resolving correctly; no schema migration needed.
  • Deliberately not routed through FileStorageService: its containment check is
    relative to the storage root, and a backup can legitimately be written to a
    user-chosen directory.

One behaviour note: the target directory stays configurable. If a user changes
backup_policy.target_directory and later changes it back, a stored filename
resolves against whatever is configured now; isAvailable reports the truth via
existsSync. Storing an absolute path did not avoid that — it just failed
differently.

Testing

  • npm run test -w @glassbeetle/api -- src/modules/application/backups/backups.service.spec.ts — 19 passed. New coverage: a fresh createBackup row stores a bare filename; a legacy absolute row still resolves and deletes; existing delete/presence tests now resolve through the target directory.
  • npm run test:e2e -w @glassbeetle/api -- test/backups.e2e-spec.ts — 14 passed.
  • npm run lint -w @glassbeetle/api — 0 warnings, 0 errors.
  • npm run build -w @glassbeetle/api — passes.

Fixes #330

`backups.file_path` held the absolute archive path, unlike every other
stored file reference. A backup restored on another machine therefore
pointed under the previous user's home directory, and the row leaked the
local filesystem layout.

Store `backup-${id}.tar.gz` instead and resolve it against
`resolveTargetDirectory()` on read through a single `archivePathFor`
helper. Applying `path.basename` keeps legacy absolute rows working.

Fixes Open-Glassbeetle#330
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

backups.file_path stores an absolute path, the one thing the storage convention forbids

1 participant