Fix backup create if not encrypted, Move more strings to strings.xml

This commit is contained in:
MrLetsplay 2023-10-03 20:54:29 +02:00
parent abe74d8315
commit 4ffd39596b
Signed by: mr
SSH Key Fingerprint: SHA256:92jBH80vpXyaZHjaIl47pjRq+Yt7XGTArqQg1V7hSqg
12 changed files with 74 additions and 34 deletions

View File

@ -107,7 +107,7 @@ public class MainActivity extends BaseActivity {
InputImage image = InputImage.fromFilePath(this, img);
qrScanner.scan(image, code -> {
if(code == null) {
DialogUtil.showErrorDialog(this, "No codes were detected in the provided image");
DialogUtil.showErrorDialog(this, getString(R.string.error_qr_scan_not_detected));
return;
}
@ -126,9 +126,9 @@ public class MainActivity extends BaseActivity {
for (OTPData dt : code.getOTPs()) frag.addOTP(dt);
}
}
}, error -> DialogUtil.showErrorDialog(this, "Failed to detect code: " + error));
}, error -> DialogUtil.showErrorDialog(this, getString(R.string.error_qr_scan_failed), error, null));
} catch (IOException e) {
DialogUtil.showErrorDialog(this, "Failed to read image: " + e);
DialogUtil.showErrorDialog(this, getString(R.string.error_qr_scan_image_failed), e);
}
});
@ -172,7 +172,7 @@ public class MainActivity extends BaseActivity {
AlertDialog dialog = new StyledDialogBuilder(this)
.setTitle("Icon pack already exists")
.setTitle(R.string.icon_pack_exists_title)
.setView(binding.getRoot())
.setNeutralButton(R.string.cancel, (d, which) -> {})
.create();
@ -184,7 +184,7 @@ public class MainActivity extends BaseActivity {
IconUtil.importIconPack(this, doc);
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
} catch (IconPackException e) {
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
DialogUtil.showErrorDialog(this, getString(R.string.error_import_icon_pack), e);
}
break;
case 1: // Rename existing
@ -193,7 +193,7 @@ public class MainActivity extends BaseActivity {
IconUtil.importIconPack(this, doc);
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
} catch (IconPackException e) {
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
DialogUtil.showErrorDialog(this, getString(R.string.error_import_icon_pack), e);
}
break;
case 2: // Rename imported
@ -201,7 +201,7 @@ public class MainActivity extends BaseActivity {
IconUtil.importIconPack(this, doc, meta.getName() + " (" + meta.getVersion() + ")", UUID.randomUUID().toString());
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
} catch (IconPackException e) {
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
DialogUtil.showErrorDialog(this, getString(R.string.error_import_icon_pack), e);
}
break;
}
@ -217,7 +217,7 @@ public class MainActivity extends BaseActivity {
IconUtil.importIconPack(this, doc);
Toast.makeText(this, getString(R.string.icon_pack_imported, meta.getIcons().length), Toast.LENGTH_LONG).show();
} catch (IconPackException e) {
DialogUtil.showErrorDialog(this, "Failed to import icon pack", e);
DialogUtil.showErrorDialog(this, getString(R.string.error_import_icon_pack), e);
}
});
@ -323,6 +323,7 @@ public class MainActivity extends BaseActivity {
finishAffinity();
}else {
backLastPressed = System.currentTimeMillis();
Toast.makeText(this, R.string.back_pressed, Toast.LENGTH_LONG).show();
}
}

View File

@ -78,8 +78,8 @@ public class EditOTPFragment extends NamedFragment {
binding.inputImage.setVisibility(SettingsUtil.isShowImages(requireContext()) ? View.VISIBLE : View.GONE);
binding.inputImage.setOnClickListener(v -> {
new StyledDialogBuilder(requireContext())
.setTitle("Choose Image")
.setItems(new String[]{"Image from icon pack", "Image from gallery", "No image", "Reset to default image"}, (d, which) -> {
.setTitle(R.string.edit_otp_choose_image)
.setItems(R.array.edit_otp_choose_image_options, (d, which) -> {
switch(which) {
case 0:
pickImageFromIconPack();
@ -231,7 +231,7 @@ public class EditOTPFragment extends NamedFragment {
binding.inputImage.setImageBitmap(bm);
}catch(IOException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to open image", e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_edit_otp_image), e);
}
});
}

View File

@ -100,7 +100,7 @@ public class GroupFragment extends NamedFragment {
OTPDatabase.saveDatabase(requireContext(), SettingsUtil.getCryptoParameters(requireContext()));
for(OTPData d : data) otpListAdapter.add(d);
} catch (OTPDatabaseException | CryptoException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to save database: " + e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_database_save), e);
}
}, null);
}
@ -112,7 +112,7 @@ public class GroupFragment extends NamedFragment {
try {
vh.refresh();
} catch (Exception e) {
DialogUtil.showErrorDialog(requireContext(), e.getMessage() == null ? "An error occurred while refreshing the code" : e.getMessage());
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_otp_refresh), e);
}
}
}

