Commit Graph

27 Commits

Author SHA1 Message Date
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
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] 6541529250 fix(mobile): address code review feedback - error handling, filename collision, hash display
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 19:13:53 +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] ec882214e2 refactor(mobile): extract normalizeFileUri to shared utility module
Address code review feedback:
- Extract normalizeFileUri to mobile/src/utils/normalizeUri.ts
- Import shared function in ShareContext and UploadScreen
- Move os import to top of test file
- Update test docstring to reflect new behavior

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 14:11:08 +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] cfe83d7efa refactor(mobile): extract shared MIME type utility and improve error handling
- Extract EXT_TO_MIME map and mimeTypeFromFilename to shared module
  at mobile/src/utils/mimeTypes.ts (used by _layout.tsx and +not-found.tsx)
- Add error logging to ensureLocalUri catch block for debugging
- Add error handling to Linking.openURL calls in ProfileScreen
- Fix incorrect LSSupportsOpeningDocumentsInPlace docs in audit report

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 12:05:47 +00:00
copilot-swe-agent[bot] f549505bfd fix(mobile): fix shared file upload hanging by copying to cache
Files shared via iOS Share Sheet / "Open In…" may reference paths
outside the app's sandbox or use security-scoped URLs that React
Native's fetch cannot read. This caused uploads to hang indefinitely
with a spinning indicator.

Fixes:
- Set LSSupportsOpeningDocumentsInPlace to false so iOS copies shared
  files to the app's accessible Inbox directory
- Use expo-file-system to copy external file:// URIs to the app's
  cache directory before uploading (ensureLocalUri helper)
- Apply ensureLocalUri to both initial uploads and retries

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 12:03:12 +00:00
copilot-swe-agent[bot] 1559686f90 fix(mobile): fix file sharing deep-link conflicts and add MIME type inference
- Skip known deep-link paths (qr-login, callback) in makeUrlHandler
  to prevent docuelevate://qr-login URLs from being treated as shared
  files and creating phantom upload errors
- Infer MIME type from file extension for files shared via iOS Share
  Sheet / "Open In…" so the server receives correct Content-Type
  instead of application/octet-stream
- Default login screen server URL to https://app.docuelevate.org

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 11:55:45 +00:00
copilot-swe-agent[bot] 136631762b fix(mobile): add user feedback when server URL is unavailable
Show alert dialogs when Privacy Policy, Terms of Service, or
account deletion links cannot be opened due to missing server URL.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 11:46:54 +00:00
copilot-swe-agent[bot] 5c15a2395a fix(mobile): Apple App Store compliance fixes
- Remove unused `fetch` from UIBackgroundModes (Guideline 2.5.4)
- Add iOS privacy manifest configuration for required reason APIs
- Add Privacy Policy and Terms of Service links to ProfileScreen
- Add account deletion capability (Guideline 5.1.1(v))
- Remove unused Switch import from ProfileScreen
- Replace emoji icons with Ionicons in UploadScreen and FilesScreen
- Add app version display to ProfileScreen

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 11:38:48 +00:00
copilot-swe-agent[bot] 71a7a57adc fix(mobile): add shared file to ShareContext directly in +not-found.tsx
When iOS delivers a file via "Open In…", expo-router strips the
docuelevate:// scheme and routes to +not-found.tsx. Previously, this
screen only redirected to the Upload tab and relied on the Linking
handler in _layout.tsx to add the file to ShareContext. This was
unreliable because expo-router may consume the URL event before the
Linking handler fires.

Now +not-found.tsx directly reconstructs the file:// URI from the
pathname and adds it to ShareContext before redirecting. ShareContext
deduplicates by URI to prevent double uploads if both mechanisms fire.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-19 11:12:34 +00:00
copilot-swe-agent[bot] 70b193e07d fix(mobile): replace gap with marginLeft for React Native compatibility
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-17 12:05:39 +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
copilot-swe-agent[bot] 51821092f4 feat(auth): add session management UI, QR login page, mobile QR support, translations
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 22:38:13 +00:00
copilot-swe-agent[bot] d322ec6dc7 feat(mobile): add retry for failed uploads via tap and long-press
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 20:35:13 +00:00
copilot-swe-agent[bot] b6af39c567 refactor(mobile): address code review feedback
Extract APP_SCHEME_PREFIX constant for the custom URL scheme string,
and derive the photo library fallback filename extension from the
asset's MIME type instead of always using .jpg.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 17:26:28 +00:00
copilot-swe-agent[bot] acfba4b58c fix(mobile): handle iOS share sheet custom scheme URLs and add photo library picker
On iOS the Share Sheet / "Open In" action may deliver the file path
under the app's custom docuelevate:// scheme instead of a file:// URL,
causing an "Unmatched Route" error.  The URL handler now detects this
and rewrites the URL to file:// before processing.

