Two related avatar bugs:
1. getAvatarUrl() returned empty string for S3 keys, so uploaded
avatars never displayed. Now constructs the full URL using
NEXT_PUBLIC_STORAGE_URL and NEXT_PUBLIC_AVATAR_BUCKET_NAME,
with support for both path-style (MinIO) and virtual-hosted
(Tigris/AWS S3) URLs.
2. Avatar crop scaled canvas by devicePixelRatio (4x pixels on
Retina), producing blobs that exceeded the 2MB upload limit
even for small source images. Now caps output at 512x512 and
uses quality=0.85 for toBlob().
Closes#440, closes#441
Co-authored-by: Claude <noreply@anthropic.com>
* refactor: replace presigned URL uploads with backend upload endpoints
* feat: update avatar upload to use new endpoint
* refactor: use createS3Client in auth hooks
* feat: generate presigned URLs for avatars
* fix: show avatar image in user menu
* fix: hide tooltip if content is empty
* fix: support external avatar URLs in generateAvatarUrl
* fix: remove content type restriction on attachments
Avatar images failed to load with 403 on Tigris and newer AWS S3 buckets
because getAvatarUrl only constructed path-style URLs. Modern S3-compatible
providers require virtual-hosted URLs (bucket.domain/key).
Add NEXT_PUBLIC_STORAGE_DOMAIN env var to signal URL style:
- If set: virtual-hosted URL (Tigris, AWS S3)
- If not set: path-style URL (MinIO, LocalStack) - backward compatible
Add vitest and tests for getAvatarUrl behavior.
Co-authored-by: Sachin Divekar <sachin.divekar@remiges.tech>
* fix: issue 23, handle external URLs in avatar rendering
* fix: add google to the remote patterns
---------
Co-authored-by: Henry <henry_ball@hotmail.co.uk>