View File

@ -103,7 +103,7 @@ public class SettingsFragment extends NamedFragment {
binding.settingsBiometricLock.setEnabled(true);
}
} catch (CryptoException | OTPDatabaseException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to enable encryption", e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_enable_encryption), e);
}
}, () -> view.setChecked(false));
}else {
@ -118,7 +118,7 @@ public class SettingsFragment extends NamedFragment {
binding.settingsBiometricLock.setChecked(false);
binding.settingsBiometricLock.setEnabled(false);
} catch (OTPDatabaseException | CryptoException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to disable encryption", e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_disable_encryption), e);
}
}, () -> view.setChecked(true));
}
@ -135,7 +135,7 @@ public class SettingsFragment extends NamedFragment {
BiometricKey biometricKey = Crypto.createBiometricKey(SettingsUtil.getCryptoParameters(requireContext()));
SettingsUtil.enableBiometricEncryption(requireContext(), biometricKey);
} catch (CryptoException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to enable: " + e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_biometric_encryption_enable), e);
}
}, () -> view.setChecked(false));
}, null);
@ -144,7 +144,7 @@ public class SettingsFragment extends NamedFragment {
BiometricKey key = SettingsUtil.getBiometricKey(requireContext());
if(key != null) Crypto.deleteBiometricKey(key);
} catch (CryptoException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to delete key: " + e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_biometric_encryption_disable), e);
}
SettingsUtil.disableBiometricEncryption(requireContext());
@ -231,6 +231,11 @@ public class SettingsFragment extends NamedFragment {
.setItems(R.array.backup_create, (d, which) -> {
switch(which) {
case 0:
if(!SettingsUtil.isDatabaseEncrypted(requireContext())) {
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_backup_database_not_encrypted));
return;
}
OTPDatabase.promptLoadDatabase(requireActivity(), () -> {
SecretKey key = OTPDatabase.getLoadedKey();
CryptoParameters parameters = SettingsUtil.getCryptoParameters(requireContext());
@ -287,7 +292,7 @@ public class SettingsFragment extends NamedFragment {
binding.manageIconPacksList.setAdapter(new IconPackListAdapter(requireContext(), IconUtil.loadAllIconPacks(requireContext())));
new StyledDialogBuilder(requireContext())
.setTitle("Manage icon packs")
.setTitle(R.string.manage_icon_packs_title)
.setView(binding.getRoot())
.setPositiveButton(R.string.ok, (d, which) -> {})
.show();
@ -319,7 +324,7 @@ public class SettingsFragment extends NamedFragment {
return;
} catch (CryptoException ignored) { // Load with password
} catch (BackupException | OTPDatabaseException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_backup_load_other), e);
return;
}
}
@ -330,9 +335,9 @@ public class SettingsFragment extends NamedFragment {
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);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_backup_load_crypto), e);
} catch (BackupException | OTPDatabaseException e) {
DialogUtil.showErrorDialog(requireContext(), "Failed to load backup", e);
DialogUtil.showErrorDialog(requireContext(), getString(R.string.error_backup_load_other), e);
}
}, null);
}, null);

View File

@ -93,7 +93,7 @@ public class IconListAdapter extends BaseExpandableListAdapter implements Expand
@Override
public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
IconListCategoryBinding binding = IconListCategoryBinding.inflate(LayoutInflater.from(context));
binding.getRoot().setText((String) getGroup(groupPosition));
binding.getRoot().setText(getGroup(groupPosition));
return binding.getRoot();
}

View File

@ -207,10 +207,11 @@ public class IconUtil {
for(IconPack pack : packs) {
for(Icon i : pack.getIcons()) {
String category = i.getMetadata().getCategory();
if(icons.containsKey(category)) {
icons.get(category).add(i);
List<Icon> is = icons.get(category);
if(is != null) {
is.add(i);
}else {
List<Icon> is = new ArrayList<>();
is = new ArrayList<>();
is.add(i);
icons.put(category, is);
}

View File

@ -190,7 +190,7 @@ public class OTPListAdapter extends RecyclerView.Adapter<OTPListItem> {
try {
h.refresh();
} catch (OTPException e) {
DialogUtil.showErrorDialog(context, e.getMessage() == null ? "An error occurred while refreshing the code" : e.getMessage());
DialogUtil.showErrorDialog(context, context.getString(R.string.error_otp_refresh), e);
}
}
}

View File

@ -28,7 +28,10 @@ public class QRScannerContract extends ActivityResultContract<Void, ScannerResul
return null;
}
return new ScannerResult((OTPData[]) intent.getSerializableExtra("data"));
OTPData[] data = (OTPData[]) intent.getSerializableExtra("data");
if(data == null) return null;
return new ScannerResult(data);
}
}

View File

