Skip to content

fix(auth): clear MFA enrollment flow state on every entry - #2463

Merged
russellwheatley merged 1 commit into
feat/mfa-enrollment-per-step-navfrom
fix/mfa-enrollment-reset-after-complete
Sep 2, 2026
Merged

fix(auth): clear MFA enrollment flow state on every entry#2463
russellwheatley merged 1 commit into
feat/mfa-enrollment-per-step-navfrom
fix/mfa-enrollment-reset-after-complete

Conversation

@demolaf

@demolaf demolaf commented Sep 1, 2026

Copy link
Copy Markdown
Member

After a successful MFA enrollment the flow state was never cleared, so re-entering landed the user on a form pre-filled from the previous attempt — phone number, verification code and a consumed smsSession all still live. #2467 moved that state above the NavHost and made most of it rememberSaveable, so it now outlives both step navigation and process death: longer-lived rather than cleaner. Across a sign-out, that is the previous user's data.

MfaEnrollmentFlowState.reset() returns all nine fields to the values rememberMfaEnrollmentFlowState() starts them at, and the host calls it on flow entry rather than on completion, through a new enterMfaEnrollment extension. Resetting on completion would mutate state a leaving step still reads while it is composed for the exit transition; on the way in there is no such step.

Every entry now goes through that helper, including one that previously did not. AuthRoute.MfaEnrollment and AuthRoute.MfaEnrollment.SelectFactor are different objects reporting the same route string, so onNavigate(AuthRoute.MfaEnrollment.SelectFactor) looked equivalent to onNavigate(AuthRoute.MfaEnrollment) but fell through to a plain navigate with no clear. A step named that way now clears and still lands on the step the host asked for, rather than being redirected through the resolved start step — a host deliberately showing the picker under a single-factor configuration keeps that behaviour.

This replaces the earlier approach on this branch, which reset inside MfaEnrollmentScreen and retained the pre-reset state through the pop transition. @russellwheatley found that the frozen snapshot's callbacks still closed over the cleared state, so Verify stayed tappable through the fade and a tap surfaced onError after enrollment had already succeeded. Per-step navigation removes the reset window altogether, so all ~117 lines of retention machinery are dropped rather than patched.

Adds 8 tests. Each clause of the widened entry condition is independently pinned by mutation, as is the step-resolution path and every field of reset(): three mutants, each killing exactly the test that names the behaviour it breaks. Note the one-clause "simplification" compiles cleanly, so only a test catches it.

A single-pop bug in this area — steps push, but completion popped one entry and landed on ConfigureSms instead of leaving the flow — was found while writing these tests and is being fixed in #2467 instead, since it propagates up the nav stack and a fix landing only here would be silently reintroduced by #2469.


Maintainer note: Fixes internal CPRN-384

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a state reset mechanism to the MFA enrollment screen upon successful enrollment, resetting it back to the SelectFactor step and clearing consumed inputs before invoking onComplete. To prevent the UI from prematurely resetting during the back-stack pop transition, a MfaEnrollmentDestination wrapper with a RetainedMfaEnrollmentState has been introduced to freeze and retain the completed state during the transition. Additionally, single-factor auto-advance is now suppressed after a completed enrollment to avoid re-triggering the flow upon state restoration. Comprehensive unit tests have been added to verify these behaviors. I have no feedback to provide as there are no review comments.

@demolaf
demolaf force-pushed the feat/mfa-enrollment-test branch from 837d1b8 to bcb4a97 Compare September 1, 2026 15:48
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from ab4f6dd to f3f02fd Compare September 1, 2026 15:48
@demolaf
demolaf force-pushed the feat/mfa-enrollment-test branch from bcb4a97 to 5a7ea86 Compare September 1, 2026 16:17
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from f3f02fd to ce24ffa Compare September 1, 2026 16:17

@russellwheatley russellwheatley left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Frozen Verify stays tappable through the pop fade. Those callbacks close over the already-reset live state, so a tap can surface onError after enrollment already succeeded.

Suggested a copy in freeze() that disables the form, and an isLoading pin on the retention test.

Comment thread auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt Outdated
@demolaf
demolaf changed the base branch from feat/mfa-enrollment-test to feat/mfa-enrollment-per-step-nav September 2, 2026 10:51
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from ce24ffa to 7e2ad77 Compare September 2, 2026 11:28
@demolaf demolaf changed the title fix(auth): reset MfaEnrollmentScreen to a clean flow after successful enrollment fix(auth): clear MFA enrollment state on entry and pop the whole flow on exit Sep 2, 2026
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from 7e2ad77 to 56f7e51 Compare September 2, 2026 12:10
@demolaf demolaf changed the title fix(auth): clear MFA enrollment state on entry and pop the whole flow on exit fix(auth): clear MFA enrollment flow state on entry Sep 2, 2026
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from 56f7e51 to d40fa39 Compare September 2, 2026 12:40
@demolaf demolaf changed the title fix(auth): clear MFA enrollment flow state on entry fix(auth): clear MFA enrollment flow state on every entry Sep 2, 2026
@demolaf
demolaf marked this pull request as draft September 2, 2026 13:00
@demolaf
demolaf force-pushed the feat/mfa-enrollment-per-step-nav branch 2 times, most recently from 548c396 to a38bb4f Compare September 2, 2026 13:30
@demolaf
demolaf marked this pull request as ready for review September 2, 2026 13:34
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from d40fa39 to 24f762d Compare September 2, 2026 13:50
@russellwheatley
russellwheatley force-pushed the feat/mfa-enrollment-per-step-nav branch from a38bb4f to bfc6583 Compare September 2, 2026 14:23
@demolaf
demolaf force-pushed the fix/mfa-enrollment-reset-after-complete branch from 24f762d to cee8bb9 Compare September 2, 2026 15:18
@russellwheatley
russellwheatley merged commit 394e299 into feat/mfa-enrollment-per-step-nav Sep 2, 2026
9 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in studio-2394994192-60a69 Sep 2, 2026
@russellwheatley
russellwheatley deleted the fix/mfa-enrollment-reset-after-complete branch September 2, 2026 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants