- Remove cors from inject chain; resolve via getResource() inside
try-catch so DB failures don't cascade when resolving the cors
resource dependency chain (cors -> allowedHostnames -> rule -> DB)
- Use override:true on addHeader to prevent duplicate CORS headers
when init() already set them before the exception was thrown
- Degrades gracefully: if cors resolution fails, error response is
sent without CORS headers (same behavior as before this PR)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The Http::error() handler was missing CORS headers, causing browsers to
block error responses (e.g. 403 PROJECT_PAUSED) with a generic CORS
error instead of showing the actual error message. This injects the cors
resource into the error handler and adds CORS headers before sending the
error response, matching the pattern already used in Http::init().
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use Utopia\Messaging\Adapter\Email\SMTP instead of raw PHPMailer
for the smtp register, Mails worker, and Doctor task. This enables
swapping email adapters (e.g. Resend) via DI override in downstream
repos by type-hinting against the EmailAdapter base class.
- Add getDatabaseResourceType() helper to map database types to resource constants
- Use database-specific resourceType for CSV/JSON import/export instead of hardcoded TYPE_DATABASE
- Skip attribute validation for schemaless databases (DocumentsDB/VectorsDB) in exports
- Parse JSON export queries in migration worker
- Restore MigrationsBase from 1.9.x and append VectorsDB/DocumentsDB E2E tests
Since setDocumentType('users', User::class) is registered on all
database instances, getDocument('users', ...) already returns User
instances. The new User($doc->getArrayCopy()) pattern was redundant
and could lose internal state managed by the database layer.
https://claude.ai/code/session_01JLPDurUgyj7qViA8JqQFTH