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
|
@ -124,6 +124,18 @@ namespace Bit.Droid.Accessibility
|
||||||
"com.ss.squarehome2",
|
"com.ss.squarehome2",
|
||||||
"com.treydev.pns"
|
"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)
|
public static void PrintTestData(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||||
{
|
{
|
||||||
|
@ -289,17 +301,50 @@ namespace Bit.Droid.Accessibility
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void GetNodesAndFill(AccessibilityNodeInfo root, AccessibilityEvent e,
|
public static AccessibilityNodeInfo GetUsernameEditText(string uriString,
|
||||||
IEnumerable<AccessibilityNodeInfo> passwordNodes)
|
IEnumerable<AccessibilityNodeInfo> allEditTexts)
|
||||||
{
|
{
|
||||||
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
|
string uriKey = null;
|
||||||
var usernameEditText = GetUsernameEditTextIfPasswordExists(allEditTexts);
|
string uriLocalPath = null;
|
||||||
FillCredentials(usernameEditText, passwordNodes);
|
if (Uri.TryCreate(uriString, UriKind.Absolute, out var uri))
|
||||||
allEditTexts.Dispose();
|
{
|
||||||
usernameEditText = null;
|
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)
|
IEnumerable<AccessibilityNodeInfo> allEditTexts)
|
||||||
{
|
{
|
||||||
AccessibilityNodeInfo previousEditText = null;
|
AccessibilityNodeInfo previousEditText = null;
|
||||||
|
@ -317,7 +362,8 @@ namespace Bit.Droid.Accessibility
|
||||||
public static bool IsUsernameEditText(AccessibilityNodeInfo root, AccessibilityEvent e)
|
public static bool IsUsernameEditText(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||||
{
|
{
|
||||||
var allEditTexts = GetWindowNodes(root, e, n => EditText(n), false);
|
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;
|
var isUsernameEditText = false;
|
||||||
if (usernameEditText != null)
|
if (usernameEditText != null)
|
||||||
|
|
|
@ -168,22 +168,24 @@ namespace Bit.Droid.Accessibility
|
||||||
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
|
public bool ScanAndAutofill(AccessibilityNodeInfo root, AccessibilityEvent e)
|
||||||
{
|
{
|
||||||
var filled = false;
|
var filled = false;
|
||||||
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
|
var uri = AccessibilityHelpers.GetUri(root);
|
||||||
if (passwordNodes.Count > 0)
|
if (uri != null && !uri.Contains(BitwardenWebsite) &&
|
||||||
|
AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
|
||||||
{
|
{
|
||||||
var uri = AccessibilityHelpers.GetUri(root);
|
var allEditTexts = AccessibilityHelpers.GetWindowNodes(root, e, n => AccessibilityHelpers.EditText(n), false);
|
||||||
if (uri != null && !uri.Contains(BitwardenWebsite))
|
var usernameEditText = AccessibilityHelpers.GetUsernameEditText(uri, allEditTexts);
|
||||||
|
var passwordNodes = AccessibilityHelpers.GetWindowNodes(root, e, n => n.Password, false);
|
||||||
|
if (usernameEditText != null || passwordNodes.Count > 0)
|
||||||
{
|
{
|
||||||
if (AccessibilityHelpers.NeedToAutofill(AccessibilityHelpers.LastCredentials, uri))
|
AccessibilityHelpers.FillCredentials(usernameEditText, passwordNodes);
|
||||||
{
|
filled = true;
|
||||||
AccessibilityHelpers.GetNodesAndFill(root, e, passwordNodes);
|
_lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis();
|
||||||
filled = true;
|
AccessibilityHelpers.LastCredentials = null;
|
||||||
_lastAutoFillTime = Java.Lang.JavaSystem.CurrentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
AccessibilityHelpers.LastCredentials = null;
|
allEditTexts.Dispose();
|
||||||
|
passwordNodes.Dispose();
|
||||||
}
|
}
|
||||||
else if (AccessibilityHelpers.LastCredentials != null)
|
if (AccessibilityHelpers.LastCredentials != null)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
|
@ -191,7 +193,6 @@ namespace Bit.Droid.Accessibility
|
||||||
AccessibilityHelpers.LastCredentials = null;
|
AccessibilityHelpers.LastCredentials = null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
passwordNodes.Dispose();
|
|
||||||
return filled;
|
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\AccessibilityService.cs" />
|
||||||
<Compile Include="Accessibility\Browser.cs" />
|
<Compile Include="Accessibility\Browser.cs" />
|
||||||
<Compile Include="Accessibility\NodeList.cs" />
|
<Compile Include="Accessibility\NodeList.cs" />
|
||||||
|
<Compile Include="Accessibility\KnownUsernameField.cs" />
|
||||||
<Compile Include="Autofill\AutofillHelpers.cs" />
|
<Compile Include="Autofill\AutofillHelpers.cs" />
|
||||||
<Compile Include="Autofill\AutofillService.cs" />
|
<Compile Include="Autofill\AutofillService.cs" />
|
||||||
<Compile Include="Autofill\Field.cs" />
|
<Compile Include="Autofill\Field.cs" />
|
||||||
|
|
Loading…
Reference in a new issue