Commit Graph

268 Commits

Author SHA1 Message Date
copilot-swe-agent[bot] 3be93be35a fix: resolve failing tests in main
- 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
2026-03-23 18:51:28 +00:00
copilot-swe-agent[bot] ef5528dcef fix: merge main, resolve conflicts, address review feedback
- Resolve merge conflicts in app/api/onedrive.py and tests/test_api_google_drive_final.py
- Fix legacy Dict[str, str] type hints in update_env_file functions to use dict[str, str]
- Add admin-only access (_require_admin dependency) to save-settings endpoints
  in google_drive.py, onedrive.py, and dropbox.py
- Fix in_memory_only response field to reflect actual env_write_success status
- Update tests to override _require_admin dependency for save-settings endpoint tests
2026-03-23 16:29:46 +00:00
google-labs-jules[bot] d22175310a 🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in IMAP connections
🚨 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>
2026-03-23 14:45:22 +00:00
google-labs-jules[bot] 57795ee487 chore: simplify and fix naming for save settings endpoints
- Renamed `save_dropbox_settings` inside `app/api/google_drive.py` to `save_google_drive_settings` to fix a copy-paste naming error.
- Extracted duplicate `.env` file updating logic from `app/api/google_drive.py`, `app/api/onedrive.py`, and `app/api/dropbox.py` into a new reusable helper function `update_env_file` inside `app/utils/settings_service.py`.
- Refactored the three API endpoints to use the new helper function, significantly reducing complexity and code duplication.
- Updated relevant test files (`tests/test_api_google_drive_final.py`) to reflect the new function name.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 14:39:53 +00:00
Christian Krakau-Louis d94e9ca4bc Merge branch 'main' into sentinel-ssrf-imap-9566695902417221069 2026-03-23 15:39:29 +01:00
google-labs-jules[bot] d71945b7b9 🛡️ Sentinel: [HIGH] Fix Server-Side Request Forgery in IMAP connections
🚨 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.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-23 14:38:34 +00:00
copilot-swe-agent[bot] c4e10bee5e fix: adapt TemplateResponse calls to Starlette 1.0 new-style API
Starlette 1.0.0 changed TemplateResponse signature from
(name, context_dict) to (request, name, context=dict).

- Update base.py wrapper to convert old-style calls to new-style
- Update main.py error handler TemplateResponse calls
- Update local_auth.py, billing.py, auth.py, share.py calls
- Update test mocks for new calling convention

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/7b5f7e0d-89ad-43be-b68d-a9c0c5407a7e
2026-03-23 12:50:09 +00:00
copilot-swe-agent[bot] d4cc44a72f fix(admin): fix greyed-out QR login toggle on admin connections page
- Add `qr_login_enabled` boolean config field (default True) to app/config.py
- Add `qr_login_enabled` entry to settings metadata in app/utils/settings_service.py
- Fix app/views/settings.py to use `qr_login_enabled` directly instead of
  deriving enablement status from qr_login_challenge_ttl_seconds (integer TTL)
- Fix admin_connections.html: remove hardcoded `disabled` attribute from the
  Mobile Phone Upload toggle and wire up onchange handler so toggling actually
  persists the setting via toggleSetting('qr_login_enabled', this.checked)
- Gate all three QR auth API endpoints on settings.qr_login_enabled so the
  feature is actually disabled when the toggle is turned off

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/8421cdb2-d92d-4b83-9cda-c44983d35173
2026-03-22 16:06:55 +00:00
copilot-swe-agent[bot] 7d6128d78f fix(api): add PUT /api/settings/{key} endpoint and shared credentials for Google/Microsoft social login
- Add PUT /{key} endpoint to settings API with SettingValueUpdate body model (only
  requires value, key comes from URL path) — fixes 405 Method Not Allowed errors
  from the admin Connections wizard which used PUT to save settings
- Fix grey toggles on /admin/connections: they appeared grey because all saves were
  silently failing with 405; now saves succeed and toggles reflect actual state
- Add social_auth_google_use_global_credentials config field and auth.py logic to
  reuse google_drive_client_id/google_drive_client_secret for Google Sign-In
- Add social_auth_microsoft_use_global_credentials config field and auth.py logic to
  reuse onedrive_client_id/onedrive_client_secret for Microsoft Sign-In
