diff --git a/app/src/main/java/me/impy/aegis/ui/PreferencesActivity.java b/app/src/main/java/me/impy/aegis/ui/PreferencesActivity.java
index 7b2d9cf5..b11638b1 100644
--- a/app/src/main/java/me/impy/aegis/ui/PreferencesActivity.java
+++ b/app/src/main/java/me/impy/aegis/ui/PreferencesActivity.java
@@ -2,12 +2,7 @@ package me.impy.aegis.ui;
import android.os.Bundle;
-import javax.crypto.Cipher;
-
-import me.impy.aegis.db.slots.Slot;
-import me.impy.aegis.ui.dialogs.PasswordDialogFragment;
-
-public class PreferencesActivity extends AegisActivity implements PasswordDialogFragment.Listener {
+public class PreferencesActivity extends AegisActivity {
private PreferencesFragment _fragment;
@Override
@@ -41,14 +36,4 @@ public class PreferencesActivity extends AegisActivity implements PasswordDialog
outState.putParcelable("result", _fragment.getResult());
super.onSaveInstanceState(outState);
}
-
- @Override
- public void onSlotResult(Slot slot, Cipher cipher) {
- _fragment.onSlotResult(slot, cipher);
- }
-
- @Override
- public void onException(Exception e) {
- _fragment.onException(e);
- }
}
diff --git a/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java b/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
index 664fd631..cfefe5d6 100644
--- a/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
+++ b/app/src/main/java/me/impy/aegis/ui/PreferencesFragment.java
@@ -29,20 +29,23 @@ import me.impy.aegis.BuildConfig;
import me.impy.aegis.R;
import me.impy.aegis.db.DatabaseEntry;
import me.impy.aegis.db.DatabaseFileCredentials;
-import me.impy.aegis.db.DatabaseFileException;
import me.impy.aegis.db.DatabaseManager;
import me.impy.aegis.db.DatabaseManagerException;
+import me.impy.aegis.db.slots.FingerprintSlot;
+import me.impy.aegis.db.slots.PasswordSlot;
import me.impy.aegis.db.slots.Slot;
import me.impy.aegis.db.slots.SlotException;
+import me.impy.aegis.db.slots.SlotList;
+import me.impy.aegis.helpers.FingerprintHelper;
import me.impy.aegis.helpers.PermissionHelper;
import me.impy.aegis.importers.AegisImporter;
import me.impy.aegis.importers.DatabaseImporter;
import me.impy.aegis.importers.DatabaseImporterException;
-import me.impy.aegis.ui.dialogs.PasswordDialogFragment;
+import me.impy.aegis.ui.dialogs.Dialogs;
import me.impy.aegis.ui.preferences.SwitchPreference;
import me.impy.aegis.util.ByteInputStream;
-public class PreferencesFragment extends PreferenceFragmentCompat implements PasswordDialogFragment.Listener {
+public class PreferencesFragment extends PreferenceFragmentCompat {
// activity request codes
private static final int CODE_IMPORT = 0;
private static final int CODE_IMPORT_DECRYPT = 1;
@@ -61,6 +64,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
private Class extends DatabaseImporter> _importerType;
private SwitchPreference _encryptionPreference;
+ private SwitchPreference _fingerprintPreference;
+ private Preference _setPasswordPreference;
private Preference _slotsPreference;
@Override
@@ -140,9 +145,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (!_db.isEncryptionEnabled()) {
- PasswordDialogFragment dialog = new PasswordDialogFragment();
- // TODO: find a less ugly way to obtain the fragment manager
- dialog.show(getActivity().getSupportFragmentManager(), null);
+ Dialogs.showSetPasswordDialog(getActivity(), new EnableEncryptionListener());
} else {
new AlertDialog.Builder(getActivity())
.setTitle(getString(R.string.disable_encryption))
@@ -154,7 +157,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
} catch (DatabaseManagerException e) {
Toast.makeText(getActivity(), getString(R.string.encrypting_error), Toast.LENGTH_SHORT).show();
}
- updateEncryptionPreference();
+ updateEncryptionPreferences();
}
})
.setNegativeButton(android.R.string.no, null)
@@ -164,20 +167,37 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
}
});
- Preference setPasswordPreference = findPreference("pref_password");
- setPasswordPreference.setOnPreferenceClickListener(preference -> {
- PasswordDialogFragment dialog = new PasswordDialogFragment();
- // TODO: find a less ugly way to obtain the fragment manager
- dialog.show(getActivity().getSupportFragmentManager(), null);
+ _fingerprintPreference = (SwitchPreference) findPreference("pref_fingerprint");
+ _fingerprintPreference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
+ @Override
+ public boolean onPreferenceChange(Preference preference, Object newValue) {
+ DatabaseFileCredentials creds = _db.getCredentials();
+ SlotList slots = creds.getSlots();
+
+ if (!slots.has(FingerprintSlot.class)) {
+ Dialogs.showFingerprintDialog(getActivity(), new RegisterFingerprintListener());
+ } else {
+ // remove the fingerprint slot
+ FingerprintSlot slot = slots.find(FingerprintSlot.class);
+ slots.remove(slot);
+ _db.setCredentials(creds);
+
+ saveDatabase();
+ updateEncryptionPreferences();
+ }
+
+ return false;
+ }
+ });
+
+ _setPasswordPreference = findPreference("pref_password");
+ _setPasswordPreference.setOnPreferenceClickListener(preference -> {
+ Dialogs.showSetPasswordDialog(getActivity(), new SetPasswordListener());
return false;
});
+
_slotsPreference = findPreference("pref_slots");
- if (BuildConfig.DEBUG) {
- _slotsPreference.setVisible(true);
- } else {
- _slotsPreference.setVisible(false);
- }
_slotsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@@ -187,7 +207,8 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
return true;
}
});
- updateEncryptionPreference();
+
+ updateEncryptionPreferences();
}
@Override
@@ -383,6 +404,7 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
DatabaseFileCredentials creds = (DatabaseFileCredentials) data.getSerializableExtra("creds");
_db.setCredentials(creds);
saveDatabase();
+ updateEncryptionPreferences();
}
private boolean saveDatabase() {
@@ -396,31 +418,108 @@ public class PreferencesFragment extends PreferenceFragmentCompat implements Pas
return true;
}
- @Override
- public void onSlotResult(Slot slot, Cipher cipher) {
- DatabaseFileCredentials creds = new DatabaseFileCredentials();
-
- try {
- slot.setKey(creds.getKey(), cipher);
- creds.getSlots().add(slot);
- _db.enableEncryption(creds);
- } catch (DatabaseManagerException | SlotException e) {
- onException(e);
- return;
- }
-
- updateEncryptionPreference();
- }
-
- @Override
- public void onException(Exception e) {
- updateEncryptionPreference();
- Toast.makeText(getActivity(), getString(R.string.encryption_set_password_error) + e.getMessage(), Toast.LENGTH_SHORT).show();
- }
-
- private void updateEncryptionPreference() {
+ private void updateEncryptionPreferences() {
boolean encrypted = _db.isEncryptionEnabled();
_encryptionPreference.setChecked(encrypted, true);
+ _setPasswordPreference.setVisible(encrypted);
+ _fingerprintPreference.setVisible(encrypted);
_slotsPreference.setEnabled(encrypted);
+
+ if (encrypted) {
+ SlotList slots = _db.getCredentials().getSlots();
+ boolean multiPassword = slots.findAll(PasswordSlot.class).size() > 1;
+ boolean multiFinger = slots.findAll(FingerprintSlot.class).size() > 1;
+ boolean showSlots = BuildConfig.DEBUG || multiPassword || multiFinger;
+ _setPasswordPreference.setEnabled(!multiPassword);
+ _fingerprintPreference.setEnabled(FingerprintHelper.getManager(getContext()) != null && !multiFinger);
+ _fingerprintPreference.setChecked(slots.has(FingerprintSlot.class), true);
+ _slotsPreference.setVisible(showSlots);
+ } else {
+ _setPasswordPreference.setEnabled(false);
+ _fingerprintPreference.setEnabled(false);
+ _fingerprintPreference.setChecked(false, true);
+ _slotsPreference.setVisible(false);
+ }
+ }
+
+ private class SetPasswordListener implements Dialogs.SlotListener {
+ @Override
+ public void onSlotResult(Slot slot, Cipher cipher) {
+ DatabaseFileCredentials creds = new DatabaseFileCredentials();
+
+ try {
+ slot.setKey(creds.getKey(), cipher);
+ creds.getSlots().add(slot);
+ _db.enableEncryption(creds);
+ } catch (DatabaseManagerException | SlotException e) {
+ onException(e);
+ return;
+ }
+
+ updateEncryptionPreferences();
+ }
+
+ @Override
+ public void onException(Exception e) {
+ updateEncryptionPreferences();
+ Toast.makeText(getActivity(), getString(R.string.encryption_set_password_error) + e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private class RegisterFingerprintListener implements Dialogs.SlotListener {
+ @Override
+ public void onSlotResult(Slot slot, Cipher cipher) {
+ DatabaseFileCredentials creds = _db.getCredentials();
+ SlotList slots = creds.getSlots();
+
+ try {
+ slot.setKey(creds.getKey(), cipher);
+ } catch (SlotException e) {
+ onException(e);
+ return;
+ }
+
+ slots.add(slot);
+ _db.setCredentials(creds);
+
+ saveDatabase();
+ updateEncryptionPreferences();
+ }
+
+ @Override
+ public void onException(Exception e) {
+ Toast.makeText(getActivity(), getString(R.string.encryption_enable_fingerprint_error) + e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ private class EnableEncryptionListener implements Dialogs.SlotListener {
+ @Override
+ public void onSlotResult(Slot slot, Cipher cipher) {
+ DatabaseFileCredentials creds = _db.getCredentials();
+ SlotList slots = creds.getSlots();
+
+ try {
+ // encrypt the master key for this slot
+ slot.setKey(creds.getKey(), cipher);
+
+ // remove the old master password slot
+ PasswordSlot oldSlot = creds.getSlots().find(PasswordSlot.class);
+ slots.remove(oldSlot);
+
+ // add the new master password slot
+ slots.add(slot);
+ } catch (SlotException e) {
+ onException(e);
+ return;
+ }
+
+ _db.setCredentials(creds);
+ saveDatabase();
+ }
+
+ @Override
+ public void onException(Exception e) {
+ Toast.makeText(getActivity(), getString(R.string.encryption_set_password_error) + e.getMessage(), Toast.LENGTH_SHORT).show();
+ }
}
}
diff --git a/app/src/main/java/me/impy/aegis/ui/SlotManagerActivity.java b/app/src/main/java/me/impy/aegis/ui/SlotManagerActivity.java
index b6ba141a..a77b7242 100644
--- a/app/src/main/java/me/impy/aegis/ui/SlotManagerActivity.java
+++ b/app/src/main/java/me/impy/aegis/ui/SlotManagerActivity.java
@@ -24,11 +24,9 @@ import me.impy.aegis.db.slots.SlotList;
import me.impy.aegis.db.slots.SlotException;
import me.impy.aegis.helpers.FingerprintHelper;
import me.impy.aegis.ui.dialogs.Dialogs;
-import me.impy.aegis.ui.dialogs.FingerprintDialogFragment;
import me.impy.aegis.ui.views.SlotAdapter;
-import me.impy.aegis.ui.dialogs.SlotDialogFragment;
-public class SlotManagerActivity extends AegisActivity implements SlotAdapter.Listener, SlotDialogFragment.Listener {
+public class SlotManagerActivity extends AegisActivity implements SlotAdapter.Listener, Dialogs.SlotListener {
private DatabaseFileCredentials _creds;
private SlotAdapter _adapter;
@@ -45,8 +43,11 @@ public class SlotManagerActivity extends AegisActivity implements SlotAdapter.Li
bar.setDisplayHomeAsUpEnabled(true);
findViewById(R.id.button_add_fingerprint).setOnClickListener(view -> {
- FingerprintDialogFragment dialog = new FingerprintDialogFragment();
- dialog.show(getSupportFragmentManager(), null);
+ Dialogs.showFingerprintDialog(this ,this);
+ });
+
+ findViewById(R.id.button_add_password).setOnClickListener(view -> {
+ Dialogs.showSetPasswordDialog(this, this);
});
// set up the recycler view
diff --git a/app/src/main/java/me/impy/aegis/ui/dialogs/Dialogs.java b/app/src/main/java/me/impy/aegis/ui/dialogs/Dialogs.java
index d1459c8d..117fac27 100644
--- a/app/src/main/java/me/impy/aegis/ui/dialogs/Dialogs.java
+++ b/app/src/main/java/me/impy/aegis/ui/dialogs/Dialogs.java
@@ -2,17 +2,40 @@ package me.impy.aegis.ui.dialogs;
import android.app.Activity;
import android.content.DialogInterface;
+import android.hardware.fingerprint.FingerprintManager;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.TextView;
+
+import com.mattprecious.swirl.SwirlView;
+
+import javax.crypto.Cipher;
+import javax.crypto.SecretKey;
+
import androidx.appcompat.app.AlertDialog;
import me.impy.aegis.R;
+import me.impy.aegis.crypto.KeyStoreHandle;
+import me.impy.aegis.crypto.KeyStoreHandleException;
+import me.impy.aegis.db.slots.FingerprintSlot;
+import me.impy.aegis.db.slots.PasswordSlot;
+import me.impy.aegis.db.slots.Slot;
+import me.impy.aegis.db.slots.SlotException;
+import me.impy.aegis.helpers.EditTextHelper;
+import me.impy.aegis.helpers.FingerprintHelper;
+import me.impy.aegis.helpers.FingerprintUiHelper;
+import me.impy.aegis.ui.tasks.DerivationTask;
public class Dialogs {
private Dialogs() {
}
- public static AlertDialog showDeleteEntryDialog(Activity activity, DialogInterface.OnClickListener onDelete) {
- return new AlertDialog.Builder(activity)
+ public static void showDeleteEntryDialog(Activity activity, DialogInterface.OnClickListener onDelete) {
+ new AlertDialog.Builder(activity)
.setTitle(activity.getString(R.string.delete_entry))
.setMessage(activity.getString(R.string.delete_entry_description))
.setPositiveButton(android.R.string.yes, onDelete)
@@ -20,12 +43,115 @@ public class Dialogs {
.show();
}
- public static AlertDialog showDiscardDialog(Activity activity, DialogInterface.OnClickListener onSave, DialogInterface.OnClickListener onDiscard) {
- return new AlertDialog.Builder(activity)
+ public static void showDiscardDialog(Activity activity, DialogInterface.OnClickListener onSave, DialogInterface.OnClickListener onDiscard) {
+ new AlertDialog.Builder(activity)
.setTitle(activity.getString(R.string.discard_changes))
.setMessage(activity.getString(R.string.discard_changes_description))
.setPositiveButton(R.string.save, onSave)
.setNegativeButton(R.string.discard, onDiscard)
.show();
}
+
+ public static void showSetPasswordDialog(Activity activity, Dialogs.SlotListener listener) {
+ View view = activity.getLayoutInflater().inflate(R.layout.dialog_password, null);
+ EditText textPassword = view.findViewById(R.id.text_password);
+ EditText textPasswordConfirm = view.findViewById(R.id.text_password_confirm);
+
+ AlertDialog alert = new AlertDialog.Builder(activity)
+ .setTitle(R.string.set_password)
+ .setView(view)
+ .setPositiveButton(android.R.string.ok, null)
+ .setNegativeButton(android.R.string.cancel, null)
+ .create();
+
+ final Button[] buttonOK = new Button[1];
+ alert.setOnShowListener(dialog -> {
+ buttonOK[0] = alert.getButton(AlertDialog.BUTTON_POSITIVE);
+ buttonOK[0].setEnabled(false);
+
+ // replace the default listener
+ buttonOK[0].setOnClickListener(v -> {
+ if (!EditTextHelper.areEditTextsEqual(textPassword, textPasswordConfirm)) {
+ return;
+ }
+
+ char[] password = EditTextHelper.getEditTextChars(textPassword);
+ PasswordSlot slot = new PasswordSlot();
+ DerivationTask task = new DerivationTask(activity, key -> {
+ Cipher cipher;
+ try {
+ cipher = Slot.createEncryptCipher(key);
+ } catch (SlotException e) {
+ listener.onException(e);
+ dialog.cancel();
+ return;
+ }
+ listener.onSlotResult(slot, cipher);
+ dialog.dismiss();
+ });
+ task.execute(new DerivationTask.Params(slot, password));
+ });
+ });
+
+ TextWatcher watcher = new TextWatcher() {
+ public void onTextChanged(CharSequence c, int start, int before, int count) {
+ boolean equal = EditTextHelper.areEditTextsEqual(textPassword, textPasswordConfirm);
+ buttonOK[0].setEnabled(equal);
+ }
+ public void beforeTextChanged(CharSequence c, int start, int count, int after) { }
+ public void afterTextChanged(Editable c) { }
+ };
+ textPassword.addTextChangedListener(watcher);
+ textPasswordConfirm.addTextChangedListener(watcher);
+
+ alert.show();
+ }
+
+ public static void showFingerprintDialog(Activity activity, Dialogs.SlotListener listener) {
+ View view = activity.getLayoutInflater().inflate(R.layout.dialog_fingerprint, null);
+ TextView textFingerprint = view.findViewById(R.id.text_fingerprint);
+ SwirlView imgFingerprint = view.findViewById(R.id.img_fingerprint);
+
+ Cipher cipher;
+ FingerprintSlot slot;
+ final FingerprintUiHelper[] helper = new FingerprintUiHelper[1];
+ FingerprintManager manager = FingerprintHelper.getManager(activity);
+
+ try {
+ slot = new FingerprintSlot();
+ SecretKey key = new KeyStoreHandle().generateKey(slot.getUUID().toString());
+ cipher = Slot.createEncryptCipher(key);
+ } catch (KeyStoreHandleException | SlotException e) {
+ throw new RuntimeException(e);
+ }
+
+ AlertDialog dialog = new AlertDialog.Builder(activity)
+ .setTitle(R.string.register_fingerprint)
+ .setView(view)
+ .setNegativeButton(android.R.string.cancel, null)
+ .setOnDismissListener(d -> {
+ helper[0].stopListening();
+ })
+ .show();
+
+ helper[0] = new FingerprintUiHelper(manager, imgFingerprint, textFingerprint, new FingerprintUiHelper.Callback() {
+ @Override
+ public void onAuthenticated() {
+ listener.onSlotResult(slot, cipher);
+ dialog.dismiss();
+ }
+
+ @Override
+ public void onError() {
+
+ }
+ });
+
+ helper[0].startListening(new FingerprintManager.CryptoObject(cipher));
+ }
+
+ public interface SlotListener {
+ void onSlotResult(Slot slot, Cipher cipher);
+ void onException(Exception e);
+ }
}
diff --git a/app/src/main/java/me/impy/aegis/ui/dialogs/FingerprintDialogFragment.java b/app/src/main/java/me/impy/aegis/ui/dialogs/FingerprintDialogFragment.java
deleted file mode 100644
index ff5b8a7b..00000000
--- a/app/src/main/java/me/impy/aegis/ui/dialogs/FingerprintDialogFragment.java
+++ /dev/null
@@ -1,82 +0,0 @@
-package me.impy.aegis.ui.dialogs;
-
-import android.app.Dialog;
-import android.hardware.fingerprint.FingerprintManager;
-import android.os.Bundle;
-import androidx.appcompat.app.AlertDialog;
-import androidx.annotation.NonNull;
-import android.view.View;
-import android.widget.TextView;
-
-import com.mattprecious.swirl.SwirlView;
-
-import javax.crypto.Cipher;
-import javax.crypto.SecretKey;
-
-import me.impy.aegis.R;
-import me.impy.aegis.crypto.KeyStoreHandle;
-import me.impy.aegis.crypto.KeyStoreHandleException;
-import me.impy.aegis.db.slots.FingerprintSlot;
-import me.impy.aegis.db.slots.Slot;
-import me.impy.aegis.db.slots.SlotException;
-import me.impy.aegis.helpers.FingerprintHelper;
-import me.impy.aegis.helpers.FingerprintUiHelper;
-
-public class FingerprintDialogFragment extends SlotDialogFragment implements FingerprintUiHelper.Callback {
- private Cipher _cipher;
- private FingerprintUiHelper _helper;
- private FingerprintSlot _slot;
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_fingerprint, null);
- TextView textFingerprint = view.findViewById(R.id.text_fingerprint);
- SwirlView imgFingerprint = view.findViewById(R.id.img_fingerprint);
-
- FingerprintManager manager = FingerprintHelper.getManager(getContext());
- try {
- _slot = new FingerprintSlot();
- SecretKey key = new KeyStoreHandle().generateKey(_slot.getUUID().toString());
- _cipher = Slot.createEncryptCipher(key);
- _helper = new FingerprintUiHelper(manager, imgFingerprint, textFingerprint, this);
- } catch (KeyStoreHandleException | SlotException e) {
- throw new RuntimeException(e);
- }
-
- return new AlertDialog.Builder(getActivity())
- .setTitle(R.string.register_fingerprint)
- .setView(view)
- .setNegativeButton(android.R.string.cancel, null)
- .create();
- }
-
- @Override
- public void onResume() {
- super.onResume();
-
- if (_helper != null) {
- _helper.startListening(new FingerprintManager.CryptoObject(_cipher));
- }
- }
-
- @Override
- public void onPause() {
- super.onPause();
-
- if (_helper != null) {
- _helper.stopListening();
- }
- }
-
- @Override
- public void onAuthenticated() {
- getListener().onSlotResult(_slot, _cipher);
- dismiss();
- }
-
- @Override
- public void onError() {
-
- }
-}
diff --git a/app/src/main/java/me/impy/aegis/ui/dialogs/PasswordDialogFragment.java b/app/src/main/java/me/impy/aegis/ui/dialogs/PasswordDialogFragment.java
deleted file mode 100644
index d2d72462..00000000
--- a/app/src/main/java/me/impy/aegis/ui/dialogs/PasswordDialogFragment.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package me.impy.aegis.ui.dialogs;
-
-import android.app.Dialog;
-import android.os.Bundle;
-import androidx.annotation.NonNull;
-import androidx.appcompat.app.AlertDialog;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.view.View;
-import android.widget.Button;
-import android.widget.EditText;
-
-import javax.crypto.Cipher;
-
-import me.impy.aegis.R;
-import me.impy.aegis.db.slots.PasswordSlot;
-import me.impy.aegis.db.slots.Slot;
-import me.impy.aegis.db.slots.SlotException;
-import me.impy.aegis.helpers.EditTextHelper;
-import me.impy.aegis.ui.tasks.DerivationTask;
-
-public class PasswordDialogFragment extends SlotDialogFragment {
- private Button _buttonOK;
-
- @NonNull
- @Override
- public Dialog onCreateDialog(Bundle savedInstanceState) {
- View view = getActivity().getLayoutInflater().inflate(R.layout.dialog_password, null);
- EditText textPassword = view.findViewById(R.id.text_password);
- EditText textPasswordConfirm = view.findViewById(R.id.text_password_confirm);
-
- AlertDialog alert = new AlertDialog.Builder(getActivity())
- .setTitle(R.string.set_password)
- .setView(view)
- .setPositiveButton(android.R.string.ok, null)
- .setNegativeButton(android.R.string.cancel, null)
- .create();
-
- alert.setOnShowListener(dialog -> {
- _buttonOK = alert.getButton(AlertDialog.BUTTON_POSITIVE);
- _buttonOK.setEnabled(false);
-
- // replace the default listener
- _buttonOK.setOnClickListener(v -> {
- if (!EditTextHelper.areEditTextsEqual(textPassword, textPasswordConfirm)) {
- return;
- }
-
- char[] password = EditTextHelper.getEditTextChars(textPassword);
- PasswordSlot slot = new PasswordSlot();
- DerivationTask task = new DerivationTask(getActivity(), key -> {
- Cipher cipher;
- try {
- cipher = Slot.createEncryptCipher(key);
- } catch (SlotException e) {
- getListener().onException(e);
- dialog.cancel();
- return;
- }
- getListener().onSlotResult(slot, cipher);
- dialog.dismiss();
- });
- task.execute(new DerivationTask.Params(slot, password));
- });
- });
-
- TextWatcher watcher = new TextWatcher() {
- public void onTextChanged(CharSequence c, int start, int before, int count) {
- boolean equal = EditTextHelper.areEditTextsEqual(textPassword, textPasswordConfirm);
- _buttonOK.setEnabled(equal);
- }
- public void beforeTextChanged(CharSequence c, int start, int count, int after) { }
- public void afterTextChanged(Editable c) { }
- };
- textPassword.addTextChangedListener(watcher);
- textPasswordConfirm.addTextChangedListener(watcher);
-
- return alert;
- }
-}
diff --git a/app/src/main/java/me/impy/aegis/ui/dialogs/SlotDialogFragment.java b/app/src/main/java/me/impy/aegis/ui/dialogs/SlotDialogFragment.java
deleted file mode 100644
index f7b41251..00000000
--- a/app/src/main/java/me/impy/aegis/ui/dialogs/SlotDialogFragment.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package me.impy.aegis.ui.dialogs;
-
-import android.content.Context;
-import androidx.fragment.app.DialogFragment;
-
-import javax.crypto.Cipher;
-
-import me.impy.aegis.db.slots.Slot;
-
-public class SlotDialogFragment extends DialogFragment {
- private Listener _listener;
-
- protected Listener getListener() {
- return _listener;
- }
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
-
- try {
- _listener = (Listener) context;
- } catch (ClassCastException e) {
- throw new ClassCastException(context.toString() + " must implement SlotDialogFragment.Listener");
- }
- }
-
- public interface Listener {
- void onSlotResult(Slot slot, Cipher cipher);
- void onException(Exception e);
- }
-}
diff --git a/app/src/main/res/layout/activity_slots.xml b/app/src/main/res/layout/activity_slots.xml
index 9d8d18d2..0b5c136b 100644
--- a/app/src/main/res/layout/activity_slots.xml
+++ b/app/src/main/res/layout/activity_slots.xml
@@ -25,6 +25,34 @@
android:layout_height="wrap_content"
android:scrollbars="vertical"/>
+
+
+
+
+
+
+
Block screenshots and other attempts to capture the screen within the app
Encryption
Encrypt the database and unlock it with a password or fingerprint
+ Fingerprint
+ Allow fingerprints registered on this device to unlock the vault
Change password
Set a new password which you will need to unlock your vault
@@ -81,6 +83,7 @@
Scan QR code
Enter manually
Add fingerprint
+ Add password
The vault is only as secure as your weakest secret. When a new fingerprint is added to your device, you will to reactivate fingerprint authentication within Aegis.
Copy
Edit
@@ -122,7 +125,8 @@
An error occurred while trying to export the database
The database has been exported to:
This action will export the database out of Aegis\' private storage.
- An error occurred while trying to set the password:
+ An error occurred while trying to set the password:
+ An error occurred while trying to enable fingerprint unlock:
No cameras available
An error occurred while trying to read the QR code
Raw
diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml
index e9d626fb..cd846caf 100644
--- a/app/src/main/res/xml/preferences.xml
+++ b/app/src/main/res/xml/preferences.xml
@@ -53,6 +53,13 @@
android:dependency="pref_encryption"
app:iconSpaceReserved="false"/>
+
+