Also adds a Photo Library button to the Upload screen so users can
select existing photos from their device library, not just capture
new ones with the camera.

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 17:25:03 +00:00
copilot-swe-agent[bot] 4de6b439ce fix(mobile): iOS share sheet, empty files tab, and stuck upload status
- app.json: add CFBundleDocumentTypes to iOS infoPlist so the app
  appears in the iOS Share Sheet; add ACTION_SEND/SEND_MULTIPLE
  intentFilters for Android share intent support

- src/context/ShareContext.tsx (new): React context that queues files
  received from the share sheet and delivers them to UploadScreen

- app/_layout.tsx: wrap in ShareProvider; add Linking handler
  (makeUrlHandler factory + getInitialURL cold-start + addEventListener
  warm-start) to capture file:// and content:// URLs

- src/services/api.ts: fix FileRecord interface (original_filename,
  nested ProcessingStatus, mime_type); fix UploadResponse interface;
  fix listFiles() (per_page param, unwrap data.files); add
  getFileStatus(fileId) for single-file status polling

- src/screens/FilesScreen.tsx: use file.original_filename and
  file.processing_status.status; fix statusEmoji to use actual backend
  status values (completed/pending/duplicate)

- src/screens/UploadScreen.tsx: consume ShareContext for auto-upload of
  shared files; add 5-second polling loop (search by filename → file_id
  → getFileStatus) to show real-time server processing status;
  uploadFile wrapped in useCallback; proper effect dependency arrays

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-16 15:52:54 +00:00
copilot-swe-agent[bot] 14285567d5 fix(auth): Expo Go support via Linking.createURL; safe token URL construction; clean up return type annotation
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 17:42:36 +00:00
copilot-swe-agent[bot] 5c373e7224 fix(auth): store mobile_redirect_uri in session and redirect to deep-link after SSO; fix SafeAreaView deprecation
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 17:35:49 +00:00
copilot-swe-agent[bot] 073627884c fix(mobile): align React version with react-native-renderer to fix version mismatch crash
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 16:28:36 +00:00
copilot-swe-agent[bot] 82d90b48e2 fix(mobile): correct asset logo path depth and add expo-router app/ routes for web support
- Fix fatal crash: require('../../../assets/logo.png') in LoginScreen and
  WelcomeScreen resolved 3 levels above mobile/src/screens/ — outside the
  mobile/ directory. Changed to ../../assets/logo.png which correctly
  resolves to the existing mobile/assets/logo.png.
- Add expo-router app/ directory (root cause of missing welcome screen and
  web support): app/_layout.tsx, (auth)/, (tabs)/ with all route files
- Add WelcomeScreen.tsx: branded intro screen with feature highlights
- Update LoginScreen/WelcomeScreen to use useRouter() (expo-router style)
- Add react-native-web ~0.20.0 and react-dom 19.2.4 for web channel
- Add expo-device ~7.0.3 (was imported but missing from package.json)
- Remove android.googleServicesFile from app.json (file is gitignored;
  README documents how to restore it for Android FCM builds)
- Add web.bundler: metro and web.output: single to app.json
- Fix aria-hidden to explicit boolean value in WelcomeScreen

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 16:02:02 +00:00
copilot-swe-agent[bot] a2de72ab72 wip: tracking plan
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 15:54:00 +00:00
copilot-swe-agent[bot] f983b20a8f fix(mobile): fix iOS TurboModule crash and npm install peer dep conflict
- UploadScreen.tsx: replace deprecated ImagePicker.MediaTypeOptions.Images
  with new array syntax ['images'] — the old enum is not accepted by the
  expo-image-picker v17 TurboModule on iOS, causing SIGABRT on Thread 2
- package.json: bump react 19.1.0 → 19.2.4 so react-dom@19.2.4 (peerOptional
  of @expo/metro-runtime) no longer conflicts; update @types/react to ~19.2.0
- package-lock.json: update react entry to 19.2.4 (integrity removed, will be
  regenerated by npm install on the next EAS build)

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-15 13:53:27 +00:00
copilot-swe-agent[bot] 971e578dd7 feat(mobile): update DocuElevate mobile app branding with original logo and UX
- Regenerate all app icons (icon.png, adaptive-icon.png, splash.png,
  favicon.png, notification-icon.png) using the DocuElevate folder+gear
  SVG logo on brand blue (#1e40af) background
- Add assets/logo.png (200×200 circular logo) for the login screen
- Update LoginScreen.tsx to display the DocuElevate logo image above
  the brand name text instead of plain text only
- Replace emoji tab bar icons (⬆️📄👤) with Ionicons vector icons
  (cloud-upload-outline, document-text-outline, person-circle-outline)
  from the already-installed @expo/vector-icons package

Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-14 22:41:02 +00:00
copilot-swe-agent[bot] d538c0879d feat(mobile): add iOS/Android mobile app with SSO login, camera upload, and push notifications
Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
2026-03-10 09:52:02 +00:00