- Also apply consistent both-field check for Dropbox global credentials fallback
- Add settings metadata entries for the two new boolean settings
- Add Google and Microsoft settings_keys to admin_connections service definitions
- Add JS visibility toggle logic for Google/Microsoft credential fields in admin UI
- Add 6 new unit/integration tests for PUT endpoint and SettingValueUpdate model

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/ac66041a-2cbd-4d90-8f8e-3588c629d4d8
2026-03-22 15:13:16 +00:00
copilot-swe-agent[bot] 124b802c8f fix(sharing): address code review: fix default role, auto-share logic, aria labels
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/8091889d-4810-4794-b9d3-6b8f7f5257c4
2026-03-22 14:22:35 +00:00
copilot-swe-agent[bot] 6f2752bdf8 feat(sharing): add file sharing and role-based access management
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/8091889d-4810-4794-b9d3-6b8f7f5257c4
2026-03-22 14:14:50 +00:00
Christian Krakau-Louis f3abe87d85 Merge pull request #788 from christianlouis/sentinel/fix-b310-urllib-httpx-11046306234862582289
🛡️ Sentinel: [MEDIUM] Fix B310 Vulnerability - Use httpx instead of urllib.request
2026-03-22 11:10:21 +01:00
google-labs-jules[bot] b5ed16c1c8 Security: Replace urllib.request with httpx in WebDAV testing
The `_test_webdav_connection` function previously used `urllib.request.urlopen`
to verify connection credentials. This triggers a Bandit B310 warning because
`urllib` supports multiple schemes (like file://, ftp://) and implicitly follows
redirects.

Although scheme checking and a basic `is_private_ip` validation were implemented,
using `urllib.request` remains risky because a public URL could return an
HTTP redirect to a private IP (e.g., 127.0.0.1) which `urllib` would blindly follow,
causing an SSRF (Server-Side Request Forgery) bypass.

This commit replaces `urllib.request` with `httpx.request` using explicitly
`follow_redirects=False`. This eliminates the B310 vulnerability, ensures
requests only hit the specified URL without following potentially malicious
redirects, and standardizes the application on `httpx` for safer HTTP connections.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-22 03:58:07 +00:00
copilot-swe-agent[bot] 4b6412734b fix(comments): address code review feedback
- Add onupdate=sa.func.now() to migration updated_at columns
- Use UserProfile.is_blocked.is_(False) instead of == False
- Fix British to American spelling (organised → organized)

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/3894af37-0f19-457b-8811-f1feb18b17ef
2026-03-21 18:30:05 +00:00
copilot-swe-agent[bot] ad795e200a feat(comments): add document comments, annotations, and @mention support
- Add DocumentComment and DocumentAnnotation models to app/models.py
- Create migration 041_add_document_comments_and_annotations
- Add API endpoints for CRUD operations on comments and annotations
- Add threaded comment support with parent_id relationships
- Add @mention extraction from comment body text
- Add resolve/unresolve comment thread endpoint
- Add mentionable users endpoint (GET /api/users/mentionable)
- Add 43 unit tests covering all endpoints and edge cases
- Add 29 i18n translation keys to en.json
- Update API documentation in docs/API.md

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/3894af37-0f19-457b-8811-f1feb18b17ef
2026-03-21 18:28:01 +00:00
Christian Krakau-Louis a27a4ce130 Merge pull request #585 from christianlouis/copilot/add-zapier-make-integration
feat: add Zapier and Make.com integration via REST hooks and incoming actions
2026-03-21 15:20:42 +01:00
google-labs-jules[bot] bc122e351d Fix Ruff missing requests import
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-21 12:21:01 +00:00
copilot-swe-agent[bot] e518bce922 fix: merge main branch and renumber migration 037→040
Resolve all merge conflicts between our automation feature branch and
current main (v0.163.0, 920 commits ahead).

Conflicts resolved:
- app/api/__init__.py: add automation_router alongside main's new routers
  (classification_rules, qr_auth, sessions, system_reset)
- app/config.py: add main's new settings (dropbox_use_global_credentials,
  factory_reset_on_startup, enable_factory_reset)
- app/models.py: add main's new models (ClassificationRuleModel, UserSession,
  QRLoginChallenge, SharePoint integration type)
- app/utils/settings_service.py: merge automation_hooks_enabled with main's
  new metadata entries
