The orphan check compared the path it was given with the paths file rows
hold, but Flysystem rewrites a path before it touches storage: "./a/b",
"a/./b", "a//b", "/a/b", "a\b" and "a/x/../b" all become "a/b". Any of
them made a file somebody owns look like an orphan, so deleting it
removed their bytes without delete_others_files, and importing it put a
second row on them. The same spellings walked past the exclusion of
derived-artifact folders.
isOrphan(), which import and delete both go through, now refuses a path
the normalizer would change or rejects outright. The scan only offers
paths as storage lists them, so nothing it sends is affected.
GHSA-pv88-7863-5hwq
The orphan scanner skips derived artifacts by path prefix, but the list
was a hard-coded ['thumbnails/', 'zips/'] that never learned about
'previews/'. ImageRendition::Preview caches under previews/ (and
previews/external/) on the local files disk, so every cached preview was
reported as an orphan: offered for import on the orphans screen, and
deleted by the purge command once past the grace period. An imported
preview also became a File row pointing at a path the rendition cache
owns -- destroyed the moment its source file was deleted or the cache
was flushed.
Derive the rendition prefixes from ImageRendition::cases() rather than
repeating them, so a future rendition can't be forgotten here the way
previews were; 'zips/' (the download-bundle job's) stays as it was.
Client file sharing, rebuilt from the ground up: a private area per
client, resumable uploads, folders, groups and categories, sharing with
expiry dates and download limits, comments, file versions, an activity
log, a REST API, and sixteen languages.
This repository begins here. ProjectSend 2 was developed privately, and
that development history is not published — the previous generation
remains available, with its own history, at projectsend/legacy.
Free software under the GNU General Public License v2, or (at your
option) any later version.