@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
import com.cringe_studios.code_guard.BaseActivity;
import com.cringe_studios.code_guard.MainActivity;
import com.cringe_studios.code_guard.R;
import com.cringe_studios.code_guard.crypto.BiometricKey;
import com.cringe_studios.code_guard.crypto.Crypto;
import com.cringe_studios.code_guard.crypto.CryptoException;
@ -49,7 +50,7 @@ public class UnlockActivity extends BaseActivity {
OTPDatabase.loadDatabase(this, key);
success();
} catch (CryptoException | OTPDatabaseException e) {
DialogUtil.showErrorDialog(this, "Failed to load database: " + e);
DialogUtil.showErrorDialog(this, getString(R.string.error_unlock_other), e);
}
};
@ -61,7 +62,7 @@ public class UnlockActivity extends BaseActivity {
binding.unlockButton.setOnClickListener(view -> {
if(binding.unlockPassword.getText().length() == 0) {
DialogUtil.showErrorDialog(this, "You need to enter a password");
DialogUtil.showErrorDialog(this, getString(R.string.error_unlock_no_password));
return;
}
@ -72,9 +73,9 @@ public class UnlockActivity extends BaseActivity {
OTPDatabase.loadDatabase(this, key);
success();
}catch(CryptoException e) {
DialogUtil.showErrorDialog(this, "Failed to load database: Invalid password or database corrupted", this::failure);
DialogUtil.showErrorDialog(this, getString(R.string.error_unlock_crypto), this::failure);
} catch (OTPDatabaseException e) {
DialogUtil.showErrorDialog(this, "Failed to load database: " + e, this::failure);
DialogUtil.showErrorDialog(this, getString(R.string.error_unlock_other), e, this::failure);
}
});
}

View File

@ -78,13 +78,17 @@ public class DialogUtil {
}
public static void showErrorDialog(Context context, String errorMessage, Runnable closed) {
showErrorDialog(context, errorMessage, null, closed);
showErrorDialog(context, errorMessage, (String) null, closed);
}
public static void showErrorDialog(Context context, String errorMessage) {
showErrorDialog(context, errorMessage, (Runnable) null);
}
public static void showErrorDialog(Context context, String errorMessage, Exception exception, Runnable closed) {
showErrorDialog(context, errorMessage, stackTraceToString(exception), closed);
}
public static void showErrorDialog(Context context, String errorMessage, Exception exception) {
showErrorDialog(context, errorMessage, stackTraceToString(exception), null);
}

View File

@ -13,8 +13,6 @@ import com.cringe_studios.code_guard.fragment.NamedFragment;
public class NavigationUtil {
// TODO: check if this still works after changes
private static void updateActivity(AppCompatActivity activity, NamedFragment newFragment) {
ActionBar bar = activity.getSupportActionBar();
if(newFragment == null) newFragment = (NamedFragment) getCurrentFragment(activity.getSupportFragmentManager());

View File

@ -128,6 +128,33 @@
<string name="icon_pack_imported">Icon pack with %d icon(s) imported</string>
<string name="enable_encryption_message">It is recommended to enable encryption to improve the security of the application.\n\nDo you want to go to the settings now to enable encryption?</string>
<string name="enable_encryption_title">Enable encryption</string>
<string name="back_pressed">Press back again to exit</string>
<string name="error_backup_database_not_encrypted">Database must be encrypted for this option</string>
<string name="manage_icon_packs_title">Manage icon packs</string>
<string name="error_backup_load_crypto">Failed to load backup. Make sure the password is valid</string>
<string name="error_backup_load_other">Failed to load backup</string>
<string name="error_biometric_encryption_enable">Failed to enable biometric encryption</string>
<string name="error_biometric_encryption_disable">Failed to enable biometric encryption</string>
<string name="edit_otp_choose_image">Choose Image</string>
<string name="error_edit_otp_image">Failed to open image</string>
<string name="error_database_save">Failed to save database</string>
<string name="error_otp_refresh">An error occurred while refreshing the code</string>
<string name="error_enable_encryption">Failed to enable encryption</string>
<string name="error_disable_encryption">Failed to disable encryption</string>
<string name="error_unlock_no_password">You need to enter a password</string>
<string name="error_unlock_crypto">Failed to load database: Invalid password or database corrupted</string>
<string name="error_unlock_other">Failed to load database</string>
<string name="error_qr_scan_not_detected">No codes were detected in the provided image</string>
<string name="error_qr_scan_failed">"Failed to detect code: "</string>
<string name="error_qr_scan_image_failed">"Failed to read image: "</string>
<string name="icon_pack_exists_title">Icon pack already exists</string>
<string name="error_import_icon_pack">Failed to import icon pack</string>
<string-array name="edit_otp_choose_image_options">
<item>Image from icon pack</item>
<item>Image from gallery</item>
<item>No image</item>
<item>Reset to default image</item>
</string-array>
<string-array name="error_icon_pack_exists_choices">
<item>Override</item>
<item>Rename existing</item>