API: fix direct upload with bearer token
Adds a new API endpoint for direct uploads that works with bearer token authentication.
The existing /rails/active_storage/direct_uploads endpoint doesn't work with API bearer tokens because ActiveStorage::DirectUploadsController inherits from ActiveStorage::BaseController (not ApplicationController), so it doesn't get Fizzy's CSRF bypass for JSON requests or the bearer token authentication (See also efbd2cc3d).
This PR adds Api::DirectUploadsController which:
- Inherits from
ApplicationController(gets bearer auth + account context automatically) - Sets the required ActiveStorage URL options for generating upload URLs
- Returns
attachable_sgid(required for ActionText) in addition tosigned_id
Follow-up to #1766.
Use case
I'm building a script to import GitHub issues into Fizzy. GitHub issues contain images hosted on github.com/user-attachments/... which require authentication to download. The import script:
- Downloads images from GitHub using
gh api - Uploads them to Fizzy via this new direct upload endpoint
- Embeds them in card descriptions using
<action-text-attachment sgid="...">
Without this endpoint, there's no way to upload files via the API.
curl -X POST \
-H "Authorization: Bearer your-token" \
-H "Content-Type: application/json" \
-d '{"blob":{"filename":"image.png","byte_size":12345,"checksum":"...","content_type":"image/png"}}' \
https://app.fizzy.do/123456789/api/direct_uploads.json
See also https://github.com/basecamp/fizzy/discussions/2054