Harden native login Cloudflare cookie handoff#87
Merged
Conversation
Redesign login flow to align with fluxdo: - Native UIKit login page (FireLoginViewController) with logo, credential inputs, remember-password checkbox, social login icons - hCaptcha + login request moved to separate dialog VC (FireCaptchaLoginDialogController), presented on-demand after user taps login - CF verification triggered on-demand instead of on page open - Social login icons route to full WebView fallback - Error handling uses inline banner instead of UIAlertController
Address 7 review items: - Merge Phase 1+2: UI and login flow wired together as one deliverable - Add live WebView handoff constraint for cookie extraction - Thread rememberCredential param through to finalization - VC owns dialog presentation, ViewModel exposes async capabilities - Replace 3 social icons with single 'other login methods' button + forgot password link - Rewrite error table per WebViewLoginDecisionState (2FA repeat, CF retry precision) - Remove duplicate Phase 2 section
8 tasks across 3 phases: - Phase 1: FireCaptchaLoginDialogController + FireLoginViewController + ViewModel async capabilities + coordinator switch + CF retry (Tasks 1-5) - Phase 2: FireWebViewBrowserViewController for OAuth/forgot-password (Task 6) - Phase 3: Error banner polish + 2FA messaging (Task 7) - Verification: Manual flow testing (Task 8)
- Fix FireWebViewBrowserProfile usage: static API, not instance - Fix FireCaptchaScriptMessageProxy delegate type - Fix hcaptcha_pass parsing: token is String not dictionary - Move classifyResult to class stored property (not extension) - CF retry uses recoverLoginCloudflareChallenge(in:) not ensureCloudflareClearance - Full WebView fallback uses completeLogin(from:) not completeMinimalLogin - Uncheck remember-password clears saved credentials (product decision) - Build commands use xcodegen + Fire.xcodeproj (not .xcworkspace) - Credential auto-fill uses Combine subscription (not viewDidLoad read) - Add xcodegen generate + project.pbxproj to commit steps
Require platform challenge flows to report the accepted fresh cf_clearance value before Rust trusts WebView cookies. Replace the iOS monolithic login WebView with a native form plus captcha/fallback WebView controllers, and align Android login extraction with WebView cookie metadata.
Document fresh cf_clearance handoff, rich WebView cookie extraction, the native login split, and move the fluxdo reference pointer to the v0.2.18-derived source used for this behavior.
Do not require the platform-reported clearance to differ from Rust's previous snapshot. The WebView baseline can be missing while Rust still has the same accepted value, and forcing a rotation leaves follow-up requests stuck behind the local Cloudflare cooldown.
P1: restore completeStartupAfterPreheat driving path via performStartupValidation P1: replace isBootstrappingSession phase derivation with isStartupValidationComplete P1: add explicit captcha dialog/logginIn phase dismissal on login success P1: extract prepareLoginForm for saved credential loading P2: add scroll/keyboard constraints to form view spec P2: expand doc sync scope to README + architecture
Step 1 of unified onboarding launch design (docs/architecture/2026-06-17-unified-onboarding-launch-design.md §2). Three new additive UIView subclasses, not yet wired into the onboarding VC: - FireOnboardingValidatingView: loading indicator + label for .validating phase - FireOnboardingCredentialFormView: scroll-backed credential form migrated from FireLoginViewController (identifier/password/remember/login/forgot/other-methods fields, keyboard inset handling, closure-based callbacks, applySavedCredential/setLoggingIn API) - FireOnboardingLoggingInView: semi-transparent overlay for .loggingIn phase Build verified: xcodebuild BUILD SUCCEEDED.
phaseContainerView is an arranged subview of bottomStack (a UIStackView with alignment=.fill); manual leading/trailing/bottom constraints duplicated and conflicted with the stack's auto-generated ones. Keep only the heightAnchor minimum so the stack manages position, matching errorBanner's treatment. Found in WS1 code quality review.
applyPhase(.loggingIn) now calls setLoginLoading(true) to disable view.isUserInteractionEnabled (restoring the original LoginVC screen-freeze invariant that was lost in the migration), and setLoginLoading(false) when leaving .loggingIn. The loggingInView overlay + form disabling alone left the brand area and dev-tools button tappable during login. Found in WS2 code quality review.
Step 6 of unified onboarding launch design: - fire-native-architecture.md: RootCoordinator comment (launch↔main), Auth/ file tree (FireLoginViewController → onboarding subviews + Startup/), changelog (login/preheat consolidated into onboarding page) - README.md: FireLoginViewController entry → FireOnboardingCredentialFormView, RootCoordinator role (two-state, no preheat/auth-modal), FireAppViewModel startup-validation bullet (phase state machine), UX note (single unified launch page, three phases, no preheat gate)
Replace stale assertions for the deleted auth-presentation modal path (syncAuthPresentation, FireLoginWebViewController/FireLoginWebView) with assertions that pin the new unified onboarding contract: launch/main two-state root in FireRootCoordinator and login orchestration (performLogin + FireCaptchaLoginDialogController) in FireOnboardingView. Also drops the four pre-existing FireLoginWebView assertions that referenced a file already absent before this branch. Found in final whole-implementation review.
Push topic details through the selected tab navigation stack and remove the presented route host. Treat Cloudflare refresh as a clearance merge instead of an authoritative login cookie replace, with regressions and docs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
cf_clearancebefore Rust trusts WebView cookie snapshots, filtering stale variants during challenge completion.Verification
cargo test -p fire-models -p fire-core -p fire-uniffi-sessioncargo fmt --check./gradlew testDebugUnitTestxcodebuild test -scheme Fire -destination 'id=D733CCB1-7B2A-49B5-B3F8-36CB6D0CB2BF' -only-testing:FireTests/FireLoginScriptsTests CODE_SIGNING_ALLOWED=NO