diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/GroupFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/GroupFragment.java index 7e20fdc..e5ec699 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/GroupFragment.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/GroupFragment.java @@ -93,14 +93,11 @@ public class GroupFragment extends NamedFragment { break; case 2: DialogUtil.showChooseGroupDialog(requireContext(), group -> { - if(OTPDatabase.getLoadedDatabase() == null) { - // TODO: prompt user - return; - } - - OTPDatabase.getLoadedDatabase().addOTP(group, data); - // TODO: save - otpListAdapter.remove(data); + OTPDatabase.promptLoadDatabase(requireContext(), () -> { + OTPDatabase.getLoadedDatabase().addOTP(group, data); + // TODO: save + otpListAdapter.remove(data); + }, () -> DialogUtil.showErrorDialog(requireContext(), "Failed to add OTP")); saveOTPs(); }, null); break; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/model/OTPData.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/model/OTPData.java index 04e1b2e..569274d 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/model/OTPData.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/model/OTPData.java @@ -107,12 +107,12 @@ public class OTPData implements Serializable { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; OTPData otpData = (OTPData) o; - return digits == otpData.digits && period == otpData.period && counter == otpData.counter && checksum == otpData.checksum && Objects.equals(name, otpData.name) && Objects.equals(issuer, otpData.issuer) && type == otpData.type && Objects.equals(secret, otpData.secret) && algorithm == otpData.algorithm && Objects.equals(otp, otpData.otp); + return digits == otpData.digits && period == otpData.period && counter == otpData.counter && checksum == otpData.checksum && Objects.equals(name, otpData.name) && Objects.equals(issuer, otpData.issuer) && type == otpData.type && Objects.equals(secret, otpData.secret) && algorithm == otpData.algorithm; } @Override public int hashCode() { - return Objects.hash(name, issuer, type, secret, algorithm, digits, period, counter, checksum, otp); + return Objects.hash(name, issuer, type, secret, algorithm, digits, period, counter, checksum); } } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/urihandler/URIHandlerActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/urihandler/URIHandlerActivity.java index 7ef5c2a..d1c1f4f 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/urihandler/URIHandlerActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/urihandler/URIHandlerActivity.java @@ -65,16 +65,14 @@ public class URIHandlerActivity extends AppCompatActivity { private void importCodes(OTPData... data) { DialogUtil.showChooseGroupDialog(this, group -> { for(OTPData d : data) { - if(OTPDatabase.getLoadedDatabase() == null) { - // TODO: prompt user - } - - OTPDatabase.getLoadedDatabase().addOTP(group, d); - try { - OTPDatabase.saveDatabase(this, SettingsUtil.getCryptoParameters(this)); - } catch (OTPDatabaseException | CryptoException e) { - DialogUtil.showErrorDialog(this, e.toString()); - } + OTPDatabase.promptLoadDatabase(this, () -> { + OTPDatabase.getLoadedDatabase().addOTP(group, d); + try { + OTPDatabase.saveDatabase(this, SettingsUtil.getCryptoParameters(this)); + } catch (OTPDatabaseException | CryptoException e) { + DialogUtil.showErrorDialog(this, e.toString()); + } + }, () -> finishAffinity()); } Toast.makeText(this, R.string.uri_handler_code_added, Toast.LENGTH_SHORT).show(); }, this::finishAndRemoveTask); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/DialogUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/DialogUtil.java index 82df1a2..e450734 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/DialogUtil.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/DialogUtil.java @@ -47,14 +47,19 @@ public class DialogUtil { dialog.show(); } - public static void showErrorDialog(Context context, String errorMessage) { + public static void showErrorDialog(Context context, String errorMessage, Runnable closed) { new StyledDialogBuilder(context) .setTitle(R.string.failed_title) .setMessage(errorMessage) .setPositiveButton(R.string.ok, (d, which) -> {}) + .setOnDismissListener(d -> { if(closed != null) closed.run(); }) .show(); } + public static void showErrorDialog(Context context, String errorMessage) { + showErrorDialog(context, errorMessage, null); + } + public static void showTOTPDialog(LayoutInflater inflater, OTPData initialData, Consumer callback, Runnable back, boolean view) { Context context = inflater.getContext(); DialogInputCodeTotpBinding binding = DialogInputCodeTotpBinding.inflate(inflater); @@ -262,24 +267,30 @@ public class DialogUtil { dialog.show(); } - public static void showInputPasswordDialog(Context context, Consumer callback, Runnable onDismiss) { + public static void showInputPasswordDialog(Context context, Consumer callback, Runnable onCancel) { EditText passwordField = new EditText(context); passwordField.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); AlertDialog dialog = new StyledDialogBuilder(context) .setTitle("Input Password") .setView(passwordField) // TODO: better layout - .setPositiveButton("Ok", (d, which) -> { - if(passwordField.getText().length() == 0) { - DialogUtil.showErrorDialog(context, "You need to enter a password"); - return; - } - - callback.accept(passwordField.getText().toString()); - }) - .setNegativeButton(R.string.cancel, (d, which) -> { if(onDismiss != null) onDismiss.run(); }) - .setOnCancelListener(d -> { if(onDismiss != null) onDismiss.run(); }) + .setPositiveButton("Ok", (d, which) -> {}) + .setNegativeButton(R.string.cancel, (d, which) -> { if(onCancel != null) onCancel.run(); }) + .setOnCancelListener(d -> { if(onCancel != null) onCancel.run(); }) .create(); + dialog.setOnShowListener(d -> { + Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); + okButton.setOnClickListener(v -> { + if(passwordField.getText().length() == 0) { + DialogUtil.showErrorDialog(context, "You need to enter a password"); + return; + } + + dialog.dismiss(); + callback.accept(passwordField.getText().toString()); + }); + }); + dialog.show(); } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/OTPDatabase.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/OTPDatabase.java index e420436..52be296 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/OTPDatabase.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/OTPDatabase.java @@ -2,6 +2,8 @@ package com.cringe_studios.cringe_authenticator.util; import android.content.Context; +import androidx.core.util.Consumer; + import com.cringe_studios.cringe_authenticator.crypto.Crypto; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; @@ -69,19 +71,20 @@ public class OTPDatabase { loadDatabase(ctx, null); if(success != null) success.run(); } catch (OTPDatabaseException | CryptoException e) { - throw new RuntimeException(e); // TODO + DialogUtil.showErrorDialog(ctx, "Failed to load database: " + e, failure); } return; } - DialogUtil.showErrorDialog(ctx, "LOAD DB!"); // TODO: implement DialogUtil.showInputPasswordDialog(ctx, password -> { try { SecretKey key = Crypto.generateKey(SettingsUtil.getCryptoParameters(ctx), password); loadDatabase(ctx, key); - if(success != null) success.run(); - } catch (CryptoException | OTPDatabaseException e) { - failure.run(); // TODO: show error + if (success != null) success.run(); + }catch(CryptoException e) { + DialogUtil.showErrorDialog(ctx, "Failed to load database: Invalid password or database corrupted", failure); + } catch (OTPDatabaseException e) { + DialogUtil.showErrorDialog(ctx, "Failed to load database: " + e, failure); } }, failure); }