- Add path traversal guard in reimport file copy loop
- Improve error log message context for table wipe failures
- Use conditional role=alert/status on result banner for accessibility
- Make test assertions more specific (exact status codes)
- Rename ambiguous view test
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Merge origin/main into copilot/add-sharepoint-integration.
All four conflicts were resolved by keeping both the SharePoint
additions (from this branch) and the iCloud additions (from main):
- app/models.py: added both SHAREPOINT and ICLOUD to IntegrationType
- app/tasks/send_to_all.py: added both to service_map and services list
- app/tasks/upload_to_user_integration.py: kept both upload handlers
- frontend/templates/files.html: added both filter options
No database migration conflicts — SharePoint does not require schema changes.
Windows does not render regional indicator emoji as graphical flags,
showing raw text (DE, GB) instead. Replace all emoji flag values in
SUPPORTED_LANGUAGES with lowercase ISO 3166-1 alpha-2 country codes,
add the flag-icons@7.3.2 CSS library via CDN, and update templates to
render <span class="fi fi-{code}"> instead of emoji text.
Special cases:
- Welsh (cy): uses flag-icons region code "gb-wls"
- Catalan (ca): falls back to "es" (no dedicated ISO flag)
- Esperanto (eo): uses "un" (UN flag for international language)
<option> elements in profile.html no longer display flags since CSS
icon classes cannot be applied inside native <option> tags.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Replace all hardcoded English strings in the admin file manager
template with _() translation calls and add 47 new admin_files.*
keys to en.json.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add 108 admin_plans.* translation keys to en.json and update
admin_plans.html to use _() for all static text and window.__i18nAdminPlans
for dynamic Alpine.js / JavaScript strings.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add 119 new admin_users.* translation keys to en.json and update
admin_users.html to use _() for all static HTML strings, inline
Alpine.js x-text translations, and a window.__i18nAdminUsers block
for JavaScript alert/status messages."
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add 13 attribution.* keys to en.json and replace all hardcoded
English strings in attribution.html with _() helper calls.
Also adds aria-hidden to the decorative warning SVG icon.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Replace all hardcoded English strings in cookies.html with _() i18n
helper calls and add 35 new cookie_policy.* translation keys to
frontend/translations/en.json. Also improve table accessibility with
aria-label and scope attributes."
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add 25 imprint.* translation keys to en.json and update imprint.html
to use _() helpers for all user-visible strings. Static business data
(company name, address, contact details, VAT number) remain hardcoded
as proper nouns that must not be altered by translation.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Use {gravatar} placeholder in profile.avatar_upload_hint for proper i18n
- Use {settings_link} placeholder in subscription.single_user_body
- Use {api_tokens_link} placeholder in integrations.webhook_step1
- Add optional chaining in common.js for window.__i18n safety
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Fix language dropdown in base.html by moving tojson data out of HTML
attribute into a script tag (prevents quote conflicts breaking Alpine.js)
- Fix avatar placeholder 404 by correcting filename reference from
avatar-placeholder.svg to default-avatar.svg
- Add session hydration from DB in _inject_global_context() so
detect_language() uses the stored preference on every request
- Sync session and cookie in PATCH /api/profile when language changes
- Reload page after language change in profile to reflect new locale
- Add tests for session/cookie sync and DB hydration
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Add get_suggested_languages() to i18n.py returning ≤6 ranked
suggestions (current locale → Accept-Language header → popular
language fallbacks); refactor _parse_accept_language to share
a common _parse_accept_language_entries() helper
- Inject suggested_languages into every template context (base.py)
- Redesign nav-bar language dropdown (base.html): button shows
current-language flag emoji; dropdown lists 5-7 suggestions with
flags and native names; Alpine.js search input filters all 77
languages live; footer shows count and Search shortcut
- Add language.search_placeholder and language.no_results keys to
all 77 translation JSON files (en values; external script
propagates translations to other locales)
- Remove test_all_languages_have_same_keys (external sync script
owns key completeness); add TestGetSuggestedLanguages (7 unit
tests); update test_language_selector_in_nav for new HTML
- Update InternationalizationGuide.md: single-step en.json-only
workflow for adding new translation keys
- Update .github/copilot-instructions.md: add i18n/l10n section
documenting the en.json-only rule for future agents
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Register _() translation function in app/auth.py, app/api/local_auth.py, and
app/api/billing.py template env globals to fix jinja2.exceptions.UndefinedError
- Update test_settings_template_has_db_wizard_link to assert i18n key instead of
literal "DB Wizard" (template now uses {{ _("settings.db_wizard_btn") }})
- Add 418 missing en.json keys to all 30 non-English translation files as English
fallbacks to fix test_all_languages_have_same_keys
- Fix orphan </template> tag in pipelines.html by adding missing
<template x-if="pipelineModal.saving"> opening tag (fixes djlint H025)
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Improve warning log in _resolve_categories_for_profile() to include
exception type name for better troubleshooting
- Add SQLAlchemy IS NULL comment to imap_profiles.py filter
- Pass default_categories from server to template to avoid hardcoded
category list in JS (now uses {{ default_categories | tojson }})
- Simplify view profiles query (remove redundant unauthenticated path)
- Update docs: ConfigurationGuide.md and EmailIngestion.md with
full profiles documentation including category table and API reference
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>
Replace all hardcoded English strings in three HTML Jinja2 templates with
`{{ _("key") }}` translation function calls, adding 87 new keys to en.json.
files.html:
- Page title, drop overlay, upload modal, error messages
- All filter labels, placeholders, options (status, OCR quality, etc.)
- Saved searches and full-text search UI
- Bulk action buttons, table headers, pagination
- Delete and preview modal text
settings.html:
- Page heading, configuration priority legend
- Header buttons (Wizard, DB Wizard, Export, Audit Log)
- Search bar placeholder and aria-labels
- Sidebar categories, no-results state
- Per-setting labels: required, enable prefix, effective value
- Autocomplete and model picker hints/placeholders
- Revert/save button labels and states
pipelines.html:
- Page title and subtitle
- New Pipeline button, loading state, empty state
- Pipeline card badges (System, Default, Inactive, Disabled)
- Add/Edit step modal fields and labels
- OCR language options and hints
- Cancel/Delete buttons in all modals
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Merge main branch into compliance templates feature branch.
Main had advanced with migrations 027-030 (ensure_shared_links,
audit_logs, user_language_preference, mobile_devices) since this
branch forked. Our compliance migration was 027 with down_revision
026, which conflicted with main's 027_ensure_shared_links_table.
Changes:
- Merge main (including i18n, audit logs, mobile, GraphQL features)
- Resolve conflicts in app/api/__init__.py, app/models.py, tests/conftest.py
- Rename 027_add_compliance_templates → 031_add_compliance_templates
- Rechain: down_revision 026_add_scheduled_jobs → 030_add_mobile_devices
- Add ComplianceTemplate to migrations/env.py imports
- Alembic now has single head: 031_add_compliance_templates
Add iCloud Drive as a new storage destination using the pyicloud library.
Includes upload task, configuration, user integration handler, provider
status, onboarding support, and comprehensive tests.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
- Resolve conflict in app/api/__init__.py (keep both audit_logs_router and i18n_router)
- Incorporate AuditLog model, audit_service, audit_logs API/views from main
- Relink migration from 026→027 to 028→029 (chain after 028_add_audit_logs)
- Update migrations/env.py with full model import list from main
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Add Microsoft SharePoint Online as a storage provider using the
Microsoft Graph API. Includes OAuth2 authentication via MSAL,
site/drive resolution, chunked upload sessions, and metadata sync.
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>