feat(auth): implement legacyFetchSignInWithEmail configuration option#2316
Conversation
There was a problem hiding this comment.
Code Review
This pull request implements a legacy recovery path for email sign-in, intended for use when email enumeration protection is disabled. It introduces the DifferentSignInMethodRequiredException and a legacyFetchSignInWithEmail configuration flag. The core logic uses the legacy fetchSignInMethodsForEmail API to suggest alternative providers when a user attempts to sign in with an incorrect method. The UI layer, including ErrorRecoveryDialog and various screens, has been updated to handle this recovery flow. Review feedback highlights a missing recovery case in the top-level FirebaseAuthScreen, a redundant check in the recovery logic, and the need to support generic OAuth providers in the provider redirection callback.
Resolves conflicts by keeping legacyFetchSignInWithEmail from this branch alongside isReauthenticationMode from beta03, and adapting the refactored rememberOnProviderSelected pattern to preserve the continueWithProvider bridge needed for DifferentSignInMethodRequiredException recovery.
5002d6e to
d06fe25
Compare
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…on (firebase#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…ng (#2354) * fix(auth): improve user identifier retrieval (#2314) * fix(auth): improve user identifier retrieval * updates * fix: ensure that when selecting phone or email, it routes straight to that screen (#2311) * fix: use secondary app if it is passed into FirebaseAuthUI (#2313) * fix(auth): make AuthException messages customisable via AuthUIStringProvider (#2320) * fix(auth): preserve linkDomain in email link ActionCodeSettings (#2321) * fix(auth): log out before Facebook sign-in to clear stale cached token (#2322) Co-authored-by: russellwheatley <russellwheatley85@gmail.com> * Fix typo in README (#2325) * fix(auth): emit AuthResult on sign-in success and fix MFA tooltip auto-open (#2326) * fix(auth): update AuthState to reflect success or idle based on user result * updates * updates * refactor: rename auth user state handler * fix(auth): expose slot parameters through FirebaseAuthScreen (#2328) * fix(auth): add configurable params for custom UI - AuthMethodPicker - EmailAuth - PhoneAuth - MFA Enrollment & Challenge * fix(auth): add demo activities for email and phone authentication with customizable UI * updates * updates * feat(auth): add customMethodPickerTermsContent slot to FirebaseAuthScreen (#2330) * feat(auth): add termsContent slot to AuthMethodPicker for custom ToS UI * feat(auth): add termsAccepted parameter to AuthMethodPicker for consent handling * update example * updates * updates * updates * feat(auth): add isCredentialLinkingEnabled for authenticated users (#2319) * feat(auth): add isCredentialLinkingEnabled for authenticated non-anonymous users * t feat(app): add CredentialLinkingDemoActivity to sample app # Conflicts: # app/src/main/AndroidManifest.xml * updates * feat(auth): surface GIdP password policy violations with actionable error messages (#2333) * feat(auth): handle GIdP password policy violations with specific error messages * updates * updates * cleanup * fix(auth): allow SAML providers in AuthUIConfiguration (#2331) * fix(auth): allow saml. prefixed provider IDs in AuthUIConfiguration validation * updates * feat(auth): add reauthentication flow with automatic operation retry (#2332) * wip # Conflicts: # auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt # auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt * feat(auth): add reauthentication flow with automatic operation retry Adds AuthState.ReauthenticationRequired, withReauth(), and createReauthFlow() to support sensitive operations that require recent sign-in. FirebaseAuthUI.delete() and withReauth() automatically catch FirebaseAuthRecentLoginRequiredException, emit the new state carrying the original operation as retryOperation, and FirebaseAuthScreen presents a ModalBottomSheet overlay scoped to the user's linked providers — no navigation away from the authenticated screen. On successful reauthentication the original operation is retried automatically. * test(auth): add e2e tests for reauthentication flow UI * updates * fix reviews * update README * feat(auth): implement `legacyFetchSignInWithEmail` configuration option (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com> * fix(auth): replace hardcoded loading state strings with translatable string resources (#2339) * feat(auth): add localized loading messages for various sign-in states * updates * feat(auth): update sign-in methods to use AuthUIConfiguration for localized messages * refactor: use periods to represent ellipsis not the unicode character * refactor: use qualifiers, not base values in tests * fix(auth): remember authStateFlow() to avoid resubscribing on every recomposition * fix(auth): remember authStateFlow() in EmailAuthScreen to avoid resubscribing * docs(auth): note FirebaseAuthUI.create() instability inside composables --------- Co-authored-by: Russell Wheatley <russellwheatley85@gmail.com> Co-authored-by: Nillan Sivarasa <nillan.sivarasa@gmail.com>
…on (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com>
…ng (#2354) * fix(auth): improve user identifier retrieval (#2314) * fix(auth): improve user identifier retrieval * updates * fix: ensure that when selecting phone or email, it routes straight to that screen (#2311) * fix: use secondary app if it is passed into FirebaseAuthUI (#2313) * fix(auth): make AuthException messages customisable via AuthUIStringProvider (#2320) * fix(auth): preserve linkDomain in email link ActionCodeSettings (#2321) * fix(auth): log out before Facebook sign-in to clear stale cached token (#2322) Co-authored-by: russellwheatley <russellwheatley85@gmail.com> * Fix typo in README (#2325) * fix(auth): emit AuthResult on sign-in success and fix MFA tooltip auto-open (#2326) * fix(auth): update AuthState to reflect success or idle based on user result * updates * updates * refactor: rename auth user state handler * fix(auth): expose slot parameters through FirebaseAuthScreen (#2328) * fix(auth): add configurable params for custom UI - AuthMethodPicker - EmailAuth - PhoneAuth - MFA Enrollment & Challenge * fix(auth): add demo activities for email and phone authentication with customizable UI * updates * updates * feat(auth): add customMethodPickerTermsContent slot to FirebaseAuthScreen (#2330) * feat(auth): add termsContent slot to AuthMethodPicker for custom ToS UI * feat(auth): add termsAccepted parameter to AuthMethodPicker for consent handling * update example * updates * updates * updates * feat(auth): add isCredentialLinkingEnabled for authenticated users (#2319) * feat(auth): add isCredentialLinkingEnabled for authenticated non-anonymous users * t feat(app): add CredentialLinkingDemoActivity to sample app # Conflicts: # app/src/main/AndroidManifest.xml * updates * feat(auth): surface GIdP password policy violations with actionable error messages (#2333) * feat(auth): handle GIdP password policy violations with specific error messages * updates * updates * cleanup * fix(auth): allow SAML providers in AuthUIConfiguration (#2331) * fix(auth): allow saml. prefixed provider IDs in AuthUIConfiguration validation * updates * feat(auth): add reauthentication flow with automatic operation retry (#2332) * wip # Conflicts: # auth/src/main/java/com/firebase/ui/auth/configuration/auth_provider/EmailAuthProvider+FirebaseAuthUI.kt # auth/src/main/java/com/firebase/ui/auth/ui/screens/FirebaseAuthScreen.kt * feat(auth): add reauthentication flow with automatic operation retry Adds AuthState.ReauthenticationRequired, withReauth(), and createReauthFlow() to support sensitive operations that require recent sign-in. FirebaseAuthUI.delete() and withReauth() automatically catch FirebaseAuthRecentLoginRequiredException, emit the new state carrying the original operation as retryOperation, and FirebaseAuthScreen presents a ModalBottomSheet overlay scoped to the user's linked providers — no navigation away from the authenticated screen. On successful reauthentication the original operation is retried automatically. * test(auth): add e2e tests for reauthentication flow UI * updates * fix reviews * update README * feat(auth): implement `legacyFetchSignInWithEmail` configuration option (#2316) * feat(auth): implement legacyFetchSignInWithEmail configuration option * test: write tests for legacyFetchSignInWithEmail * fix(pr): address reviewer feedback on email recovery routing * refactor(pr): address reviewer feedback on legacy email recovery * fix: cancellation callback + test * chore: ignore kotlin cache * chore: run demo app script from command line --------- Co-authored-by: demolaf <demolafadumo@gmail.com> * fix(auth): replace hardcoded loading state strings with translatable string resources (#2339) * feat(auth): add localized loading messages for various sign-in states * updates * feat(auth): update sign-in methods to use AuthUIConfiguration for localized messages * refactor: use periods to represent ellipsis not the unicode character * refactor: use qualifiers, not base values in tests * fix(auth): remember authStateFlow() to avoid resubscribing on every recomposition * fix(auth): remember authStateFlow() in EmailAuthScreen to avoid resubscribing * docs(auth): note FirebaseAuthUI.create() instability inside composables --------- Co-authored-by: Russell Wheatley <russellwheatley85@gmail.com> Co-authored-by: Nillan Sivarasa <nillan.sivarasa@gmail.com>
Screen recording shows my attempt at trying to sign-in with Github when I have an account with email provider only:
Screen_recording_20260420_132518.webm