Gallery

Features

Feature Description
Directory navigation Two-level hierarchy: Year > Date + Event name
Thumbnail grid Paginated (60 images per page) with full-screen view
S3 Storage RustFS (Apache 2.0) instead of MinIO (AGPL)
Passkey Authentication WebAuthn/FIDO2 via one-time password registration
Image Upload Multi-file, MIME validation (JPEG, PNG, WebP), automatic thumbnails with EXIF rotation
Delete Individual images and entire galleries (incl. S3 cleanup)
Battle submission Send photos from the gallery directly to FotoBattle
Darkroom UI Dark design with amber accents, WCAG 2.1 AA, responsive

Routing

Method Path Description
GET / Home page (annual directories)
GET /browse/{id} Directory with subfolders + image grid
GET /image/{id} Image proxy from S3 (with ETag caching)
GET/POST /register Passkey registration via OTP
POST /register/challenge WebAuthn registration challenge
POST /register/complete Complete WebAuthn registration
GET/POST /login Passkey login
POST /login/challenge WebAuthn login challenge
POST /login/complete Complete WebAuthn login
POST /logout Log out (CSRF-protected)
GET/POST /gallery/create Create Event Gallery (Auth)
GET/POST /upload Image Upload (Auth)
POST /image/{id}/delete Delete Image (Auth, CSRF)
POST /gallery/{id}/delete Delete Gallery (Auth, CSRF)
POST /battle/withdraw/{image_id} Battle Withdrawal (HMAC Token)

Services

Service Description
GalleryService Directory/image CRUD, breadcrumbs, event gallery creation
PasskeyService WebAuthn registration and authentication, OTP management
UploadService Multi-file upload, MIME validation, thumbnail workflow
ThumbnailGenerator GD-based resizing (max 400×300px) with EXIF rotation
BucketScanner Catalog S3 bucket in database
S3ClientFactory AWS SDK S3Client for RustFS endpoint
DatabaseFactory PDO connection from environment variables

CLI Tools

# Bucket scannen und Bilder in DB eintragen
docker compose exec php php bin/scan.php

# Thumbnails für alle Bilder ohne Thumbnail erzeugen
docker compose exec php php bin/thumbs.php

Database (Gallery Tables)

Table Description
dirs Directory hierarchy with parent_id self-reference, unique on dirname + bucket
images Image files with S3 metadata (name, size, hash), FK on dir_id
thumbs Thumbnail paths, FK on image_id (1:1)
passkeys WebAuthn credentials (credential_id, public_key, counter, transports JSON)
otp_status Single-row table: OTP used yes/no