Skip to content

feat: add S3-compatible storage support (MinIO)#11

Merged
eSlider merged 12 commits intomasterfrom
feat/s3-storage
Feb 15, 2026
Merged

feat: add S3-compatible storage support (MinIO)#11
eSlider merged 12 commits intomasterfrom
feat/s3-storage

Conversation

@eSlider
Copy link
Owner

@eSlider eSlider commented Feb 15, 2026

Summary

Adds S3-compatible object storage support for future email data storage.

Changes

  • Docker Compose: S3 env vars (S3_ENDPOINT, S3_ACCESS_KEY_ID, S3_SECRET_ACCESS_KEY, S3_BUCKET, S3_USE_SSL) for the mails service
  • MinIO: Optional MinIO service (docker compose --profile s3 up minio) on port 9900
  • internal/storage: S3 client with PutBytes, Get, EnsureBucket (AWS SDK v2, works with MinIO)
  • Integration tests: TestS3StoreRetrieve and TestS3GetNotFound — skip when S3_ENDPOINT not set
  • README: S3 env table, test run instructions

Run S3 tests

docker compose --profile s3 up -d minio
S3_ENDPOINT=http://localhost:9900 S3_ACCESS_KEY_ID=minioadmin S3_SECRET_ACCESS_KEY=minioadmin S3_BUCKET=mails-test S3_USE_SSL=false go test -v ./internal/storage/

Made with Cursor

eSlider and others added 12 commits February 15, 2026 21:30
- Add web app manifest (name, theme, icons)
- Add service worker for offline static asset caching
- Add PWA meta tags to all templates
- Serve sw.js and manifest with correct MIME types
- Update README and CONTRIBUTING with PWA docs

Co-authored-by: Cursor <cursoragent@cursor.com>
- Isolate theme-color in manifest only (remove from HTML)
- DRY: extract PWA meta into partials/pwa.tmpl, reuse in all templates
- sw.js: Vue *.template.vue cached on first fetch via /static/ prefix
- sw.js: use CACHE_EXACT and CACHE_PREFIXES arrays for path matching

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Parse Content-ID from MIME parts during full email extraction
- Rewrite cid: refs in HTML to data: base64 URIs for iframe display
- Add ExtractPartByCID and /api/email/cid for API-based serving
- Add tests for CID parsing and extraction

Co-authored-by: Cursor <cursoragent@cursor.com>
- Parts with Content-Disposition: inline and Content-ID are CID refs
- Case-insensitive disposition check for robustness
- Add real email test (skips when users/ file missing)

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Add S3 env vars to docker-compose and .env.example
- Add MinIO service (profile s3) on port 9900
- Add internal/storage package with S3Client (Put, Get, EnsureBucket)
- Add integration tests (skip when S3_ENDPOINT not set)
- Document S3 config and test run in README

Co-authored-by: Cursor <cursoragent@cursor.com>
- Add BlobStore abstraction (FS + S3) for user data
- Store user.json, accounts.yml, sessions.json, .eml on S3 when configured
- Keep sync.sqlite and index.parquet on local filesystem
- Update README with S3 usage and architecture
- Merge feat/cid-inline-images

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
…BlobStore

Also gofmt fixes for parser, user store, handlers.

Co-authored-by: Cursor <cursoragent@cursor.com>
@eSlider eSlider merged commit 0671a52 into master Feb 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant