mirror of
https://github.com/multica-ai/multica.git
synced 2026-06-16 19:29:26 +02:00
Fix attachment download for self-hosted deployments using private S3-compatible buckets without CloudFront. Closes #3721. **Server** - New unified `GET /api/attachments/{id}/download` endpoint that picks CloudFront / S3 presign / server proxy at request time. - `ATTACHMENT_DOWNLOAD_MODE=auto|cloudfront|presign|proxy` and `ATTACHMENT_DOWNLOAD_URL_TTL` env knobs; `auto` routes Docker hostnames / localhost / private IPs through the proxy and public S3 endpoints through presign. - `Storage.PresignGet` capability; S3 implementation generates presigned GET URLs. - `attachmentToResponse` returns the unified relative endpoint instead of leaking raw unsigned S3 URLs when CloudFront is not configured. Proxy path streams via `io.Copy` with `Content-Disposition` / `Content-Length` / `Cache-Control: no-store` / `X-Content-Type-Options: nosniff`. **Clients** - CLI / Desktop / Mobile resolve relative `download_url` values against the configured API base. Desktop covers the Electron native download bridge and the media preview modal; Mobile covers `Linking.openURL`, the markdown image RN loader, and the composer's completed non-image file chip. - Mobile gains a minimal Node-environment vitest lane wired into `mobile-verify.yml`. **Docs** - `.env.example`, `docker-compose.selfhost.yml`, `SELF_HOSTING_ADVANCED.md`, and the `environment-variables` doc set updated with the new env keys and the `ATTACHMENT_DOWNLOAD_MODE=proxy` recommendation for Docker / VPC-internal object stores. **Tests** - `internal/storage`, `internal/cli`, `internal/handler` (download endpoint, mode selection, proxy header, `/content` non-regression), `cmd/server` (trusted proxy parser). - `packages/views/editor/use-download-attachment.test.tsx` and `attachment-preview-modal.test.tsx` exercise relative URL resolution + absolute pass-through. - `apps/mobile/lib/attachment-url.test.ts` covers every helper branch plus the composer non-image chip case.
20 lines
737 B
TypeScript
20 lines
737 B
TypeScript
import { defineConfig } from "vitest/config";
|
|
|
|
// Mobile vitest is intentionally minimal — Node environment only, scoped to
|
|
// pure-function tests in `lib/`. We don't ship jsdom or RN test renderers
|
|
// here because the app runs on Hermes / native shims and any DOM-shaped
|
|
// runner would be a lie. Tests that need RN component rendering would
|
|
// need a separate jest+react-native-testing-library track; for now we
|
|
// keep this lane for helpers and serializers only.
|
|
//
|
|
// Co-located test files (foo.ts + foo.test.ts) match how the rest of the
|
|
// monorepo organises vitest suites.
|
|
export default defineConfig({
|
|
test: {
|
|
environment: "node",
|
|
globals: true,
|
|
include: ["lib/**/*.test.ts"],
|
|
passWithNoTests: true,
|
|
},
|
|
});
|