# Simple Mail Cleaner State-of-the-art mail cleanup tool with multi-tenant support, newsletter unsubscribe automation, and a modern web UI. ## Stack - Backend: Node.js + TypeScript + Fastify - Frontend: React + Vite + TypeScript + i18n - DB: PostgreSQL - Queue: Redis + BullMQ worker Node.js: - Docker images use Node.js 24.13.0 (LTS) ## Quick start ```bash docker compose up --build ``` - Web UI: `http://localhost:${WEB_PORT}` (see root `.env`) - API: `http://localhost:${API_PORT}` - API Docs: `http://localhost:${API_PORT}/docs` ## API (initial) - `POST /auth/register` `{ tenantName, email, password }` - `POST /auth/login` `{ email, password }` - `GET /tenants/me` (auth) - `GET /mail/accounts` (auth) - `POST /mail/accounts` (auth) - `POST /mail/cleanup` (auth) `{ mailboxAccountId, dryRun, unsubscribeEnabled, routingEnabled }` - `GET /jobs` (auth) - `GET /jobs/:id/events` (auth) - `GET /jobs/:id/stream?token=...` (auth via query token, SSE) - `GET /rules` (auth) - `POST /rules` (auth) - `PUT /rules/:id` (auth) - `DELETE /rules/:id` (auth) - `GET /admin/tenants` (admin) - `PUT /admin/tenants/:id` (admin) - `GET /admin/users` (admin) - `PUT /admin/users/:id` (admin) - `PUT /admin/users/:id/role` (admin) - `POST /admin/users/:id/reset` (admin) - `GET /admin/accounts` (admin) - `PUT /admin/accounts/:id` (admin) - `GET /admin/jobs` (admin) - `GET /admin/jobs/:id/events` (admin) - `POST /admin/jobs/:id/cancel` (admin) - `POST /admin/jobs/:id/retry` (admin) - `POST /admin/impersonate/:userId` (admin) - `GET /admin/tenants/:id/export` (admin) - `GET /admin/tenants/:id/export?scope=users|accounts|jobs|rules&format=csv|zip` (admin, zip returns jobId) - `GET /admin/exports` (admin) - `GET /admin/exports/:id` (admin) - `GET /admin/exports/:id/download` (admin) - `POST /admin/exports/purge` (admin) - `DELETE /admin/exports/:id` (admin) - `GET /jobs/exports/:id/stream` (auth, SSE) Export queue: - ZIP exports are queued via Redis/BullMQ and processed by the worker container. - `DELETE /admin/tenants/:id` (admin) OAuth: - `POST /oauth/gmail/url` (auth) - `GET /oauth/gmail/callback` (Google redirect) - `GET /oauth/gmail/status/:accountId` (auth) - `GET /oauth/gmail/ping/:accountId` (auth) UI: - Admin panel supports password reset, job cancel/retry, tenant export/delete, and impersonation. ## Notes - Newsletter detection will use `List-Unsubscribe` headers + heuristics. - Weblink unsubscribe uses HTTP first, mailto fallback (SMTP required). - Worker scans headers and applies routing rules (MOVE/DELETE) when not in dry run. ## Seed data ```bash cd backend DATABASE_URL=postgresql://mailcleaner:mailcleaner@localhost:5432/mailcleaner \\ SEED_ADMIN_EMAIL=admin@simplemailcleaner.local \\ SEED_ADMIN_PASSWORD=change-me-now \\ SEED_TENANT=Default Tenant \\ SEED_TENANT_ID=seed-tenant \\ npm run prisma:seed ``` - DSGVO: data storage is designed for tenant isolation; encryption at rest will be added. ## Environment All config lives in the repo root `.env` (see `.env.example`). Export settings: - `EXPORT_DIR` (default `/tmp/mailcleaner-exports`) - `EXPORT_TTL_HOURS` (default `24`) Proxy settings (Nginx Proxy Manager): - `TRUST_PROXY=true` - `VITE_API_URL=https://your-domain.tld` - `GOOGLE_REDIRECT_URI=https://your-domain.tld/oauth/gmail/callback` Local ports (override via `.env` in repo root): - `API_PORT` (default `8000`, now set to `8201` in `.env`) - `WEB_PORT` (default `3000`, now set to `3201` in `.env`)