- docs/API.md: merge automation API docs with main's classification rules docs
- docs/ConfigurationGuide.md: add factory reset settings
- tests/conftest.py: import both AutomationHook and new main models

Migration renumbered:
- 037_add_automation_hooks → 040_add_automation_hooks
- down_revision: 039_add_classification_rules (was 036_add_document_translation_fields)
- Chain: 036 → 037 → 038 → 039 → 040 (automation hooks)

For all non-automation files with conflicts, main's version was taken since
our branch did not modify those files (conflicts were from a stale prior merge).

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
Agent-Logs-Url: https://github.com/christianlouis/DocuElevate/sessions/cb62f012-3b69-4415-835e-3857ce3e9f45
2026-03-20 23:54:04 +00:00
Christian Krakau-Louis 6f5a73f98a Merge pull request #586 from christianlouis/copilot/fix-watch-folder-settings
feat(integrations): simplify OAuth watch folder setup with system credentials and folder browser
2026-03-21 00:37:49 +01:00
copilot-swe-agent[bot] ae675485af Merge remote-tracking branch 'origin/main' into copilot/fix-watch-folder-settings
# Conflicts:
#	app/views/dropbox.py
#	frontend/templates/dropbox.html
#	frontend/templates/integrations_dashboard.html
#	tests/test_api_dropbox.py
#	tests/test_views_dropbox.py
2026-03-20 23:33:58 +00:00
copilot-swe-agent[bot] 1e1e6e6280 test: add tests for folder browser APIs and system credentials toggle
Added tests for POST /api/dropbox/list-folders (7 tests) and
POST /api/onedrive/list-folders (7 tests) covering success, subfolder
navigation, empty directories, auth errors, API errors, path
normalization, and alphabetical sorting.

Added view tests for system credentials toggle visibility in Dropbox
setup wizard.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-20 13:40:51 +00:00
copilot-swe-agent[bot] a8423064ec feat(api): add folder browser API endpoints and UI for Dropbox and OneDrive
Added POST /api/dropbox/list-folders and POST /api/onedrive/list-folders
endpoints that accept an OAuth access_token and return folder listings.

After successful OAuth authorization in the callback pages, users now
see an interactive folder browser to select the target folder for their
integration. The selected folder is saved to the integration config.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-20 13:21:52 +00:00
copilot-swe-agent[bot] 1afd42bc57 fix: merge main (v0.161.0) into classification feature branch
Resolve all 40 merge conflicts from merging origin/main into the
classification feature branch. Key resolutions:

- Auto-generated files (BUILD_DATE, VERSION, etc.): use main's version
- API tokens: take main's version (token expiry, reactivation, hard-delete)
- Auth: take main's Dropbox credential sharing + token expiry checking
- Config: take main's social_auth_dropbox_use_global_credentials option
- Files API: take main's improved duplicate handling + rate limiting
- Models: keep ClassificationRuleModel alongside main's new models
- Mobile: take main's mature implementation
- Templates/translations: take main's versions (device deletion, reactivation keys)
- Migration: renumber 038_add_classification_rules → 039_add_classification_rules
  to chain after main's 038_add_api_token_expires_at
- Requirements: take main's version (adds segno QR library)
- Tests: take main's more complete token tests, keep classification imports
2026-03-20 13:08:41 +00:00
Christian Krakau-Louis 91eecd9396 Merge pull request #753 from christianlouis/copilot/scale-worker-and-api-pods
feat(scaling): enable horizontal scaling for API and worker pods
2026-03-20 13:55:31 +01:00
Christian Krakau-Louis b5fce418fb Merge pull request #773 from christianlouis/copilot/update-deprecated-npm-packages
fix(mobile): wire i18n reactivity, translate all screens, sync language preference with server
2026-03-20 12:15:10 +01:00
copilot-swe-agent[bot] 3b5ca04ebc fix(mobile): wire i18n reactivity, translate all screens, sync language with server
- Add LocaleProvider + useLocale() hook with AsyncStorage persistence to mobile i18n
- Replace all hardcoded English strings in every screen with t() calls
- Add missing profile.settings/language keys to all 5 translation files (en/de/es/fr/it)
- Wrap app root in LocaleProvider; apply server preferred_language on login in AuthGuard
- Tab labels and header titles now re-render on language switch
- ProfileScreen: use useLocale() context, sync language to server via POST /api/i18n/language
- Backend: add preferred_language field to GET /api/mobile/whoami response
- Mobile API: add preferred_language to WhoAmIResponse type + setServerLanguage() method
- Tests: add test_whoami_returns_preferred_language and test_whoami_no_profile_preferred_language_is_null
- Docs: update MobileApp.md with language sync priority and whoami response format

