fix: post-review punch-list — upload concurrency cap, atomic release, ban SSE

Follow-up to the adversarial re-review of the audit-fix branch.

MUST-FIX:
- H3: bound aggregate upload RAM. The body limit alone didn't cap concurrency,
  so ~N parallel 550MB uploads could OOM the box. Add an Arc<Semaphore>
  (UPLOAD_MAX_CONCURRENCY=4) in AppState, acquired at the top of the upload
  handler before the multipart body is read, so waiting requests hold only a
  connection — peak buffered RAM ≈ 4×550MB. (Matches the CompressionWorker
  semaphore pattern; avoids tower's non-default `limit` feature.)
- M8: release_gallery now runs the claim UPDATE + both job INSERTs in one
  transaction, so the row lock is held until the jobs exist — closing the
  cross-table TOCTOU where two concurrent presses could both spawn workers
  racing the same output files. Export temp filenames are now per-run
  (Gallery.{uuid}.zip.tmp, viewer_tmp_{event}_{uuid}, Memories.{uuid}.zip.tmp)
  so overlapping runs can't truncate each other. Final served names unchanged.
- M11: 'user-banned' was missing from sse.ts KNOWN_EVENTS, so EventSource
  silently dropped the frame and the forced-logout handler never fired. Added.

SHOULD-FIX:
- M8-3: re-release is now allowed when nothing is in progress and at least one
  job failed (was: only when *every* job failed), so a one-sided failure (zip
  done, html failed) is no longer permanently unrecoverable.
- M18: two light-mode contrast spots the earlier sweep missed — the LightboxModal
  char-counter class: directives and the account PIN-missing notice.
- M15: the diashow auto-advance is now slowed to a ≥30s floor under
  prefers-reduced-motion (WCAG 2.2.2), making the app.css comment accurate.

Verified: cargo build + 6 tests, npm run check (0 errors), and a live smoke test
against Postgres — first release 204, second 400, one-sided-failure re-release
204, no SQL errors; a normal upload still returns 201 through the new permit.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
MechaCat02
2026-06-27 17:40:54 +02:00
parent d4181b1119
commit db1e5b8833
8 changed files with 82 additions and 26 deletions

View File

@@ -218,8 +218,8 @@
</div>
<div
class="mt-1 text-right text-xs"
class:text-gray-400={newComment.length < 450}
class:dark:text-gray-500={newComment.length < 450}
class:text-gray-500={newComment.length < 450}
class:dark:text-gray-400={newComment.length < 450}
class:text-amber-600={newComment.length >= 450 && newComment.length < COMMENT_MAX}
class:dark:text-amber-400={newComment.length >= 450 && newComment.length < COMMENT_MAX}
class:text-red-600={newComment.length >= COMMENT_MAX}

View File

@@ -38,6 +38,7 @@ const KNOWN_EVENTS = [
'upload-deleted',
'like-update',
'new-comment',
'user-banned',
'event-closed',
'event-opened',
'event-updated',