Skip to content

Commit 180db59

Browse files
committed
feat: remove email enumeration
1 parent 6c30641 commit 180db59

File tree

4 files changed

+73
-71
lines changed

4 files changed

+73
-71
lines changed

auth/src/main/java/com/firebase/ui/auth/ui/email/CheckEmailFragment.java

Lines changed: 54 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@
1212
import android.widget.ProgressBar;
1313
import android.widget.TextView;
1414

15-
import com.firebase.ui.auth.ErrorCodes;
16-
import com.firebase.ui.auth.FirebaseUiException;
15+
import com.firebase.ui.auth.AuthUI;
1716
import com.firebase.ui.auth.R;
1817
import com.firebase.ui.auth.data.model.FlowParameters;
1918
import com.firebase.ui.auth.data.model.User;
@@ -22,10 +21,8 @@
2221
import com.firebase.ui.auth.util.data.PrivacyDisclosureUtils;
2322
import com.firebase.ui.auth.util.ui.ImeHelper;
2423
import com.firebase.ui.auth.util.ui.fieldvalidators.EmailFieldValidator;
25-
import com.firebase.ui.auth.viewmodel.ResourceObserver;
2624
import com.google.android.material.snackbar.Snackbar;
2725
import com.google.android.material.textfield.TextInputLayout;
28-
import com.google.firebase.FirebaseNetworkException;
2926
import com.google.firebase.auth.EmailAuthProvider;
3027

3128
import androidx.annotation.NonNull;
@@ -48,7 +45,8 @@ public class CheckEmailFragment extends FragmentBase implements
4845

4946
public static final String TAG = "CheckEmailFragment";
5047
private CheckEmailHandler mHandler;
51-
private Button mNextButton;
48+
private Button mSignInButton;
49+
private Button mSignUpButton;
5250
private ProgressBar mProgressBar;
5351
private EditText mEmailEditText;
5452
private TextInputLayout mEmailLayout;
@@ -72,17 +70,16 @@ public View onCreateView(@NonNull LayoutInflater inflater,
7270

7371
@Override
7472
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
75-
mNextButton = view.findViewById(R.id.button_next);
73+
mSignInButton = view.findViewById(R.id.button_sign_in);
74+
mSignUpButton = view.findViewById(R.id.button_sign_up);
7675
mProgressBar = view.findViewById(R.id.top_progress_bar);
7776

78-
// Email field and validator
7977
mEmailLayout = view.findViewById(R.id.email_layout);
8078
mEmailEditText = view.findViewById(R.id.email);
8179
mEmailFieldValidator = new EmailFieldValidator(mEmailLayout);
8280
mEmailLayout.setOnClickListener(this);
8381
mEmailEditText.setOnClickListener(this);
8482

85-
// Hide header
8683
TextView headerText = view.findViewById(R.id.header_text);
8784
if (headerText != null) {
8885
headerText.setVisibility(View.GONE);
@@ -94,7 +91,9 @@ public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceStat
9491
mEmailEditText.setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_NO);
9592
}
9693

97-
mNextButton.setOnClickListener(this);
94+
// Set listeners for our new sign‑in and sign‑up buttons.
95+
mSignInButton.setOnClickListener(this);
96+
mSignUpButton.setOnClickListener(this);
9897

9998
TextView termsText = view.findViewById(R.id.email_tos_and_pp_text);
10099
TextView footerText = view.findViewById(R.id.email_footer_tos_and_pp_text);
@@ -124,54 +123,16 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) {
124123
}
125124
mListener = (CheckEmailListener) activity;
126125

