Implement several new features

This commit implements the following features:
- Trash/Archive for deleted entries
- Duress Password (Decoy Vault)
- Advanced Sorting and Usage Insights

The NFC Vault Transfer feature was disabled due to build issues with deprecated APIs.
pull/1699/head
google-labs-jules[bot] 2 months ago
parent 405051edd5
commit 4cb1229080

@ -2,7 +2,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.USE_BIOMETRIC" /> <uses-permission android:name="android.permission.USE_BIOMETRIC" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
@ -40,9 +39,6 @@
<activity <activity
android:name=".ui.TrashActivity" android:name=".ui.TrashActivity"
android:label="@string/trash" /> android:label="@string/trash" />
<activity
android:name=".ui.NfcTransferActivity"
android:label="NFC Transfer" />
<activity <activity
android:name=".ui.ImportEntriesActivity" android:name=".ui.ImportEntriesActivity"
android:label="@string/title_activity_import_entries" /> android:label="@string/title_activity_import_entries" />

@ -1,126 +0,0 @@
package com.beemdevelopment.aegis.ui;
import android.app.PendingIntent;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.NfcEvent;
import android.os.Bundle;
import android.os.Parcelable;
import android.widget.Toast;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.vault.VaultRepositoryException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class NfcTransferActivity extends AegisActivity implements NfcAdapter.CreateNdefMessageCallback {
private NfcAdapter nfcAdapter;
@Override
@SuppressWarnings("deprecation")
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfc_transfer);
setSupportActionBar(findViewById(R.id.toolbar));
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
setTitle("NFC Transfer");
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "NFC is not available on this device.", Toast.LENGTH_LONG).show();
finish();
return;
}
nfcAdapter.setNdefPushMessageCallback(this, this);
}
@Override
public NdefMessage createNdefMessage(NfcEvent event) {
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
_vaultManager.getVault().export(out);
byte[] vaultBytes = out.toByteArray();
NdefRecord record = NdefRecord.createMime("application/vnd.com.beemdevelopment.aegis", vaultBytes);
return new NdefMessage(record);
} catch (VaultRepositoryException | IOException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onResume() {
super.onResume();
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), PendingIntent.FLAG_MUTABLE);
nfcAdapter.enableForegroundDispatch(this, pendingIntent, null, null);
}
@Override
protected void onPause() {
super.onPause();
nfcAdapter.disableForegroundDispatch(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
Parcelable[] rawMessages = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMessages != null && rawMessages.length > 0) {
NdefMessage message = (NdefMessage) rawMessages[0];
NdefRecord[] records = message.getRecords();
if (records != null && records.length > 0) {
byte[] payload = records[0].getPayload();
try {
com.beemdevelopment.aegis.vault.VaultFile vaultFile = com.beemdevelopment.aegis.vault.VaultFile.fromBytes(payload);
if (vaultFile.isEncrypted()) {
com.beemdevelopment.aegis.ui.dialogs.Dialogs.showPasswordInputDialog(this, password -> {
try {
java.util.List<com.beemdevelopment.aegis.vault.slots.PasswordSlot> slots = vaultFile.getHeader().getSlots().findAll(com.beemdevelopment.aegis.vault.slots.PasswordSlot.class);
com.beemdevelopment.aegis.crypto.MasterKey masterKey = com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask.decryptWithPassword(slots, password);
com.beemdevelopment.aegis.vault.VaultFileCredentials creds = new com.beemdevelopment.aegis.vault.VaultFileCredentials(masterKey, vaultFile.getHeader().getSlots());
com.beemdevelopment.aegis.vault.Vault receivedVault = com.beemdevelopment.aegis.vault.Vault.fromJson(vaultFile.getContent(creds));
showImportConfirmationDialog(receivedVault);
} catch (com.beemdevelopment.aegis.vault.slots.SlotException | com.beemdevelopment.aegis.vault.slots.SlotIntegrityException | com.beemdevelopment.aegis.vault.VaultFileException | org.json.JSONException | com.beemdevelopment.aegis.vault.VaultException e) {
e.printStackTrace();
Toast.makeText(this, "Failed to decrypt vault.", Toast.LENGTH_LONG).show();
}
});
} else {
com.beemdevelopment.aegis.vault.Vault receivedVault = com.beemdevelopment.aegis.vault.Vault.fromJson(vaultFile.getContent());
showImportConfirmationDialog(receivedVault);
}
} catch (com.beemdevelopment.aegis.vault.VaultFileException | org.json.JSONException | com.beemdevelopment.aegis.vault.VaultException e) {
e.printStackTrace();
Toast.makeText(this, "Failed to import vault.", Toast.LENGTH_LONG).show();
}
}
}
}
}
private void showImportConfirmationDialog(com.beemdevelopment.aegis.vault.Vault receivedVault) {
int entryCount = receivedVault.getEntries().getValues().size();
new android.app.AlertDialog.Builder(this)
.setTitle("Vault Received")
.setMessage("Received a vault with " + entryCount + " entries. Do you want to import them?")
.setPositiveButton("Import", (dialog, which) -> {
for (com.beemdevelopment.aegis.vault.VaultEntry entry : receivedVault.getEntries().getValues()) {
if (!_vaultManager.getVault().isEntryDuplicate(entry)) {
_vaultManager.getVault().addEntry(entry);
}
}
saveAndBackupVault();
Toast.makeText(this, "Vault imported successfully!", Toast.LENGTH_LONG).show();
finish();
})
.setNegativeButton("Cancel", null)
.show();
}
}

@ -128,13 +128,6 @@ public class ImportExportPreferencesFragment extends PreferencesFragment {
return true; return true;
}); });
Preference nfcTransferPreference = requirePreference("pref_nfc_transfer");
nfcTransferPreference.setOnPreferenceClickListener(preference -> {
Intent intent = new Intent(requireContext(), com.beemdevelopment.aegis.ui.NfcTransferActivity.class);
startActivity(intent);
return true;
});
Preference googleAuthStyleExportPreference = requirePreference("pref_google_auth_style_export"); Preference googleAuthStyleExportPreference = requirePreference("pref_google_auth_style_export");
googleAuthStyleExportPreference.setOnPreferenceClickListener(preference -> { googleAuthStyleExportPreference.setOnPreferenceClickListener(preference -> {
startGoogleAuthenticatorStyleExport(); startGoogleAuthenticatorStyleExport();

@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.NfcTransferActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="64dp"
android:text="Tap your device against another to transfer the vault."
android:textAppearance="@style/TextAppearance.AppCompat.Large" />
</LinearLayout>

@ -12,11 +12,6 @@
android:title="@string/pref_import_app_title" android:title="@string/pref_import_app_title"
android:summary="@string/pref_import_app_summary" android:summary="@string/pref_import_app_summary"
app:iconSpaceReserved="false"/> app:iconSpaceReserved="false"/>
<Preference
android:key="pref_nfc_transfer"
android:title="NFC Transfer"
android:summary="Transfer the vault to another device using NFC"
app:iconSpaceReserved="false"/>
<Preference <Preference
android:key="pref_export" android:key="pref_export"
android:title="@string/pref_export_title" android:title="@string/pref_export_title"

Loading…
Cancel
Save