Fix S3 collision, alias clearing, upload limit, TOCTOU; add tests

Bug fixes:
- S3 key is now emoji/{uuid}.{ext} instead of emoji/{filename},
  preventing silent overwrites when two emotes share a filename
- UpdateEmoteRequest.alias uses Option<Option<String>> with a custom
  deserializer so a JSON null clears the alias rather than being ignored;
  the manage UI now sends null when the alias field is emptied
- POST /emotes is limited to 8 MiB via DefaultBodyLimit
- update_emote replaced the fetch-then-update pair with a single
  UPDATE … RETURNING using COALESCE/CASE WHEN, eliminating the TOCTOU
  race between concurrent edits

Refactoring:
- Extracted src/lib.rs so domain logic is a library crate; src/main.rs
  is now a thin startup entry point
- auth::check decoupled from AppState — takes Option<&AuthConfig> directly
- Removed unused config field from Database struct

Tests (40 total):
- auth: 10 unit tests covering all check() branches
- models: 6 unit tests for timestamp parsing and alias deserialization
- db: 9 unit tests against in-memory SQLite covering full CRUD
- routes: 15 integration tests in tests/routes.rs covering auth
  middleware, input validation, and all mutating endpoints
This commit is contained in:
Ganonmaster
2026-04-28 03:40:25 +02:00
parent 08fd6cea70
commit 2c219f5565
10 changed files with 736 additions and 95 deletions
+3
View File
@@ -23,3 +23,6 @@ mime_guess = "2"
tokio-util = { version = "0.7", features = ["io"] }
bytes = "1"
base64 = "0.22"
[dev-dependencies]
tower = { version = "0.5", features = ["util"] }