Skip to content

Commit a346bf2

Browse files
lsiracsamtstern
authored andcommitted
Country selector fixes (#1345)
1 parent 36b118f commit a346bf2

File tree

8 files changed

+385
-660
lines changed

8 files changed

+385
-660
lines changed

auth/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,11 @@ The country code selector will exclude all countries with a country code of +1 a
357357
Note: You can't provide both a list of countries to whitelist and blacklist. If you do, a runtime
358358
exception will be thrown.
359359

360+
This change is purely UI based. We do not restrict users from signing in with their phone number.
361+
They will simply be unable to choose their country in the selector, but there may be another country
362+
sharing the same country code (e.g. US and CA are +1).
363+
364+
360365
#####
361366

362367
### Handling the sign-in response

auth/src/main/java/com/firebase/ui/auth/AuthUI.java

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -658,16 +658,24 @@ public PhoneBuilder setDefaultCountryIso(@NonNull String iso) {
658658
* https://en.wikipedia.org/wiki/ISO_3166-1
659659
* and e-164 codes here: https://en.wikipedia.org/wiki/List_of_country_calling_codes
660660
*
661-
* @param whitelistedCountries a case insensitive list of country codes and/or
662-
* isos to be whitelisted
661+
* @param whitelistedCountries a non empty case insensitive list of country codes
662+
* and/or isos to be whitelisted
663+
* @throws IllegalArgumentException if an empty whitelist is provided.
664+
* @throws NullPointerException if a null whitelist is provided.
663665
*/
664666
public PhoneBuilder setWhitelistedCountries(
665667
@NonNull List<String> whitelistedCountries) {
666668
if (getParams().containsKey(ExtraConstants.BLACKLISTED_COUNTRIES)) {
667-
throw new RuntimeException(
669+
throw new IllegalStateException(
668670
"You can either whitelist or blacklist country codes for phone " +
669671
"authentication.");
670672
}
673+
674+
String message = "Invalid argument: Only non-%s whitelists are valid. " +
675+
"To specify no whitelist, do not call this method.";
676+
Preconditions.checkNotNull(whitelistedCountries, String.format(message, "null"));
677+
Preconditions.checkArgument(!whitelistedCountries.isEmpty(), String.format(message, "empty"));
678+
671679
addCountriesToBundle(whitelistedCountries, ExtraConstants.WHITELISTED_COUNTRIES);
672680
return this;
673681
}
@@ -685,16 +693,25 @@ public PhoneBuilder setWhitelistedCountries(
685693
* For a list of country iso or codes, see Alpha-2 codes here:
686694
* https://en.wikipedia.org/wiki/ISO_3166-1
687695
* and e-164 codes here: https://en.wikipedia.org/wiki/List_of_country_calling_codes
688-
* @param blacklistedCountries a case insensitive list of country codes and/or isos
689-
* to be blacklisted
696+
*
697+
* @param blacklistedCountries a non empty case insensitive list of country codes
698+
* and/or isos to be blacklisted
699+
* @throws IllegalArgumentException if an empty blacklist is provided.
700+
* @throws NullPointerException if a null blacklist is provided.
690701
*/
691702
public PhoneBuilder setBlacklistedCountries(
692703
@NonNull List<String> blacklistedCountries) {
693704
if (getParams().containsKey(ExtraConstants.WHITELISTED_COUNTRIES)) {
694-
throw new RuntimeException(
705+
throw new IllegalStateException(
695706
"You can either whitelist or blacklist country codes for phone " +
696707
"authentication.");
697708
}
709+
710+
String message = "Invalid argument: Only non-%s blacklists are valid. " +
711+
"To specify no blacklist, do not call this method.";
712+
Preconditions.checkNotNull(blacklistedCountries, String.format(message, "null"));
713+
Preconditions.checkArgument(!blacklistedCountries.isEmpty(), String.format(message, "empty"));
714+
698715
addCountriesToBundle(blacklistedCountries, ExtraConstants.BLACKLISTED_COUNTRIES);
699716
return this;
700717
}
@@ -722,41 +739,70 @@ private void validateInputs() {
722739

723740
if (whitelistedCountries != null &&
724741
blacklistedCountries != null) {
725-
throw new RuntimeException(
742+
throw new IllegalStateException(
726743
"You can either whitelist or blacklist country codes for phone " +
727744
"authentication.");
728745
} else if (whitelistedCountries != null) {
729-
validateCountries(whitelistedCountries);
730-
validateDefaultCountryIso(whitelistedCountries, true);
746+
validateInputs(whitelistedCountries, true);
731747

732748
} else if (blacklistedCountries != null) {
733-
validateCountries(blacklistedCountries);
734-
validateDefaultCountryIso(blacklistedCountries, false);
749+
validateInputs(blacklistedCountries, false);
735750
}
736751
}
737752

738-
private void validateCountries(List<String> codes) {
753+
private void validateInputs(List<String> countries, boolean whitelisted) {
754+
validateCountryInput(countries);
755+
validateDefaultCountryInput(countries, whitelisted);
756+
}
757+
758+
private void validateCountryInput(List<String> codes) {
739759
for (String code : codes) {
740760
if (!PhoneNumberUtils.isValidIso(code) && !PhoneNumberUtils.isValid(code)) {
741-
throw new RuntimeException("Invalid input: You must provide a valid " +
742-
"country iso (alpha-2) or code (e-164). e.g. 'us' or '+1'.");
761+
throw new IllegalArgumentException("Invalid input: You must provide a " +
762+
"valid country iso (alpha-2) or code (e-164). e.g. 'us' or '+1'.");
743763
}
744764
}
745765
}
746766

747-
private void validateDefaultCountryIso(List<String> codes, boolean whitelisted) {
748-
if (getParams().containsKey(ExtraConstants.COUNTRY_ISO) && codes != null) {
749-
String defaultIso = getParams().getString(ExtraConstants.COUNTRY_ISO);
750-
boolean containsIso = containsCountryIso(codes, defaultIso);
751-
if (!containsIso && whitelisted || containsIso && !whitelisted) {
752-
throw new RuntimeException("Invalid default country iso. Make sure it " +
753-
"is either part of the whitelisted list or that you " +
754-
"haven't blacklisted it.");
767+
private void validateDefaultCountryInput(List<String> codes, boolean whitelisted) {
768+
// A default iso/code can be set via #setDefaultCountryIso() or #setDefaultNumber()
769+
if (getParams().containsKey(ExtraConstants.COUNTRY_ISO) ||
770+
getParams().containsKey(ExtraConstants.PHONE)) {
771+
772+
if (!validateDefaultCountryIso(codes, whitelisted)
773+
|| !validateDefaultPhoneIsos(codes, whitelisted)) {
774+
throw new IllegalArgumentException("Invalid default country iso. Make " +
775+
"sure it is either part of the whitelisted list or that you "
776+
+ "haven't blacklisted it.");
755777
}
756778
}
779+
780+
}
781+
782+
private boolean validateDefaultCountryIso(List<String> codes, boolean whitelisted) {
783+
String defaultIso = getDefaultIso();
784+
return isValidDefaultIso(codes, defaultIso, whitelisted);
785+
}
786+
787+
private boolean validateDefaultPhoneIsos(List<String> codes, boolean whitelisted) {
788+
List<String> phoneIsos = getPhoneIsosFromCode();
789+
for (String iso : phoneIsos) {
790+
if (isValidDefaultIso(codes, iso, whitelisted)) {
791+
return true;
792+
}
793+
}
794+
return phoneIsos.isEmpty();
795+
}
796+
797+
private boolean isValidDefaultIso(List<String> codes, String iso, boolean whitelisted) {
798+
if (iso == null) return true;
799+
boolean containsIso = containsCountryIso(codes, iso);
800+
return containsIso && whitelisted || !containsIso && !whitelisted;
801+
757802
}
758803

759804
private boolean containsCountryIso(List<String> codes, String iso) {
805+
iso = iso.toUpperCase(Locale.getDefault());
760806
for (String code : codes) {
761807
if (PhoneNumberUtils.isValidIso(code)) {
762808
if (code.equals(iso)) {
@@ -771,6 +817,26 @@ private boolean containsCountryIso(List<String> codes, String iso) {
771817
}
772818
return false;
773819
}
820+
821+
private List<String> getPhoneIsosFromCode() {
822+
List<String> isos = new ArrayList<>();
823+
String phone = getParams().getString(ExtraConstants.PHONE);
824+
if (phone != null && phone.startsWith("+")) {
825+
String countryCode = "+" + PhoneNumberUtils.getPhoneNumber(phone)
826+
.getCountryCode();
827+
List<String> isosToAdd = PhoneNumberUtils.
828+
getCountryIsosFromCountryCode(countryCode);
829+
if (isosToAdd != null) {
830+
isos.addAll(isosToAdd);
831+
}
832+
}
833+
return isos;
834+
}
835+
836+
private String getDefaultIso() {
837+
return getParams().containsKey(ExtraConstants.COUNTRY_ISO) ?
838+
getParams().getString(ExtraConstants.COUNTRY_ISO) : null;
839+
}
774840
}
775841

776842
/**
@@ -933,8 +999,8 @@ public T setLogo(@DrawableRes int logo) {
933999
/**
9341000
* Specifies the terms-of-service URL for the application.
9351001
*
936-
* @deprecated Please use {@link #setTosAndPrivacyPolicyUrls(String, String)}
937-
* For the Tos link to be displayed a Privacy Policy url must also be provided.
1002+
* @deprecated Please use {@link #setTosAndPrivacyPolicyUrls(String, String)} For the Tos
1003+
* link to be displayed a Privacy Policy url must also be provided.
9381004
*/
9391005
@NonNull
9401006
@Deprecated
@@ -946,8 +1012,8 @@ public T setTosUrl(@Nullable String tosUrl) {
9461012
/**
9471013
* Specifies the privacy policy URL for the application.
9481014
*
949-
* @deprecated Please use {@link #setTosAndPrivacyPolicyUrls(String, String)}
950-
* For the Privacy Policy link to be displayed a Tos url must also be provided.
1015+
* @deprecated Please use {@link #setTosAndPrivacyPolicyUrls(String, String)} For the
1016+
* Privacy Policy link to be displayed a Tos url must also be provided.
9511017
*/
9521018
@NonNull
9531019
@Deprecated

auth/src/main/java/com/firebase/ui/auth/data/client/CountryListLoadTask.java

Lines changed: 0 additions & 125 deletions
This file was deleted.

0 commit comments

Comments
 (0)