diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java index 7c9f0ff..6efa59a 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java @@ -2,7 +2,6 @@ package com.cringe_studios.cringe_authenticator; import android.net.Uri; import android.os.Bundle; -import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -330,7 +329,7 @@ public class MainActivity extends BaseActivity { lockOnStop = true; callback.accept(uri); }; - pickBackupFileLoad.launch(new String[]{"application/json"}); + pickBackupFileLoad.launch(new String[]{"application/json", "*/*"}); } @Override @@ -342,7 +341,6 @@ public class MainActivity extends BaseActivity { @Override protected void onStop() { super.onStop(); - Log.d("STOP", lockOnStop+""); if(lockOnStop) OTPDatabase.unloadDatabase(); } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java index c73c8eb..c5d61a6 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/SettingsFragment.java @@ -267,27 +267,32 @@ public class SettingsFragment extends NamedFragment { } private void loadBackup(Uri uri) { - OTPDatabase.promptLoadDatabase(requireActivity(), () -> { - if(SettingsUtil.isDatabaseEncrypted(requireContext())) { - try { - SecretKey key = OTPDatabase.getLoadedKey(); - CryptoParameters parameters = SettingsUtil.getCryptoParameters(requireContext()); - loadBackup(uri, key, parameters); - } catch (CryptoException ignored) { // Load with password - } catch (BackupException | OTPDatabaseException e) { - DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e); - return; + DialogUtil.showYesNo(requireContext(), R.string.load_backup_title, R.string.backup_load_message, () -> { + OTPDatabase.promptLoadDatabase(requireActivity(), () -> { + if(SettingsUtil.isDatabaseEncrypted(requireContext())) { + try { + SecretKey key = OTPDatabase.getLoadedKey(); + CryptoParameters parameters = SettingsUtil.getCryptoParameters(requireContext()); + loadBackup(uri, key, parameters); + return; + } catch (CryptoException ignored) { // Load with password + } catch (BackupException | OTPDatabaseException e) { + DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e); + return; + } } - } - DialogUtil.showInputPasswordDialog(requireContext(), password -> { - try { - CryptoParameters parameters = BackupUtil.loadParametersFromBackup(requireContext(), uri); - SecretKey key = Crypto.generateKey(parameters, password); - loadBackup(uri, key, parameters); - } catch (BackupException | OTPDatabaseException | CryptoException e2) { - DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e2); - } + DialogUtil.showInputPasswordDialog(requireContext(), password -> { + try { + CryptoParameters parameters = BackupUtil.loadParametersFromBackup(requireContext(), uri); + SecretKey key = Crypto.generateKey(parameters, password); + loadBackup(uri, key, parameters); + } catch (CryptoException e) { + DialogUtil.showErrorDialog(requireContext(), "Failed to load backup. Make sure the password is valid", e); + } catch (BackupException | OTPDatabaseException e) { + DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e); + } + }, null); }, null); }, null); } @@ -302,6 +307,8 @@ public class SettingsFragment extends NamedFragment { SettingsUtil.restoreGroups(requireContext(), data.getGroups()); OTPDatabase.setLoadedDatabase(db); OTPDatabase.saveDatabase(requireContext(), SettingsUtil.getCryptoParameters(requireContext())); + + DialogUtil.showBackupLoadedDialog(requireContext(), data); } catch (OTPDatabaseException | CryptoException e) { OTPDatabase.setLoadedDatabase(oldDatabase); throw new RuntimeException(e); 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 c406224..dd4d4e7 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 @@ -12,6 +12,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.core.util.Consumer; import com.cringe_studios.cringe_authenticator.R; +import com.cringe_studios.cringe_authenticator.backup.BackupData; import com.cringe_studios.cringe_authenticator.databinding.DialogCreateGroupBinding; import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeHotpBinding; import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeTotpBinding; @@ -277,7 +278,7 @@ public class DialogUtil { AlertDialog dialog = new StyledDialogBuilder(context) .setTitle(R.string.set_password) .setView(binding.getRoot()) - .setPositiveButton("Ok", (d, which) -> {}) + .setPositiveButton(R.string.ok, (d, which) -> {}) .setNegativeButton(R.string.cancel, (d, which) -> { if(onCancel != null) onCancel.run(); }) .setOnCancelListener(d -> { if(onCancel != null) onCancel.run(); }) .create(); @@ -310,8 +311,8 @@ public class DialogUtil { AlertDialog dialog = new StyledDialogBuilder(context) .setTitle("Input Password") - .setView(binding.inputPassword) - .setPositiveButton("Ok", (d, which) -> {}) + .setView(binding.getRoot()) + .setPositiveButton(R.string.ok, (d, which) -> {}) .setNegativeButton(R.string.cancel, (d, which) -> { if(onCancel != null) onCancel.run(); }) .setOnCancelListener(d -> { if(onCancel != null) onCancel.run(); }) .create(); @@ -371,4 +372,14 @@ public class DialogUtil { showYesNoCancel(context, title, message, R.string.yes, R.string.no, R.string.cancel, yes, no, cancel); } + public static void showBackupLoadedDialog(Context context, BackupData data) { + AlertDialog dialog = new StyledDialogBuilder(context) + .setTitle("Backup loaded") + .setMessage(String.format("Successfully loaded %s group(s) from the backup", data.getGroups().length)) + .setPositiveButton(R.string.ok, (d, which) -> {}) + .create(); + + dialog.show(); + } + } diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 4c8b023..7a03de7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -96,4 +96,6 @@ Passwort eingeben Verschlüsselung deaktivieren Willst du wirklich die Verschlüsselung deaktivieren? + Backup laden + Willst du dieses Backup laden?\n\nDadurch werden ALLE Daten der App gelöscht und mit denen aus dem Backup ersetzt! \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e65c9be..24c640b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -97,4 +97,6 @@ Enter Password Disable encryption Do you really want to disable encryption? + Load backup + Do you want to load this backup?\n\nThis will delete ALL of the current data in the app and replace it with the data from the backup! \ No newline at end of file