10 Commits

Author SHA1 Message Date
ec432a037c feat: Implement OAuth 2.0 authentication with PKCE and automatic fallback
Add complete OAuth 2.0 Authorization Code Flow with PKCE as alternative
to API token authentication, with automatic server detection and graceful
fallback to classic login.

**OAuth Core (RFC 7636 PKCE):**
- PKCEGenerator: S256 challenge generation for secure code exchange
- OAuth DTOs: Client registration, token request/response models
- OAuthClient, OAuthToken, AuthenticationMethod domain models
- API.swift: registerOAuthClient() and exchangeOAuthToken() endpoints
- OAuthRepository + POAuthRepository protocol

**Browser Integration (ASWebAuthenticationSession):**
- OAuthSession: Wraps native authentication session
- OAuthFlowCoordinator: Orchestrates 5-phase OAuth flow
- readeck:// URL scheme for OAuth callback handling
- State verification for CSRF protection
- User cancellation handling

**Token Management:**
- KeychainHelper: OAuth token storage alongside API tokens
- TokenProvider: getOAuthToken(), setOAuthToken(), getAuthMethod()
- AuthenticationMethod enum to distinguish token types
- AuthRepository: loginWithOAuth(), getAuthenticationMethod()
- Endpoint persistence in both Keychain and Settings

**Server Feature Detection:**
- ServerInfo extended with features array and supportsOAuth flag
- GET /api/info endpoint integration (backward compatible)
- GetServerInfoUseCase with optional endpoint parameter

**User Profile Integration:**
- ProfileApiClient: Fetch user data via GET /api/profile
- UserProfileDto with username, email, provider information
- GetUserProfileUseCase: Extract username from profile
- Username saved and displayed for OAuth users (like classic auth)

**Automatic OAuth Flow (No User Selection):**
- OnboardingServerView: 2-phase flow (endpoint → auto-OAuth or classic)
- OAuth attempted automatically if server supports it
- Fallback to username/password on OAuth failure or unsupported
- SettingsServerViewModel: checkServerOAuthSupport(), loginWithOAuth()

**Cleanup & Refactoring:**
- Remove all #if os(iOS) && !APP_EXTENSION conditionals
- Remove LoginMethodSelectionView (no longer needed)
- Remove switchToClassicLogin() method
- Factories updated with OAuth dependencies

**Testing:**
- PKCEGeneratorTests: Verify RFC 7636 compliance
- ServerInfoTests: Feature detection and backward compatibility
- Mock implementations for all OAuth components

**Documentation:**
- docs/OAuth2-Implementation-Plan.md: Complete implementation guide
- openapi.json: Readeck API specification

**Scopes Requested:**
- bookmarks:read, bookmarks:write, profile:read

OAuth users now have full feature parity with classic authentication.
Server auto-detects OAuth support via /info endpoint. Seamless UX with
browser-based login and automatic fallback.
2025-12-19 21:56:40 +01:00
03cd32dd4d fix: Prevent sync during onboarding and improve Share Extension UX
- Add guard checks in AppViewModel to prevent sync when hasFinishedSetup is false
- Share Extension now shows friendly UI when app not configured or session expired
- Check token existence via KeychainHelper instead of attempting API calls
- Improve 401 error messages: "Session expired. Please log in via the Readeck app."
- Replace #if DEBUG with BuildEnvironment.isDebugBuild for runtime checks
- Enable Debug Menu in both DEBUG and TestFlight builds
- Replace print() statements with Logger.sync/Logger.viewModel
2025-12-19 21:34:22 +01:00
997d740597 fix: Replace local() with url() for WKWebView font loading
Fix custom fonts not displaying in WKWebView by replacing CSS `src: local()`
with `src: url()` using bundle file paths. WKWebView cannot resolve fonts via
local() even when registered in Info.plist UIAppFonts.

Changes:
- Add fontFileNames and cssFontFamily properties to FontFamily enum
- Implement generateFontFaceCSS() helper in WebView.swift and NativeWebView.swift
- Generate @font-face CSS with file:// URLs for all 12 font files
- Fonts are now dynamically loaded from FontFamily enum (single source of truth)

