Require bio for showing password

This commit is contained in:
M66B 2023-02-01 19:50:42 +01:00
parent 6e3829c974
commit 5aed8223a9
4 changed files with 83 additions and 18 deletions

View File

@ -20,7 +20,6 @@ package eu.faircode.email;
*/
import static android.app.Activity.RESULT_OK;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_GMAIL;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_OAUTH;
@ -614,7 +613,11 @@ public class FragmentAccount extends FragmentBase {
rgEncryption.setVisibility(View.GONE);
cbInsecure.setVisibility(View.GONE);
tilPassword.setEndIconMode(id < 0 || Helper.isSecure(getContext()) ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
if (id < 0)
tilPassword.setEndIconMode(END_ICON_PASSWORD_TOGGLE);
else
Helper.setupPasswordToggle(getActivity(), tilPassword);
btnAdvanced.setVisibility(View.GONE);

View File

@ -20,7 +20,6 @@ package eu.faircode.email;
*/
import static android.app.Activity.RESULT_OK;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_OAUTH;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
@ -69,7 +68,6 @@ import java.io.FileNotFoundException;
import java.net.UnknownHostException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
@ -527,7 +525,11 @@ public class FragmentIdentity extends FragmentBase {
btnAutoConfig.setEnabled(false);
pbAutoConfig.setVisibility(View.GONE);
cbInsecure.setVisibility(View.GONE);
tilPassword.setEndIconMode(id < 0 || Helper.isSecure(getContext()) ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
if (id < 0)
tilPassword.setEndIconMode(END_ICON_PASSWORD_TOGGLE);
else
Helper.setupPasswordToggle(getActivity(), tilPassword);
btnAdvanced.setVisibility(View.GONE);

View File

@ -20,7 +20,6 @@ package eu.faircode.email;
*/
import static android.app.Activity.RESULT_OK;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE;
import static eu.faircode.email.ServiceAuthenticator.AUTH_TYPE_PASSWORD;
@ -320,7 +319,11 @@ public class FragmentPop extends FragmentBase {
// Initialize
Helper.setViewsEnabled(view, false);
tilPassword.setEndIconMode(id < 0 || Helper.isSecure(getContext()) ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
if (id < 0)
tilPassword.setEndIconMode(END_ICON_PASSWORD_TOGGLE);
else
Helper.setupPasswordToggle(getActivity(), tilPassword);
pbSave.setVisibility(View.GONE);
grpError.setVisibility(View.GONE);

View File

@ -22,6 +22,9 @@ package eu.faircode.email;
import static android.os.Process.THREAD_PRIORITY_BACKGROUND;
import static androidx.browser.customtabs.CustomTabsService.ACTION_CUSTOM_TABS_CONNECTION;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_NONE;
import static com.google.android.material.textfield.TextInputLayout.END_ICON_PASSWORD_TOGGLE;
import android.Manifest;
import android.animation.Animator;
import android.animation.ObjectAnimator;
@ -73,6 +76,8 @@ import android.text.Spannable;
import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.text.method.PasswordTransformationMethod;
import android.text.method.TransformationMethod;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.util.TypedValue;
@ -125,6 +130,7 @@ import androidx.viewpager.widget.PagerAdapter;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.android.material.snackbar.Snackbar;
import com.google.android.material.textfield.TextInputLayout;
import org.openintents.openpgp.util.OpenPgpApi;
@ -2725,14 +2731,13 @@ public class Helper {
}
static boolean canAuthenticate(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String pin = prefs.getString("pin", null);
if (!TextUtils.isEmpty(pin))
return true;
try {
BiometricManager bm = BiometricManager.from(context);
return (bm.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS);
if (bm.canAuthenticate(BiometricManager.Authenticators.BIOMETRIC_WEAK) == BiometricManager.BIOMETRIC_SUCCESS)
return true;
if (bm.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS)
return true;
return false;
} catch (Throwable ex) {
/*
java.lang.SecurityException: eu.faircode.email from uid 10377 not allowed to perform USE_FINGERPRINT
@ -2802,13 +2807,14 @@ public class Helper {
BiometricPrompt.PromptInfo.Builder info = new BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(enabled == null ? R.string.app_name : R.string.title_setup_biometrics));
KeyguardManager kgm = (KeyguardManager) activity.getSystemService(Context.KEYGUARD_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && kgm != null && kgm.isDeviceSecure())
info.setDeviceCredentialAllowed(true);
BiometricManager bm = BiometricManager.from(activity);
int authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK;
if (bm.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS)
authenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL;
else
info.setNegativeButtonText(activity.getString(android.R.string.cancel));
info.setConfirmationRequired(false);
info.setAllowedAuthenticators(authenticators)
.setConfirmationRequired(false);
info.setSubtitle(activity.getString(enabled == null ? R.string.title_setup_biometrics_unlock
: enabled
@ -3036,6 +3042,57 @@ public class Helper {
prefs.edit().remove("last_authentication").apply();
}
static void setupPasswordToggle(FragmentActivity activity, TextInputLayout tilPassword) {
boolean can = canAuthenticate(activity);
boolean secure = isSecure(activity);
tilPassword.setEndIconMode(can || secure ? END_ICON_PASSWORD_TOGGLE : END_ICON_NONE);
tilPassword.setEndIconOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TransformationMethod tm = tilPassword.getEditText().getTransformationMethod();
if (tm == null)
tilPassword.getEditText().setTransformationMethod(PasswordTransformationMethod.getInstance());
else {
if (can) {
BiometricPrompt.PromptInfo.Builder info = new BiometricPrompt.PromptInfo.Builder()
.setTitle(activity.getString(R.string.title_setup_biometrics))
.setSubtitle(activity.getString(R.string.title_password));
BiometricManager bm = BiometricManager.from(activity);
int authenticators = BiometricManager.Authenticators.BIOMETRIC_WEAK;
if (bm.canAuthenticate(BiometricManager.Authenticators.DEVICE_CREDENTIAL) == BiometricManager.BIOMETRIC_SUCCESS)
authenticators |= BiometricManager.Authenticators.DEVICE_CREDENTIAL;
else
info.setNegativeButtonText(activity.getString(android.R.string.cancel));
info.setAllowedAuthenticators(authenticators)
.setConfirmationRequired(false);
BiometricPrompt prompt = new BiometricPrompt(activity, Helper.getUIExecutor(),
new BiometricPrompt.AuthenticationCallback() {
@Override
public void onAuthenticationSucceeded(@NonNull BiometricPrompt.AuthenticationResult result) {
tilPassword.post(new RunnableEx("tilPassword") {
@Override
protected void delegate() {
tilPassword.getEditText().setTransformationMethod(null);
}
});
}
@Override
public void onAuthenticationError(int errorCode, @NonNull CharSequence errString) {
ToastEx.makeText(activity, "Error " + errorCode + ": " + errString, Toast.LENGTH_LONG).show();
}
});
prompt.authenticate(info.build());
} else if (secure)
tilPassword.getEditText().setTransformationMethod(null);
}
}
});
}
static void selectKeyAlias(final Activity activity, final LifecycleOwner owner, final String alias, final IKeyAlias intf) {
final Context context = activity.getApplicationContext();
new Thread(new Runnable() {