88b7afb195
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com> Agent-Logs-Url: https://github.com/christianlouis/pop_puller_to_gmail/sessions/131238a2-437c-4a85-b98b-fcb3d80e69e0
11 KiB
11 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[Unreleased]
Fixed
- Fixed frontend API calls being hardcoded to
http://localhost:8000in production:NEXT_PUBLIC_API_URLis baked into the JavaScript bundle at Next.js build time, so it can never be overridden at container runtime. Replaced theNEXT_PUBLIC_API_URLmechanism with a Next.js Route Handler proxy at/api/v1/[...path]that readsprocess.env.BACKEND_URLat server startup and proxies all/api/v1/*requests to the real backend. The frontend Axios client now uses a relative base URL (/api/v1), which also eliminates the CORS issue since the browser only ever talks to the same-origin Next.js server. UpdateBACKEND_URL=http://backend:8000indocker-compose.new.yml(or your deployment env) to point the proxy at your backend. - Fixed infinite spinning wheel on the home page:
authStoreno longer initialisesisLoadingastrueunconditionally — it is nowfalsewhen no access token exists inlocalStorage, so unauthenticated users see the landing page immediately instead of an endless spinner - Home page now performs an auth check when a token is present in
localStorage, redirecting authenticated users to the dashboard and clearing stale tokens on failure - Wrapped
useSearchParams()in aSuspenseboundary infrontend/src/app/auth/callback/page.tsxto fix the Next.js build error: "useSearchParams() should be wrapped in a suspense boundary at page /auth/callback" - Fixed TypeScript build error in
frontend/src/app/accounts/page.tsx: replaced non-existentaccount.usernamewithaccount.email_address,account.last_checked_atwithaccount.last_check_at, andaccount.last_errorwithaccount.last_error_message(the backend intentionally excludesusernamefrom API responses for security) - Fixed TypeScript error in
frontend/src/app/auth/callback/page.tsx:TokenResponsedoesn't includeuser; now fetches user viauserApi.getCurrentUser()after OAuth token exchange - Fixed TypeScript errors in
frontend/src/app/dashboard/page.tsx: replaced non-existenterrors_countwithemails_failedonProcessingRun - Fixed TypeScript errors in
frontend/src/components/AddMailAccountModal.tsx: removed invalidaccount.usernameaccess, added missing required fields to initial form state, and fixed autoDetect suggestions access - Made
email_address,use_tls,forward_tooptional in theMailAccountCreateTypeScript interface to align with form usage - Added typed suggestion fields to
autoDetectreturn type inapi.ts - Excluded test files (
*.test.ts,*.spec.ts) from TypeScript compilation intsconfig.json - Upgraded Node.js base image in
frontend/Dockerfilefromnode:18-alpinetonode:20-alpineto satisfy the Node.js >= 20.9.0 requirement for Next.js and fix Docker build failures - Removed
actions/attest-build-provenancestep and associatedid-token: write/attestations: writepermissions from the CIbuildjob — this action is not available for private user-owned repositories and caused every build to fail - Downgraded
eslintfrom^10to^9in the frontend to resolveTypeError: contextOrFilename.getFilename is not a functioncaused by ESLint 10 removing thegetFilename()API used byeslint-plugin-reactbundled ineslint-config-next - Upgraded
sqlalchemyfrom2.0.25to2.0.48to fixAssertionError: Class ... directly inherits TypingOnly but has additional attributeson Python 3.14 (__static_attributes__,__firstlineno__)
Added
- Backend URL logged at startup: The Next.js server now logs the resolved
BACKEND_URL(e.g.[proxy] BACKEND_URL = http://backend:8000) viasrc/instrumentation.tswhen the server starts, making it easy to diagnoseECONNREFUSEDproxy errors. The per-request error log now also includes the full target URL. - Dual-registry Docker deployment: CI now builds separate backend and frontend images and pushes to both GHCR (
ghcr.io) and private registry (registry.cklnet.com) using a matrix strategy - Database-backed configuration:
AppSettingmodel andConfigServicefor hybrid config (DB-first, env-var fallback) - Admin API endpoints for managing settings (
GET/PUT/DELETE /api/v1/settings) - Default settings seeded into database on first startup (SMTP, processing, Gmail API, notifications)
- Unit tests for
ConfigService(24 tests covering resolution order, CRUD, SMTP helper, defaults) - Gmail API delivery documentation with comparison table (Gmail API vs SMTP forwarding)
- GitHub issue templates (bug report, feature request, test needed)
- Pull request template with comprehensive checklist
docs/CODING_PATTERNS.mdwith development best practicesdocs/ERRORS.mddocumenting all error codesdocs/adr/directory with Architecture Decision RecordsMakefilewith common development tasks.pre-commit-config.yamlfor code quality enforcementCHANGELOG.mdfor version tracking- Security validation for SECRET_KEY and ENCRYPTION_KEY on startup
- CSRF protection middleware
- Security headers middleware (X-Frame-Options, CSP, HSTS)
- Rate limiting per user/tier
- Comprehensive test infrastructure setup
- CI/CD pipeline for testing and security scanning
- Dependabot configuration for automated dependency updates (pip, npm, GitHub Actions, Docker)
- Copilot instructions requiring TODO.md and CHANGELOG.md updates
- Unit tests for security middleware (SecurityHeadersMiddleware, CSRFProtectionMiddleware)
- Unit tests for JWT token lifecycle (access tokens, refresh tokens, decode, edge cases)
- Unit tests for credential encryption edge cases (empty, long, unicode, special chars)
- Unit tests for FastAPI application factory and core endpoints (root, health, OpenAPI)
- Unit tests for Pydantic schema validation (users, mail accounts, notifications, subscriptions)
- Unit tests for JWT
subclaim string encoding and token type verification - Created
frontend/src/lib/api.ts— API client module (fixes frontend compilation blocker) - Reached 57% test coverage (up from 54%)
Changed
- Configuration system now supports database-backed settings in addition to environment variables
- Celery tasks (
tasks.py) useConfigServicefor SMTP config instead of rawos.getenv()calls - README updated with hybrid configuration docs, Gmail API vs SMTP comparison, and Apprise notifications
- Architecture docs updated to reflect Gmail API service, hybrid config, and new API endpoints
- Reorganized documentation into
docs/directory - Improved error handling with specific exception types
- Updated datetime usage to timezone-aware
- Enhanced logging with structured context
- Bumped Docker Python base image from 3.11-slim to 3.14-slim
- Bumped CI Python version from 3.11 to 3.14
- Bumped CI Node.js version from 18 to 20
- Bumped GitHub Actions:
actions/setup-pythonv5 → v6,actions/setup-nodev4 → v6,docker/setup-buildx-actionv3 → v4,codecov/codecov-actionv3 → v5 - Bumped backend dependencies: pydantic 2.5.3 → 2.12.5, pydantic-settings 2.1.0 → 2.13.1, psycopg2-binary 2.9.9 → 2.9.11, asyncpg 0.29.0 → 0.31.0, stripe 7.11.0 → 14.4.1, aioimaplib 1.0.1 → 2.0.1, google-auth-httplib2 0.2.0 → 0.3.0, celery 5.3.6 → 5.6.2, redis 5.0.1 → 7.3.0, tenacity 8.2.3 → 9.1.4
- Bumped frontend dependencies: react 19.2.3 → 19.2.4, @tanstack/react-query ^5.90.20 → ^5.95.0, axios ^1.13.5 → ^1.13.6, zustand ^5.0.11 → ^5.0.12, eslint ^9 → ^10, eslint-config-next 16.1.6 → 16.2.1
- Synced
frontend/package.jsoneslint-config-nextto16.2.1to matchpackage-lock.json(resolvesnpm ciEUSAGE failure)
Removed
- Removed CodeQL analysis from CI pipeline (was blocking builds)
Fixed
- JWT
subclaim now encoded as string per JWT spec (python-jose rejects integer subjects) TokenPayloadschemasubfield type changed frominttostrfor consistency- Replaced deprecated
datetime.utcnow()withdatetime.now(timezone.utc)throughout backend - Replaced deprecated FastAPI
@app.on_event()handlers with modernlifespancontext manager - Replaced deprecated Pydantic
class Configwithmodel_config = ConfigDict(...)in all schemas - Replaced deprecated Pydantic
.dict()with.model_dump()in mail account updates - Removed overly broad
except (GmailInjectionError, Exception)in task error handler - Bare exception handlers replaced with specific types
- Open redirect vulnerability in OAuth redirect_uri
- Default encryption keys security issue
Security
- All dependencies updated to patched versions
- Security headers added to all API responses
- Input validation improved for all endpoints
- Credential handling audited and improved
[1.0.0] - 2026-02-01
Added
- Multi-tenant SaaS backend with FastAPI
- JWT and OAuth2 (Google Sign-In) authentication
- Encrypted credential storage with Fernet
- Subscription management with Stripe integration
- PostgreSQL database with SQLAlchemy ORM
- Redis for caching and session management
- Celery for background task processing
- Apprise for multi-channel notifications
- Docker and docker-compose support
- Comprehensive API documentation with OpenAPI
- Extensive documentation (README, ARCHITECTURE, SECURITY_REPORT, etc.)
Changed
- Upgraded from single-user script to multi-tenant platform
[0.1.0] - 2025-12-15 (Legacy Version)
Added
- Initial release of single-user pop3_forwarder.py script
- Docker support with docker-compose
- Multiple POP3 account support
- Gmail forwarding via SMTP
- Rate limiting and throttling
- Error notifications via Postmarkapp
- Environment-based configuration
- Basic logging
Version History
- [Unreleased] - Current development (agentic coding improvements, security hardening)
- [1.0.0] - Multi-tenant SaaS platform (2026-02-01)
- [0.1.0] - Legacy single-user script (2025-12-15)
How to Update This Changelog
Categories
Use these standard categories:
- Added - New features
- Changed - Changes in existing functionality
- Deprecated - Soon-to-be removed features
- Removed - Removed features
- Fixed - Bug fixes
- Security - Vulnerability fixes
Format
## [Version] - YYYY-MM-DD
### Added
- New feature description (#issue-number)
### Fixed
- Bug fix description (#issue-number)
Workflow
- Add unreleased changes to
[Unreleased]section - When releasing, move unreleased changes to new version section
- Add version number, date, and comparison link
- Create git tag:
git tag -a v1.0.0 -m "Release v1.0.0"
Maintained by: Development Team Last Updated: 2026-03-23