getDomainSet();
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/Options.java
================================================
/*
* LockOptions.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.internal.configuration;
import android.annotation.SuppressLint;
import android.os.Build;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Patterns;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StyleRes;
import com.auth0.android.Auth0;
import com.auth0.android.authentication.AuthenticationAPIClient;
import com.auth0.android.lock.Auth0Parcelable;
import com.auth0.android.lock.InitialScreen;
import com.auth0.android.lock.UsernameStyle;
import com.auth0.android.lock.utils.SignUpField;
import com.auth0.android.provider.CustomTabsOptions;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Helper class to resolve Local settings for configuring the Lock Widget.
*
* Disclaimer: The classes in the internal package may change in the future. Don't use them directly.
*/
@SuppressLint("KotlinPropertyAccess")
public class Options implements Parcelable {
private static final int WITHOUT_DATA = 0x00;
private static final int HAS_DATA = 0x01;
private static final int DEFAULT_VISIBLE_SIGN_UP_FIELDS_THRESHOLD = 2;
private static final String KEY_AUTHENTICATION_PARAMETERS = "authenticationParameters";
private static final String KEY_CONNECTIONS_SCOPE = "connectionsScope";
private static final String SCOPE_KEY = "scope";
private static final String DEVICE_KEY = "device";
private static final String SCOPE_OFFLINE_ACCESS = "offline_access";
private Auth0 account;
private boolean closable;
private int usernameStyle;
private boolean useCodePasswordless;
private boolean allowLogIn;
private boolean allowSignUp;
private boolean allowForgotPassword;
private boolean allowShowPassword;
private boolean loginAfterSignUp;
private boolean mustAcceptTerms;
private boolean showTerms;
private boolean useLabeledSubmitButton;
private boolean hideMainScreenTitle;
private boolean rememberLastPasswordlessLogin;
private String defaultDatabaseConnection;
private List connections;
private List enterpriseConnectionsUsingWebForm;
private final HashMap authStyles;
private HashMap authenticationParameters;
private final HashMap connectionsScope;
private List signUpFields;
private int initialScreen;
private int visibleSignUpFieldsthreshold;
private Theme theme;
private CustomTabsOptions customTabsOptions;
private String privacyURL;
private String termsURL;
private String supportURL;
private String scope;
private String audience;
private String scheme;
public Options() {
usernameStyle = UsernameStyle.DEFAULT;
initialScreen = InitialScreen.LOG_IN;
visibleSignUpFieldsthreshold = DEFAULT_VISIBLE_SIGN_UP_FIELDS_THRESHOLD;
allowLogIn = true;
allowSignUp = true;
allowForgotPassword = true;
allowShowPassword = true;
loginAfterSignUp = true;
showTerms = true;
useCodePasswordless = true;
useLabeledSubmitButton = true;
authenticationParameters = new HashMap<>();
authStyles = new HashMap<>();
connectionsScope = new HashMap<>();
signUpFields = new ArrayList<>();
theme = Theme.newBuilder().build();
}
protected Options(@NonNull Parcel in) {
Auth0Parcelable auth0Parcelable = (Auth0Parcelable) in.readValue(Auth0Parcelable.class.getClassLoader());
account = auth0Parcelable.getAuth0();
closable = in.readByte() != WITHOUT_DATA;
allowLogIn = in.readByte() != WITHOUT_DATA;
allowSignUp = in.readByte() != WITHOUT_DATA;
allowForgotPassword = in.readByte() != WITHOUT_DATA;
allowShowPassword = in.readByte() != WITHOUT_DATA;
loginAfterSignUp = in.readByte() != WITHOUT_DATA;
mustAcceptTerms = in.readByte() != WITHOUT_DATA;
showTerms = in.readByte() != WITHOUT_DATA;
useCodePasswordless = in.readByte() != WITHOUT_DATA;
useLabeledSubmitButton = in.readByte() != WITHOUT_DATA;
hideMainScreenTitle = in.readByte() != WITHOUT_DATA;
rememberLastPasswordlessLogin = in.readByte() != WITHOUT_DATA;
defaultDatabaseConnection = in.readString();
usernameStyle = in.readInt();
initialScreen = in.readInt();
visibleSignUpFieldsthreshold = in.readInt();
theme = in.readParcelable(Theme.class.getClassLoader());
customTabsOptions = in.readParcelable(CustomTabsOptions.class.getClassLoader());
privacyURL = in.readString();
termsURL = in.readString();
supportURL = in.readString();
scope = in.readString();
audience = in.readString();
scheme = in.readString();
if (in.readByte() == HAS_DATA) {
connections = new ArrayList<>();
in.readList(connections, String.class.getClassLoader());
} else {
connections = null;
}
if (in.readByte() == HAS_DATA) {
enterpriseConnectionsUsingWebForm = new ArrayList<>();
in.readList(enterpriseConnectionsUsingWebForm, String.class.getClassLoader());
} else {
enterpriseConnectionsUsingWebForm = null;
}
if (in.readByte() == HAS_DATA) {
// FIXME this is something to improve
Bundle mapBundle = in.readBundle(getClass().getClassLoader());
authenticationParameters = (HashMap) mapBundle.getSerializable(KEY_AUTHENTICATION_PARAMETERS);
} else {
authenticationParameters = null;
}
if (in.readByte() == HAS_DATA) {
List authStylesKeys = new ArrayList<>();
List authStylesValues = new ArrayList<>();
in.readList(authStylesKeys, String.class.getClassLoader());
in.readList(authStylesValues, Integer.class.getClassLoader());
authStyles = new HashMap<>();
for (int i = 0; i < authStylesKeys.size(); i++) {
authStyles.put(authStylesKeys.get(i), authStylesValues.get(i));
}
} else {
authStyles = null;
}
if (in.readByte() == HAS_DATA) {
// FIXME this is something to improve
Bundle mapBundle = in.readBundle(getClass().getClassLoader());
connectionsScope = (HashMap) mapBundle.getSerializable(KEY_CONNECTIONS_SCOPE);
} else {
connectionsScope = null;
}
if (in.readByte() == HAS_DATA) {
signUpFields = new ArrayList<>();
in.readList(signUpFields, SignUpField.class.getClassLoader());
} else {
signUpFields = null;
}
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeValue(new Auth0Parcelable(account));
dest.writeByte((byte) (closable ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (allowLogIn ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (allowSignUp ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (allowForgotPassword ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (allowShowPassword ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (loginAfterSignUp ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (mustAcceptTerms ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (showTerms ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (useCodePasswordless ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (useLabeledSubmitButton ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (hideMainScreenTitle ? HAS_DATA : WITHOUT_DATA));
dest.writeByte((byte) (rememberLastPasswordlessLogin ? HAS_DATA : WITHOUT_DATA));
dest.writeString(defaultDatabaseConnection);
dest.writeInt(usernameStyle);
dest.writeInt(initialScreen);
dest.writeInt(visibleSignUpFieldsthreshold);
dest.writeParcelable(theme, flags);
dest.writeParcelable(customTabsOptions, flags);
dest.writeString(privacyURL);
dest.writeString(termsURL);
dest.writeString(supportURL);
dest.writeString(scope);
dest.writeString(audience);
dest.writeString(scheme);
if (connections == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
dest.writeList(connections);
}
if (enterpriseConnectionsUsingWebForm == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
dest.writeList(enterpriseConnectionsUsingWebForm);
}
if (authenticationParameters == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
// FIXME this is something to improve
Bundle mapBundle = new Bundle();
mapBundle.putSerializable(KEY_AUTHENTICATION_PARAMETERS, authenticationParameters);
dest.writeBundle(mapBundle);
}
if (authStyles == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
dest.writeList(new ArrayList<>(authStyles.keySet()));
dest.writeList(new ArrayList<>(authStyles.values()));
}
if (connectionsScope == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
// FIXME this is something to improve
Bundle mapBundle = new Bundle();
mapBundle.putSerializable(KEY_CONNECTIONS_SCOPE, connectionsScope);
dest.writeBundle(mapBundle);
}
if (signUpFields == null) {
dest.writeByte((byte) (WITHOUT_DATA));
} else {
dest.writeByte((byte) (HAS_DATA));
dest.writeList(signUpFields);
}
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Options createFromParcel(Parcel in) {
return new Options(in);
}
@Override
public Options[] newArray(int size) {
return new Options[size];
}
};
@NonNull
public Auth0 getAccount() {
return account;
}
public void setAccount(@NonNull Auth0 account) {
this.account = account;
}
public void withTheme(@NonNull Theme theme) {
this.theme = theme;
}
@NonNull
public Theme getTheme() {
return theme;
}
public boolean isClosable() {
return closable;
}
public void setClosable(boolean closable) {
this.closable = closable;
}
@UsernameStyle
public int usernameStyle() {
return usernameStyle;
}
public void setUsernameStyle(@UsernameStyle int usernameStyle) {
this.usernameStyle = usernameStyle;
}
public void setAllowLogIn(boolean allowLogIn) {
this.allowLogIn = allowLogIn;
}
public boolean allowLogIn() {
return allowLogIn;
}
public boolean allowSignUp() {
return allowSignUp;
}
public void setAllowSignUp(boolean allowSignUp) {
this.allowSignUp = allowSignUp;
}
public void setAllowForgotPassword(boolean allowForgotPassword) {
this.allowForgotPassword = allowForgotPassword;
}
public boolean allowForgotPassword() {
return allowForgotPassword;
}
public boolean allowShowPassword() {
return allowShowPassword;
}
public void setAllowShowPassword(boolean allow) {
allowShowPassword = allow;
}
@Nullable
public String getDefaultDatabaseConnection() {
return defaultDatabaseConnection;
}
public void useDatabaseConnection(@NonNull String defaultDatabaseConnection) {
this.defaultDatabaseConnection = defaultDatabaseConnection;
}
@Nullable
public List getConnections() {
return connections;
}
public void setConnections(@NonNull List connections) {
this.connections = connections;
}
@Nullable
public List getEnterpriseConnectionsUsingWebForm() {
return enterpriseConnectionsUsingWebForm;
}
public void setEnterpriseConnectionsUsingWebForm(@NonNull List enterpriseConnectionsUsingWebForm) {
this.enterpriseConnectionsUsingWebForm = enterpriseConnectionsUsingWebForm;
}
@Nullable
public HashMap getAuthenticationParameters() {
return authenticationParameters;
}
public void setAuthenticationParameters(@NonNull HashMap authenticationParameters) {
final String scope = authenticationParameters.get(SCOPE_KEY);
final String device = authenticationParameters.get(DEVICE_KEY);
if (scope != null && scope.contains(SCOPE_OFFLINE_ACCESS) && device == null) {
authenticationParameters.put(DEVICE_KEY, Build.MODEL);
}
this.authenticationParameters = authenticationParameters;
}
public boolean loginAfterSignUp() {
return loginAfterSignUp;
}
public void setLoginAfterSignUp(boolean loginAfterSignUp) {
this.loginAfterSignUp = loginAfterSignUp;
}
@NonNull
public AuthenticationAPIClient getAuthenticationAPIClient() {
return new AuthenticationAPIClient(account);
}
public void setUseCodePasswordless(boolean useCode) {
this.useCodePasswordless = useCode;
}
public boolean useCodePasswordless() {
return this.useCodePasswordless;
}
public void setSignUpFields(@NonNull List signUpFields) {
this.signUpFields = signUpFields;
}
@Nullable
public List getSignUpFields() {
return signUpFields;
}
public void setInitialScreen(@InitialScreen int screen) {
this.initialScreen = screen;
}
@InitialScreen
public int initialScreen() {
return initialScreen;
}
public void setPrivacyURL(@NonNull String url) throws IllegalArgumentException {
if (!Patterns.WEB_URL.matcher(url).matches()) {
throw new IllegalArgumentException("The given Policy Privacy URL doesn't have a valid URL format: " + url);
}
this.privacyURL = url;
}
@Nullable
public String getPrivacyURL() {
return privacyURL;
}
public void setTermsURL(@NonNull String url) throws IllegalArgumentException {
if (!Patterns.WEB_URL.matcher(url).matches()) {
throw new IllegalArgumentException("The given Terms of Service URL doesn't have a valid URL format: " + url);
}
this.termsURL = url;
}
@Nullable
public String getTermsURL() {
return termsURL;
}
public void setSupportURL(@NonNull String url) {
if (!Patterns.WEB_URL.matcher(url).matches()) {
throw new IllegalArgumentException("The given Support URL doesn't have a valid URL format: " + url);
}
this.supportURL = url;
}
@Nullable
public String getSupportURL() {
return supportURL;
}
public void setMustAcceptTerms(boolean mustAcceptTerms) {
this.mustAcceptTerms = mustAcceptTerms;
}
public boolean mustAcceptTerms() {
return mustAcceptTerms;
}
public void setShowTerms(boolean showTerms) {
this.showTerms = showTerms;
}
public boolean showTerms() {
return showTerms;
}
public void withAuthStyle(@NonNull String connectionName, @StyleRes int style) {
authStyles.put(connectionName, style);
}
@Nullable
public Map getAuthStyles() {
return new HashMap<>(authStyles);
}
public void setUseLabeledSubmitButton(boolean useLabeledSubmitButton) {
this.useLabeledSubmitButton = useLabeledSubmitButton;
}
public boolean useLabeledSubmitButton() {
return useLabeledSubmitButton;
}
public void setHideMainScreenTitle(boolean hideMainScreenTitle) {
this.hideMainScreenTitle = hideMainScreenTitle;
}
public boolean hideMainScreenTitle() {
return hideMainScreenTitle;
}
public void setRememberLastPasswordlessLogin(boolean remember) {
this.rememberLastPasswordlessLogin = remember;
}
public boolean rememberLastPasswordlessAccount() {
return rememberLastPasswordlessLogin;
}
public void withConnectionScope(@NonNull String connectionName, @NonNull String scope) {
connectionsScope.put(connectionName, scope);
}
@Nullable
public Map getConnectionsScope() {
return connectionsScope;
}
public void withScope(@NonNull String scope) {
this.scope = scope;
}
@Nullable
public String getScope() {
return scope;
}
public void withAudience(@NonNull String audience) {
this.audience = audience;
}
@Nullable
public String getAudience() {
return audience;
}
public void withScheme(@NonNull String scheme) {
this.scheme = scheme;
}
@Nullable
public String getScheme() {
return scheme;
}
public void setVisibleSignUpFieldsThreshold(int threshold) {
this.visibleSignUpFieldsthreshold = threshold;
}
public int visibleSignUpFieldsThreshold() {
return visibleSignUpFieldsthreshold;
}
public void withCustomTabsOptions(@NonNull CustomTabsOptions customTabsOptions) {
this.customTabsOptions = customTabsOptions;
}
@Nullable
public CustomTabsOptions getCustomTabsOptions() {
return customTabsOptions;
}
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/PasswordComplexity.java
================================================
package com.auth0.android.lock.internal.configuration;
import androidx.annotation.Nullable;
public class PasswordComplexity {
private final int policy;
private final Integer minLengthOverride;
public PasswordComplexity(@PasswordStrength int policy, @Nullable Integer minLengthOverride) {
this.policy = policy;
this.minLengthOverride = minLengthOverride;
}
/**
* Getter for the Password Policy associated to this connection.
*
* @return the Password Policy level for this connection.
*/
@PasswordStrength
public int getPasswordPolicy() {
return policy;
}
/**
* Getter for the minimum length the password requires
*
* @return the minimum length the password requires
*/
@Nullable
public Integer getMinLengthOverride() {
return minLengthOverride;
}
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/PasswordStrength.java
================================================
package com.auth0.android.lock.internal.configuration;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static com.auth0.android.lock.internal.configuration.PasswordStrength.EXCELLENT;
import static com.auth0.android.lock.internal.configuration.PasswordStrength.FAIR;
import static com.auth0.android.lock.internal.configuration.PasswordStrength.GOOD;
import static com.auth0.android.lock.internal.configuration.PasswordStrength.LOW;
import static com.auth0.android.lock.internal.configuration.PasswordStrength.NONE;
@IntDef({NONE, LOW, FAIR, GOOD, EXCELLENT})
@Retention(RetentionPolicy.SOURCE)
public @interface PasswordStrength {
int NONE = 0;
int LOW = 1;
int FAIR = 2;
int GOOD = 3;
int EXCELLENT = 4;
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/PasswordlessConnection.java
================================================
package com.auth0.android.lock.internal.configuration;
public interface PasswordlessConnection extends BaseConnection {
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/PasswordlessMode.java
================================================
/*
* PasswordlessMode.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.internal.configuration;
import androidx.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static com.auth0.android.lock.internal.configuration.PasswordlessMode.DISABLED;
import static com.auth0.android.lock.internal.configuration.PasswordlessMode.EMAIL_CODE;
import static com.auth0.android.lock.internal.configuration.PasswordlessMode.EMAIL_LINK;
import static com.auth0.android.lock.internal.configuration.PasswordlessMode.SMS_CODE;
import static com.auth0.android.lock.internal.configuration.PasswordlessMode.SMS_LINK;
@IntDef({DISABLED, SMS_LINK, SMS_CODE, EMAIL_LINK, EMAIL_CODE})
@Retention(RetentionPolicy.SOURCE)
public @interface PasswordlessMode {
int DISABLED = 0;
int SMS_LINK = 1;
int SMS_CODE = 2;
int EMAIL_LINK = 3;
int EMAIL_CODE = 4;
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/internal/configuration/Theme.java
================================================
/*
* Theme.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.internal.configuration;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import android.util.TypedValue;
import com.auth0.android.lock.R;
/**
* Helper class to resolve Lock.Theme values.
*
* Disclaimer: The classes in the internal package may change in the future. Don't use them directly.
*/
public class Theme implements Parcelable {
private final int headerTitle;
private final int headerLogo;
private final int headerColor;
private final int headerTitleColor;
private final int primaryColor;
private final int darkPrimaryColor;
private Theme(int headerTitle, int headerLogo, int headerColor, int headerTitleColor, int primaryColor, int darkPrimaryColor) {
this.headerTitle = headerTitle;
this.headerLogo = headerLogo;
this.headerColor = headerColor;
this.headerTitleColor = headerTitleColor;
this.primaryColor = primaryColor;
this.darkPrimaryColor = darkPrimaryColor;
}
@SuppressLint("ResourceType")
private String resolveStringResource(Context context, @StringRes int res, @AttrRes int attrName) {
if (res > 0) {
return context.getString(res);
}
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attrName, typedValue, true);
return context.getString(typedValue.resourceId);
}
@SuppressLint("ResourceType")
@ColorInt
private int resolveColorResource(Context context, @ColorRes int res, @AttrRes int attrName) {
if (res > 0) {
return ContextCompat.getColor(context, res);
}
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attrName, typedValue, true);
return ContextCompat.getColor(context, typedValue.resourceId);
}
@SuppressLint("ResourceType")
private Drawable resolveDrawableResource(Context context, @DrawableRes int res, @AttrRes int attrName) {
if (res > 0) {
return ContextCompat.getDrawable(context, res);
}
TypedValue typedValue = new TypedValue();
context.getTheme().resolveAttribute(attrName, typedValue, true);
return ContextCompat.getDrawable(context, typedValue.resourceId);
}
@NonNull
public String getHeaderTitle(@NonNull Context context) {
return resolveStringResource(context, headerTitle, R.attr.Auth0_HeaderTitle);
}
@NonNull
public Drawable getHeaderLogo(@NonNull Context context) {
return resolveDrawableResource(context, headerLogo, R.attr.Auth0_HeaderLogo);
}
@ColorInt
public int getHeaderColor(@NonNull Context context) {
return resolveColorResource(context, headerColor, R.attr.Auth0_HeaderBackground);
}
@ColorInt
public int getHeaderTitleColor(@NonNull Context context) {
return resolveColorResource(context, headerTitleColor, R.attr.Auth0_HeaderTitleColor);
}
@ColorInt
public int getPrimaryColor(@NonNull Context context) {
return resolveColorResource(context, primaryColor, R.attr.Auth0_PrimaryColor);
}
@ColorInt
public int getDarkPrimaryColor(@NonNull Context context) {
return resolveColorResource(context, darkPrimaryColor, R.attr.Auth0_DarkPrimaryColor);
}
int getCustomHeaderTitleRes() {
return headerTitle;
}
int getCustomHeaderLogoRes() {
return headerLogo;
}
int getCustomHeaderColorRes() {
return headerColor;
}
int getCustomHeaderTitleColorRes() {
return headerTitleColor;
}
int getCustomPrimaryColorRes() {
return primaryColor;
}
int getCustomDarkPrimaryColorRes() {
return darkPrimaryColor;
}
protected Theme(@NonNull Parcel in) {
headerTitle = in.readInt();
headerLogo = in.readInt();
headerColor = in.readInt();
headerTitleColor = in.readInt();
primaryColor = in.readInt();
darkPrimaryColor = in.readInt();
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeInt(headerTitle);
dest.writeInt(headerLogo);
dest.writeInt(headerColor);
dest.writeInt(headerTitleColor);
dest.writeInt(primaryColor);
dest.writeInt(darkPrimaryColor);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public Theme createFromParcel(Parcel in) {
return new Theme(in);
}
@Override
public Theme[] newArray(int size) {
return new Theme[size];
}
};
static Builder newBuilder() {
return new Theme.Builder();
}
static class Builder {
private int headerTitleRes;
private int headerLogoRes;
private int headerColorRes;
private int headerTitleColorRes;
private int primaryColorRes;
private int darkPrimaryColorRes;
public Builder withHeaderTitle(@StringRes int title) {
headerTitleRes = title;
return this;
}
public Builder withHeaderLogo(@DrawableRes int logo) {
headerLogoRes = logo;
return this;
}
public Builder withHeaderColor(@ColorRes int color) {
headerColorRes = color;
return this;
}
public Builder withHeaderTitleColor(@ColorRes int color) {
headerTitleColorRes = color;
return this;
}
public Builder withPrimaryColor(@ColorRes int primary) {
primaryColorRes = primary;
return this;
}
public Builder withDarkPrimaryColor(@ColorRes int darkPrimary) {
darkPrimaryColorRes = darkPrimary;
return this;
}
public Theme build() {
return new Theme(headerTitleRes, headerLogoRes, headerColorRes, headerTitleColorRes, primaryColorRes, darkPrimaryColorRes);
}
}
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/provider/AuthResolver.java
================================================
package com.auth0.android.lock.provider;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.auth0.android.provider.AuthHandler;
import com.auth0.android.provider.AuthProvider;
import java.util.ArrayList;
import java.util.List;
/**
* Holds instances of AuthHandlers that can be used to query for AuthProviders given
* a strategy and connection name.
* When no AuthProvider is matched, it will return null
*/
public final class AuthResolver {
private static List authHandlers;
private AuthResolver() {
}
/**
* Sets the AuthHandler list to use on this instance.
*
* @param handlers the list of AuthHandlers to use.
*/
public static void setAuthHandlers(@NonNull List handlers) {
authHandlers = new ArrayList<>(handlers);
}
/**
* Get an AuthProvider that can handle a given strategy and connection name, or null if there are no
* providers to handle them.
*
* @param strategy to handle
* @param connection to handle
* @return an AuthProvider to handle the authentication or null if no providers are available.
*/
@Nullable
public static AuthProvider providerFor(@Nullable String strategy, @NonNull String connection) {
if (authHandlers == null) {
return null;
}
AuthProvider provider = null;
for (AuthHandler p : authHandlers) {
provider = p.providerFor(strategy, connection);
if (provider != null) {
break;
}
}
return provider;
}
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/utils/CustomField.java
================================================
/*
* CustomField.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.utils;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.DrawableRes;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.StringRes;
import android.view.View;
import android.view.ViewGroup;
import com.auth0.android.lock.views.ValidatedInputView;
import com.auth0.android.lock.views.ValidatedInputView.DataType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import static com.auth0.android.lock.utils.CustomField.FieldType.TYPE_EMAIL;
import static com.auth0.android.lock.utils.CustomField.FieldType.TYPE_NAME;
import static com.auth0.android.lock.utils.CustomField.FieldType.TYPE_NUMBER;
import static com.auth0.android.lock.utils.CustomField.FieldType.TYPE_PHONE_NUMBER;
import static com.auth0.android.lock.utils.CustomField.Storage.PROFILE_ROOT;
import static com.auth0.android.lock.utils.CustomField.Storage.USER_METADATA;
public class CustomField extends SignUpField {
@IntDef({TYPE_NAME, TYPE_NUMBER, TYPE_PHONE_NUMBER, TYPE_EMAIL})
@Retention(RetentionPolicy.SOURCE)
public @interface FieldType {
int TYPE_NAME = 0;
int TYPE_NUMBER = 1;
int TYPE_PHONE_NUMBER = 2;
int TYPE_EMAIL = 3;
}
/**
* Location to store the field into.
*/
@IntDef({PROFILE_ROOT, USER_METADATA})
@Retention(RetentionPolicy.SOURCE)
public @interface Storage {
/**
* Store the field into the user profile root.
* The list of attributes that can be added to your root profile is here https://auth0.com/docs/api/authentication#signup.
*/
int PROFILE_ROOT = 0;
/**
* Store the field into the user_metadata object.
*/
int USER_METADATA = 1;
}
@DrawableRes
private final int icon;
@FieldType
private final int type;
@StringRes
private final int hint;
/**
* Constructor for CustomField instance
* When this constructor is used the field will be stored under the {@link Storage#USER_METADATA} attribute.
* If you want to change the storage location use the constructor that accepts a {@link Storage} value.
*
* @param icon the icon resource to display next to the field.
* @param type the type of input this field will receive. Used to determine the applied validation.
* @param key the key to store this field as.
* @param hint the placeholder to display when this field is empty.
*/
public CustomField(@DrawableRes int icon, @FieldType int type, @NonNull String key, @StringRes int hint) {
this(icon, type, key, hint, USER_METADATA);
}
/**
* Constructor for CustomField instance
*
* @param icon the icon resource to display next to the field.
* @param type the type of input this field will receive. Used to determine the applied validation.
* @param key the key to store this field as.
* @param hint the placeholder to display when this field is empty.
* @param storage the location to store this value into.
*/
public CustomField(@DrawableRes int icon, @FieldType int type, @NonNull String key, @StringRes int hint, @Storage int storage) {
super(key, storage);
this.icon = icon;
this.type = type;
this.hint = hint;
}
public void configureField(@NonNull ValidatedInputView field) {
switch (type) {
case TYPE_NAME:
field.setDataType(DataType.TEXT_NAME);
break;
case TYPE_NUMBER:
field.setDataType(DataType.NUMBER);
break;
case TYPE_PHONE_NUMBER:
field.setDataType(DataType.PHONE_NUMBER);
break;
case TYPE_EMAIL:
field.setDataType(DataType.EMAIL);
break;
}
field.setHint(hint);
field.setIcon(icon);
field.setTag(getKey());
}
@Nullable
public String findValue(@NonNull ViewGroup container) {
String value = null;
View view = container.findViewWithTag(getKey());
if (view != null) {
value = ((ValidatedInputView) view).getText();
}
return value;
}
@StringRes
int getHint() {
return hint;
}
@DrawableRes
int getIcon() {
return icon;
}
@FieldType
int getType() {
return type;
}
protected CustomField(@NonNull Parcel in) {
super(in);
icon = in.readInt();
type = in.readInt();
hint = in.readInt();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(icon);
dest.writeInt(type);
dest.writeInt(hint);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public CustomField createFromParcel(Parcel in) {
return new CustomField(in);
}
@Override
public CustomField[] newArray(int size) {
return new CustomField[size];
}
};
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/utils/EnterpriseConnectionMatcher.java
================================================
/*
* DomainParser.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.utils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import android.util.Log;
import com.auth0.android.lock.internal.configuration.OAuthConnection;
import java.util.ArrayList;
import java.util.List;
/**
* Helper class to find out which email domains can be valid for the current Auth0 configuration.
*/
public class EnterpriseConnectionMatcher {
private static final String TAG = EnterpriseConnectionMatcher.class.getSimpleName();
private static final String DOMAIN_KEY = "domain";
private static final String DOMAIN_ALIASES_KEY = "domain_aliases";
private static final String AT_SYMBOL = "@";
private final List connections;
public EnterpriseConnectionMatcher(@NonNull List connections) {
this.connections = new ArrayList<>(connections);
Log.v(TAG, String.format("Creating a new instance to match %d Enterprise Connections", this.connections.size()));
}
/**
* Tries to find a valid domain with the given input.
*
* @param email to search the Domain for.
* @return a Connection if found, null otherwise.
*/
@Nullable
public OAuthConnection parse(@NonNull String email) {
String domain = extractDomain(email);
if (domain == null) {
return null;
}
domain = domain.toLowerCase();
for (OAuthConnection c : connections) {
String mainDomain = domainForConnection(c);
if (domain.equalsIgnoreCase(mainDomain)) {
return c;
}
//noinspection unchecked
List aliases = c.valueForKey(DOMAIN_ALIASES_KEY, List.class);
if (aliases != null) {
for (String d : aliases) {
if (d.equalsIgnoreCase(domain)) {
return c;
}
}
}
}
return null;
}
/**
* Extracts the username part from the email
*
* @param email to parse
* @return the username String if found, an empty String otherwise
*/
@Nullable
public String extractUsername(@NonNull String email) {
int indexAt = email.indexOf(AT_SYMBOL);
if (indexAt == -1) {
return null;
}
return email.substring(0, indexAt);
}
/**
* Extracts the domain part from the email
*
* @param email to parse
* @return the domain String if found, an empty String otherwise
*/
@Nullable
private String extractDomain(String email) {
int indexAt = email.indexOf(AT_SYMBOL) + 1;
if (indexAt == 0) {
return null;
}
String domain = email.substring(indexAt);
if (domain.isEmpty()) {
return null;
}
return domain;
}
/**
* Extracts the Connection's main domain.
*
* @param connection to extract the domain from
* @return the main domain.
*/
@Nullable
public String domainForConnection(@NonNull OAuthConnection connection) {
return connection.valueForKey(DOMAIN_KEY, String.class);
}
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/utils/HiddenField.java
================================================
package com.auth0.android.lock.utils;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.NonNull;
public class HiddenField extends SignUpField {
private final String value;
/**
* Constructor for HiddenField instance
*
* @param key the key to store this field as.
* @param value the fixed value to set for this field
* @param storage the location to store this value into.
*/
public HiddenField(@NonNull String key, @NonNull String value, @CustomField.Storage int storage) {
super(key, storage);
this.value = value;
}
@NonNull
public String getValue() {
return value;
}
protected HiddenField(@NonNull Parcel in) {
super(in);
value = in.readString();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeString(value);
}
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
@Override
public HiddenField createFromParcel(Parcel in) {
return new HiddenField(in);
}
@Override
public HiddenField[] newArray(int size) {
return new HiddenField[size];
}
};
}
================================================
FILE: lib/src/main/java/com/auth0/android/lock/utils/LoadCountriesTask.java
================================================
/*
* LoadCountriesTask.java
*
* Copyright (c) 2016 Auth0 (http://auth0.com)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package com.auth0.android.lock.utils;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import androidx.annotation.NonNull;
import com.auth0.android.lock.adapters.Country;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
public abstract class LoadCountriesTask extends AsyncTask> {
private static final String TAG = LoadCountriesTask.class.getName();
private static final String COUNTRIES_JSON_FILE = "com_auth0_lock_passwordless_countries.json";
@Override
@NonNull
protected List doInBackground(@NonNull Context... params) {
final Type mapType = new TypeToken