diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/BaseActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/BaseActivity.java index 38b85f4..85b7b5c 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/BaseActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/BaseActivity.java @@ -2,7 +2,6 @@ package com.cringe_studios.cringe_authenticator; import android.content.res.Configuration; import android.os.Bundle; -import android.util.Log; import android.view.WindowManager; import androidx.activity.result.ActivityResultLauncher; @@ -50,7 +49,7 @@ public class BaseActivity extends AppCompatActivity { public void setLocale(Locale locale) { Locale.setDefault(locale); Configuration config = new Configuration(); - config.locale = locale; + config.setLocale(locale); getResources().updateConfiguration(config, getResources().getDisplayMetrics()); } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java index 56a6acb..eb38b6f 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/IntroActivity.java @@ -7,8 +7,6 @@ import android.os.Bundle; import android.view.ViewGroup; import android.widget.Toast; -import androidx.appcompat.app.AppCompatActivity; - import com.cringe_studios.cringe_authenticator.databinding.ActivityIntroBinding; import com.cringe_studios.cringe_authenticator.unlock.UnlockActivity; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; 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 c26803b..7c9f0ff 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 @@ -1,8 +1,8 @@ package com.cringe_studios.cringe_authenticator; -import android.content.res.Configuration; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -32,14 +32,12 @@ import com.cringe_studios.cringe_authenticator.scanner.QRScannerContract; import com.cringe_studios.cringe_authenticator.util.DialogUtil; import com.cringe_studios.cringe_authenticator.util.NavigationUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; -import com.cringe_studios.cringe_authenticator.util.SettingsUtil; import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder; import com.cringe_studios.cringe_authenticator.util.ThemeUtil; import com.cringe_studios.cringe_authenticator_library.OTPType; import com.google.mlkit.vision.common.InputImage; import java.io.IOException; -import java.util.Locale; public class MainActivity extends BaseActivity { @@ -61,7 +59,7 @@ public class MainActivity extends BaseActivity { private boolean fullyLaunched; - private boolean lockOnPause = true; + private boolean lockOnStop = true; @Override protected void onCreate(Bundle savedInstanceState) { @@ -70,7 +68,7 @@ public class MainActivity extends BaseActivity { qrScanner = new QRScanner(); startQRCodeScan = registerForActivityResult(new QRScannerContract(), obj -> { - lockOnPause = true; + lockOnStop = true; if(obj == null) return; // Cancelled @@ -98,19 +96,13 @@ public class MainActivity extends BaseActivity { } if(code.isMigrationPart()) { - new StyledDialogBuilder(this) // TODO: duplicated from QRScannerActivity - .setTitle(R.string.qr_scanner_migration_title) - .setMessage(R.string.qr_scanner_migration_message) - .setPositiveButton(R.string.yes, (d, which) -> { - Fragment fragment = NavigationUtil.getCurrentFragment(this); - if (fragment instanceof GroupFragment) { - GroupFragment frag = (GroupFragment) fragment; - for (OTPData dt : code.getOTPs()) frag.addOTP(dt); - } - }) - .setNegativeButton(R.string.no, (d, which) -> {}) - .show() - .setCanceledOnTouchOutside(false); + DialogUtil.showYesNo(this, R.string.qr_scanner_migration_title, R.string.qr_scanner_migration_message, () -> { + Fragment fragment = NavigationUtil.getCurrentFragment(this); + if (fragment instanceof GroupFragment) { + GroupFragment frag = (GroupFragment) fragment; + for (OTPData dt : code.getOTPs()) frag.addOTP(dt); + } + }, null); }else { Fragment fragment = NavigationUtil.getCurrentFragment(this); if (fragment instanceof GroupFragment) { @@ -149,7 +141,7 @@ public class MainActivity extends BaseActivity { private void launchApp() { fullyLaunched = true; - lockOnPause = true; + lockOnStop = true; binding = ActivityMainBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); @@ -225,7 +217,7 @@ public class MainActivity extends BaseActivity { } public void scanCode(MenuItem item) { - lockOnPause = false; + lockOnStop = false; startQRCodeScan.launch(null); } @@ -324,18 +316,18 @@ public class MainActivity extends BaseActivity { } public void promptPickBackupFileSave(String name, Consumer callback) { - this.lockOnPause = false; + this.lockOnStop = false; this.pickBackupFileSaveCallback = uri -> { - lockOnPause = true; + lockOnStop = true; callback.accept(uri); }; pickBackupFileSave.launch(name); } public void promptPickBackupFileLoad(Consumer callback) { - this.lockOnPause = false; + this.lockOnStop = false; this.pickBackupFileLoadCallback = uri -> { - lockOnPause = true; + lockOnStop = true; callback.accept(uri); }; pickBackupFileLoad.launch(new String[]{"application/json"}); @@ -343,14 +335,15 @@ public class MainActivity extends BaseActivity { @Override public void recreate() { - lockOnPause = false; + lockOnStop = false; super.recreate(); } @Override protected void onStop() { super.onStop(); - if(lockOnPause) OTPDatabase.unloadDatabase(); + Log.d("STOP", lockOnStop+""); + if(lockOnStop) OTPDatabase.unloadDatabase(); } @Override diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupData.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupData.java index fae127a..dc973d3 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupData.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupData.java @@ -1,16 +1,12 @@ package com.cringe_studios.cringe_authenticator.backup; import android.util.Base64; -import android.util.Log; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; -import com.cringe_studios.cringe_authenticator.model.OTPData; -import com.cringe_studios.cringe_authenticator.proto.OTPMigration; import com.cringe_studios.cringe_authenticator.util.BackupException; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; -import com.cringe_studios.cringe_authenticator.util.SettingsUtil; import javax.crypto.SecretKey; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupGroup.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupGroup.java index 7aa19a2..053690c 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupGroup.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupGroup.java @@ -1,7 +1,5 @@ package com.cringe_studios.cringe_authenticator.backup; -import org.jetbrains.annotations.Contract; - public class BackupGroup { public String id; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupUtil.java index 26c79e2..837d8ea 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupUtil.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/backup/BackupUtil.java @@ -9,21 +9,14 @@ import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; import com.cringe_studios.cringe_authenticator.util.BackupException; import com.cringe_studios.cringe_authenticator.util.IOUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; -import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; -import org.json.JSONObject; - import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.text.SimpleDateFormat; -import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/crypto/Crypto.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/crypto/Crypto.java index 7f08abb..1cc277e 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/crypto/Crypto.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/crypto/Crypto.java @@ -1,15 +1,12 @@ package com.cringe_studios.cringe_authenticator.crypto; -import android.content.Context; import android.os.Build; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; -import android.util.Log; import androidx.annotation.RequiresApi; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; -import com.cringe_studios.cringe_authenticator.util.SettingsUtil; import org.bouncycastle.crypto.generators.Argon2BytesGenerator; import org.bouncycastle.crypto.params.Argon2Parameters; @@ -25,7 +22,6 @@ import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; -import java.util.Arrays; import java.util.UUID; import javax.crypto.BadPaddingException; 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 c537946..2e651ed 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 @@ -20,8 +20,6 @@ import com.cringe_studios.cringe_authenticator.util.DialogUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; -import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder; -import com.cringe_studios.cringe_authenticator_library.OTPType; import java.util.List; @@ -153,11 +151,12 @@ public class GroupFragment extends NamedFragment { for(OTPListItem item : items) { OTPData data = item.getOTPData(); OTPDatabase.getLoadedDatabase().addOTP(group, data); - OTPDatabase.saveDatabase(requireContext(), SettingsUtil.getCryptoParameters(requireContext())); otpListAdapter.remove(data); } + OTPDatabase.saveDatabase(requireContext(), SettingsUtil.getCryptoParameters(requireContext())); saveOTPs(); + otpListAdapter.finishEditing(); } catch (OTPDatabaseException | CryptoException e) { DialogUtil.showErrorDialog(requireContext(), e.toString()); } @@ -171,19 +170,14 @@ public class GroupFragment extends NamedFragment { List items = otpListAdapter.getSelectedCodes(); - new StyledDialogBuilder(requireContext()) - .setTitle(R.string.otp_delete_title) - .setMessage(R.string.otp_delete_message) - .setPositiveButton(R.string.yes, (d, w) -> { - for(OTPListItem item : items) { - otpListAdapter.remove(item.getOTPData()); - } + DialogUtil.showYesNoCancel(requireContext(), R.string.otp_delete_title, R.string.otp_delete_message, () -> { + for(OTPListItem item : items) { + otpListAdapter.remove(item.getOTPData()); + } - saveOTPs(); - finishEditing(); - }) - .setNegativeButton(R.string.no, (d, w) -> {}) - .show(); + saveOTPs(); + finishEditing(); + }, null, null); } public boolean isEditing() { diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuDrawerFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuDrawerFragment.java index a6897ce..cecfc71 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuDrawerFragment.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuDrawerFragment.java @@ -18,7 +18,6 @@ import com.cringe_studios.cringe_authenticator.util.NavigationUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; -import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder; import com.google.android.material.bottomsheet.BottomSheetDialogFragment; import java.util.List; @@ -91,18 +90,13 @@ public class MenuDrawerFragment extends BottomSheetDialogFragment { public void removeSelectedGroups() { if(!groupListAdapter.isEditing()) return; - new StyledDialogBuilder(requireContext()) - .setTitle(R.string.group_delete_title) - .setMessage(R.string.group_delete_message) - .setPositiveButton(R.string.yes, (d, w) -> { - for(GroupListItem item : groupListAdapter.getSelectedGroups()) { - removeGroup(item.getGroupId()); - } + DialogUtil.showYesNo(requireContext(), R.string.group_delete_title, R.string.group_delete_message, () -> { + for(GroupListItem item : groupListAdapter.getSelectedGroups()) { + removeGroup(item.getGroupId()); + } - groupListAdapter.finishEditing(); - }) - .setNegativeButton(R.string.no, (d, w) -> {}) - .show(); + groupListAdapter.finishEditing(); + }, null); } public void removeGroup(String group) { 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 a580bbe..c73c8eb 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 @@ -15,6 +15,7 @@ import androidx.annotation.Nullable; import com.cringe_studios.cringe_authenticator.MainActivity; import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.backup.BackupData; +import com.cringe_studios.cringe_authenticator.backup.BackupUtil; import com.cringe_studios.cringe_authenticator.crypto.BiometricKey; import com.cringe_studios.cringe_authenticator.crypto.Crypto; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; @@ -22,7 +23,6 @@ import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; import com.cringe_studios.cringe_authenticator.databinding.FragmentSettingsBinding; import com.cringe_studios.cringe_authenticator.util.Appearance; import com.cringe_studios.cringe_authenticator.util.BackupException; -import com.cringe_studios.cringe_authenticator.backup.BackupUtil; import com.cringe_studios.cringe_authenticator.util.BiometricUtil; import com.cringe_studios.cringe_authenticator.util.DialogUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; @@ -66,7 +66,6 @@ public class SettingsFragment extends NamedFragment { if(locale.equals(SettingsUtil.getLocale(requireContext()))) return; SettingsUtil.setLocale(requireContext(), locale); - //((MainActivity) requireActivity()).setLocale(locale); requireActivity().recreate(); } @@ -79,6 +78,8 @@ public class SettingsFragment extends NamedFragment { binding.settingsEnableEncryption.setChecked(SettingsUtil.isDatabaseEncrypted(requireContext())); binding.settingsEnableEncryption.setOnCheckedChangeListener((view, checked) -> { if(checked) { + if(SettingsUtil.isDatabaseEncrypted(requireContext())) return; + DialogUtil.showSetPasswordDialog(requireContext(), password -> { CryptoParameters params = CryptoParameters.createNew(); Log.d("Crypto", "Created new crypto params"); @@ -94,24 +95,29 @@ public class SettingsFragment extends NamedFragment { binding.settingsBiometricLock.setEnabled(true); } } catch (CryptoException | OTPDatabaseException e) { - throw new RuntimeException(e); // TODO + DialogUtil.showErrorDialog(requireContext(), "Failed to enable encryption", e); } - }, null); + }, () -> view.setChecked(false)); }else { - try { - OTPDatabase.decrypt(requireContext()); - SettingsUtil.disableEncryption(requireContext()); - Log.d("Crypto", "DB encryption disabled"); + if(!SettingsUtil.isDatabaseEncrypted(requireContext())) return; - binding.settingsBiometricLock.setChecked(false); - binding.settingsBiometricLock.setEnabled(false); - } catch (OTPDatabaseException | CryptoException e) { - throw new RuntimeException(e); // TODO - } + DialogUtil.showYesNo(requireContext(), R.string.disable_encryption_title, R.string.disable_encryption_message, () -> { + try { + OTPDatabase.decrypt(requireContext()); + SettingsUtil.disableEncryption(requireContext()); + Log.d("Crypto", "DB encryption disabled"); + + binding.settingsBiometricLock.setChecked(false); + binding.settingsBiometricLock.setEnabled(false); + } catch (OTPDatabaseException | CryptoException e) { + DialogUtil.showErrorDialog(requireContext(), "Failed to disable encryption", e); + } + }, () -> view.setChecked(true)); } }); - if(SettingsUtil.isDatabaseEncrypted(requireContext()) && BiometricUtil.isSupported(requireContext())) { + boolean biometricSupported = BiometricUtil.isSupported(requireContext()); + if(SettingsUtil.isDatabaseEncrypted(requireContext()) && biometricSupported) { binding.settingsBiometricLock.setChecked(SettingsUtil.isBiometricEncryption(requireContext())); binding.settingsBiometricLock.setOnCheckedChangeListener((view, checked) -> { if(checked) { @@ -289,7 +295,6 @@ public class SettingsFragment extends NamedFragment { private void loadBackup(Uri uri, SecretKey key, CryptoParameters parameters) throws BackupException, OTPDatabaseException, CryptoException { BackupData data = BackupUtil.loadBackup(requireContext(), uri); OTPDatabase db = data.loadDatabase(key, parameters); - //DialogUtil.showErrorDialog(requireContext(), "Success: " + db); // TODO: prompt user that all current data will be deleted OTPDatabase.promptLoadDatabase(requireActivity(), () -> { OTPDatabase oldDatabase = OTPDatabase.getLoadedDatabase(); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java index 139ff10..d5315ff 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListAdapter.java @@ -1,7 +1,5 @@ package com.cringe_studios.cringe_authenticator.grouplist; -import android.app.Activity; -import android.app.Application; import android.content.Context; import android.os.Handler; import android.os.Looper; @@ -9,19 +7,13 @@ import android.view.LayoutInflater; import android.view.ViewGroup; import androidx.annotation.NonNull; -import androidx.appcompat.app.AppCompatActivity; import androidx.core.util.Consumer; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; -import com.cringe_studios.cringe_authenticator.BaseActivity; -import com.cringe_studios.cringe_authenticator.MainActivity; import com.cringe_studios.cringe_authenticator.databinding.MenuItemBinding; -import com.cringe_studios.cringe_authenticator.otplist.OTPListItem; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; -import org.bouncycastle.jcajce.provider.symmetric.ARC4; - import java.util.ArrayList; import java.util.Collections; import java.util.List; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java index 777e2dc..787680d 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/grouplist/GroupListItem.java @@ -1,10 +1,8 @@ package com.cringe_studios.cringe_authenticator.grouplist; -import android.content.res.ColorStateList; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.drawable.ColorDrawable; -import android.os.Build; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; 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 569274d..77f920c 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 @@ -6,7 +6,6 @@ import com.cringe_studios.cringe_authenticator_library.OTPException; import com.cringe_studios.cringe_authenticator_library.OTPType; import java.io.Serializable; -import java.util.Objects; public class OTPData implements Serializable { @@ -102,17 +101,4 @@ public class OTPData implements Serializable { } } - @Override - public boolean equals(Object o) { - 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; - } - - @Override - public int hashCode() { - return Objects.hash(name, issuer, type, secret, algorithm, digits, period, counter, checksum); - } - } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java index cae26a3..fd06cb4 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java @@ -3,14 +3,12 @@ package com.cringe_studios.cringe_authenticator.otplist; import android.content.Context; import android.os.Handler; import android.os.Looper; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Toast; import androidx.annotation.NonNull; -import androidx.core.util.Consumer; import androidx.recyclerview.widget.ItemTouchHelper; import androidx.recyclerview.widget.RecyclerView; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/DetectedCode.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/DetectedCode.java index d97f8f1..883fdbb 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/DetectedCode.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/DetectedCode.java @@ -2,7 +2,6 @@ package com.cringe_studios.cringe_authenticator.scanner; import com.cringe_studios.cringe_authenticator.model.OTPData; import com.cringe_studios.cringe_authenticator.model.OTPMigrationPart; -import com.cringe_studios.cringe_authenticator.proto.OTPMigration; public class DetectedCode { diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScanner.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScanner.java index 85e55fa..67e71f6 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScanner.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScanner.java @@ -3,7 +3,6 @@ package com.cringe_studios.cringe_authenticator.scanner; import android.net.Uri; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.util.Consumer; import com.cringe_studios.cringe_authenticator.model.OTPMigrationPart; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScannerActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScannerActivity.java index 5bf9a80..7dc5ffe 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScannerActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/scanner/QRScannerActivity.java @@ -8,13 +8,11 @@ import android.media.Image; import android.os.Build; import android.os.Bundle; import android.view.MotionEvent; -import android.view.WindowManager; import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.OptIn; -import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.Camera; import androidx.camera.core.CameraSelector; import androidx.camera.core.ExperimentalGetImage; @@ -32,9 +30,7 @@ import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.databinding.ActivityQrScannerBinding; import com.cringe_studios.cringe_authenticator.model.OTPData; import com.cringe_studios.cringe_authenticator.model.OTPMigrationPart; -import com.cringe_studios.cringe_authenticator.util.SettingsUtil; -import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder; -import com.cringe_studios.cringe_authenticator.util.ThemeUtil; +import com.cringe_studios.cringe_authenticator.util.DialogUtil; import com.google.common.util.concurrent.ListenableFuture; import com.google.mlkit.vision.common.InputImage; @@ -157,22 +153,16 @@ public class QRScannerActivity extends BaseActivity { } if(part.getBatchIndex() == 0) { - new StyledDialogBuilder(this) - .setTitle(R.string.qr_scanner_migration_title) - .setMessage(R.string.qr_scanner_migration_message) - .setPositiveButton(R.string.yes, (d, which) -> { - if(part.getBatchSize() == 1) { - success(part.getOTPs()); - }else { - currentCodes.addAll(Arrays.asList(part.getOTPs())); - lastPart = part; - Toast.makeText(this, getString(R.string.qr_scanner_migration_part, part.getBatchIndex()+ 1, part.getBatchSize()), Toast.LENGTH_LONG).show(); - process = true; - } - }) - .setNegativeButton(R.string.no, (d, which) -> cancel()) - .show() - .setCanceledOnTouchOutside(false); + DialogUtil.showYesNo(this, R.string.qr_scanner_migration_title, R.string.qr_scanner_migration_message, () -> { + if(part.getBatchSize() == 1) { + success(part.getOTPs()); + }else { + currentCodes.addAll(Arrays.asList(part.getOTPs())); + lastPart = part; + Toast.makeText(this, getString(R.string.qr_scanner_migration_part, part.getBatchIndex()+ 1, part.getBatchSize()), Toast.LENGTH_LONG).show(); + process = true; + } + }, null); }else { currentCodes.addAll(Arrays.asList(part.getOTPs())); Toast.makeText(this, getString(R.string.qr_scanner_migration_part, part.getBatchIndex()+ 1, part.getBatchSize()), Toast.LENGTH_LONG).show(); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockActivity.java index 6de16df..9fd77e2 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockActivity.java @@ -1,26 +1,13 @@ package com.cringe_studios.cringe_authenticator.unlock; -import static androidx.biometric.BiometricManager.Authenticators.BIOMETRIC_STRONG; -import static androidx.biometric.BiometricManager.Authenticators.DEVICE_CREDENTIAL; - import android.content.Intent; import android.os.Bundle; -import android.security.KeyStoreParameter; -import android.security.keystore.KeyGenParameterSpec; -import android.security.keystore.KeyProtection; import android.view.View; -import android.view.WindowManager; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.app.AppCompatActivity; -import androidx.biometric.BiometricManager; -import androidx.biometric.BiometricPrompt; -import androidx.core.content.ContextCompat; import com.cringe_studios.cringe_authenticator.BaseActivity; import com.cringe_studios.cringe_authenticator.MainActivity; -import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.crypto.BiometricKey; import com.cringe_studios.cringe_authenticator.crypto.Crypto; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; @@ -32,21 +19,11 @@ import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; import com.cringe_studios.cringe_authenticator.util.ThemeUtil; -import java.io.IOException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.cert.CertificateException; -import java.util.concurrent.Executor; - -import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; public class UnlockActivity extends BaseActivity { - private static final long LOCK_TIMEOUT = 10000; - private ActivityUnlockBinding binding; @Override diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockContract.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockContract.java index 8485fb8..65511aa 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockContract.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/unlock/UnlockContract.java @@ -8,9 +8,6 @@ import androidx.activity.result.contract.ActivityResultContract; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.cringe_studios.cringe_authenticator.scanner.QRScannerActivity; -import com.cringe_studios.cringe_authenticator.scanner.ScannerResult; - public class UnlockContract extends ActivityResultContract { @NonNull @Override 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 693c207..b5108ef 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 @@ -3,26 +3,21 @@ package com.cringe_studios.cringe_authenticator.urihandler; import android.content.Intent; import android.net.Uri; import android.os.Bundle; -import android.util.Log; -import android.view.WindowManager; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; -import androidx.appcompat.app.AppCompatActivity; import com.cringe_studios.cringe_authenticator.BaseActivity; import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; import com.cringe_studios.cringe_authenticator.model.OTPData; -import com.cringe_studios.cringe_authenticator.unlock.UnlockContract; import com.cringe_studios.cringe_authenticator.util.DialogUtil; import com.cringe_studios.cringe_authenticator.util.OTPDatabase; import com.cringe_studios.cringe_authenticator.util.OTPDatabaseException; import com.cringe_studios.cringe_authenticator.util.OTPParser; import com.cringe_studios.cringe_authenticator.util.SettingsUtil; import com.cringe_studios.cringe_authenticator.util.StyledDialogBuilder; -import com.cringe_studios.cringe_authenticator.util.ThemeUtil; public class URIHandlerActivity extends BaseActivity { 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 2cb9aed..c406224 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 @@ -1,14 +1,13 @@ package com.cringe_studios.cringe_authenticator.util; import android.content.Context; -import android.text.InputType; import android.view.LayoutInflater; import android.view.View; import android.widget.ArrayAdapter; import android.widget.Button; -import android.widget.EditText; import androidx.annotation.NonNull; +import androidx.annotation.StringRes; import androidx.appcompat.app.AlertDialog; import androidx.core.util.Consumer; @@ -16,6 +15,7 @@ import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.databinding.DialogCreateGroupBinding; import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeHotpBinding; import com.cringe_studios.cringe_authenticator.databinding.DialogInputCodeTotpBinding; +import com.cringe_studios.cringe_authenticator.databinding.DialogInputPasswordBinding; import com.cringe_studios.cringe_authenticator.databinding.DialogSetPasswordBinding; import com.cringe_studios.cringe_authenticator.model.OTPData; import com.cringe_studios.cringe_authenticator_library.OTPAlgorithm; @@ -306,11 +306,11 @@ public class DialogUtil { } public static void showInputPasswordDialog(Context context, Consumer callback, Runnable onCancel) { - EditText passwordField = new EditText(context); - passwordField.setInputType(InputType.TYPE_TEXT_VARIATION_PASSWORD); + DialogInputPasswordBinding binding = DialogInputPasswordBinding.inflate(LayoutInflater.from(context)); + AlertDialog dialog = new StyledDialogBuilder(context) .setTitle("Input Password") - .setView(passwordField) // TODO: better layout + .setView(binding.inputPassword) .setPositiveButton("Ok", (d, which) -> {}) .setNegativeButton(R.string.cancel, (d, which) -> { if(onCancel != null) onCancel.run(); }) .setOnCancelListener(d -> { if(onCancel != null) onCancel.run(); }) @@ -319,17 +319,56 @@ public class DialogUtil { dialog.setOnShowListener(d -> { Button okButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE); okButton.setOnClickListener(v -> { - if(passwordField.getText().length() == 0) { + if(binding.inputPassword.getText().length() == 0) { DialogUtil.showErrorDialog(context, "You need to enter a password"); return; } dialog.dismiss(); - callback.accept(passwordField.getText().toString()); + callback.accept(binding.inputPassword.getText().toString()); }); }); dialog.show(); } + public static void showYesNo(Context context, @StringRes int title, @StringRes int message, @StringRes int yesText, @StringRes int noText, Runnable yes, Runnable no) { + new StyledDialogBuilder(context) + .setTitle(title) + .setMessage(message) + .setPositiveButton(yesText, (d, w) -> { + if(yes != null) yes.run(); + }) + .setNegativeButton(noText, (d, w) -> { + if(no != null) no.run(); + }) + .show() + .setCanceledOnTouchOutside(false); + } + + public static void showYesNo(Context context, @StringRes int title, @StringRes int message, Runnable yes, Runnable no) { + showYesNo(context, title, message, R.string.yes, R.string.no, yes, no); + } + + public static void showYesNoCancel(Context context, @StringRes int title, @StringRes int message, @StringRes int yesText, @StringRes int noText, @StringRes int cancelText, Runnable yes, Runnable no, Runnable cancel) { + new StyledDialogBuilder(context) + .setTitle(title) + .setMessage(message) + .setPositiveButton(yesText, (d, w) -> { + if(yes != null) yes.run(); + }) + .setNegativeButton(noText, (d, w) -> { + if(no != null) no.run(); + }) + .setNeutralButton(cancelText, (d, w) -> d.cancel()) + .setOnCancelListener(d -> { + if(cancel != null) cancel.run(); + }) + .show(); + } + + public static void showYesNoCancel(Context context, @StringRes int title, @StringRes int message, Runnable yes, Runnable no, Runnable cancel) { + showYesNoCancel(context, title, message, R.string.yes, R.string.no, R.string.cancel, yes, no, cancel); + } + } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java index 03ced84..87f1340 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/NavigationUtil.java @@ -6,7 +6,6 @@ import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.Fragment; import androidx.fragment.app.FragmentManager; -import androidx.fragment.app.FragmentTransaction; import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.fragment.MenuDrawerFragment; 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 10a9dcb..e0906bb 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,25 +2,18 @@ package com.cringe_studios.cringe_authenticator.util; import android.app.Activity; import android.content.Context; -import android.util.Log; - -import androidx.appcompat.app.AppCompatActivity; -import androidx.core.util.Consumer; import com.cringe_studios.cringe_authenticator.BaseActivity; import com.cringe_studios.cringe_authenticator.crypto.Crypto; import com.cringe_studios.cringe_authenticator.crypto.CryptoException; import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; import com.cringe_studios.cringe_authenticator.model.OTPData; -import com.cringe_studios.cringe_authenticator.unlock.UnlockContract; import com.google.gson.JsonObject; import com.google.gson.JsonSyntaxException; import java.io.File; -import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; -import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java index 4d69639..e74460c 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/SettingsUtil.java @@ -2,24 +2,16 @@ package com.cringe_studios.cringe_authenticator.util; import android.content.Context; import android.content.SharedPreferences; -import android.util.Base64; -import com.cringe_studios.cringe_authenticator.R; import com.cringe_studios.cringe_authenticator.backup.BackupGroup; import com.cringe_studios.cringe_authenticator.crypto.BiometricKey; -import com.cringe_studios.cringe_authenticator.crypto.CryptoException; import com.cringe_studios.cringe_authenticator.crypto.CryptoParameters; import com.google.gson.Gson; -import org.bouncycastle.jcajce.provider.symmetric.ARC4; - import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; -import java.util.LinkedHashMap; import java.util.List; import java.util.Locale; -import java.util.Map; public class SettingsUtil { diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/ThemeUtil.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/ThemeUtil.java index 682dc06..84167e2 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/util/ThemeUtil.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/util/ThemeUtil.java @@ -1,8 +1,6 @@ package com.cringe_studios.cringe_authenticator.util; -import android.annotation.SuppressLint; import android.content.res.Configuration; -import android.util.Log; import android.view.View; import androidx.appcompat.app.AppCompatActivity; diff --git a/app/src/main/res/layout/dialog_input_password.xml b/app/src/main/res/layout/dialog_input_password.xml new file mode 100644 index 0000000..cbb02b3 --- /dev/null +++ b/app/src/main/res/layout/dialog_input_password.xml @@ -0,0 +1,29 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values-de-rDE/strings.xml b/app/src/main/res/values-de/strings.xml similarity index 95% rename from app/src/main/res/values-de-rDE/strings.xml rename to app/src/main/res/values-de/strings.xml index b8ac5a6..4c8b023 100644 --- a/app/src/main/res/values-de-rDE/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -93,4 +93,7 @@ Backups Backup erstellen Backup laden + Passwort eingeben + Verschlüsselung deaktivieren + Willst du wirklich die Verschlüsselung deaktivieren? \ 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 2ae8055..e65c9be 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -94,4 +94,7 @@ Backups Create backup Load backup + Enter Password + Disable encryption + Do you really want to disable encryption? \ No newline at end of file