
* updates themes and color definitions * removed many color attributes from views and special configurations * reworked settings completely to get rid of "settings toolsbar" * use DayNight theme instead of custom light/dark Note that there are quite a few issues left.
226 lines
8.9 KiB
C#
226 lines
8.9 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
|
|
using Android.App;
|
|
using Android.Content;
|
|
using Android.Content.PM;
|
|
using Android.OS;
|
|
using Android.Runtime;
|
|
using Android.Views;
|
|
using Android.Widget;
|
|
using AndroidX.Preference;
|
|
using KeePass.Util.Spr;
|
|
using keepass2android.services.AutofillBase;
|
|
using keepass2android.services.AutofillBase.model;
|
|
using Keepass2android.Pluginsdk;
|
|
using keepass2android_appSdkStyle;
|
|
using KeePassLib;
|
|
using KeePassLib.Utility;
|
|
using Kp2aAutofillParser;
|
|
|
|
namespace keepass2android.services.Kp2aAutofill
|
|
{
|
|
[Activity(Label = "@string/app_name",
|
|
ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden,
|
|
Theme = "@style/Kp2aTheme_ActionBar",
|
|
WindowSoftInputMode = SoftInput.AdjustResize,
|
|
Permission = "keepass2android." + AppNames.PackagePart + ".permission.Kp2aChooseAutofill")]
|
|
public class ChooseForAutofillActivity : ChooseForAutofillActivityBase
|
|
{
|
|
public bool ActivateKeyboardWhenTotpPreference
|
|
{
|
|
get
|
|
{
|
|
return PreferenceManager.GetDefaultSharedPreferences(this)
|
|
.GetBoolean("AutoFillTotp_prefs_ActivateKeyboard_key", false);
|
|
}
|
|
}
|
|
public bool CopyTotpToClipboardPreference
|
|
{
|
|
get
|
|
{
|
|
return PreferenceManager.GetDefaultSharedPreferences(this)
|
|
.GetBoolean("AutoFillTotp_prefs_CopyTotpToClipboard_key", true);
|
|
}
|
|
}
|
|
|
|
public bool ShowNotificationPreference
|
|
{
|
|
get
|
|
{
|
|
return PreferenceManager.GetDefaultSharedPreferences(this)
|
|
.GetBoolean("AutoFillTotp_prefs_ShowNotification_key", true);
|
|
}
|
|
}
|
|
|
|
protected override Intent GetQueryIntent(string requestedUrl, bool autoReturnFromQuery, bool useLastOpenedEntry)
|
|
{
|
|
if (useLastOpenedEntry && (App.Kp2a.LastOpenedEntry?.SearchUrl == requestedUrl))
|
|
{
|
|
return null;
|
|
}
|
|
//launch SelectCurrentDbActivity (which is root of the stack (exception: we're even below!)) with the appropriate task.
|
|
//will return the results later
|
|
Intent i = new Intent(this, typeof(SelectCurrentDbActivity));
|
|
//don't show user notifications when an entry is opened.
|
|
var task = new SearchUrlTask()
|
|
{
|
|
UrlToSearchFor = requestedUrl,
|
|
AutoReturnFromQuery = autoReturnFromQuery
|
|
};
|
|
SetTotpDependantActionsOnTask(task);
|
|
|
|
task.ToIntent(i);
|
|
return i;
|
|
}
|
|
|
|
private void SetTotpDependantActionsOnTask(SelectEntryTask task)
|
|
{
|
|
task.ShowUserNotifications =
|
|
ShowNotificationPreference ? ActivationCondition.WhenTotp : ActivationCondition.Never;
|
|
task.CopyTotpToClipboard = CopyTotpToClipboardPreference;
|
|
task.ActivateKeyboard = ActivateKeyboardWhenTotpPreference
|
|
? ActivationCondition.WhenTotp
|
|
: ActivationCondition.Never;
|
|
}
|
|
|
|
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 };
|
|
SetTotpDependantActionsOnTask(task);
|
|
task.ToIntent(i);
|
|
return i;
|
|
}
|
|
|
|
protected override Result ExpectedActivityResult => KeePass.ExitCloseAfterTaskComplete;
|
|
|
|
protected override FilledAutofillFieldCollection<ViewNodeInputField> GetDataset()
|
|
{
|
|
if (App.Kp2a.CurrentDb==null || (App.Kp2a.QuickLocked))
|
|
return null;
|
|
var entryOutput = App.Kp2a.LastOpenedEntry;
|
|
|
|
return GetFilledAutofillFieldCollectionFromEntry(entryOutput, this);
|
|
}
|
|
|
|
public static FilledAutofillFieldCollection<ViewNodeInputField> GetFilledAutofillFieldCollectionFromEntry(PwEntryOutput pwEntryOutput, Context context)
|
|
{
|
|
if (pwEntryOutput == null)
|
|
return null;
|
|
FilledAutofillFieldCollection<ViewNodeInputField> fieldCollection = new FilledAutofillFieldCollection<ViewNodeInputField>();
|
|
var pwEntry = pwEntryOutput.Entry;
|
|
|
|
foreach (string key in pwEntryOutput.OutputStrings.GetKeys())
|
|
{
|
|
|
|
FilledAutofillField field =
|
|
new FilledAutofillField
|
|
{
|
|
AutofillHints = GetCanonicalHintsFromKp2aField(key).ToArray(),
|
|
TextValue = pwEntryOutput.OutputStrings.ReadSafe(key)
|
|
};
|
|
fieldCollection.Add(field);
|
|
|
|
}
|
|
if (IsCreditCard(pwEntry, context) && pwEntry.Expires)
|
|
{
|
|
DateTime expTime = pwEntry.ExpiryTime;
|
|
FilledAutofillField field =
|
|
new FilledAutofillField
|
|
{
|
|
AutofillHints = new[] {View.AutofillHintCreditCardExpirationDate},
|
|
DateValue = (long) (1000 * TimeUtil.SerializeUnix(expTime))
|
|
};
|
|
fieldCollection.Add(field);
|
|
|
|
field =
|
|
new FilledAutofillField
|
|
{
|
|
AutofillHints = new[] {View.AutofillHintCreditCardExpirationDay},
|
|
TextValue = expTime.Day.ToString()
|
|
};
|
|
fieldCollection.Add(field);
|
|
|
|
field =
|
|
new FilledAutofillField
|
|
{
|
|
AutofillHints = new[] {View.AutofillHintCreditCardExpirationMonth},
|
|
TextValue = expTime.Month.ToString()
|
|
};
|
|
fieldCollection.Add(field);
|
|
|
|
field =
|
|
new FilledAutofillField
|
|
{
|
|
AutofillHints = new[] {View.AutofillHintCreditCardExpirationYear},
|
|
TextValue = expTime.Year.ToString()
|
|
};
|
|
fieldCollection.Add(field);
|
|
}
|
|
|
|
|
|
fieldCollection.DatasetName = pwEntry.Strings.ReadSafe(PwDefs.TitleField);
|
|
fieldCollection.DatasetName = SprEngine.Compile(fieldCollection.DatasetName, new SprContext(pwEntry, App.Kp2a.CurrentDb.KpDatabase, SprCompileFlags.All));
|
|
|
|
return fieldCollection;
|
|
}
|
|
|
|
private static bool IsCreditCard(PwEntry pwEntry, Context context)
|
|
{
|
|
return pwEntry.Strings.Exists("cc-number")
|
|
|| pwEntry.Strings.Exists("cc-csc")
|
|
|| pwEntry.Strings.Exists(context.GetString(Resource.String.TemplateField_CreditCard_CVV));
|
|
}
|
|
|
|
private static readonly Dictionary<string, List<string>> keyToHint = BuildKeyToHints();
|
|
|
|
public static string GetKp2aKeyFromHint(string canonicalHint)
|
|
{
|
|
var key = keyToHint.FirstOrDefault(p => p.Value.Contains(canonicalHint)).Key;
|
|
if (string.IsNullOrWhiteSpace(key))
|
|
return canonicalHint;
|
|
return key;
|
|
}
|
|
|
|
private static Dictionary<string, List<string>> BuildKeyToHints()
|
|
{
|
|
var result = new Dictionary<string, List<string>>
|
|
{
|
|
{PwDefs.UserNameField, new List<string>{View.AutofillHintUsername, View.AutofillHintEmailAddress}},
|
|
{PwDefs.PasswordField, new List<string>{View.AutofillHintPassword}},
|
|
{PwDefs.UrlField, new List<string>{W3cHints.URL}},
|
|
{
|
|
LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_CreditCard_CVV),
|
|
new List<string>{View.AutofillHintCreditCardSecurityCode}
|
|
},
|
|
{
|
|
LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_CreditCard_Owner),
|
|
new List<string>{W3cHints.CC_NAME}
|
|
},
|
|
{LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_Number), new List<string>{View.AutofillHintCreditCardNumber}},
|
|
{LocaleManager.LocalizedAppContext.GetString(Resource.String.TemplateField_IdCard_Name), new List<string>{View.AutofillHintName}},
|
|
};
|
|
return result;
|
|
}
|
|
|
|
private static List<string> GetCanonicalHintsFromKp2aField(string key)
|
|
{
|
|
List<string> result = new List<string>() {key};
|
|
List<string> hints;
|
|
if (keyToHint.TryGetValue(key, out hints))
|
|
result = hints;
|
|
for (int i = 0; i < result.Count; i++)
|
|
{
|
|
result[i] = result[i].ToLower();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public override IAutofillIntentBuilder IntentBuilder => new Kp2aAutofillIntentBuilder();
|
|
|
|
}
|
|
} |