mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 02:18:27 +03:00
Support for establishing a username field without a password field (#880)
* Support for establishing a username field without a password field * added aws login
This commit is contained in:
parent
4104f6f772
commit
b29440556a
4 changed files with 87 additions and 23 deletions
|
@ -125,6 +125,18 @@ namespace Bit.Droid.Accessibility
|
|||
"com.treydev.pns"
|
||||
};
|
||||
|
||||
// Be sure to keep these entries sorted alphabetically
|
||||
public static Dictionary<string, KnownUsernameField> KnownUsernameFields => new List<KnownUsernameField>
|
||||
{
|
||||
new KnownUsernameField("accounts.google.com","ServiceLogin", "Email"),
|
||||
new KnownUsernameField("amazon.com","signin", "ap_email_login"),
|
||||
new KnownUsernameField("github.com", "", "user[login]-footer"),
|
||||
new KnownUsernameField("paypal.com","signin", "email"),
|
||||
new KnownUsernameField("signin.aws.amazon.com","signin", "resolving_input"),
|
||||
new KnownUsernameField("signin.ebay.com","eBayISAPI.dll", "userid"),
|
||||
|
||||
}.ToDictionary(n => n.UriAuthority);
|
||||
|
||||
public static void PrintTestData(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||
{
|
||||
var testNodes = GetWindowNodes(root, e, n => n.ViewIdResourceName != null && n.Text != null, false);
|
||||
|
@ -289,17 +301,50 @@ namespace Bit.Droid.Accessibility
|
|||
return nodes;
|
||||
}
|
||||
|
||||
public static void GetNodesAndFill(AccessibilityNodeInfo root, AccessibilityEvent e,
|
||||
IEnumerable<AccessibilityNodeInfo> passwordNodes)
|
||||
public static AccessibilityNodeInfo GetUsernameEditText(string uriString,
|
||||
IEnumerable<AccessibilityNodeInfo> allEditTexts)
|
||||
{
|
||||
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
|
||||
var usernameEditText = GetUsernameEditTextIfPasswordExists(allEditTexts);
|
||||
FillCredentials(usernameEditText, passwordNodes);
|
||||
allEditTexts.Dispose();
|
||||
usernameEditText = null;
|
||||
string uriKey = null;
|
||||
string uriLocalPath = null;
|
||||
if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri))
|
||||
{
|
||||
uriKey = uri.Authority;
|
||||
uriLocalPath = uri.LocalPath;
|
||||
}
|
||||
|
||||
public static AccessibilityNodeInfo GetUsernameEditTextIfPasswordExists(
|
||||
if (!string.IsNullOrEmpty(uriKey))
|
||||
{
|
||||
// Uncomment this to log values necessary for username field discovery
|
||||
// foreach (var editText in allEditTexts)
|
||||
// {
|
||||
// System.Diagnostics.Debug.WriteLine(">>> uriKey: {0}, uriLocalPath: {1}, viewId: {2}", uriKey,
|
||||
// uriLocalPath, editText.ViewIdResourceName);
|
||||
// }
|
||||
|
||||
if (KnownUsernameFields.ContainsKey(uriKey))
|
||||
{
|
||||
var usernameField = KnownUsernameFields[uriKey];
|
||||
if (uriLocalPath.EndsWith(usernameField.UriPathEnd))
|
||||
{
|
||||
foreach (var editText in allEditTexts)
|
||||
{
|
||||
foreach (var usernameViewId in usernameField.UsernameViewId.Split(","))
|
||||
{
|
||||
if (usernameViewId == editText.ViewIdResourceName)
|
||||
{
|
||||
return editText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// no match found, attempt to establish username field based on password field
|
||||
return GetUsernameEditTextIfPasswordExists(allEditTexts);
|
||||
}
|
||||
|
||||
private static AccessibilityNodeInfo GetUsernameEditTextIfPasswordExists(
|
||||
IEnumerable<AccessibilityNodeInfo> allEditTexts)
|
||||
{
|
||||
AccessibilityNodeInfo previousEditText = null;
|
||||
|
@ -317,7 +362,8 @@ namespace Bit.Droid.Accessibility
|
|||
public static bool IsUsernameEditText(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||
{
|
||||
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
|
||||
var usernameEditText = GetUsernameEditTextIfPasswordExists(allEditTexts);
|
||||
var uriString = GetUri(root);
|
||||
var usernameEditText = GetUsernameEditText(uriString, allEditTexts);
|
||||
|
||||
var isUsernameEditText = false;
|
||||
if (usernameEditText != null)
|
||||
|
|
|
@ -168,22 +168,24 @@ namespace Bit.Droid.Accessibility
|
|||
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||
{
|
||||
var filled = false;
|
||||
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
|
||||
if (passwordNodes.Count > 0)
|
||||
{
|
||||
var uri = AccessibilityHelpers.GetUri(root);
|
||||
if (uri != null && !uri.Contains(BitwardenWebsite))
|
||||
if (uri != null && !uri.Contains(BitwardenWebsite) &&
|
||||
AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
|
||||
{
|
||||
if (AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
|
||||
var allEditTexts = AccessibilityHelpers.GetWindowNodes(root, e, n => AccessibilityHelpers.EditText(n), false);
|
||||
var usernameEditText = AccessibilityHelpers.GetUsernameEditText(uri, allEditTexts);
|
||||
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
|
||||
if (usernameEditText != null || passwordNodes.Count > 0)
|
||||
{
|
||||
AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes);
|
||||
AccessibilityHelpers.FillCredentials(usernameEditText, passwordNodes);
|
||||
filled = true;
|
||||
_lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis();
|
||||
}
|
||||
}
|
||||
AccessibilityHelpers.LastCredentials = null;
|
||||
}
|
||||
else if (AccessibilityHelpers.LastCredentials != null)
|
||||
allEditTexts.Dispose();
|
||||
passwordNodes.Dispose();
|
||||
}
|
||||
if (AccessibilityHelpers.LastCredentials != null)
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
|
@ -191,7 +193,6 @@ namespace Bit.Droid.Accessibility
|
|||
AccessibilityHelpers.LastCredentials = null;
|
||||
});
|
||||
}
|
||||
passwordNodes.Dispose();
|
||||
return filled;
|
||||
}
|
||||
|
||||
|
|
16
src/Android/Accessibility/KnownUsernameField.cs
Normal file
16
src/Android/Accessibility/KnownUsernameField.cs
Normal file
|
@ -0,0 +1,16 @@
|
|||
namespace Bit.Droid.Accessibility
|
||||
{
|
||||
public class KnownUsernameField
|
||||
{
|
||||
public KnownUsernameField(string uriAuthority, string uriPathEnd, string usernameViewId)
|
||||
{
|
||||
UriAuthority = uriAuthority;
|
||||
UriPathEnd = uriPathEnd;
|
||||
UsernameViewId = usernameViewId;
|
||||
}
|
||||
|
||||
public string UriAuthority { get; set; }
|
||||
public string UriPathEnd { get; set; }
|
||||
public string UsernameViewId { get; set; }
|
||||
}
|
||||
}
|
|
@ -100,6 +100,7 @@
|
|||
<Compile Include="Accessibility\AccessibilityService.cs" />
|
||||
<Compile Include="Accessibility\Browser.cs" />
|
||||
<Compile Include="Accessibility\NodeList.cs" />
|
||||
<Compile Include="Accessibility\KnownUsernameField.cs" />
|
||||
<Compile Include="Autofill\AutofillHelpers.cs" />
|
||||
<Compile Include="Autofill\AutofillService.cs" />
|
||||
<Compile Include="Autofill\Field.cs" />
|
||||
|
|
Loading…
Reference in a new issue