Affected fonts:
- Literata (Regular, Bold)
- Merriweather (Regular, Bold)
- Source Serif 4 (Regular, Bold)
- Lato (Regular, Bold)
- Montserrat (Regular, Bold)
- Source Sans 3 (Regular, Bold)
2025-12-19 21:31:01 +01:00
358037427c refactor: Remove unused stripHTMLSimple method from StringExtensions
- Remove stripHTMLSimple regex-based HTML stripping method
- Keep stripHTML with NSAttributedString-based implementation (used in codebase)
- Method was not used anywhere in the project
2025-12-01 22:06:52 +01:00
f3719fa9d4 Refactor tag management to use Core Data with configurable sorting
This commit introduces a comprehensive refactoring of the tag management
system, replacing the previous API-based approach with a Core Data-first
strategy for improved performance and offline support.

Major Changes:

Tag Management Architecture:
- Add CoreDataTagManagementView using @FetchRequest for reactive updates
- Implement cache-first sync strategy in LabelsRepository
- Create SyncTagsUseCase following Clean Architecture principles
- Add TagSortOrder enum for configurable tag sorting (by count/alphabetically)
- Mark LegacyTagManagementView as deprecated

Share Extension Improvements:
- Replace API-based tag loading with Core Data queries
- Display top 150 tags sorted by usage count
- Remove unnecessary label fetching logic
- Add "Most used tags" localized title
- Improve offline bookmark tag management

Main App Enhancements:
- Add tag sync triggers in AddBookmarkView and BookmarkLabelsView
- Implement user-configurable tag sorting in settings
- Add sort order indicator labels with localization
- Automatic UI updates via SwiftUI @FetchRequest reactivity

Settings & Configuration:
- Add TagSortOrder setting with persistence
- Refactor Settings model structure
- Add FontFamily and FontSize domain models
- Improve settings repository with tag sort order support

Use Case Layer:
- Add SyncTagsUseCase for background tag synchronization
- Update UseCaseFactory with tag sync support
- Add mock implementations for testing

Localization:
- Add German and English translations for:
  - "Most used tags"
  - "Sorted by usage count"
  - "Sorted alphabetically"

Technical Improvements:
- Batch tag updates with conflict detection
- Background sync with silent failure handling
- Reduced server load through local caching
- Better separation of concerns following Clean Architecture
2025-11-08 13:46:40 +01:00
db3cbf41d4 Fix URL label translation and formatting
- Add localization keys for "open_url" and "open_original_page" in EN/DE
- Create URLUtil.openUrlLabel() helper function for consistent formatting
- Replace incorrect string concatenation with proper localized labels
- Fix: "example.comopen" now displays as "Open example.com" (EN) or "example.com öffnen" (DE)
- Update BookmarkDetailLegacyView, BookmarkDetailView2, and BookmarkCardView
2025-10-30 21:14:40 +01:00
e5334d456d refactor: Remove NWPathMonitor auto-sync, keep only on-demand server checks
- Delete NetworkConnectivity.swift with problematic NWPathMonitor
- Remove serverDidBecomeAvailable notification
- Remove unused startAutoSync from OfflineSyncManager
- Server check now only on app start via AppViewModel
2025-10-19 10:47:19 +02:00
Christian Putzke
f78de1f740 Added setting to select in app or default browser to open external links 2025-09-18 22:35:43 +02:00
df8a7b64b2 feat: Add Kingfisher caching, card layouts, dynamic tag layout, and undo delete
- Integrate Kingfisher for image caching with CachedAsyncImage component
- Add CacheSettingsView for managing image cache size and clearing cache
- Implement three card layout styles: compact, magazine (default), natural
- Add AppearanceSettingsView with visual layout previews and theme settings
- Create Clean Architecture for card layout with domain models and use cases
- Implement FlowLayout for dynamic label width calculation
- Add skeleton loading animation for initial bookmark loads
- Replace delete confirmation dialogs with immediate delete + 3-second undo
- Support multiple simultaneous undo operations with individual progress bars
- Add grayed-out visual feedback for pending deletions
- Centralize notification names in dedicated NotificationNames file
- Remove pagination logic from label management (replaced with FlowLayout)
- Update AsyncImage usage across BookmarkCardView, BookmarkDetailView, ImageViewerView
- Improve UI consistency and spacing throughout the app
2025-09-04 10:43:27 +02:00
e68959afce Refactor: Move Utils to UI/Utils, improve SpeechPlayer UI, enhance state management, remove legacy files, and optimize queue handling
- Move and replace utility files (SafariUtil, SpeechQueue, StringExtensions, TTSManager, VoiceManager)
- Refactor and extend SpeechPlayer components (UI, progress, volume, queue)
- Improved state and EnvironmentObject management (PlayerUIState)
- UI and logic optimizations in menu and tab views
- Remove obsolete and duplicate files
- General code and UX improvements
2025-07-14 21:34:39 +02:00