You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
POST /uploads/batch-register — register up to 100 files in a single round-trip; returns TUS upload IDs for immediate PATCH sequencing
Per-account pacing soft-lock: a second batch cannot be registered until the first reaches 50% completion, preventing runaway queuing
GET /uploads/batch/{id} — poll batch progress (total, complete, failed counts)
DELETE /uploads/batch/{id} — cancel a pending batch and release the lock early
POST /files/batch-manifest — fetch chunk manifests for up to 100 files in one call; used by the download path to prefetch decryption metadata
Name validation
Folder and team names now accept [], {}, #, @, +, and other characters that are valid on all major operating systems. Previously a narrow whitelist blocked these. The validator now uses the same blacklist approach as filenames (< > : " / \ | ? * and control characters only).
ZIP download paths run through _sanitizeZipComponent() to strip any embedded path separators from file/folder names before archive construction.
Supply-chain hardening (v1.1.x)
Frontend script tags carry SRI hashes (integrity= + crossorigin=anonymous); integrity manifest (manifest.json) verified at container start
Python wheels pinned with SHA-256 hashes in requirements-hashed.txt; Docker build installs from hashes, not bare version pins
OPAQUE server ID derived from a stable secret rather than regenerated on each restart, preventing session invalidation across container restarts
Dependency updates
pydantic-settings 2.14.1 to 2.14.2 (GHSA-4xgf-cpjx-pc3j: symlink traversal in NestedSecretsSettingsSource; not used in this project but cleared as a precaution)
python-multipart to 0.0.31 (quadratic querystring DoS, Content-Disposition smuggling, Negative Content-Length)
cryptography to 48.0.1 (patched OpenSSL bundled in Alpine wheels)