Add ability to import otpauth uri from clipboard

This commit is contained in:
Michael Schättgen
2026-01-21 21:55:45 +01:00
parent 7897a0941b
commit 170cd930e9
3 changed files with 69 additions and 2 deletions
@@ -17,6 +17,7 @@ import android.provider.Settings;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
@@ -63,6 +64,7 @@ import com.beemdevelopment.aegis.ui.models.VaultGroupModel;
import com.beemdevelopment.aegis.ui.tasks.IconOptimizationTask;
import com.beemdevelopment.aegis.ui.tasks.QrDecodeTask;
import com.beemdevelopment.aegis.ui.views.EntryListView;
import com.beemdevelopment.aegis.util.ClipboardUtils;
import com.beemdevelopment.aegis.util.TimeUtils;
import com.beemdevelopment.aegis.util.UUIDMap;
import com.beemdevelopment.aegis.vault.VaultEntry;
@@ -89,7 +91,6 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.SequencedMap;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicReference;
@@ -252,7 +253,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
LinkedHashMap<View, Runnable> actions = new LinkedHashMap<>();
actions.put(fabMenuLayout.findViewById(R.id.fab_menu_item_scan), this::startScanActivity);
actions.put(fabMenuLayout.findViewById(R.id.fab_menu_item_scan_image), this::startScanImageActivity);
actions.put(fabMenuLayout.findViewById(R.id.fab_menu_item_enter), this::startEditEntryActivityForManual);
actions.put(fabMenuLayout.findViewById(R.id.fab_menu_item_enter), this::startEditEntryActivity);
_fabMenuHelper = new FabMenuHelper(scrimOverlay, menuItemsContainer, fab, actions);
_fabMenuHelper.setOnFabMenuStateChangeListener(_fabMenuBackPressHandler::setEnabled);
@@ -470,6 +471,34 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene
}
}
private void startEditEntryActivity() {
String clip = ClipboardUtils.readText(this);
if (clip != null) {
GoogleAuthInfo parsed;
try {
parsed = GoogleAuthInfo.parseUri(clip.trim());
String message = getString(
R.string.import_from_clipboard_message,
parsed.getAccountName(),
parsed.getIssuer()
);
Dialogs.showSecureDialog(new MaterialAlertDialogBuilder(this)
.setTitle(R.string.import_from_clipboard_title)
.setMessage(message)
.setPositiveButton(R.string.yes, (dialog, which) -> startEditEntryActivityForNew(new VaultEntry(parsed)))
.setNegativeButton(R.string.no, (dialog, which) -> startEditEntryActivityForManual())
.create());
return;
} catch (GoogleAuthInfoException e) {
Log.i("EntryActivity", "Clipboard did not contain a valid otpauth URI", e);
}
}
startEditEntryActivityForManual();
}
private void startEditEntryActivityForNew(VaultEntry entry) {
Intent intent = new Intent(this, EditEntryActivity.class);
intent.putExtra("newEntry", entry);
@@ -0,0 +1,34 @@
package com.beemdevelopment.aegis.util;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
public final class ClipboardUtils {
public static String readText(Context context) {
ClipboardManager clipboard =
(ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
if (clipboard == null) {
return null;
}
ClipData clip = clipboard.getPrimaryClip();
if (clip == null || clip.getItemCount() == 0) {
return null;
}
ClipData.Item item = clip.getItemAt(0);
CharSequence cs = item.coerceToText(context);
if (cs == null) {
return null;
}
String text = cs.toString().trim();
if (text.isEmpty()) {
return null;
}
return text;
}
}
+4
View File
@@ -539,6 +539,10 @@
<string name="dialog_wipe_entries_message">Your vault already contains entries. Do you want to remove these entries before importing this file?\n\n<b>In doing so, you will permanently lose access to the existing entries in the vault.</b></string>
<string name="dialog_wipe_entries_checkbox">Wipe vault contents</string>
<string name="import_from_clipboard_title">Import from clipboard</string>
<string name="import_from_clipboard_message">We found a valid otpauth uri on your clipboard.\n\n<b>Name</b>: %1$s\n<b>Issuer</b>: %2$s\n\nDo you want to use it to prefill this entry?</string>
<string name="panic_trigger_ignore_toast">Aegis received panic trigger but setting is disabled, ignoring</string>
<string name="pref_panic_trigger_title">Delete vault on panic trigger</string>
<string name="pref_panic_trigger_summary">Delete vault when a panic trigger is received from Ripple</string>