feat: rename project to InboxConverge with configurable contact details

Agent-Logs-Url: https://github.com/christianlouis/pop_puller_to_gmail/sessions/82f2f361-3513-44e6-991b-db1a19902772

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-03-26 18:06:46 +00:00
parent eba086fff0
commit 92d67369e9
46 changed files with 226 additions and 192 deletions
+6 -1
View File
@@ -14,7 +14,7 @@ POP3_ACCOUNT_1_USE_SSL=true
# POP3_ACCOUNT_2_USE_SSL=true # POP3_ACCOUNT_2_USE_SSL=true
# ── Bootstrap Settings (always from env, never from database) ────── # ── Bootstrap Settings (always from env, never from database) ──────
# DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/pop3_forwarder # DATABASE_URL=postgresql+asyncpg://user:password@localhost:5432/inbox_converge
# SECRET_KEY=<generate with: python -c 'import secrets; print(secrets.token_urlsafe(32))'> # SECRET_KEY=<generate with: python -c 'import secrets; print(secrets.token_urlsafe(32))'>
# ENCRYPTION_KEY=<generate with: python -c 'import secrets; print(secrets.token_urlsafe(32))'> # ENCRYPTION_KEY=<generate with: python -c 'import secrets; print(secrets.token_urlsafe(32))'>
@@ -41,5 +41,10 @@ MAX_EMAILS_PER_RUN=50
# Throttling (emails per minute) # Throttling (emails per minute)
THROTTLE_EMAILS_PER_MINUTE=10 THROTTLE_EMAILS_PER_MINUTE=10
# Application identity (used by frontend server components at runtime)
APP_NAME=InboxConverge
APP_URL=https://inboxconverge.com
CONTACT_EMAIL=christian@inboxconverge.com
# Logging # Logging
LOG_LEVEL=INFO LOG_LEVEL=INFO
+1 -1
View File
@@ -21,7 +21,7 @@ assignees: ''
<!-- What actually happened --> <!-- What actually happened -->
## Environment ## Environment
- **Component**: [e.g., Backend API, Worker, Docker, pop3_forwarder.py] - **Component**: [e.g., Backend API, Worker, Docker, inbox_converge.py]
- **Version**: [e.g., v1.0.0, main branch] - **Version**: [e.g., v1.0.0, main branch]
- **Deployment**: [e.g., Docker, Kubernetes, local] - **Deployment**: [e.g., Docker, Kubernetes, local]
- **OS**: [e.g., Ubuntu 22.04, macOS, Windows] - **OS**: [e.g., Ubuntu 22.04, macOS, Windows]
+4 -4
View File
@@ -77,7 +77,7 @@ jobs:
env: env:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres POSTGRES_PASSWORD: postgres
POSTGRES_DB: pop3_forwarder_test POSTGRES_DB: inbox_converge_test
options: >- options: >-
--health-cmd pg_isready --health-cmd pg_isready
--health-interval 10s --health-interval 10s
@@ -113,7 +113,7 @@ jobs:
- name: Run tests with coverage - name: Run tests with coverage
env: env:
DATABASE_URL: postgresql+asyncpg://postgres:postgres@localhost:5432/pop3_forwarder_test DATABASE_URL: postgresql+asyncpg://postgres:postgres@localhost:5432/inbox_converge_test
REDIS_URL: redis://localhost:6379/0 REDIS_URL: redis://localhost:6379/0
SECRET_KEY: test-secret-key-for-ci-cd-at-least-32-chars SECRET_KEY: test-secret-key-for-ci-cd-at-least-32-chars
ENCRYPTION_KEY: test-encryption-key-for-ci-cd-at-least-32-chars ENCRYPTION_KEY: test-encryption-key-for-ci-cd-at-least-32-chars
@@ -173,9 +173,9 @@ jobs:
matrix: matrix:
include: include:
- context: ./backend - context: ./backend
image_name: gmail-puller/backend image_name: inboxconverge/backend
- context: ./frontend - context: ./frontend
image_name: gmail-puller/frontend image_name: inboxconverge/frontend
steps: steps:
- name: Checkout repository - name: Checkout repository
+2 -2
View File
@@ -33,7 +33,7 @@ repos:
- id: black - id: black
language_version: python3.11 language_version: python3.11
args: [--line-length=100] args: [--line-length=100]
files: ^(backend/|pop3_forwarder\.py) files: ^(backend/|inboxconverge\.py)
# Python linting with Ruff (replaces flake8, isort, etc.) # Python linting with Ruff (replaces flake8, isort, etc.)
- repo: https://github.com/astral-sh/ruff-pre-commit - repo: https://github.com/astral-sh/ruff-pre-commit
@@ -41,7 +41,7 @@ repos:
hooks: hooks:
- id: ruff - id: ruff
args: [--fix, --exit-non-zero-on-fix] args: [--fix, --exit-non-zero-on-fix]
files: ^(backend/|pop3_forwarder\.py) files: ^(backend/|inboxconverge\.py)
# Type checking with mypy # Type checking with mypy
- repo: https://github.com/pre-commit/mirrors-mypy - repo: https://github.com/pre-commit/mirrors-mypy
+16 -5
View File
@@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Changed
- **Project renamed to InboxConverge**: All user-visible strings, Docker container names, database defaults, Docker image paths, monitoring job names, Grafana dashboard titles, and documentation updated from the legacy names (`POP3 to Gmail Forwarder`, `InboxRescue`, `gmail-puller`, `pop3_forwarder`, etc.) to **InboxConverge** / `inboxconverge`.
- **Domain updated to `inboxconverge.com`**: All contact and administrative email addresses now default to `@inboxconverge.com` (e.g. `christian@inboxconverge.com`).
- **Configurable contact details**: Two new environment variables make contact information overridable at deployment time:
- `CONTACT_EMAIL` (default: `christian@inboxconverge.com`) — used by the frontend legal pages (Impressum, Datenschutz) and surfaced in the backend `Settings`.
- `APP_URL` (default: `https://inboxconverge.com`) — the canonical public URL of the deployment.
- `NEXT_PUBLIC_APP_NAME` (default: `InboxConverge`) — the application name shown in frontend legal-page titles; readable by Next.js server components at runtime.
- **Legacy script renamed**: `pop3_forwarder.py``inboxconverge.py`; root `Dockerfile` and `Makefile` updated accordingly.
- **Grafana dashboard file renamed**: `monitoring/grafana/dashboards/inboxrescue.json``inboxconverge.json`.
- **Note on encryption salt**: The internal PBKDF2 salt `b"pop3_forwarder_0"` in `backend/app/core/security.py` is intentionally **not** renamed — changing it would invalidate all existing encrypted credentials stored in the database.
### Added ### Added
- **Prometheus metrics** (`/metrics` endpoint on the FastAPI backend, scraped every 15 s): - **Prometheus metrics** (`/metrics` endpoint on the FastAPI backend, scraped every 15 s):
- **HTTP layer** — `http_requests_total` (counter, labelled `method`/`endpoint`/`status_code`) and `http_request_duration_seconds` (histogram). Path segments that are numeric IDs are normalised to `{id}` to avoid label-set explosion. - **HTTP layer** — `http_requests_total` (counter, labelled `method`/`endpoint`/`status_code`) and `http_request_duration_seconds` (histogram). Path segments that are numeric IDs are normalised to `{id}` to avoid label-set explosion.
@@ -17,14 +28,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **All metrics** defined as module-level singletons in `backend/app/core/metrics.py` (imported by HTTP middleware, task workers, GmailService, and auth endpoints). - **All metrics** defined as module-level singletons in `backend/app/core/metrics.py` (imported by HTTP middleware, task workers, GmailService, and auth endpoints).
- **Prometheus service** added to `docker-compose.new.yml` (port 9090, 30-day retention, config from `monitoring/prometheus.yml`). - **Prometheus service** added to `docker-compose.new.yml` (port 9090, 30-day retention, config from `monitoring/prometheus.yml`).
- **Grafana service** added to `docker-compose.new.yml` (port 3001, auto-provisioned datasource + pre-built dashboard). Default credentials: `admin` / `admin`. - **Grafana service** added to `docker-compose.new.yml` (port 3001, auto-provisioned datasource + pre-built dashboard). Default credentials: `admin` / `admin`.
- **Pre-built Grafana dashboard** (`monitoring/grafana/dashboards/inboxrescue.json`) with five sections: Mail Processing, Gmail API, Authentication & OAuth, HTTP API, and Celery Workers. Dashboard auto-refreshes every 30 s. - **Pre-built Grafana dashboard** (`monitoring/grafana/dashboards/inboxconverge.json`) with five sections: Mail Processing, Gmail API, Authentication & OAuth, HTTP API, and Celery Workers. Dashboard auto-refreshes every 30 s.
- **Admin interface**: Superusers now have access to a dedicated Admin section in the sidebar with three pages: - **Admin interface**: Superusers now have access to a dedicated Admin section in the sidebar with three pages:
- **Admin Overview** (`/admin`): System-wide stats (total users, mail accounts, processing runs). - **Admin Overview** (`/admin`): System-wide stats (total users, mail accounts, processing runs).
- **Manage Users** (`/admin/users`): Table of all registered users with their subscription tier, status, mail account count, and last login. Admins can edit any user's name, email, plan, active status, and promote/demote admin (superuser) privileges. Users can be deleted (with confirmation). - **Manage Users** (`/admin/users`): Table of all registered users with their subscription tier, status, mail account count, and last login. Admins can edit any user's name, email, plan, active status, and promote/demote admin (superuser) privileges. Users can be deleted (with confirmation).
- **Manage Plans** (`/admin/plans`): Full CRUD for subscription plans—create, edit, and delete plans with fields for tier, name, pricing, max mailboxes, max emails/day, check interval, and support level. - **Manage Plans** (`/admin/plans`): Full CRUD for subscription plans—create, edit, and delete plans with fields for tier, name, pricing, max mailboxes, max emails/day, check interval, and support level.
- **Auto-promotion of admin email**: When the user whose email matches the `ADMIN_EMAIL` environment variable logs in or registers (via email/password or Google OAuth), they are automatically promoted to superuser. Default value is `christianlouis@gmail.com` (configurable via the `ADMIN_EMAIL` env var). - **Auto-promotion of admin email**: When the user whose email matches the `ADMIN_EMAIL` environment variable logs in or registers (via email/password or Google OAuth), they are automatically promoted to superuser. Default value is `christian@inboxconverge.com` (configurable via the `ADMIN_EMAIL` env var).
- **`is_superuser` field in API responses**: `GET /users/me` and all admin user endpoints now include `is_superuser` so the frontend can conditionally show admin UI. - **`is_superuser` field in API responses**: `GET /users/me` and all admin user endpoints now include `is_superuser` so the frontend can conditionally show admin UI.
- **New admin API endpoints** (all require superuser role): - **New admin API endpoints** (all require superuser role):
- `GET /admin/users` List all users with mail account counts. - `GET /admin/users` List all users with mail account counts.
@@ -39,7 +50,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- **`DEFAULT_USER_TIER` env var**: Controls the subscription tier assigned to every new user on registration. Defaults to `free`. Set to `enterprise` (or any other tier) for B2B / Google Workspace installations where all employees should start on a zero-rate plan. - **`DEFAULT_USER_TIER` env var**: Controls the subscription tier assigned to every new user on registration. Defaults to `free`. Set to `enterprise` (or any other tier) for B2B / Google Workspace installations where all employees should start on a zero-rate plan.
- **`ALLOWED_DOMAINS` env var**: Comma-separated list of permitted email domains (e.g. `company.com,subsidiary.com`). When set, only addresses from those domains may register or log in. Superusers always bypass this check. Empty (default) = no restriction (normal B2C mode). - **`ALLOWED_DOMAINS` env var**: Comma-separated list of permitted email domains (e.g. `company.com,subsidiary.com`). When set, only addresses from those domains may register or log in. Superusers always bypass this check. Empty (default) = no restriction (normal B2C mode).
- **Dynamic pricing section on landing page**: The home page now fetches `GET /subscriptions/plans` and renders a pricing section only when paid plans exist. In enterprise / all-zero-rate deployments the pricing section is silently hidden — the page just shows features and a "Get started free" CTA. - **Dynamic pricing section on landing page**: The home page now fetches `GET /subscriptions/plans` and renders a pricing section only when paid plans exist. In enterprise / all-zero-rate deployments the pricing section is silently hidden — the page just shows features and a "Get started free" CTA.
- **B2C copy and branding**: App renamed to **InboxRescue** throughout (was "POP3 Forwarder SaaS"). Landing page hero, feature cards, how-it-works, and footer rewritten in a personal, consumer-friendly tone. Pricing updated to €0.99 / €1.99 / €2.99 per month for Good / Better / Best plans. - **B2C copy and branding**: App renamed to **InboxConverge** throughout (was "InboxConverge"). Landing page hero, feature cards, how-it-works, and footer rewritten in a personal, consumer-friendly tone. Pricing updated to €0.99 / €1.99 / €2.99 per month for Good / Better / Best plans.
### Fixed ### Fixed
- Test email sender name corrected from "Christian Loris" to "Christian Krakau-Louis". - Test email sender name corrected from "Christian Loris" to "Christian Krakau-Louis".
@@ -52,7 +63,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Fixed ### Fixed
- Fixed `TypeError: can't subtract offset-naive and offset-aware datetimes` in `process_mail_account` task when computing `duration_seconds`. After a database refresh, `started_at` may be returned as a naive datetime; it is now normalized to UTC before subtraction. - Fixed `TypeError: can't subtract offset-naive and offset-aware datetimes` in `process_mail_account` task when computing `duration_seconds`. After a database refresh, `started_at` may be returned as a naive datetime; it is now normalized to UTC before subtraction.
- **Admin user not seeing admin dashboard**: Added startup auto-promotion in `main.py` lifespan handler — on every application start, if the user matching `ADMIN_EMAIL` exists in the database but does not yet have `is_superuser=True`, they are promoted immediately. This fixes accounts created before the auto-promotion-on-login code was deployed (e.g. `christianlouis@gmail.com` was logged in but saw no admin section). - **Admin user not seeing admin dashboard**: Added startup auto-promotion in `main.py` lifespan handler — on every application start, if the user matching `ADMIN_EMAIL` exists in the database but does not yet have `is_superuser=True`, they are promoted immediately. This fixes accounts created before the auto-promotion-on-login code was deployed (e.g. `christian@inboxconverge.com` was logged in but saw no admin section).
- **Blank page on direct navigation to `/admin`, `/admin/users`, `/admin/plans`**: All three admin pages had `if (!user?.is_superuser) return null` before the `<AuthGuard>` was ever rendered. On a direct page load or refresh the Zustand store initialises with `user = null`, so the guard fired immediately and returned an empty render — `AuthGuard` was never mounted, its `checkAuth` effect never ran, and the user data was never fetched. Fixed by removing the early return and moving the superuser guard inside the `<AuthGuard>/<DashboardLayout>` tree, so authentication always runs first. - **Blank page on direct navigation to `/admin`, `/admin/users`, `/admin/plans`**: All three admin pages had `if (!user?.is_superuser) return null` before the `<AuthGuard>` was ever rendered. On a direct page load or refresh the Zustand store initialises with `user = null`, so the guard fired immediately and returned an empty render — `AuthGuard` was never mounted, its `checkAuth` effect never ran, and the user data was never fetched. Fixed by removing the early return and moving the superuser guard inside the `<AuthGuard>/<DashboardLayout>` tree, so authentication always runs first.
### Security ### Security
@@ -212,7 +223,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [0.1.0] - 2025-12-15 (Legacy Version) ## [0.1.0] - 2025-12-15 (Legacy Version)
### Added ### Added
- Initial release of single-user pop3_forwarder.py script - Initial release of single-user inbox_converge.py script
- Docker support with docker-compose - Docker support with docker-compose
- Multiple POP3 account support - Multiple POP3 account support
- Gmail forwarding via SMTP - Gmail forwarding via SMTP
+5 -5
View File
@@ -1,4 +1,4 @@
# Contributing to POP3 to Gmail Forwarder # Contributing to InboxConverge
Thank you for your interest in contributing! This document provides guidelines for contributing to the project. Thank you for your interest in contributing! This document provides guidelines for contributing to the project.
@@ -10,7 +10,7 @@ Be respectful and inclusive. We welcome contributions from everyone.
### Reporting Bugs ### Reporting Bugs
1. Check if the bug has already been reported in [Issues](https://github.com/christianlouis/pop_puller_to_gmail/issues) 1. Check if the bug has already been reported in [Issues](https://github.com/christianlouis/inboxconverge/issues)
2. If not, create a new issue with: 2. If not, create a new issue with:
- Clear title and description - Clear title and description
- Steps to reproduce - Steps to reproduce
@@ -77,8 +77,8 @@ Be respectful and inclusive. We welcome contributions from everyone.
```bash ```bash
# Clone your fork # Clone your fork
git clone https://github.com/YOUR-USERNAME/pop_puller_to_gmail.git git clone https://github.com/YOUR-USERNAME/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
# Install all development dependencies # Install all development dependencies
make install-dev make install-dev
@@ -88,7 +88,7 @@ cp .env.example .env
# Edit .env with test credentials # Edit .env with test credentials
# Run the legacy forwarder script directly # Run the legacy forwarder script directly
python pop3_forwarder.py python inbox_converge.py
# Or start the SaaS backend in dev mode # Or start the SaaS backend in dev mode
make run-dev make run-dev
+5 -5
View File
@@ -8,13 +8,13 @@ COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt RUN pip install --no-cache-dir -r requirements.txt
# Copy application code # Copy application code
COPY pop3_forwarder.py . COPY inboxconverge.py .
# Create non-root user for security # Create non-root user for security
RUN useradd -m -u 1000 forwarder && \ RUN useradd -m -u 1000 inboxconverge && \
chown -R forwarder:forwarder /app chown -R inboxconverge:inboxconverge /app
USER forwarder USER inboxconverge
# Run the application # Run the application
CMD ["python", "-u", "pop3_forwarder.py"] CMD ["python", "-u", "inboxconverge.py"]
+3 -3
View File
@@ -120,12 +120,12 @@ run-beat: ## Run Celery beat scheduler
run-flower: ## Run Flower (Celery monitoring) run-flower: ## Run Flower (Celery monitoring)
cd backend && celery -A app.core.celery_app flower --port=5555 cd backend && celery -A app.core.celery_app flower --port=5555
run-legacy: ## Run legacy pop3_forwarder script run-legacy: ## Run legacy inboxconverge script
python pop3_forwarder.py python inboxconverge.py
# Database Shell # Database Shell
shell: ## Open database shell shell: ## Open database shell
docker-compose exec db psql -U postgres -d pop3_forwarder docker-compose exec db psql -U postgres -d inbox_converge
shell-python: ## Open Python shell with app context shell-python: ## Open Python shell with app context
cd backend && python -c "from app.core.database import SessionLocal; db = SessionLocal(); print('Database session available as db')" cd backend && python -c "from app.core.database import SessionLocal; db = SessionLocal(); print('Database session available as db')"
+11 -11
View File
@@ -1,9 +1,9 @@
# POP3 to Gmail Forwarder # InboxConverge
[![CI Tests](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/test.yml/badge.svg)](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/test.yml) [![CI Tests](https://github.com/christianlouis/inboxconverge/actions/workflows/test.yml/badge.svg)](https://github.com/christianlouis/inboxconverge/actions/workflows/test.yml)
[![Lint](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/lint.yml/badge.svg)](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/lint.yml) [![Lint](https://github.com/christianlouis/inboxconverge/actions/workflows/lint.yml/badge.svg)](https://github.com/christianlouis/inboxconverge/actions/workflows/lint.yml)
[![Security Scan](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/security.yml/badge.svg)](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/security.yml) [![Security Scan](https://github.com/christianlouis/inboxconverge/actions/workflows/security.yml/badge.svg)](https://github.com/christianlouis/inboxconverge/actions/workflows/security.yml)
[![Docker Build](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/docker-build.yml/badge.svg)](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/docker-build.yml) [![Docker Build](https://github.com/christianlouis/inboxconverge/actions/workflows/docker-build.yml/badge.svg)](https://github.com/christianlouis/inboxconverge/actions/workflows/docker-build.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/) [![Python 3.11+](https://img.shields.io/badge/python-3.11+-blue.svg)](https://www.python.org/downloads/)
[![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://www.docker.com/) [![Docker](https://img.shields.io/badge/docker-ready-blue.svg)](https://www.docker.com/)
@@ -31,8 +31,8 @@ The repository also includes a multi-tenant SaaS backend built with FastAPI, Pos
```bash ```bash
# Pull and configure # Pull and configure
curl -O https://raw.githubusercontent.com/christianlouis/pop_puller_to_gmail/main/docker-compose.yml curl -O https://raw.githubusercontent.com/christianlouis/inboxconverge/main/docker-compose.yml
curl -o .env https://raw.githubusercontent.com/christianlouis/pop_puller_to_gmail/main/.env.example curl -o .env https://raw.githubusercontent.com/christianlouis/inboxconverge/main/.env.example
# Edit .env with your credentials # Edit .env with your credentials
nano .env nano .env
@@ -44,8 +44,8 @@ docker-compose up -d
### Building from Source ### Building from Source
```bash ```bash
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
cp .env.example .env # then edit .env cp .env.example .env # then edit .env
docker-compose up -d docker-compose up -d
``` ```
@@ -257,5 +257,5 @@ This project is licensed under the MIT License — see [LICENSE](LICENSE) for de
## Support ## Support
- [Issue Tracker](https://github.com/christianlouis/pop_puller_to_gmail/issues) - [Issue Tracker](https://github.com/christianlouis/inboxconverge/issues)
- [Discussions](https://github.com/christianlouis/pop_puller_to_gmail/discussions) - [Discussions](https://github.com/christianlouis/inboxconverge/discussions)
+1 -1
View File
@@ -15,7 +15,7 @@
If you discover a security vulnerability, please report it responsibly: If you discover a security vulnerability, please report it responsibly:
1. **Email**: Send details to the repository maintainer via the email listed on the [GitHub profile](https://github.com/christianlouis). 1. **Email**: Send details to the repository maintainer via the email listed on the [GitHub profile](https://github.com/christianlouis).
2. **GitHub Private Vulnerability Reporting**: Use [GitHub's security advisory feature](https://github.com/christianlouis/pop_puller_to_gmail/security/advisories/new) to report privately. 2. **GitHub Private Vulnerability Reporting**: Use [GitHub's security advisory feature](https://github.com/christianlouis/inboxconverge/security/advisories/new) to report privately.
### What to Include ### What to Include
+5 -3
View File
@@ -1,5 +1,5 @@
# Database Configuration # Database Configuration
DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/pop3_forwarder DATABASE_URL=postgresql+asyncpg://postgres:password@localhost:5432/inbox_converge
# Security # Security
SECRET_KEY=change-this-to-a-secure-random-secret-key-minimum-32-characters SECRET_KEY=change-this-to-a-secure-random-secret-key-minimum-32-characters
@@ -41,12 +41,14 @@ CELERY_RESULT_BACKEND=redis://localhost:6379/0
LOG_LEVEL=INFO LOG_LEVEL=INFO
# Admin Account (created on first startup) # Admin Account (created on first startup)
ADMIN_EMAIL=admin@example.com ADMIN_EMAIL=christian@inboxconverge.com
ADMIN_PASSWORD=change-this-secure-password ADMIN_PASSWORD=change-this-secure-password
# Application # Application
APP_NAME=POP3 Forwarder SaaS APP_NAME=InboxConverge
APP_VERSION=2.0.0 APP_VERSION=2.0.0
APP_URL=https://inboxconverge.com
CONTACT_EMAIL=christian@inboxconverge.com
DEBUG=false DEBUG=false
HOST=0.0.0.0 HOST=0.0.0.0
PORT=8000 PORT=8000
+5 -3
View File
@@ -27,8 +27,10 @@ class Settings(BaseSettings):
) )
# Application # Application
APP_NAME: str = "InboxRescue" APP_NAME: str = "InboxConverge"
APP_VERSION: str = "2.0.0" APP_VERSION: str = "2.0.0"
APP_URL: str = "https://inboxconverge.com"
CONTACT_EMAIL: str = "christian@inboxconverge.com"
DEBUG: bool = False DEBUG: bool = False
API_V1_PREFIX: str = "/api/v1" API_V1_PREFIX: str = "/api/v1"
@@ -38,7 +40,7 @@ class Settings(BaseSettings):
# Database # Database
DATABASE_URL: str = ( DATABASE_URL: str = (
"postgresql+asyncpg://user:password@localhost:5432/pop3_forwarder" "postgresql+asyncpg://user:password@localhost:5432/inbox_converge"
) )
DATABASE_POOL_SIZE: int = 20 DATABASE_POOL_SIZE: int = 20
DATABASE_MAX_OVERFLOW: int = 10 DATABASE_MAX_OVERFLOW: int = 10
@@ -94,7 +96,7 @@ class Settings(BaseSettings):
LOG_LEVEL: str = "INFO" LOG_LEVEL: str = "INFO"
# Admin # Admin
ADMIN_EMAIL: Optional[str] = "christianlouis@gmail.com" ADMIN_EMAIL: Optional[str] = "christian@inboxconverge.com"
ADMIN_PASSWORD: Optional[str] = None ADMIN_PASSWORD: Optional[str] = None
# User defaults & access control # User defaults & access control
+1 -1
View File
@@ -1,5 +1,5 @@
""" """
Prometheus metrics definitions for InboxRescue. Prometheus metrics definitions for InboxConverge.
All application metrics are defined here as module-level singletons so that All application metrics are defined here as module-level singletons so that
every subsystem (HTTP layer, Celery workers, Gmail service, auth) imports every subsystem (HTTP layer, Celery workers, Gmail service, auth) imports
+1 -1
View File
@@ -148,7 +148,7 @@ def create_application() -> FastAPI:
async def root(): async def root():
"""Root endpoint""" """Root endpoint"""
return { return {
"message": "InboxRescue API", "message": "InboxConverge API",
"version": settings.APP_VERSION, "version": settings.APP_VERSION,
"docs": "/api/docs", "docs": "/api/docs",
} }
+1 -1
View File
@@ -12,7 +12,7 @@ logger = logging.getLogger(__name__)
# Create Celery app # Create Celery app
celery_app = Celery( celery_app = Celery(
"pop3_forwarder", "inboxconverge",
broker=settings.CELERY_BROKER_URL, broker=settings.CELERY_BROKER_URL,
backend=settings.CELERY_RESULT_BACKEND, backend=settings.CELERY_RESULT_BACKEND,
include=["app.workers.tasks"], include=["app.workers.tasks"],
+1 -1
View File
@@ -16,7 +16,7 @@ from app.core.security import get_password_hash, create_access_token
# Test database URL (use different database for tests) # Test database URL (use different database for tests)
TEST_DATABASE_URL = settings.DATABASE_URL.replace( TEST_DATABASE_URL = settings.DATABASE_URL.replace(
"/pop3_forwarder", "/pop3_forwarder_test" "/inbox_converge", "/inbox_converge_test"
) )
+1 -1
View File
@@ -89,7 +89,7 @@ class TestApplicationFactory:
async def test_app_title(self, app): async def test_app_title(self, app):
"""Test that app has correct title""" """Test that app has correct title"""
assert app.title == "InboxRescue" assert app.title == "InboxConverge"
async def test_app_version(self, app): async def test_app_version(self, app):
"""Test that app has a version""" """Test that app has a version"""
+12 -9
View File
@@ -4,11 +4,11 @@ services:
# PostgreSQL Database # PostgreSQL Database
postgres: postgres:
image: postgres:15-alpine image: postgres:15-alpine
container_name: pop3-postgres container_name: inboxconverge-postgres
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: password POSTGRES_PASSWORD: password
POSTGRES_DB: pop3_forwarder POSTGRES_DB: inbox_converge
ports: ports:
- "5432:5432" - "5432:5432"
volumes: volumes:
@@ -22,7 +22,7 @@ services:
# Redis for caching and Celery # Redis for caching and Celery
redis: redis:
image: redis:7-alpine image: redis:7-alpine
container_name: pop3-redis container_name: inboxconverge-redis
ports: ports:
- "6379:6379" - "6379:6379"
volumes: volumes:
@@ -38,7 +38,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-backend container_name: inboxconverge-backend
ports: ports:
- "8000:8000" - "8000:8000"
env_file: env_file:
@@ -58,7 +58,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-celery-worker container_name: inboxconverge-celery-worker
env_file: env_file:
- ./backend/.env - ./backend/.env
depends_on: depends_on:
@@ -75,7 +75,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-celery-beat container_name: inboxconverge-celery-beat
env_file: env_file:
- ./backend/.env - ./backend/.env
depends_on: depends_on:
@@ -92,11 +92,14 @@ services:
build: build:
context: ./frontend context: ./frontend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-frontend container_name: inboxconverge-frontend
ports: ports:
- "3000:3000" - "3000:3000"
environment: environment:
- BACKEND_URL=http://backend:8000 - BACKEND_URL=http://backend:8000
- CONTACT_EMAIL=christian@inboxconverge.com
- APP_URL=https://inboxconverge.com
- APP_NAME=InboxConverge
depends_on: depends_on:
- backend - backend
restart: unless-stopped restart: unless-stopped
@@ -104,7 +107,7 @@ services:
# Prometheus metrics collection # Prometheus metrics collection
prometheus: prometheus:
image: prom/prometheus:v2.51.2 image: prom/prometheus:v2.51.2
container_name: pop3-prometheus container_name: inboxconverge-prometheus
ports: ports:
- "9090:9090" - "9090:9090"
volumes: volumes:
@@ -122,7 +125,7 @@ services:
# Grafana dashboards # Grafana dashboards
grafana: grafana:
image: grafana/grafana:10.4.3 image: grafana/grafana:10.4.3
container_name: pop3-grafana container_name: inboxconverge-grafana
ports: ports:
- "3001:3000" - "3001:3000"
environment: environment:
+3 -3
View File
@@ -1,13 +1,13 @@
version: '3.8' version: '3.8'
services: services:
pop3-forwarder: inboxconverge:
# Option 1: Build from source (default) # Option 1: Build from source (default)
build: . build: .
# Option 2: Use pre-built image from GitHub Container Registry # Option 2: Use pre-built image from GitHub Container Registry
# Uncomment the line below and comment out 'build: .' to use pre-built image # Uncomment the line below and comment out 'build: .' to use pre-built image
# image: ghcr.io/christianlouis/pop_puller_to_gmail:latest # image: ghcr.io/christianlouis/inboxconverge:latest
container_name: pop3-gmail-forwarder container_name: inboxconverge
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env - .env
+8 -8
View File
@@ -1,4 +1,4 @@
# POP3 Forwarder SaaS - Multi-Tenant Architecture # InboxConverge - Multi-Tenant Architecture
This document describes the new multi-tenant SaaS architecture for the POP3/IMAP email forwarder. This document describes the new multi-tenant SaaS architecture for the POP3/IMAP email forwarder.
@@ -20,7 +20,7 @@ The project has been transformed from a single-user Docker application into a fu
## 📁 Project Structure ## 📁 Project Structure
``` ```
pop_puller_to_gmail/ inboxconverge/
├── backend/ # FastAPI backend application ├── backend/ # FastAPI backend application
│ ├── app/ │ ├── app/
│ │ ├── api/ # API endpoints │ │ ├── api/ # API endpoints
@@ -50,7 +50,7 @@ pop_puller_to_gmail/
│ └── .env.example # Environment template │ └── .env.example # Environment template
├── frontend/ # React/Next.js frontend (to be implemented) ├── frontend/ # React/Next.js frontend (to be implemented)
├── docker-compose.new.yml # Docker Compose for all services ├── docker-compose.new.yml # Docker Compose for all services
├── pop3_forwarder.py # Legacy single-user script ├── inbox_converge.py # Legacy single-user script
└── README.md # This file └── README.md # This file
``` ```
@@ -68,8 +68,8 @@ pop_puller_to_gmail/
1. **Clone and navigate to repository** 1. **Clone and navigate to repository**
```bash ```bash
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
``` ```
2. **Configure backend environment** 2. **Configure backend environment**
@@ -329,7 +329,7 @@ Coming soon: Kubernetes manifests and Helm charts.
## 🔄 Migration from Legacy Version ## 🔄 Migration from Legacy Version
To migrate from the single-user `pop3_forwarder.py`: To migrate from the single-user `inbox_converge.py`:
1. **Export existing configuration** from `.env` file 1. **Export existing configuration** from `.env` file
2. **Create user account** via API or admin panel 2. **Create user account** via API or admin panel
@@ -404,8 +404,8 @@ MIT License - See [LICENSE](../LICENSE) file
## 🆘 Support ## 🆘 Support
- **Issues**: https://github.com/christianlouis/pop_puller_to_gmail/issues - **Issues**: https://github.com/christianlouis/inboxconverge/issues
- **Discussions**: https://github.com/christianlouis/pop_puller_to_gmail/discussions - **Discussions**: https://github.com/christianlouis/inboxconverge/discussions
- **Email**: support@example.com - **Email**: support@example.com
## 🙏 Acknowledgments ## 🙏 Acknowledgments
+1 -1
View File
@@ -1,6 +1,6 @@
# Coding Patterns and Best Practices # Coding Patterns and Best Practices
This document outlines the coding patterns, conventions, and best practices for the POP3 to Gmail Forwarder project. This document outlines the coding patterns, conventions, and best practices for the InboxConverge project.
## Table of Contents ## Table of Contents
- [General Principles](#general-principles) - [General Principles](#general-principles)
+7 -7
View File
@@ -1,6 +1,6 @@
# Deployment Checklist and Next Steps # Deployment Checklist and Next Steps
This document provides a checklist for deploying the multi-tenant POP3 Forwarder with web interface. This document provides a checklist for deploying the multi-tenant InboxConverge with web interface.
## 🚀 Pre-Deployment Checklist ## 🚀 Pre-Deployment Checklist
@@ -48,7 +48,7 @@ This document provides a checklist for deploying the multi-tenant POP3 Forwarder
#### Database #### Database
- [ ] PostgreSQL 15+ instance running - [ ] PostgreSQL 15+ instance running
- [ ] Database created: `pop3_forwarder` - [ ] Database created: `inbox_converge`
- [ ] Connection details configured in backend/.env - [ ] Connection details configured in backend/.env
- [ ] Backups configured - [ ] Backups configured
@@ -89,8 +89,8 @@ sudo certbot --nginx -d yourdomain.com -d api.yourdomain.com
```bash ```bash
# On production server # On production server
cd /opt cd /opt
sudo git clone https://github.com/christianlouis/pop_puller_to_gmail.git sudo git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
``` ```
### Step 2: Configure Environment ### Step 2: Configure Environment
@@ -195,9 +195,9 @@ curl -X POST https://api.yourdomain.com/api/v1/auth/register \
# Automated daily backup script # Automated daily backup script
cat > /usr/local/bin/backup-pop3-db.sh << 'EOF' cat > /usr/local/bin/backup-pop3-db.sh << 'EOF'
#!/bin/bash #!/bin/bash
BACKUP_DIR=/var/backups/pop3_forwarder BACKUP_DIR=/var/backups/inbox_converge
DATE=$(date +%Y%m%d_%H%M%S) DATE=$(date +%Y%m%d_%H%M%S)
docker exec pop3-postgres pg_dump -U postgres pop3_forwarder | gzip > $BACKUP_DIR/backup_$DATE.sql.gz docker exec inboxconverge-postgres pg_dump -U postgres inbox_converge | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
find $BACKUP_DIR -type f -mtime +30 -delete find $BACKUP_DIR -type f -mtime +30 -delete
EOF EOF
@@ -394,4 +394,4 @@ Use this checklist after deployment:
## 🎉 Congratulations! ## 🎉 Congratulations!
If all checkboxes above are complete, your multi-tenant POP3 Forwarder with web interface is successfully deployed and ready to serve users! If all checkboxes above are complete, your multi-tenant InboxConverge with web interface is successfully deployed and ready to serve users!
+50 -50
View File
@@ -1,6 +1,6 @@
# Deployment Guide # Deployment Guide
This guide walks you through deploying **POP3 to Gmail Forwarder** from scratch — whether you just want a single container pulling emails, a full multi-service SaaS stack with Docker Compose, or a production-grade Kubernetes setup. This guide walks you through deploying **InboxConverge** from scratch — whether you just want a single container pulling emails, a full multi-service SaaS stack with Docker Compose, or a production-grade Kubernetes setup.
--- ---
@@ -52,13 +52,13 @@ You will also need:
## Option 1 — Legacy Single-Container Deployment ## Option 1 — Legacy Single-Container Deployment
The legacy mode runs a single Python script (`pop3_forwarder.py`) that polls POP3 mailboxes and forwards email via SMTP. No database, no web UI — just a container and an `.env` file. The legacy mode runs a single Python script (`inbox_converge.py`) that polls POP3 mailboxes and forwards email via SMTP. No database, no web UI — just a container and an `.env` file.
### 1. Create the environment file ### 1. Create the environment file
```bash ```bash
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
cp .env.example .env cp .env.example .env
``` ```
@@ -97,12 +97,12 @@ The repository ships `docker-compose.yml` for this mode. Here is the content for
version: "3.8" version: "3.8"
services: services:
pop3-forwarder: inbox-converge:
# Build from source # Build from source
build: . build: .
# Or use the pre-built image: # Or use the pre-built image:
# image: ghcr.io/christianlouis/pop_puller_to_gmail:latest # image: ghcr.io/christianlouis/inboxconverge:latest
container_name: pop3-gmail-forwarder container_name: inboxconverge
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- .env - .env
@@ -149,7 +149,7 @@ Save both values — you will need them below.
### 2. Create the backend environment file ### 2. Create the backend environment file
```bash ```bash
cd pop_puller_to_gmail cd inboxconverge
cp backend/.env.example backend/.env cp backend/.env.example backend/.env
``` ```
@@ -157,7 +157,7 @@ Edit `backend/.env`:
```ini ```ini
# ── Database ────────────────────────────────────────────── # ── Database ──────────────────────────────────────────────
DATABASE_URL=postgresql+asyncpg://postgres:change-me@postgres:5432/pop3_forwarder DATABASE_URL=postgresql+asyncpg://postgres:change-me@postgres:5432/inbox_converge
# ── Security (paste the values you generated above) ────── # ── Security (paste the values you generated above) ──────
SECRET_KEY=<your-64-char-hex-secret> SECRET_KEY=<your-64-char-hex-secret>
@@ -198,12 +198,12 @@ services:
# ── PostgreSQL ─────────────────────────────────────────── # ── PostgreSQL ───────────────────────────────────────────
postgres: postgres:
image: postgres:15-alpine image: postgres:15-alpine
container_name: pop3-postgres container_name: inboxconverge-postgres
restart: unless-stopped restart: unless-stopped
environment: environment:
POSTGRES_USER: postgres POSTGRES_USER: postgres
POSTGRES_PASSWORD: change-me # must match DATABASE_URL POSTGRES_PASSWORD: change-me # must match DATABASE_URL
POSTGRES_DB: pop3_forwarder POSTGRES_DB: inbox_converge
volumes: volumes:
- postgres_data:/var/lib/postgresql/data - postgres_data:/var/lib/postgresql/data
healthcheck: healthcheck:
@@ -219,7 +219,7 @@ services:
# ── Redis ──────────────────────────────────────────────── # ── Redis ────────────────────────────────────────────────
redis: redis:
image: redis:7-alpine image: redis:7-alpine
container_name: pop3-redis container_name: inboxconverge-redis
restart: unless-stopped restart: unless-stopped
command: redis-server --appendonly yes command: redis-server --appendonly yes
volumes: volumes:
@@ -235,7 +235,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-backend container_name: inboxconverge-backend
restart: unless-stopped restart: unless-stopped
ports: ports:
- "8000:8000" - "8000:8000"
@@ -260,7 +260,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-celery-worker container_name: inboxconverge-celery-worker
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- ./backend/.env - ./backend/.env
@@ -278,7 +278,7 @@ services:
build: build:
context: ./backend context: ./backend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-celery-beat container_name: inboxconverge-celery-beat
restart: unless-stopped restart: unless-stopped
env_file: env_file:
- ./backend/.env - ./backend/.env
@@ -296,7 +296,7 @@ services:
build: build:
context: ./frontend context: ./frontend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-frontend container_name: inboxconverge-frontend
restart: unless-stopped restart: unless-stopped
ports: ports:
- "3000:3000" - "3000:3000"
@@ -358,7 +358,7 @@ Below is a set of example Kubernetes manifests to get you started. Adapt namespa
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
metadata: metadata:
name: pop3-forwarder name: inbox-converge
``` ```
### Secrets ### Secrets
@@ -369,13 +369,13 @@ Store sensitive values in a Kubernetes Secret. In production, consider using an
apiVersion: v1 apiVersion: v1
kind: Secret kind: Secret
metadata: metadata:
name: pop3-forwarder-secrets name: inbox-converge-secrets
namespace: pop3-forwarder namespace: inbox-converge
type: Opaque type: Opaque
stringData: stringData:
SECRET_KEY: "<your-64-char-hex-secret>" SECRET_KEY: "<your-64-char-hex-secret>"
ENCRYPTION_KEY: "<your-64-char-hex-encryption-key>" ENCRYPTION_KEY: "<your-64-char-hex-encryption-key>"
DATABASE_URL: "postgresql+asyncpg://postgres:change-me@postgres:5432/pop3_forwarder" DATABASE_URL: "postgresql+asyncpg://postgres:change-me@postgres:5432/inbox_converge"
REDIS_URL: "redis://redis:6379/0" REDIS_URL: "redis://redis:6379/0"
CELERY_BROKER_URL: "redis://redis:6379/0" CELERY_BROKER_URL: "redis://redis:6379/0"
CELERY_RESULT_BACKEND: "redis://redis:6379/0" CELERY_RESULT_BACKEND: "redis://redis:6379/0"
@@ -396,7 +396,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: postgres name: postgres
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@@ -416,11 +416,11 @@ spec:
- name: POSTGRES_USER - name: POSTGRES_USER
value: postgres value: postgres
- name: POSTGRES_DB - name: POSTGRES_DB
value: pop3_forwarder value: inbox_converge
- name: POSTGRES_PASSWORD - name: POSTGRES_PASSWORD
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: pop3-forwarder-secrets name: inbox-converge-secrets
key: POSTGRES_PASSWORD key: POSTGRES_PASSWORD
volumeMounts: volumeMounts:
- name: pgdata - name: pgdata
@@ -439,7 +439,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: postgres name: postgres
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
selector: selector:
app: postgres app: postgres
@@ -451,7 +451,7 @@ apiVersion: v1
kind: PersistentVolumeClaim kind: PersistentVolumeClaim
metadata: metadata:
name: postgres-pvc name: postgres-pvc
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
accessModes: [ReadWriteOnce] accessModes: [ReadWriteOnce]
resources: resources:
@@ -466,7 +466,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: redis name: redis
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 1 replicas: 1
selector: selector:
@@ -493,7 +493,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: redis name: redis
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
selector: selector:
app: redis app: redis
@@ -509,7 +509,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: backend name: backend
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 2 replicas: 2
selector: selector:
@@ -522,22 +522,22 @@ spec:
spec: spec:
initContainers: initContainers:
- name: run-migrations - name: run-migrations
image: ghcr.io/christianlouis/pop_puller_to_gmail-backend:latest image: ghcr.io/christianlouis/inboxconverge-backend:latest
command: ["alembic", "upgrade", "head"] command: ["alembic", "upgrade", "head"]
envFrom: envFrom:
- secretRef: - secretRef:
name: pop3-forwarder-secrets name: inbox-converge-secrets
env: env:
- name: DEBUG - name: DEBUG
value: "false" value: "false"
containers: containers:
- name: backend - name: backend
image: ghcr.io/christianlouis/pop_puller_to_gmail-backend:latest image: ghcr.io/christianlouis/inboxconverge-backend:latest
ports: ports:
- containerPort: 8000 - containerPort: 8000
envFrom: envFrom:
- secretRef: - secretRef:
name: pop3-forwarder-secrets name: inbox-converge-secrets
env: env:
- name: HOST - name: HOST
value: "0.0.0.0" value: "0.0.0.0"
@@ -567,7 +567,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: backend name: backend
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
selector: selector:
app: backend app: backend
@@ -583,7 +583,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: celery-worker name: celery-worker
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 2 replicas: 2
selector: selector:
@@ -596,7 +596,7 @@ spec:
spec: spec:
containers: containers:
- name: worker - name: worker
image: ghcr.io/christianlouis/pop_puller_to_gmail-backend:latest image: ghcr.io/christianlouis/inboxconverge-backend:latest
command: command:
- celery - celery
- -A - -A
@@ -606,7 +606,7 @@ spec:
- --concurrency=2 - --concurrency=2
envFrom: envFrom:
- secretRef: - secretRef:
name: pop3-forwarder-secrets name: inbox-converge-secrets
resources: resources:
requests: requests:
cpu: 250m cpu: 250m
@@ -625,7 +625,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: celery-beat name: celery-beat
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 1 # Must be exactly 1 replicas: 1 # Must be exactly 1
strategy: strategy:
@@ -640,7 +640,7 @@ spec:
spec: spec:
containers: containers:
- name: beat - name: beat
image: ghcr.io/christianlouis/pop_puller_to_gmail-backend:latest image: ghcr.io/christianlouis/inboxconverge-backend:latest
command: command:
- celery - celery
- -A - -A
@@ -649,7 +649,7 @@ spec:
- --loglevel=info - --loglevel=info
envFrom: envFrom:
- secretRef: - secretRef:
name: pop3-forwarder-secrets name: inbox-converge-secrets
resources: resources:
requests: requests:
cpu: 100m cpu: 100m
@@ -666,7 +666,7 @@ apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
name: frontend name: frontend
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
replicas: 2 replicas: 2
selector: selector:
@@ -679,7 +679,7 @@ spec:
spec: spec:
containers: containers:
- name: frontend - name: frontend
image: ghcr.io/christianlouis/pop_puller_to_gmail-frontend:latest image: ghcr.io/christianlouis/inboxconverge-frontend:latest
ports: ports:
- containerPort: 3000 - containerPort: 3000
env: env:
@@ -697,7 +697,7 @@ apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: frontend name: frontend
namespace: pop3-forwarder namespace: inbox-converge
spec: spec:
selector: selector:
app: frontend app: frontend
@@ -714,8 +714,8 @@ The Ingress below assumes you have an Ingress controller installed (e.g., [ingre
apiVersion: networking.k8s.io/v1 apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: pop3-forwarder-ingress name: inbox-converge-ingress
namespace: pop3-forwarder namespace: inbox-converge
annotations: annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/proxy-body-size: "10m" nginx.ingress.kubernetes.io/proxy-body-size: "10m"
@@ -725,7 +725,7 @@ spec:
- hosts: - hosts:
- your-domain.com - your-domain.com
- api.your-domain.com - api.your-domain.com
secretName: pop3-forwarder-tls secretName: inbox-converge-tls
rules: rules:
- host: your-domain.com - host: your-domain.com
http: http:
@@ -754,7 +754,7 @@ spec:
If you manage many environments (staging, production, etc.) consider wrapping the manifests above into a Helm chart: If you manage many environments (staging, production, etc.) consider wrapping the manifests above into a Helm chart:
```text ```text
helm/pop3-forwarder/ helm/inbox-converge/
├── Chart.yaml ├── Chart.yaml
├── values.yaml # defaults for all environments ├── values.yaml # defaults for all environments
├── values-staging.yaml ├── values-staging.yaml
@@ -782,8 +782,8 @@ replicaCount:
frontend: 2 frontend: 2
image: image:
backend: ghcr.io/christianlouis/pop_puller_to_gmail-backend backend: ghcr.io/christianlouis/inboxconverge-backend
frontend: ghcr.io/christianlouis/pop_puller_to_gmail-frontend frontend: ghcr.io/christianlouis/inboxconverge-frontend
tag: latest tag: latest
ingress: ingress:
@@ -862,7 +862,7 @@ In production you should place a reverse proxy in front of the backend and front
### Example: nginx ### Example: nginx
```nginx ```nginx
# /etc/nginx/sites-available/pop3-forwarder # /etc/nginx/sites-available/inbox-converge
# Frontend # Frontend
server { server {
@@ -969,7 +969,7 @@ If you prefer Traefik, add it as a service in your Compose file and use labels o
## Upgrading ## Upgrading
```bash ```bash
cd pop_puller_to_gmail cd inboxconverge
# Pull latest code # Pull latest code
git pull origin main git pull origin main
+1 -1
View File
@@ -1,6 +1,6 @@
# Error Codes and Messages # Error Codes and Messages
This document catalogs all error codes used in the POP3 to Gmail Forwarder application. This document catalogs all error codes used in the InboxConverge application.
## Error Code Format ## Error Code Format
+3 -3
View File
@@ -2,7 +2,7 @@
## 🎯 Mission Accomplished ## 🎯 Mission Accomplished
This document summarizes the completion of the web interface and multitenancy features for the POP3 to Gmail Forwarder project. This document summarizes the completion of the web interface and multitenancy features for the InboxConverge project.
## 📦 What Was Delivered ## 📦 What Was Delivered
@@ -320,7 +320,7 @@ These are potential future improvements outside the current task:
### What Was Accomplished ### What Was Accomplished
**Complete implementation of web interface and multitenancy features** **Complete implementation of web interface and multitenancy features**
The POP3 to Gmail Forwarder now has: The InboxConverge now has:
- A modern, responsive web interface - A modern, responsive web interface
- Complete user authentication system - Complete user authentication system
- Full mail account management capabilities - Full mail account management capabilities
@@ -356,7 +356,7 @@ The implementation is **complete and ready for**:
## 👏 Thank You ## 👏 Thank You
This implementation represents a significant milestone in transforming the POP3 Forwarder from a simple script into a production-ready multi-tenant SaaS application. The web interface makes the service accessible to users of all technical levels, while maintaining the robust backend infrastructure. This implementation represents a significant milestone in transforming the InboxConverge from a simple script into a production-ready multi-tenant SaaS application. The web interface makes the service accessible to users of all technical levels, while maintaining the robust backend infrastructure.
**The multitenancy and web interface implementation is now complete and ready for deployment!** 🎉 **The multitenancy and web interface implementation is now complete and ready for deployment!** 🎉
+11 -11
View File
@@ -1,6 +1,6 @@
# Implementation Guide # Implementation Guide
This guide provides step-by-step instructions for setting up and deploying the multi-tenant POP3 Forwarder SaaS application. This guide provides step-by-step instructions for setting up and deploying the multi-tenant InboxConverge application.
## Table of Contents ## Table of Contents
@@ -36,8 +36,8 @@ This guide provides step-by-step instructions for setting up and deploying the m
```bash ```bash
# Clone repository # Clone repository
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
# Create backend environment file # Create backend environment file
cp backend/.env.example backend/.env cp backend/.env.example backend/.env
@@ -49,7 +49,7 @@ Edit `backend/.env` with your settings:
```bash ```bash
# Minimum required for development # Minimum required for development
DATABASE_URL=postgresql+asyncpg://postgres:password@postgres:5432/pop3_forwarder DATABASE_URL=postgresql+asyncpg://postgres:password@postgres:5432/inbox_converge
SECRET_KEY=$(openssl rand -hex 32) SECRET_KEY=$(openssl rand -hex 32)
ENCRYPTION_KEY=$(openssl rand -hex 32) ENCRYPTION_KEY=$(openssl rand -hex 32)
GOOGLE_CLIENT_ID=your-client-id GOOGLE_CLIENT_ID=your-client-id
@@ -176,7 +176,7 @@ ADMIN_EMAIL=admin@yourdomain.com
Use nginx or Traefik as reverse proxy: Use nginx or Traefik as reverse proxy:
```nginx ```nginx
# /etc/nginx/sites-available/pop3-forwarder # /etc/nginx/sites-available/inbox-converge
server { server {
listen 443 ssl http2; listen 443 ssl http2;
server_name api.yourdomain.com; server_name api.yourdomain.com;
@@ -202,7 +202,7 @@ cat > /etc/cron.daily/backup-postgres << 'EOF'
#!/bin/bash #!/bin/bash
BACKUP_DIR=/var/backups/postgres BACKUP_DIR=/var/backups/postgres
DATE=$(date +%Y%m%d_%H%M%S) DATE=$(date +%Y%m%d_%H%M%S)
docker exec pop3-postgres pg_dump -U postgres pop3_forwarder | gzip > $BACKUP_DIR/backup_$DATE.sql.gz docker exec inboxconverge-postgres pg_dump -U postgres inbox_converge | gzip > $BACKUP_DIR/backup_$DATE.sql.gz
find $BACKUP_DIR -type f -mtime +7 -delete # Keep 7 days find $BACKUP_DIR -type f -mtime +7 -delete # Keep 7 days
EOF EOF
@@ -348,10 +348,10 @@ docker-compose -f docker-compose.new.yml exec celery-worker celery -A app.worker
```bash ```bash
# Check connections # Check connections
docker exec pop3-postgres psql -U postgres -d pop3_forwarder -c "SELECT count(*) FROM pg_stat_activity;" docker exec inboxconverge-postgres psql -U postgres -d inbox_converge -c "SELECT count(*) FROM pg_stat_activity;"
# Check table sizes # Check table sizes
docker exec pop3-postgres psql -U postgres -d pop3_forwarder -c " docker exec inboxconverge-postgres psql -U postgres -d inbox_converge -c "
SELECT SELECT
schemaname, schemaname,
tablename, tablename,
@@ -376,7 +376,7 @@ docker-compose -f docker-compose.new.yml ps postgres
docker-compose -f docker-compose.new.yml logs postgres docker-compose -f docker-compose.new.yml logs postgres
# Test connection # Test connection
docker exec pop3-postgres psql -U postgres -c "SELECT version();" docker exec inboxconverge-postgres psql -U postgres -c "SELECT version();"
``` ```
#### Celery Worker Not Processing #### Celery Worker Not Processing
@@ -480,8 +480,8 @@ redis:
For additional help: For additional help:
- **Documentation**: See [ARCHITECTURE.md](ARCHITECTURE.md) - **Documentation**: See [ARCHITECTURE.md](ARCHITECTURE.md)
- **Issues**: https://github.com/christianlouis/pop_puller_to_gmail/issues - **Issues**: https://github.com/christianlouis/inboxconverge/issues
- **Discussions**: https://github.com/christianlouis/pop_puller_to_gmail/discussions - **Discussions**: https://github.com/christianlouis/inboxconverge/discussions
--- ---
+2 -2
View File
@@ -1,6 +1,6 @@
# Migration Guide: Single-User to Multi-Tenant SaaS # Migration Guide: Single-User to Multi-Tenant SaaS
This guide helps you migrate from the legacy single-user `pop3_forwarder.py` script to the new multi-tenant SaaS application. This guide helps you migrate from the legacy single-user `inbox_converge.py` script to the new multi-tenant SaaS application.
## Overview ## Overview
@@ -230,7 +230,7 @@ docker-compose -f docker-compose.yml down
# Archive old configuration # Archive old configuration
mkdir -p archive mkdir -p archive
mv pop3_forwarder.py archive/ mv inbox_converge.py archive/
mv .env.legacy.backup archive/ mv .env.legacy.backup archive/
mv docker-compose.yml archive/docker-compose.legacy.yml mv docker-compose.yml archive/docker-compose.legacy.yml
+10 -10
View File
@@ -1,6 +1,6 @@
# Quick Start Guide # Quick Start Guide
Get your POP3 to Gmail forwarder running in under 10 minutes! Get your InboxConverge instance running in under 10 minutes!
## Prerequisites ## Prerequisites
@@ -13,8 +13,8 @@ Get your POP3 to Gmail forwarder running in under 10 minutes!
### 1. Clone the Repository ### 1. Clone the Repository
```bash ```bash
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
``` ```
### 2. Generate Gmail App Password ### 2. Generate Gmail App Password
@@ -23,7 +23,7 @@ cd pop_puller_to_gmail
2. Sign in to your Google Account 2. Sign in to your Google Account
3. Select "App passwords" under Security 3. Select "App passwords" under Security
4. Choose "Mail" and "Other (Custom name)" 4. Choose "Mail" and "Other (Custom name)"
5. Enter "POP3 Forwarder" as the name 5. Enter "InboxConverge" as the name
6. Click "Generate" 6. Click "Generate"
7. **Copy the 16-character password** (you'll need this in step 3) 7. **Copy the 16-character password** (you'll need this in step 3)
@@ -66,10 +66,10 @@ docker-compose logs -f
You should see: You should see:
``` ```
pop3-gmail-forwarder | INFO - POP3 to Gmail Forwarder starting... inboxconverge | INFO - InboxConverge starting...
pop3-gmail-forwarder | INFO - Loaded POP3 account: ... inboxconverge | INFO - Loaded POP3 account: ...
pop3-gmail-forwarder | INFO - Configuration validated successfully inboxconverge | INFO - Configuration validated successfully
pop3-gmail-forwarder | INFO - Starting email processing cycle inboxconverge | INFO - Starting email processing cycle
``` ```
### 6. Test the Forwarder ### 6. Test the Forwarder
@@ -192,13 +192,13 @@ Restart after changes: `docker-compose restart`
## Need Help? ## Need Help?
- Open an issue: https://github.com/christianlouis/pop_puller_to_gmail/issues - Open an issue: https://github.com/christianlouis/inboxconverge/issues
- Check existing discussions - Check existing discussions
- Review troubleshooting section in README.md - Review troubleshooting section in README.md
## Success! 🎉 ## Success! 🎉
Your POP3 to Gmail forwarder is now running. Emails will be automatically forwarded every 5 minutes (or your configured interval). Your InboxConverge instance is now running. Emails will be automatically forwarded every 5 minutes (or your configured interval).
**Remember**: **Remember**:
- The forwarder deletes emails from POP3 after successful forwarding - The forwarder deletes emails from POP3 after successful forwarding
+4 -4
View File
@@ -39,8 +39,8 @@ This project has been **completely transformed** from a single-user Docker scrip
```bash ```bash
# Clone repository # Clone repository
git clone https://github.com/christianlouis/pop_puller_to_gmail.git git clone https://github.com/christianlouis/inboxconverge.git
cd pop_puller_to_gmail cd inboxconverge
# Configure environment # Configure environment
cp backend/.env.example backend/.env cp backend/.env.example backend/.env
@@ -330,8 +330,8 @@ MIT License - See [LICENSE](../LICENSE) file for details.
## 🆘 Support ## 🆘 Support
- **Documentation**: See docs in repository - **Documentation**: See docs in repository
- **Issues**: https://github.com/christianlouis/pop_puller_to_gmail/issues - **Issues**: https://github.com/christianlouis/inboxconverge/issues
- **Discussions**: https://github.com/christianlouis/pop_puller_to_gmail/discussions - **Discussions**: https://github.com/christianlouis/inboxconverge/discussions
- **Email**: support@example.com (for Enterprise customers) - **Email**: support@example.com (for Enterprise customers)
## 🎉 Acknowledgments ## 🎉 Acknowledgments
+1 -1
View File
@@ -1,7 +1,7 @@
# Roadmap # Roadmap
## Vision ## Vision
Create a robust, scalable, and user-friendly POP3 to Gmail forwarding solution that serves as a complete replacement for Gmail's discontinued POP3 import feature. Create a robust, scalable, and user-friendly InboxConverge email-forwarding solution that serves as a complete replacement for Gmail's discontinued POP3 import feature.
--- ---
+1 -1
View File
@@ -2,7 +2,7 @@
## Overview ## Overview
Security analysis completed on February 1, 2026 for the Multi-Tenant POP3 Forwarder SaaS application. Security analysis completed on February 1, 2026 for the Multi-Tenant InboxConverge application.
## CodeQL Security Scan ## CodeQL Security Scan
+1 -1
View File
@@ -25,7 +25,7 @@ This guide will help you test the complete multi-tenant web interface with the b
3. Edit the `.env` file and update the following critical values: 3. Edit the `.env` file and update the following critical values:
```bash ```bash
# Database - should point to Docker service # Database - should point to Docker service
DATABASE_URL=postgresql+asyncpg://postgres:password@postgres:5432/pop3_forwarder DATABASE_URL=postgresql+asyncpg://postgres:password@postgres:5432/inbox_converge
# Redis - should point to Docker service # Redis - should point to Docker service
REDIS_URL=redis://redis:6379/0 REDIS_URL=redis://redis:6379/0
+7 -1
View File
@@ -2,6 +2,12 @@
Comprehensive task breakdown for repository improvements and production readiness. Comprehensive task breakdown for repository improvements and production readiness.
## ✅ Recently Completed
- [x] Rename entire project to **InboxConverge**: all user-visible strings, Docker container/image names, DB defaults, monitoring, and docs updated.
- [x] Domain updated to `inboxconverge.com`; contact email defaults to `christian@inboxconverge.com`.
- [x] New configurable env vars: `CONTACT_EMAIL`, `APP_URL`, `NEXT_PUBLIC_APP_NAME`.
## 🔴 Critical - Security (In Progress) ## 🔴 Critical - Security (In Progress)
### Completed ✅ ### Completed ✅
@@ -245,7 +251,7 @@ because the API client layer is missing.
- [x] Admin overview page (`/admin`) with system-wide stats - [x] Admin overview page (`/admin`) with system-wide stats
- [x] User management page (`/admin/users`) — list, edit, delete users; assign plans; promote/demote admin - [x] User management page (`/admin/users`) — list, edit, delete users; assign plans; promote/demote admin
- [x] Plan management page (`/admin/plans`) — full CRUD for subscription plans (mailboxes, emails/day, interval, pricing) - [x] Plan management page (`/admin/plans`) — full CRUD for subscription plans (mailboxes, emails/day, interval, pricing)
- [x] `ADMIN_EMAIL` env var with default `christianlouis@gmail.com`; admin auto-promoted on login and on every application startup (fixes pre-existing accounts) - [x] `ADMIN_EMAIL` env var with default `christian@inboxconverge.com`; admin auto-promoted on login and on every application startup (fixes pre-existing accounts)
- [x] `is_superuser` exposed in `/users/me` response - [x] `is_superuser` exposed in `/users/me` response
- [x] Admin badge (purple shield) shown in top bar for superusers - [x] Admin badge (purple shield) shown in top bar for superusers
- [x] Fix blank page on direct navigation to `/admin*`: moved superuser guard inside `<AuthGuard>` so auth check always runs on fresh load - [x] Fix blank page on direct navigation to `/admin*`: moved superuser guard inside `<AuthGuard>` so auth check always runs on fresh load
+2 -2
View File
@@ -1,6 +1,6 @@
# Web Interface Quick Start Guide # Web Interface Quick Start Guide
The POP3 to Gmail Forwarder now includes a modern web interface built with Next.js, making it easy to manage your email forwarding without API calls. The InboxConverge now includes a modern web interface built with Next.js, making it easy to manage your email forwarding without API calls.
## 🌐 Accessing the Web Interface ## 🌐 Accessing the Web Interface
@@ -104,7 +104,7 @@ frontend:
build: build:
context: ./frontend context: ./frontend
dockerfile: Dockerfile dockerfile: Dockerfile
container_name: pop3-frontend container_name: inboxconverge-frontend
ports: ports:
- "3000:3000" - "3000:3000"
environment: environment:
+1 -1
View File
@@ -126,7 +126,7 @@ elif version == 'v2':
def get_or_create_user_salt(user_id: int) -> bytes: def get_or_create_user_salt(user_id: int) -> bytes:
# Use deterministic salt based on user_id + global salt # Use deterministic salt based on user_id + global salt
# OR store random salt in database per user # OR store random salt in database per user
return hashlib.sha256(f'pop3_forwarder_user_{user_id}'.encode()).digest() return hashlib.sha256(f'inbox_converge_user_{user_id}'.encode()).digest()
``` ```
## Security Best Practices ## Security Best Practices
+1 -1
View File
@@ -64,7 +64,7 @@ async def lifespan(app: FastAPI):
# Shutdown: cleanup # Shutdown: cleanup
app = FastAPI( app = FastAPI(
title="POP3 Forwarder API", title="InboxConverge API",
lifespan=lifespan, lifespan=lifespan,
openapi_url="/api/openapi.json", openapi_url="/api/openapi.json",
docs_url="/api/docs", docs_url="/api/docs",
+5 -3
View File
@@ -1,12 +1,14 @@
import Link from 'next/link'; import Link from 'next/link';
import type { Metadata } from 'next'; import type { Metadata } from 'next';
const APP_NAME = process.env.APP_NAME ?? 'InboxConverge';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Datenschutz POP3 Forwarder', title: `Datenschutz ${APP_NAME}`,
}; };
const LAST_UPDATED = 'March 26, 2026'; const LAST_UPDATED = 'March 26, 2026';
const CONTACT_EMAIL = 'christianlouis@gmail.com'; const CONTACT_EMAIL = process.env.CONTACT_EMAIL ?? 'christian@inboxconverge.com';
export default function DatenschutzPage() { export default function DatenschutzPage() {
return ( return (
@@ -82,7 +84,7 @@ export default function DatenschutzPage() {
2. Geltungsbereich dieser Datenschutzerklärung 2. Geltungsbereich dieser Datenschutzerklärung
</h2> </h2>
<p className="text-gray-700"> <p className="text-gray-700">
Dieser Hinweis gilt für die POP3 Forwarder-Webanwendung. Er gilt Dieser Hinweis gilt für die {APP_NAME}-Webanwendung. Er gilt
für alle Nutzer weltweit, einschließlich derjenigen in der für alle Nutzer weltweit, einschließlich derjenigen in der
Europäischen Union (EU), dem Europäischen Wirtschaftsraum (EWR), Europäischen Union (EU), dem Europäischen Wirtschaftsraum (EWR),
Deutschland, dem Vereinigten Königreich (UK), der Schweiz, der Deutschland, dem Vereinigten Königreich (UK), der Schweiz, der
+6 -3
View File
@@ -1,8 +1,11 @@
import Link from 'next/link'; import Link from 'next/link';
import type { Metadata } from 'next'; import type { Metadata } from 'next';
const APP_NAME = process.env.APP_NAME ?? 'InboxConverge';
const CONTACT_EMAIL = process.env.CONTACT_EMAIL ?? 'christian@inboxconverge.com';
export const metadata: Metadata = { export const metadata: Metadata = {
title: 'Impressum POP3 Forwarder', title: `Impressum ${APP_NAME}`,
}; };
export default function ImpressumPage() { export default function ImpressumPage() {
@@ -36,10 +39,10 @@ export default function ImpressumPage() {
Fax: +49 40 97074609<br /> Fax: +49 40 97074609<br />
E-Mail:{' '} E-Mail:{' '}
<a <a
href="mailto:christianlouis@gmail.com" href={`mailto:${CONTACT_EMAIL}`}
className="text-blue-600 hover:text-blue-500" className="text-blue-600 hover:text-blue-500"
> >
christianlouis@gmail.com {CONTACT_EMAIL}
</a> </a>
</p> </p>
</section> </section>
+1 -1
View File
@@ -14,7 +14,7 @@ const geistMono = Geist_Mono({
}); });
export const metadata: Metadata = { export const metadata: Metadata = {
title: "InboxRescue — your old inboxes, delivered to Gmail", title: "InboxConverge — your old inboxes, delivered to Gmail",
description: "Poll your legacy POP3 and IMAP mailboxes and have everything land quietly in Gmail. Set it once, forget it exists.", description: "Poll your legacy POP3 and IMAP mailboxes and have everything land quietly in Gmail. Set it once, forget it exists.",
}; };
+1 -1
View File
@@ -46,7 +46,7 @@ export default function LoginPage() {
<div className="max-w-md w-full space-y-8"> <div className="max-w-md w-full space-y-8">
<div> <div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900"> <h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900">
POP3 to Gmail Forwarder InboxConverge
</h2> </h2>
<p className="mt-2 text-center text-sm text-gray-600"> <p className="mt-2 text-center text-sm text-gray-600">
Sign in to your account Sign in to your account
+6 -6
View File
@@ -106,7 +106,7 @@ export default function Home() {
<div className="flex justify-between items-center py-4"> <div className="flex justify-between items-center py-4">
<div className="flex items-center"> <div className="flex items-center">
<Mail className="h-8 w-8 text-blue-600 mr-2" /> <Mail className="h-8 w-8 text-blue-600 mr-2" />
<h1 className="text-2xl font-bold text-gray-900">InboxRescue</h1> <h1 className="text-2xl font-bold text-gray-900">InboxConverge</h1>
</div> </div>
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
<Link <Link
@@ -136,7 +136,7 @@ export default function Home() {
</h2> </h2>
<p className="text-xl text-gray-600 mb-4 max-w-2xl mx-auto"> <p className="text-xl text-gray-600 mb-4 max-w-2xl mx-auto">
You know the ones that GMX account from 2009, the old ISP address your You know the ones that GMX account from 2009, the old ISP address your
bank still sends to, the Hotmail you gave out in school. InboxRescue bank still sends to, the Hotmail you gave out in school. InboxConverge
quietly polls them all and drops everything into your Gmail. Set it once, quietly polls them all and drops everything into your Gmail. Set it once,
forget it exists. forget it exists.
</p> </p>
@@ -171,7 +171,7 @@ export default function Home() {
Auto-detects everything Auto-detects everything
</h3> </h3>
<p className="text-gray-600"> <p className="text-gray-600">
Type your old email address and InboxRescue figures out the server Type your old email address and InboxConverge figures out the server
settings. No Googling port numbers required. settings. No Googling port numbers required.
</p> </p>
</div> </div>
@@ -215,7 +215,7 @@ export default function Home() {
</div> </div>
<h4 className="text-xl font-semibold text-gray-900 mb-2">Add your old inbox</h4> <h4 className="text-xl font-semibold text-gray-900 mb-2">Add your old inbox</h4>
<p className="text-gray-600"> <p className="text-gray-600">
Paste the email address InboxRescue auto-detects the POP3/IMAP Paste the email address InboxConverge auto-detects the POP3/IMAP
settings in seconds. settings in seconds.
</p> </p>
</div> </div>
@@ -225,7 +225,7 @@ export default function Home() {
</div> </div>
<h4 className="text-xl font-semibold text-gray-900 mb-2">Connect Gmail</h4> <h4 className="text-xl font-semibold text-gray-900 mb-2">Connect Gmail</h4>
<p className="text-gray-600"> <p className="text-gray-600">
Sign in with Google once. InboxRescue delivers mail directly into Sign in with Google once. InboxConverge delivers mail directly into
your inbox using the Gmail API no SMTP relay needed. your inbox using the Gmail API no SMTP relay needed.
</p> </p>
</div> </div>
@@ -270,7 +270,7 @@ export default function Home() {
<footer className="mt-20 border-t border-gray-200 bg-white"> <footer className="mt-20 border-t border-gray-200 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"> <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<p className="text-center text-gray-600 text-sm"> <p className="text-center text-gray-600 text-sm">
© {new Date().getFullYear()} InboxRescue made for people, not enterprises. © {new Date().getFullYear()} InboxConverge made for people, not enterprises.
</p> </p>
</div> </div>
</footer> </footer>
+2 -2
View File
@@ -54,7 +54,7 @@ export function DashboardLayout({ children }: DashboardLayoutProps) {
<div className="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col"> <div className="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
<div className="flex flex-col flex-grow bg-white border-r border-gray-200"> <div className="flex flex-col flex-grow bg-white border-r border-gray-200">
<div className="flex items-center h-16 flex-shrink-0 px-4 border-b border-gray-200"> <div className="flex items-center h-16 flex-shrink-0 px-4 border-b border-gray-200">
<h1 className="text-xl font-bold text-gray-900">InboxRescue</h1> <h1 className="text-xl font-bold text-gray-900">InboxConverge</h1>
</div> </div>
<nav className="flex-1 px-2 py-4 space-y-1"> <nav className="flex-1 px-2 py-4 space-y-1">
{navigation.map((item) => { {navigation.map((item) => {
@@ -117,7 +117,7 @@ export function DashboardLayout({ children }: DashboardLayoutProps) {
<div className="fixed inset-0 bg-gray-600/75" onClick={() => setSidebarOpen(false)} /> <div className="fixed inset-0 bg-gray-600/75" onClick={() => setSidebarOpen(false)} />
<div className="fixed inset-y-0 left-0 flex w-64 flex-col bg-white"> <div className="fixed inset-y-0 left-0 flex w-64 flex-col bg-white">
<div className="flex items-center justify-between h-16 px-4 border-b border-gray-200"> <div className="flex items-center justify-between h-16 px-4 border-b border-gray-200">
<h1 className="text-xl font-bold text-gray-900">InboxRescue</h1> <h1 className="text-xl font-bold text-gray-900">InboxConverge</h1>
<button onClick={() => setSidebarOpen(false)} className="text-gray-500 hover:text-gray-700"> <button onClick={() => setSidebarOpen(false)} className="text-gray-500 hover:text-gray-700">
<X className="h-6 w-6" /> <X className="h-6 w-6" />
</button> </button>
+4 -4
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
""" """
POP3 to Gmail Forwarder InboxConverge
Fetches emails from POP3 mailboxes and forwards them to Gmail Fetches emails from POP3 mailboxes and forwards them to Gmail
""" """
@@ -80,7 +80,7 @@ class POP3Account:
class EmailForwarder: class EmailForwarder:
"""Main class for forwarding emails from POP3 to Gmail""" """Main class for forwarding emails from POP3 to Gmail via InboxConverge"""
def __init__(self): def __init__(self):
self.smtp_host = os.getenv('SMTP_HOST', 'smtp.gmail.com') self.smtp_host = os.getenv('SMTP_HOST', 'smtp.gmail.com')
@@ -241,7 +241,7 @@ class EmailForwarder:
payload = json.dumps({ payload = json.dumps({
"From": self.postmark_from, "From": self.postmark_from,
"To": self.postmark_to, "To": self.postmark_to,
"Subject": f"[POP3 Forwarder Alert] {subject}", "Subject": f"[InboxConverge Alert] {subject}",
"TextBody": f"Error occurred at {datetime.now().isoformat()}\n\n{error_message}", "TextBody": f"Error occurred at {datetime.now().isoformat()}\n\n{error_message}",
"MessageStream": "outbound" "MessageStream": "outbound"
}) })
@@ -312,7 +312,7 @@ class EmailForwarder:
def main(): def main():
"""Main entry point""" """Main entry point"""
logger.info("POP3 to Gmail Forwarder starting...") logger.info("InboxConverge starting...")
forwarder = EmailForwarder() forwarder = EmailForwarder()
@@ -51,7 +51,7 @@
} }
] ]
}, },
"description": "InboxRescue system health: mail processing, Gmail API, auth, and HTTP metrics", "description": "InboxConverge system health: mail processing, Gmail API, auth, and HTTP metrics",
"editable": true, "editable": true,
"fiscalYearStartMonth": 0, "fiscalYearStartMonth": 0,
"graphTooltip": 1, "graphTooltip": 1,
@@ -1111,7 +1111,7 @@
], ],
"refresh": "30s", "refresh": "30s",
"schemaVersion": 38, "schemaVersion": 38,
"tags": ["inboxrescue", "monitoring", "email"], "tags": ["inboxconverge", "monitoring", "email"],
"templating": { "templating": {
"list": [] "list": []
}, },
@@ -1121,8 +1121,8 @@
}, },
"timepicker": {}, "timepicker": {},
"timezone": "browser", "timezone": "browser",
"title": "InboxRescue - System Health", "title": "InboxConverge - System Health",
"uid": "inboxrescue-health", "uid": "inboxconverge-health",
"version": 1, "version": 1,
"weekStart": "" "weekStart": ""
} }
@@ -1,7 +1,7 @@
apiVersion: 1 apiVersion: 1
providers: providers:
- name: InboxRescue - name: InboxConverge
orgId: 1 orgId: 1
type: file type: file
disableDeletion: false disableDeletion: false
+1 -1
View File
@@ -3,7 +3,7 @@ global:
evaluation_interval: 15s evaluation_interval: 15s
scrape_configs: scrape_configs:
- job_name: "inboxrescue-backend" - job_name: "inboxconverge-backend"
static_configs: static_configs:
- targets: ["backend:8000"] - targets: ["backend:8000"]
metrics_path: /metrics metrics_path: /metrics