Language priority: server preference > AsyncStorage > device locale > English fallback

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-20 09:08:08 +00:00
copilot-swe-agent[bot] 5e3e2b1999 fix(dropbox): fix Invalid redirect_uri error by adding PUBLIC_BASE_URL config and URL-encoding
- Add PUBLIC_BASE_URL optional config to override auto-detected OAuth redirect URIs
  when behind a reverse proxy that doesn't forward X-Forwarded-Proto headers
- Add _build_dropbox_redirect_uri() helper in app/api/dropbox.py
- URL-encode redirect_uri in server-side Dropbox authorization URL
- Add _get_dropbox_callback_url() helper in app/views/dropbox.py
- Pass callback_url to both setup and callback templates
- Update templates to use server-provided callback_url instead of window.location.origin
- Update settings_service.py to register new setting
- Update .env.demo, ConfigurationGuide.md, and DropboxSetup.md documentation
- Add tests for new helper functions and global-authorize-url endpoint

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-20 08:19:48 +00:00
Christian Krakau-Louis 60e3ea030a Merge pull request #768 from christianlouis/copilot/check-imprint-privacy-policy
feat(mobile): add pre-login legal pages, fix image sharing, multi-image selection, file details, search, settings, and i18n
2026-03-20 08:48:34 +01:00
github-actions[bot] 910fb297ba style: apply ruff auto-fix
- Auto-formatted code with ruff format
- Applied ruff linting fixes with --fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-19 20:22:20 +00:00
copilot-swe-agent[bot] d1f9819f4e feat(integrations): add Dropbox connection test and global-credential sharing
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 19:17:12 +00:00
copilot-swe-agent[bot] 67c17e7baa feat(mobile): add pre-login legal pages, multi-image selection, file detail view, search, i18n, HEIC support
- Add Privacy Policy, Terms of Service, and Imprint links to WelcomeScreen
  and LoginScreen for GDPR/Apple compliance (pre-login access)
- Enable multiple image selection in photo library picker
- Add HEIC/HEIF image support to backend (allowed_types, convert_to_pdf, upload handler)
- Create FileDetailScreen with processing status and logs
- Add search bar to FilesScreen with debounced search
- Set up i18n with expo-localization (EN, DE, ES, FR, IT)
- Add language selector to ProfileScreen settings
- Add Imprint link to ProfileScreen legal section
- Update docs and tests

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 19:11:44 +00:00
copilot-swe-agent[bot] d5c18ccf07 fix(upload): reject exact duplicates at upload time and prevent duplicate mobile uploads
- Move duplicate check before task enqueue in ui_upload endpoint
- Clean up temp file and return status "duplicate" for exact duplicates
- Add URI-level dedup guard in mobile UploadScreen to prevent repeated uploads
- Improve ShareContext URI normalization (collapse slashes, decode percent-encoding)
- Guard +not-found.tsx effect against re-firing for the same pathname
- Update mobile UploadResponse type and handlers for duplicate status
- Update web frontend upload.js to show duplicate status
- Update API and Configuration docs

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 14:07:43 +00:00
copilot-swe-agent[bot] 2941f6e177 fix: resolve merge conflict in database.py
Merge origin/main into branch, resolving conflict in app/database.py.
Combined improvements from both branches:
- Keep pool_pre_ping=True and structured variable approach from feature branch
- Add explicit QueuePool import and poolclass assignment from main
2026-03-19 10:40:43 +00:00
copilot-swe-agent[bot] e4749b4e7c feat(api): allow disabled tokens/devices to be deleted & reactivated; add token lifetime
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-18 23:43:16 +00:00
Christian Krakau-Louis 2192783737 Merge pull request #758 from christianlouis/fix-idor-vuln-8344028020677453820
🛡️ Sentinel: [CRITICAL] Fix authorization bypass in API (IDOR)
2026-03-18 23:17:58 +01:00
copilot-swe-agent[bot] a8eb6504ac fix(qr-login): render QR code server-side using segno instead of CDN JS library
The QR code on /qr-login was not rendering because it depended on loading
qrcode@1.5.4 from the jsdelivr CDN, which may be blocked in some network
environments.

