- Add _require_admin + AdminUser dependency to google_drive.py, dropbox.py, onedrive.py
and switch save-settings endpoints from @require_login to Depends(_require_admin) so
tests can use dependency_overrides to bypass auth
- Wrap lifespan shutdown section (logging.info + notify_shutdown) in try/except to
silence OSError and other exceptions during shutdown (test_lifespan_shutdown_*)
- Add @patch("app.tasks.imap_tasks.is_private_ip", return_value=False) to 5 IMAP
tests that use imap.example.com (unresolvable in CI, causing is_private_ip to return
True and pull_inbox to return early before any IMAP operations)
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/06fb29ae-8e36-4f13-89b8-68c06378e8a6
- fix(api/dropbox): _require_admin bypasses auth when AUTH_ENABLED=False,
fixing all 5 TestSaveDropboxSettings failures
- fix(api/onedrive): same AUTH_ENABLED bypass in _require_admin; fix one-arg
update_env_file call using env_utils version for token rotation
- fix(auth): update login TemplateResponse to Starlette 1.0+ API
(request as first arg instead of in context dict)
- fix(api/local_auth): update all TemplateResponse calls to Starlette 1.0+ API
- fix(views/share): update TemplateResponse call to Starlette 1.0+ API
- fix(api/billing): update TemplateResponse call to Starlette 1.0+ API
- fix(tests/test_imap_tasks): mock is_private_ip for tests using
imap.example.com (unresolvable in sandboxed/CI environments)
- fix(tests): update TemplateResponse call_args assertions to new API
(call_args.kwargs['context'] instead of call_args[0][1])
- fix(tests): update fake_original signatures in dark_mode tests
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/52d7b7b7-3a71-4a96-b2b1-b675b8a6d3b4
🚨 Severity: HIGH
💡 Vulnerability: User-provided IMAP `host` in `_test_imap_connection` and `pull_inbox` was not validated against private IPs, creating an SSRF risk.
🎯 Impact: Attackers could abuse the endpoints to port-scan or interact with internal/private network services.
🔧 Fix: Integrated `is_private_ip` from `app.utils.network` to block connections resolving to private, loopback, link-local, or reserved IPs.
✅ Verification: Ran `test_imap_tasks.py` and `test_api_imap_accounts.py` successfully. Checked `ruff` output and diffs. Removed all scratch files from the commit.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add a configurable switch to control which attachment types are ingested
via IMAP. Images are excluded by default; office files and PDFs are ingested.
- Add global `IMAP_ATTACHMENT_FILTER` config setting (default: `documents_only`)
- Add `attachment_filter` column to `UserImapAccount` model for per-user override
- Migration 032 adds the column to `user_imap_accounts` table
- Update `fetch_attachments_and_enqueue()` to respect filter (documents_only/all)
- Update `pull_inbox()`, `_pull_user_imap_accounts()`, and
`_pull_user_integration_imap()` to pass the resolved filter
- Update IMAP accounts API (schemas, create/update handlers, response serializer)
- Update IMAP accounts UI to show attachment filter dropdown in modal and
display filter badges on account cards
- Add 6 new tests covering attachment filter behaviour
- Update ConfigurationGuide.md, EmailIngestion.md, and .env.demo
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add test_gmail_labels_disabled_when_gmail_apply_labels_false to verify
that Gmail star/label operations are skipped when gmail_apply_labels=False.
Add four tests to TestPullUserIntegrationWatchFolders for cloud source
type dispatching: S3, Dropbox, unknown provider, and explicit local type.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When enabled, IMAP processing will fetch and process attachments but
will NOT modify the mailbox state (no starring, labeling, deleting,
or flag changes). This allows preprod instances to safely share a
Gmail inbox with production without interfering with production
email processing.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add comprehensive tests for imap_tasks.py covering:
- Lock acquire/release mechanisms
- pull_all_inboxes task with various scenarios
- pull_inbox for Gmail and non-Gmail with edge cases
- find_all_mail_xlist functionality
- Extended fetch_attachments tests for all MIME types
- Edge cases: invalid JSON, missing Message-ID, already processed, etc.
- Achieve 98.26% coverage for imap_tasks.py (up from 48.78%)
- Fix config_validator.py to include validate_auth_config export
- Update tests to verify all exports including validate_auth_config
- Note: config_validator.py file is shadowed by config_validator/ directory
in Python's module resolution, so it cannot be directly imported or tested.
The package's __init__.py (which has 100% coverage) is what's actually used.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add @staticmethod to 9 test methods in test_external_integrations.py
that don't use self (PYL-R0201)
- Extract hard-coded password literals to constants in 6 test files
to resolve S2068 warnings (fixtures_integration, test_imap_tasks,
test_upload_tasks, test_upload_webdav_comprehensive,
test_upload_webdav_integration, test_views_coverage)
- Migrate Form() dependency injection to Annotated type hints in
dropbox.py, google_drive.py, onedrive.py (Sonar fastapi convention)
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>