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:
+6
-1
@@ -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
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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"]
|
||||||
|
|||||||
@@ -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')"
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
# POP3 to Gmail Forwarder
|
# InboxConverge
|
||||||
|
|
||||||
[](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/test.yml)
|
[](https://github.com/christianlouis/inboxconverge/actions/workflows/test.yml)
|
||||||
[](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/lint.yml)
|
[](https://github.com/christianlouis/inboxconverge/actions/workflows/lint.yml)
|
||||||
[](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/security.yml)
|
[](https://github.com/christianlouis/inboxconverge/actions/workflows/security.yml)
|
||||||
[](https://github.com/christianlouis/pop_puller_to_gmail/actions/workflows/docker-build.yml)
|
[](https://github.com/christianlouis/inboxconverge/actions/workflows/docker-build.yml)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
[](https://www.python.org/downloads/)
|
[](https://www.python.org/downloads/)
|
||||||
[](https://www.docker.com/)
|
[](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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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,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
@@ -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",
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"],
|
||||||
|
|||||||
@@ -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"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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,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)
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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!** 🎉
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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
@@ -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.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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.",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|
||||||
+4
-4
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user