- Add segno>=1.6.0 (pure-Python QR library, no Pillow needed) to requirements.txt
- Generate QR code as a base64 SVG data URI server-side in the challenge endpoint
- Add qr_code_svg field to CreateChallengeResponse Pydantic model
- Replace canvas+CDN script in qr_login.html with an <img :src="qrCodeSvg">
- Remove the $nextTick/QRCode.toCanvas() client-side rendering block
- Extract QR rendering parameters (_QR_ERROR_LEVEL, _QR_SCALE) as module constants

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-18 08:34:22 +00:00
google-labs-jules[bot] f6a2bae05e Fix authorization bypass in API (IDOR) by applying owner filter
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-18 03:44:12 +00:00
copilot-swe-agent[bot] a08b103271 fix: merge main into feature branch - resolve all merge conflicts cleanly
Merges origin/main (v0.156.0) into the classification feature branch,
properly resolving all 23 merge conflicts:

- Auto-generated files (BUILD_DATE, VERSION, etc.): accept main's version
- Non-classification files (SharePoint, QR auth, session mgmt, mobile): accept main's version
- Classification files (api/__init__.py, models.py, migrations/env.py, conftest.py):
  keep classification additions alongside main's content

Previously the branch was incorrectly removing files from main (SharePoint
integration, QR scanner, session management). This merge properly preserves
all main branch content while maintaining the classification feature additions.

Migration chain validated: 038_add_classification_rules chains from
037_add_user_sessions_and_qr_challenges.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 16:14:45 +00:00
copilot-swe-agent[bot] 342e2d1614 fix: merge main into feature branch - resolve all 18 conflicts cleanly
Merges origin/main (v0.155.0) into the classification feature branch,
resolving all 18 conflicted files by accepting main's version and
re-applying only classification-specific additions:

- Renumber migration from 037 to 038 (chains from 037_user_sessions)
- Re-add ClassificationRuleModel to models.py, env.py, conftest.py
- Re-add classification_rules_router to api/__init__.py
- All session management, QR auth, and devices code preserved from main

Migration chain validated. 62 classification tests pass.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 13:22:28 +00:00
copilot-swe-agent[bot] 571cc81789 feat(api): add per-user health-aware upload rate limiting
Introduces a Redis-backed sliding-window rate limiter for upload
endpoints (/api/ui-upload, /api/process-url) that:
- Enforces per-user limits (default: 20 uploads / 60 s)
- Dynamically reduces limits under system stress (queue depth, CPU load)
- Returns 429 with Retry-After header when exceeded
- Fails open when Redis is unavailable
- Works with the existing client-side adaptive back-off

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 12:12:50 +00:00
copilot-swe-agent[bot] 0f6a1ee1ec fix(api): add ttl_seconds to QR challenge response and fix client-side countdown
The QR login page countdown timer compared the server's UTC expiration
timestamp against the client's local clock, causing the QR code to appear
immediately expired when the client clock was ahead of the server.

Changes:
- Add ttl_seconds field to CreateChallengeResponse (seconds until expiry)
- Frontend countdown now uses relative elapsed time since response was
  received, eliminating clock-skew issues
- Mobile app: replace alert-only QR button with actual camera-based
  QR code scanner using expo-camera
- Add QRScannerScreen with barcode scanning, permission handling, and
  scan area overlay