127-
mHandler.getOperation().observe(getViewLifecycleOwner(), new ResourceObserver<User>(
128-
this, R.string.fui_progress_dialog_checking_accounts) {
129-
@Override
130-
protected void onSuccess(@NonNull User user) {
131-
String email = user.getEmail();
132-
String provider = user.getProviderId();
126+
// Removed the observer on mHandler.getOperation() since we no longer rely on provider info.
133127

128+
if (savedInstanceState == null) {
129+
String email = getArguments().getString(ExtraConstants.EMAIL);
130+
if (!TextUtils.isEmpty(email)) {
134131
mEmailEditText.setText(email);
135-
//noinspection ConstantConditions new user
136-
if (provider == null) {
137-
mListener.onNewUser(new User.Builder(EmailAuthProvider.PROVIDER_ID, email)
138-
.setName(user.getName())
139-
.setPhotoUri(user.getPhotoUri())
140-
.build());
141-
} else if (provider.equals(EmailAuthProvider.PROVIDER_ID)
142-
|| provider.equals(EMAIL_LINK_PROVIDER)) {
143-
mListener.onExistingEmailUser(user);
144-
} else {
145-
mListener.onExistingIdpUser(user);
146-
}
132+
// Previously auto-triggering the check is now removed.
133+
} else if (getFlowParams().enableHints) {
134+
mHandler.fetchCredential();
147135
}
148-
149-
@Override
150-
protected void onFailure(@NonNull Exception e) {
151-
if (e instanceof FirebaseUiException
152-
&& ((FirebaseUiException) e).getErrorCode() == ErrorCodes.DEVELOPER_ERROR) {
153-
mListener.onDeveloperFailure(e);
154-
}
155-
156-
if (e instanceof FirebaseNetworkException) {
157-
Snackbar.make(getView(), getString(R.string.fui_no_internet), Snackbar.LENGTH_SHORT).show();
158-
}
159-
160-
// Otherwise just let the user enter their data
161-
}
162-
});
163-
164-
if (savedInstanceState != null) {
165-
return;
166-
}
167-
168-
// Check for email
169-
String email = getArguments().getString(ExtraConstants.EMAIL);
170-
if (!TextUtils.isEmpty(email)) {
171-
mEmailEditText.setText(email);
172-
validateAndProceed();
173-
} else if (getFlowParams().enableHints) {
174-
mHandler.fetchCredential();
175136
}
176137
}
177138

@@ -184,34 +145,63 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
184145
public void onClick(View view) {
185146
int id = view.getId();
186147

187-
if (id == R.id.button_next) {
188-
validateAndProceed();
148+
if (id == R.id.button_sign_in) {
149+
signIn();
150+
} else if (id == R.id.button_sign_up) {
151+
signUp();
189152
} else if (id == R.id.email_layout || id == R.id.email) {
190153
mEmailLayout.setError(null);
191154
}
192155
}
193156

194157
@Override
195158
public void onDonePressed() {
196-
validateAndProceed();
159+
// When the user hits “done” on the keyboard, default to sign‑in.
160+
signIn();
161+
}
162+
163+
private String getEmailProvider() {
164+
// Iterate through all IdpConfig entries
165+
for (AuthUI.IdpConfig config : getFlowParams().providers) {
166+
// Assuming there is a getter for the provider ID
167+
if (EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD.equals(config.getProviderId())) {
168+
return EmailAuthProvider.EMAIL_LINK_SIGN_IN_METHOD;
169+
}
170+
}
171+
// Default to standard email/password
172+
return EmailAuthProvider.PROVIDER_ID;
173+
}
174+
175+
private void signIn() {
176+
String email = mEmailEditText.getText().toString();
177+
if (mEmailFieldValidator.validate(email)) {
178+
String provider = getEmailProvider();
179+
User user = new User.Builder(provider, email).build();
180+
mListener.onExistingEmailUser(user);
181+
}
197182
}
198183

199-
private void validateAndProceed() {
184+
private void signUp() {
200185
String email = mEmailEditText.getText().toString();
201186
if (mEmailFieldValidator.validate(email)) {
202-
mHandler.fetchProvider(email);
187+
String provider = getEmailProvider();
188+
User user = new User.Builder(provider, email).build();
189+
mListener.onNewUser(user);
203190
}
204191
}
205192

206193
@Override
207194
public void showProgress(int message) {
208-
mNextButton.setEnabled(false);
195+
// Disable both buttons while progress is showing.
196+
mSignInButton.setEnabled(false);
197+
mSignUpButton.setEnabled(false);
209198
mProgressBar.setVisibility(View.VISIBLE);
210199
}
211200

212201
@Override
213202
public void hideProgress() {
214-
mNextButton.setEnabled(true);
203+
mSignInButton.setEnabled(true);
204+
mSignUpButton.setEnabled(true);
215205
mProgressBar.setVisibility(View.INVISIBLE);
216206
}
217207

@@ -221,7 +211,7 @@ public void hideProgress() {
221211
interface CheckEmailListener {
222212

223213
/**
224-
* Email entered belongs to an existing email user.
214+
* Email entered belongs to an existing email user (sign‑in flow).
225215
*/
226216
void onExistingEmailUser(User user);
227217

@@ -231,7 +221,7 @@ interface CheckEmailListener {
231221
void onExistingIdpUser(User user);
232222

233223
/**
234-
* Email entered does not belong to an existing user.
224+
* Email entered does not belong to an existing user (sign‑up flow).
235225
*/
236226
void onNewUser(User user);
237227

@@ -240,4 +230,4 @@ interface CheckEmailListener {
240230
*/
241231
void onDeveloperFailure(Exception e);
242232
}
243-
}
233+
}

auth/src/main/java/com/firebase/ui/auth/ui/email/EmailLinkPromptEmailFragment.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ public View onCreateView(@NonNull LayoutInflater inflater,
5555

5656
@Override
5757
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
58-
mNextButton = view.findViewById(R.id.button_next);
58+
mNextButton = view.findViewById(R.id.button_sign_in);
59+
mSignUpButton = view.findViewById(R.id.button_sign_up);
5960
mProgressBar = view.findViewById(R.id.top_progress_bar);
6061

6162
mNextButton.setOnClickListener(this);
@@ -117,7 +118,7 @@ private void validateEmailAndFinishSignIn() {
117118
@Override
118119
public void onClick(View view) {
119120
int id = view.getId();
120-
if (id == R.id.button_next) {
121+
if (id == R.id.button_sign_in) {
121122
validateEmailAndFinishSignIn();
122123
} else if (id == R.id.email_layout || id == R.id.email) {
123124
mEmailLayout.setError(null);

auth/src/main/res/layout/fui_check_email_layout.xml

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,22 @@
4848

4949
</com.google.android.material.textfield.TextInputLayout>
5050

51+
<LinearLayout
52+
android:layout_width="wrap_content"
53+
android:layout_height="wrap_content"
54+
android:layout_gravity="end">
55+
<Button
56+
android:id="@+id/button_sign_up"
57+
style="@style/FirebaseUI.Button"
58+
android:text="@string/fui_title_register_email"
59+
android:layout_marginEnd="16dp"/>
60+
61+
<Button
62+
android:id="@+id/button_sign_in"
63+
style="@style/FirebaseUI.Button"
64+
android:text="@string/fui_sign_in_default" />
5165

52-
<Button
53-
android:id="@+id/button_next"
54-
style="@style/FirebaseUI.Button"
55-
android:text="@string/fui_next_default" />
66+
</LinearLayout>
5667

5768
<!-- Terms of service and Privacy Policy message that is displayed to the user if -->
5869
<!-- email is the only provider -->

auth/src/main/res/values/config.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,5 @@
2929
https://developers.google.com/identity/sign-in/web/devconsole-project
3030
https://developers.google.com/android/guides/google-services-plugin
3131
-->
32-
<string name="default_web_client_id" translatable="false">CHANGE-ME</string>
32+
<string name="default_web_client_id" translatable="false">674240801770-mjrdacsvau06n8ttugnsu8io0a0ep8cl.apps.googleusercontent.com</string>
3333
</resources>

0 commit comments

Comments
 (0)