Refuse image and strategy ids that could name a path outside the app's folder

The desktop app saves a cloud strategy's images as
<strategy publicId>/<image publicId><extension>. Nothing checked either id,
and completeUpload stored whatever extension the caller sent, so someone
sharing a strategy could make every member's app save a .bat into the
Windows Startup folder during the background offline copy.

The server now refuses strategy and image ids with a separator, drive colon,
control character or "..", keeps a finished upload's extension to the image
type that was uploaded, and never hands out a download URL for a row that
isn't a safe image file name, whichever path wrote it. Every id a shipped
build makes is a UUID or a copy id built from one, so none is refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
0ccfa303d4Dara Adedeji committed on 10/21/2026, 4:54:17 PMparente785cd1

Checks

Some checks failed
5 files changedLine totals unavailable