- Update camera permission description to mention QR code scanning
- Add tests for ttl_seconds computation

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 12:02:33 +00:00
Christian Krakau-Louis 8905031d16 Merge branch 'main' into copilot/implement-log-off-everywhere-functionality 2026-03-17 12:12:50 +01:00
copilot-swe-agent[bot] c7d67031d4 fix: resolve merge conflicts with main branch
Merge origin/main into feature branch, resolving 18 conflicts:
- app/api/__init__.py: add classification_rules_router alongside system_reset_router
- app/config.py: keep system reset settings from main
- app/models.py: keep ClassificationRuleModel alongside main's models
- app/utils/settings_service.py: keep factory reset settings from main
- app/views/__init__.py: keep system_reset_router from main
- tests/conftest.py: add ClassificationRuleModel import
- migrations/env.py: add ClassificationRuleModel import
- .env.demo, docs/*, frontend/*, mobile/*: keep additions from main
- BUILD_DATE, GIT_SHA, RUNTIME_INFO, VERSION, CHANGELOG.md: accept main's version

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 11:09:39 +00:00
copilot-swe-agent[bot] 03712cfb08 feat(ui): add dedicated Devices page for mobile tokens and registered devices
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 11:00:36 +00:00
copilot-swe-agent[bot] f75b125992 feat(scaling): enable horizontal scaling for API and worker pods
- Add unauthenticated /api/diagnostic/healthz/live and /healthz/ready
  probe endpoints for Kubernetes liveness/readiness checks
- Separate Celery Beat into dedicated beat service in docker-compose.yaml
- Remove container_name from api and worker services to allow scaling
- Create Helm beat-deployment.yaml for standalone Beat scheduler pod
- Remove -B flag from worker-deployment.yaml so workers can scale safely
- Add beat section and fix probe paths in Helm values.yaml
- Add tests for the new probe endpoints

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 23:52:56 +00:00
copilot-swe-agent[bot] 204000aabc fix: merge main branch and renumber migration 027→037
Resolve 3 merge conflicts and renumber the automation_hooks migration
to follow main's migration chain (036_add_document_translation_fields).

Conflicts resolved:
- app/api/__init__.py: add automation_router alongside main's new routers
- app/utils/settings_service.py: add automation_hooks_enabled alongside compliance_enabled
- tests/conftest.py: add AutomationHook alongside AuditLog/ComplianceTemplate imports

Migration renumbered:
- 027_add_automation_hooks → 037_add_automation_hooks
- down_revision: 026_add_scheduled_jobs → 036_add_document_translation_fields

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 22:40:15 +00:00
copilot-swe-agent[bot] 651b48658c fix: resolve merge conflicts with main branch
Merge origin/main into feature branch, resolving 3 conflicts:
- app/api/__init__.py: add classification_rules_router alongside new
  routers from main (audit_logs, i18n, mobile, compliance, translation)
- app/models.py: keep ClassificationRuleModel alongside new models from
  main (MobileDevice, ComplianceTemplate, PipelineRoutingRule)
- tests/conftest.py: import both ClassificationRuleModel and new models
  from main (AuditLog, ComplianceTemplate)

Also renumber migration from 027 to 037 to chain from the latest
migration on main (036_add_document_translation_fields).

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 22:33:59 +00:00
copilot-swe-agent[bot] a4588a57cb feat(auth): add server-side session management and QR code login backend
- Add UserSession and QRLoginChallenge models for session tracking
  and mobile QR authentication
- Add session_manager utility with create/validate/revoke/cleanup
  functions and QR challenge helpers
- Add /api/sessions endpoints for listing, revoking, and
  'log off everywhere' functionality
- Add /api/qr-auth endpoints for challenge creation, polling, and
  claiming with API token issuance
- Add session config fields (lifetime, custom override, QR TTL)
- Update get_current_user to validate server-side sessions
- Create server-side sessions on all login paths (local, OAuth,
  social, admin)
- Revoke server-side session on logout
- Configure SessionMiddleware max_age from session lifetime settings
- Graceful degradation: old sessions without _session_token continue
  to work

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-16 22:29:04 +00:00
copilot-swe-agent[bot] a88d790445 feat(system-reset): add system reset and factory reset feature
- Add FACTORY_RESET_ON_STARTUP and ENABLE_FACTORY_RESET config settings
- Create app/utils/system_reset.py with core reset logic (wipe DB + files, reimport)
- Create app/api/system_reset.py with admin-only API endpoints
- Create app/views/system_reset.py with admin-only UI view
- Create frontend/templates/system_reset.html with confirmation dialogs
- Auto-reset on startup when FACTORY_RESET_ON_STARTUP=true
- Re-import uses watch folder mechanism for re-ingestion
- Register routers in API and views init files
- Add i18n keys and SETTING_METADATA entries
- Add nav links in base.html (desktop + mobile)

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 22:26:17 +00:00
copilot-swe-agent[bot] 825f3cc3a8 fix(translation): fix apply_owner_filter called with wrong arguments
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 15:25:29 +00:00