show entry notification when autofilling an entry with TOTP (to allow copying TOTP to clipboard)
fixes https://github.com/PhilippC/keepass2android/issues/1272
This commit is contained in:
@@ -91,7 +91,29 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
private static String ExtractHost(String url)
|
||||
public PwGroup SearchForUuid(Database database, string uuid)
|
||||
{
|
||||
SearchParameters sp = SearchParameters.None;
|
||||
sp.SearchInUuids = true;
|
||||
sp.SearchString = uuid;
|
||||
|
||||
if (sp.RegularExpression) // Validate regular expression
|
||||
{
|
||||
new Regex(sp.SearchString);
|
||||
}
|
||||
|
||||
string strGroupName = _app.GetResourceString(UiStringKey.search_results);
|
||||
PwGroup pgResults = new PwGroup(true, true, strGroupName, PwIcon.EMailSearch) { IsVirtual = true };
|
||||
|
||||
PwObjectList<PwEntry> listResults = pgResults.Entries;
|
||||
|
||||
database.Root.SearchEntries(sp, listResults, new NullStatusLogger());
|
||||
|
||||
return pgResults;
|
||||
|
||||
}
|
||||
|
||||
private static String ExtractHost(String url)
|
||||
{
|
||||
return UrlUtil.GetHost(url.Trim());
|
||||
}
|
||||
|
@@ -174,10 +174,17 @@ namespace keepass2android
|
||||
PwGroup group = SearchHelper.SearchForExactUrl(this, url);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
||||
}
|
||||
public PwGroup SearchForUuid(String uuid)
|
||||
{
|
||||
PwGroup group = SearchHelper.SearchForUuid(this, uuid);
|
||||
|
||||
return group;
|
||||
|
||||
}
|
||||
|
||||
public PwGroup SearchForHost(String url, bool allowSubdomains) {
|
||||
PwGroup group = SearchHelper.SearchForHost(this, url, allowSubdomains);
|
||||
|
||||
return group;
|
||||
|
@@ -488,10 +488,11 @@ namespace keepass2android
|
||||
_pluginFieldReceiver = new PluginFieldReceiver(this);
|
||||
RegisterReceiver(_pluginFieldReceiver, new IntentFilter(Strings.ActionSetEntryField));
|
||||
|
||||
new Thread(NotifyPluginsOnOpen).Start();
|
||||
var notifyPluginsOnOpenThread = new Thread(NotifyPluginsOnOpen);
|
||||
notifyPluginsOnOpenThread.Start();
|
||||
|
||||
//the rest of the things to do depends on the current app task:
|
||||
AppTask.CompleteOnCreateEntryActivity(this);
|
||||
AppTask.CompleteOnCreateEntryActivity(this, notifyPluginsOnOpenThread);
|
||||
}
|
||||
|
||||
private void RemoveFromHistory()
|
||||
|
@@ -63,6 +63,12 @@ namespace keepass2android
|
||||
launchMode.Launch(act, i);
|
||||
}
|
||||
|
||||
public static void Launch(Activity act, OpenSpecificEntryTask task, ActivityLaunchMode launchMode)
|
||||
{
|
||||
Intent i = new Intent(act, typeof(ShareUrlResults));
|
||||
task.ToIntent(i);
|
||||
launchMode.Launch(act, i);
|
||||
}
|
||||
|
||||
public override bool IsSearchResult
|
||||
{
|
||||
@@ -83,9 +89,8 @@ namespace keepass2android
|
||||
|
||||
if (App.Kp2a.DatabaseIsUnlocked)
|
||||
{
|
||||
var searchUrlTask = ((SearchUrlTask)AppTask);
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
Query(searchUrl, searchUrlTask.AutoReturnFromQuery);
|
||||
|
||||
Query();
|
||||
}
|
||||
// else: LockCloseListActivity.OnResume will trigger a broadcast (LockDatabase) which will cause the activity to be finished.
|
||||
|
||||
@@ -99,12 +104,25 @@ namespace keepass2android
|
||||
AppTask.ToBundle(outState);
|
||||
}
|
||||
|
||||
private void Query(string url, bool autoReturnFromQuery)
|
||||
private void Query()
|
||||
{
|
||||
|
||||
bool canAutoReturnFromQuery = true;
|
||||
bool shouldAutoReturnFromQuery = true;
|
||||
try
|
||||
{
|
||||
Group = GetSearchResultsForUrl(url);
|
||||
if (AppTask is SearchUrlTask searchUrlTask)
|
||||
{
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
canAutoReturnFromQuery = searchUrlTask.AutoReturnFromQuery;
|
||||
shouldAutoReturnFromQuery = PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key), true);
|
||||
Group = GetSearchResultsForUrl(searchUrl);
|
||||
}
|
||||
else if (AppTask is OpenSpecificEntryTask openEntryTask)
|
||||
{
|
||||
Group = GetSearchResultsForUuid(openEntryTask.EntryUuid);
|
||||
}
|
||||
|
||||
} catch (Exception e)
|
||||
{
|
||||
Toast.MakeText(this, e.Message, ToastLength.Long).Show();
|
||||
@@ -114,7 +132,7 @@ namespace keepass2android
|
||||
}
|
||||
|
||||
//if there is exactly one match: open the entry
|
||||
if ((Group.Entries.Count() == 1) && autoReturnFromQuery && PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(GetString(Resource.String.AutoReturnFromQuery_key),true))
|
||||
if ((Group.Entries.Count() == 1) && canAutoReturnFromQuery && shouldAutoReturnFromQuery)
|
||||
{
|
||||
LaunchActivityForEntry(Group.Entries.Single(),0);
|
||||
return;
|
||||
@@ -131,32 +149,49 @@ namespace keepass2android
|
||||
FragmentManager.FindFragmentById<GroupListFragment>(Resource.Id.list_fragment).ListAdapter = new PwGroupListAdapter(this, Group);
|
||||
|
||||
View selectOtherEntry = FindViewById (Resource.Id.select_other_entry);
|
||||
View createUrlEntry = FindViewById(Resource.Id.add_url_entry);
|
||||
|
||||
var newTask = new SearchUrlTask() {AutoReturnFromQuery = false, UrlToSearchFor = url};
|
||||
if (AppTask is SelectEntryTask currentSelectTask)
|
||||
newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications;
|
||||
|
||||
selectOtherEntry.Click += (sender, e) => {
|
||||
GroupActivity.Launch (this, newTask, new ActivityLaunchModeRequestCode(0));
|
||||
if (AppTask is OpenSpecificEntryTask)
|
||||
{
|
||||
selectOtherEntry.Visibility = ViewStates.Gone;
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
else
|
||||
{
|
||||
var searchUrlTask = AppTask as SearchUrlTask;
|
||||
String searchUrl = searchUrlTask.UrlToSearchFor;
|
||||
selectOtherEntry.Visibility = ViewStates.Visible;
|
||||
|
||||
var newTask = new SearchUrlTask() { AutoReturnFromQuery = false, UrlToSearchFor = searchUrl };
|
||||
if (AppTask is SelectEntryTask currentSelectTask)
|
||||
newTask.ShowUserNotifications = currentSelectTask.ShowUserNotifications;
|
||||
|
||||
selectOtherEntry.Click += (sender, e) => {
|
||||
GroupActivity.Launch(this, newTask, new ActivityLaunchModeRequestCode(0));
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Visible;
|
||||
createUrlEntry.Click += (sender, e) =>
|
||||
{
|
||||
GroupActivity.Launch(this, new CreateEntryThenCloseTask { Url = searchUrl, ShowUserNotifications = (AppTask as SelectEntryTask)?.ShowUserNotifications ?? ShowUserNotificationsMode.Always }, new ActivityLaunchModeRequestCode(0));
|
||||
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), ToastLength.Long).Show();
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
View createUrlEntry = FindViewById (Resource.Id.add_url_entry);
|
||||
|
||||
if (App.Kp2a.OpenDatabases.Any(db => db.CanWrite))
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Visible;
|
||||
createUrlEntry.Click += (sender, e) =>
|
||||
{
|
||||
GroupActivity.Launch(this, new CreateEntryThenCloseTask { Url = url, ShowUserNotifications = (AppTask as SelectEntryTask)?.ShowUserNotifications ?? ShowUserNotificationsMode.Always }, new ActivityLaunchModeRequestCode(0));
|
||||
Toast.MakeText(this, GetString(Resource.String.select_group_then_add, new Java.Lang.Object[] { GetString(Resource.String.add_entry) }), ToastLength.Long).Show();
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
createUrlEntry.Visibility = ViewStates.Gone;
|
||||
}
|
||||
|
||||
Util.MoveBottomBarButtons(Resource.Id.select_other_entry, Resource.Id.add_url_entry, Resource.Id.bottom_bar, this);
|
||||
}
|
||||
@@ -201,6 +236,31 @@ namespace keepass2android
|
||||
return resultsGroup;
|
||||
}
|
||||
|
||||
|
||||
public static PwGroup GetSearchResultsForUuid(string uuid)
|
||||
{
|
||||
PwGroup resultsGroup = null;
|
||||
foreach (var db in App.Kp2a.OpenDatabases)
|
||||
{
|
||||
|
||||
var resultsForThisDb = db.SearchForUuid(uuid);
|
||||
|
||||
if (resultsGroup == null)
|
||||
{
|
||||
resultsGroup = resultsForThisDb;
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var entry in resultsForThisDb.Entries)
|
||||
{
|
||||
resultsGroup.AddEntry(entry, false, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return resultsGroup;
|
||||
}
|
||||
|
||||
public override bool OnSearchRequested()
|
||||
{
|
||||
Intent i = new Intent(this, typeof(SearchActivity));
|
||||
|
@@ -46,7 +46,7 @@ namespace keepass2android
|
||||
foreach (ITotpPluginAdapter adapter in _pluginAdapters)
|
||||
{
|
||||
TotpData totpData = adapter.GetTotpData(
|
||||
App.Kp2a.LastOpenedEntry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key),
|
||||
entry.OutputStrings.ToDictionary(pair => StrUtil.SafeXmlString(pair.Key),
|
||||
pair => pair.Value.ReadString()), LocaleManager.LocalizedAppContext, false);
|
||||
if (totpData.IsTotpEntry)
|
||||
{
|
||||
|
@@ -6,6 +6,7 @@ using Android.OS;
|
||||
using Android.Widget;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using KeePassLib;
|
||||
using KeePassLib.Security;
|
||||
using KeePassLib.Utility;
|
||||
@@ -339,7 +340,7 @@ namespace keepass2android
|
||||
|
||||
}
|
||||
|
||||
public virtual void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public virtual void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
activity.StartNotificationsService(false);
|
||||
}
|
||||
@@ -453,7 +454,7 @@ namespace keepass2android
|
||||
intent.PutExtra(UrlToSearchKey, UrlToSearchFor);
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
if (App.Kp2a.LastOpenedEntry != null)
|
||||
App.Kp2a.LastOpenedEntry.SearchUrl = UrlToSearchFor;
|
||||
@@ -462,18 +463,18 @@ namespace keepass2android
|
||||
//if the database is readonly (or no URL exists), don't offer to modify the URL
|
||||
if ((App.Kp2a.CurrentDb.CanWrite == false) || (String.IsNullOrEmpty(UrlToSearchFor) || keepass2android.ShareUrlResults.GetSearchResultsForUrl(UrlToSearchFor).Entries.Any(e => e == activity.Entry) ))
|
||||
{
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
return;
|
||||
}
|
||||
|
||||
AskAddUrlThenCompleteCreate(activity, UrlToSearchFor);
|
||||
AskAddUrlThenCompleteCreate(activity, UrlToSearchFor, notifyPluginsOnOpenThread);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// brings up a dialog asking the user whether he wants to add the given URL to the entry for automatic finding
|
||||
/// </summary>
|
||||
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url)
|
||||
public void AskAddUrlThenCompleteCreate(EntryActivity activity, string url, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
builder.SetTitle(activity.GetString(Resource.String.AddUrlToEntryDialog_title));
|
||||
@@ -482,12 +483,13 @@ namespace keepass2android
|
||||
|
||||
builder.SetPositiveButton(activity.GetString(Resource.String.yes), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity));
|
||||
activity.AddUrlToEntry(url, (EntryActivity thenActiveActivity) => base.CompleteOnCreateEntryActivity(thenActiveActivity, notifyPluginsOnOpenThread
|
||||
));
|
||||
});
|
||||
|
||||
builder.SetNegativeButton(activity.GetString(Resource.String.no), (dlgSender, dlgEvt) =>
|
||||
{
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
});
|
||||
|
||||
Dialog dialog = builder.Create();
|
||||
@@ -495,6 +497,44 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public class OpenSpecificEntryTask : SelectEntryTask
|
||||
{
|
||||
public OpenSpecificEntryTask()
|
||||
{
|
||||
}
|
||||
|
||||
public const String EntryUuidKey = "EntryUuid";
|
||||
|
||||
public string EntryUuid
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public override void Setup(Bundle b)
|
||||
{
|
||||
base.Setup(b);
|
||||
EntryUuid = b.GetString(EntryUuidKey);
|
||||
|
||||
}
|
||||
public override IEnumerable<IExtra> Extras
|
||||
{
|
||||
get
|
||||
{
|
||||
foreach (IExtra e in base.Extras)
|
||||
yield return e;
|
||||
|
||||
yield return new StringExtra { Key = EntryUuidKey, Value = EntryUuid };
|
||||
}
|
||||
}
|
||||
|
||||
public override void LaunchFirstGroupActivity(Activity act)
|
||||
{
|
||||
ShareUrlResults.Launch(act, this, new ActivityLaunchModeRequestCode(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public enum ShowUserNotificationsMode
|
||||
{
|
||||
@@ -545,7 +585,7 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
Context ctx = activity;
|
||||
if (ctx == null)
|
||||
@@ -563,9 +603,11 @@ namespace keepass2android
|
||||
CopyToClipboardService.CancelNotifications(activity);
|
||||
}
|
||||
if (CloseAfterCreate)
|
||||
{
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
{
|
||||
//give plugins and TOTP time to do their work:
|
||||
notifyPluginsOnOpenThread.Join(TimeSpan.FromSeconds(1));
|
||||
//close
|
||||
activity.CloseAfterTaskComplete();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -729,10 +771,10 @@ namespace keepass2android
|
||||
//no need to call Finish here, that's done in EntryEditActivity ("closeOrShowError")
|
||||
}
|
||||
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity)
|
||||
public override void CompleteOnCreateEntryActivity(EntryActivity activity, Thread notifyPluginsOnOpenThread)
|
||||
{
|
||||
//if the user selects an entry before creating the new one, we're not closing the app
|
||||
base.CompleteOnCreateEntryActivity(activity);
|
||||
base.CompleteOnCreateEntryActivity(activity, notifyPluginsOnOpenThread);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -20,6 +20,7 @@ using AndroidX.AutoFill.Inline;
|
||||
using AndroidX.AutoFill.Inline.V1;
|
||||
using Java.Util.Concurrent.Atomic;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
using KeePassLib;
|
||||
using Kp2aAutofillParser;
|
||||
|
||||
namespace keepass2android.services.AutofillBase
|
||||
@@ -29,7 +30,7 @@ namespace keepass2android.services.AutofillBase
|
||||
PendingIntent GetAuthPendingIntentForResponse(Context context, string query, string queryDomain, string queryPackage,
|
||||
bool isManualRequest, bool autoReturnFromQuery, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
PendingIntent GetAuthPendingIntentForWarning(Context context, string query, string queryDomain, string queryPackage, AutofillServiceBase.DisplayWarning warning);
|
||||
PendingIntent GetAuthPendingIntentForWarning(Context context, PwUuid entryUuid, AutofillServiceBase.DisplayWarning warning);
|
||||
|
||||
PendingIntent GetDisablePendingIntentForResponse(Context context, string query,
|
||||
bool isManualRequest, bool isDisable);
|
||||
@@ -262,33 +263,42 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
List<Dataset> result = new List<Dataset>();
|
||||
Kp2aLog.Log("AF: BuildEntryDatasets");
|
||||
var suggestedEntries = GetSuggestedEntries(query).ToDictionary(e => e.DatasetName, e => e);
|
||||
Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> suggestedEntries = GetSuggestedEntries(query);
|
||||
Kp2aLog.Log("AF: BuildEntryDatasets found " + suggestedEntries.Count + " entries");
|
||||
|
||||
int count = 0;
|
||||
foreach (var filledAutofillFieldCollection in suggestedEntries.Values)
|
||||
|
||||
var totpHelper = new Kp2aTotp();
|
||||
|
||||
foreach (var kvp in suggestedEntries)
|
||||
{
|
||||
var filledAutofillFieldCollection = kvp.Value;
|
||||
PwEntryOutput entry = kvp.Key;
|
||||
|
||||
if (filledAutofillFieldCollection == null)
|
||||
continue;
|
||||
|
||||
var inlinePresentationSpec = AutofillHelper.ExtractSpec(inlinePresentationSpecs, count);
|
||||
|
||||
if (warning == DisplayWarning.None)
|
||||
if ((warning == DisplayWarning.None)
|
||||
&& (totpHelper.TryGetAdapter(entry) == null))
|
||||
{
|
||||
|
||||
//no special dataset, we can immediately return the field collection
|
||||
FilledAutofillFieldCollection<ViewNodeInputField> partitionData =
|
||||
AutofillHintsHelper.FilterForPartition(filledAutofillFieldCollection, parser.AutofillFields.FocusedAutofillCanonicalHints);
|
||||
|
||||
Kp2aLog.Log("AF: Add dataset");
|
||||
|
||||
result.Add(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder,
|
||||
result.Add(AutofillHelper.NewDataset(this, parser.AutofillFields, partitionData, IntentBuilder,
|
||||
inlinePresentationSpec));
|
||||
}
|
||||
else
|
||||
{
|
||||
//return an "auth" dataset (actually for just warning the user in case domain/package dont match)
|
||||
|
||||
//return an "auth" dataset (actually for just warning the user in case domain/package dont match and/or to make sure that we open the EntryActivity,
|
||||
// thus opening the entry notification in case of TOTP)
|
||||
PendingIntent pendingIntent =
|
||||
IntentBuilder.GetAuthPendingIntentForWarning(this, query, queryDomain, queryPackage, warning);
|
||||
IntentBuilder.GetAuthPendingIntentForWarning(this, entry.Uuid, warning);
|
||||
var datasetName = filledAutofillFieldCollection.DatasetName;
|
||||
if (datasetName == null)
|
||||
{
|
||||
@@ -320,7 +330,7 @@ namespace keepass2android.services.AutofillBase
|
||||
|
||||
}
|
||||
|
||||
protected abstract List<FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query);
|
||||
protected abstract Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query);
|
||||
|
||||
public enum DisplayWarning
|
||||
{
|
||||
|
@@ -24,7 +24,7 @@ namespace keepass2android.services.AutofillBase
|
||||
{
|
||||
protected Intent ReplyIntent;
|
||||
|
||||
|
||||
public static string ExtraUuidString => "EXTRA_UUID_STRING";
|
||||
public static string ExtraQueryString => "EXTRA_QUERY_STRING";
|
||||
public static string ExtraQueryPackageString => "EXTRA_QUERY_PACKAGE_STRING";
|
||||
public static string ExtraQueryDomainString => "EXTRA_QUERY_DOMAIN_STRING";
|
||||
@@ -50,9 +50,10 @@ namespace keepass2android.services.AutofillBase
|
||||
}
|
||||
|
||||
string requestedUrl = Intent.GetStringExtra(ExtraQueryString);
|
||||
if (requestedUrl == null)
|
||||
string requestedUuid = Intent.GetStringExtra(ExtraUuidString);
|
||||
if (requestedUrl == null && requestedUuid == null)
|
||||
{
|
||||
Kp2aLog.Log("ChooseForAutofillActivityBase: no requestedUrl ");
|
||||
Kp2aLog.Log("ChooseForAutofillActivityBase: no requestedUrl and no requestedUuid");
|
||||
Toast.MakeText(this, "Cannot execute query for null.", ToastLength.Long).Show();
|
||||
RestartApp();
|
||||
return;
|
||||
@@ -134,18 +135,30 @@ namespace keepass2android.services.AutofillBase
|
||||
private void Proceed()
|
||||
{
|
||||
string requestedUrl = Intent.GetStringExtra(ExtraQueryString);
|
||||
string requestedUuid = Intent.GetStringExtra(ExtraUuidString);
|
||||
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true), Intent.GetBooleanExtra(ExtraUseLastOpenedEntry, false));
|
||||
if (i == null)
|
||||
if (requestedUuid != null)
|
||||
{
|
||||
//GetQueryIntent returns null if no query is required
|
||||
ReturnSuccess();
|
||||
var i = GetOpenEntryIntent(requestedUuid);
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
}
|
||||
else
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
{
|
||||
var i = GetQueryIntent(requestedUrl, Intent.GetBooleanExtra(ExtraAutoReturnFromQuery, true), Intent.GetBooleanExtra(ExtraUseLastOpenedEntry, false));
|
||||
if (i == null)
|
||||
{
|
||||
//GetQueryIntent returns null if no query is required
|
||||
ReturnSuccess();
|
||||
}
|
||||
else
|
||||
StartActivityForResult(i, RequestCodeQuery);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
protected abstract Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry);
|
||||
protected abstract Intent GetOpenEntryIntent(string entryUuid);
|
||||
|
||||
protected void RestartApp()
|
||||
{
|
||||
|
@@ -41,6 +41,15 @@ namespace keepass2android.services.Kp2aAutofill
|
||||
return i;
|
||||
}
|
||||
|
||||
protected override Intent GetOpenEntryIntent(string entryUuid)
|
||||
{
|
||||
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
||||
//don't show user notifications when an entry is opened.
|
||||
var task = new OpenSpecificEntryTask() { EntryUuid = entryUuid, ShowUserNotifications = ShowUserNotificationsMode.WhenTotp, ActivateKeyboard = false};
|
||||
task.ToIntent(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
protected override Result ExpectedActivityResult => KeePass.ExitCloseAfterTaskComplete;
|
||||
|
||||
protected override FilledAutofillFieldCollection<ViewNodeInputField> GetDataset()
|
||||
|
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Android;
|
||||
using Android.App;
|
||||
using Android.Content;
|
||||
using Android.Preferences;
|
||||
using Android.Runtime;
|
||||
using keepass2android.services.AutofillBase;
|
||||
using keepass2android.services.AutofillBase.model;
|
||||
@@ -34,24 +35,29 @@ namespace keepass2android.services
|
||||
{
|
||||
}
|
||||
|
||||
protected override List<FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query)
|
||||
protected override Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>> GetSuggestedEntries(string query)
|
||||
{
|
||||
if (!App.Kp2a.DatabaseIsUnlocked)
|
||||
return new List<FilledAutofillFieldCollection<ViewNodeInputField>>();
|
||||
return new Dictionary<PwEntryOutput, FilledAutofillFieldCollection<ViewNodeInputField>>();
|
||||
var foundEntries = (ShareUrlResults.GetSearchResultsForUrl(query)?.Entries ?? new PwObjectList<PwEntry>())
|
||||
.Select(e => new PwEntryOutput(e, App.Kp2a.FindDatabaseForElement(e)))
|
||||
.ToList();
|
||||
|
||||
if (App.Kp2a.LastOpenedEntry?.SearchUrl == query)
|
||||
{
|
||||
foundEntries.Clear();
|
||||
foundEntries.Add(App.Kp2a.LastOpenedEntry);
|
||||
foundEntries.Add(App.Kp2a.LastOpenedEntry?.Entry);
|
||||
}
|
||||
|
||||
//it seems like at least with Firefox we can have at most 3 datasets. Reserve space for the disable/enable dataset and the "fill with KP2A" which allows to select another item
|
||||
//so take only 1:
|
||||
return foundEntries.Take(1).Select(e => ChooseForAutofillActivity.GetFilledAutofillFieldCollectionFromEntry(e, this))
|
||||
.ToList();
|
||||
int numDisableDatasets = 0;
|
||||
if (!PreferenceManager.GetDefaultSharedPreferences(this)
|
||||
.GetBoolean(GetString(Resource.String.NoAutofillDisabling_key), false))
|
||||
numDisableDatasets = 1;
|
||||
|
||||
//it seems like at least with Firefox we can have at most 3 datasets. Reserve space for the disable dataset and the "fill with KP2A" which allows to select another item
|
||||
return foundEntries.Take(2-numDisableDatasets)
|
||||
.Select(e => new PwEntryOutput(e, App.Kp2a.FindDatabaseForElement(e)))
|
||||
.ToDictionary(e => e,
|
||||
e => ChooseForAutofillActivity.GetFilledAutofillFieldCollectionFromEntry(e, this));
|
||||
}
|
||||
|
||||
protected override void HandleSaveRequest(StructureParser parser, StructureParser.AutofillTargetId query)
|
||||
|
@@ -9,6 +9,7 @@ using Android.Views;
|
||||
using Android.Widget;
|
||||
using keepass2android.services.AutofillBase;
|
||||
using keepass2android.services.Kp2aAutofill;
|
||||
using KeePassLib;
|
||||
|
||||
namespace keepass2android.services
|
||||
{
|
||||
@@ -29,16 +30,14 @@ namespace keepass2android.services
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Mutable));
|
||||
}
|
||||
|
||||
public PendingIntent GetAuthPendingIntentForWarning(Context context, string query, string queryDomain, string queryPackage,
|
||||
public PendingIntent GetAuthPendingIntentForWarning(Context context,PwUuid entryUuid,
|
||||
AutofillServiceBase.DisplayWarning warning)
|
||||
{
|
||||
Intent intent = new Intent(context, typeof(ChooseForAutofillActivity));
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryString, query);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryDomainString, queryDomain);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraQueryPackageString, queryPackage);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraUuidString, entryUuid.ToHexString());
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraDisplayWarning, (int)warning);
|
||||
intent.PutExtra(ChooseForAutofillActivityBase.ExtraUseLastOpenedEntry, true);
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Immutable));
|
||||
return PendingIntent.GetActivity(context, _pendingIntentRequestCode++, intent, Util.AddMutabilityFlag(PendingIntentFlags.CancelCurrent, PendingIntentFlags.Mutable));
|
||||
}
|
||||
|
||||
public PendingIntent GetDisablePendingIntentForResponse(Context context, string query,
|
||||
|
Reference in New Issue
Block a user