feat: add signed bind-backed user icon uploads
This commit is contained in:
@@ -134,6 +134,32 @@ Never give either caller `image_admin_secret`, which also authorizes explicit
|
||||
branch changes. This fallback handles webhook delivery outages; if the image
|
||||
service itself is stopped, restore it and run the caller command again.
|
||||
|
||||
### Short-lived user-icon uploads
|
||||
|
||||
Core and Core2026 can store validated account icons in this repository through
|
||||
`PUT /v1/uploads/user-icons/<client>/<random-32-hex>.<extension>`. Each game
|
||||
server validates the authenticated user and image first, then sends the raw
|
||||
image body with `X-Image-Client`, `X-Image-Expires`, `X-Image-Request-Id`, and
|
||||
`X-Image-Signature` headers.
|
||||
|
||||
The signature is HMAC-SHA256 over
|
||||
`expires.requestId.pathname.contentType.sha256(body)`. Expiry may be at most
|
||||
five minutes in the future, so a grant cannot be reused for another path,
|
||||
content type, body, or later upload. The service also checks the image magic,
|
||||
caller scope, and request replay before it writes one immutable file below the
|
||||
host bind directory `runtime-data/uploads`. User uploads are deliberately not
|
||||
added to Git; Nginx exposes that bind read-only at `/icons/users/`.
|
||||
|
||||
Create separate upload secrets with `deploy/scripts/init-secrets.sh`. Mount only
|
||||
the matching `image_upload_core_secret` or `image_upload_core2026_secret` on the
|
||||
game server. The shared secrets stay server-side in Docker secrets; they are
|
||||
not returned to browsers or forwarded to Cloudflare.
|
||||
|
||||
Run `deploy/scripts/init-secrets.sh` before the first Compose start so
|
||||
`runtime-data/uploads` exists with permissions that allow the hook container to
|
||||
write and the Nginx container to read. Back up this directory independently of
|
||||
the Git repository when moving servers.
|
||||
|
||||
Legacy HTTP mutation is disabled by default. An emergency PHP rollback must
|
||||
first stop `image-hook`, then create the ignored `hook/legacy-enabled` sentinel
|
||||
in the legacy checkout before restoring its Caddy/Gitea route. Remove the
|
||||
|
||||
Reference in New Issue
Block a user