1
0
mirror of https://github.com/bitwarden/mobile synced 2026-01-21 03:43:17 +00:00

merge fixes

This commit is contained in:
Kyle Spearrin
2019-05-28 12:15:38 -04:00
1384 changed files with 50451 additions and 103964 deletions

View File

@@ -1,17 +1,16 @@
using System;
using System.Collections.Generic;
using System.Collections.Generic;
using Android.Content;
using Android.Service.Autofill;
using Android.Widget;
using System.Linq;
using Android.App;
using Bit.App.Abstractions;
using System.Threading.Tasks;
using Bit.App.Resources;
using Bit.App.Enums;
using Bit.Core.Enums;
using Android.Views.Autofill;
using Bit.Core.Abstractions;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public static class AutofillHelpers
{
@@ -20,74 +19,91 @@ namespace Bit.Android.Autofill
// These browser work natively with the autofill framework
public static HashSet<string> TrustedBrowsers = new HashSet<string>
{
"org.mozilla.focus","org.mozilla.klar","com.duckduckgo.mobile.android"
"org.mozilla.focus",
"org.mozilla.klar",
"com.duckduckgo.mobile.android",
};
// These browsers work using the compatibility shim for the autofill framework
public static HashSet<string> CompatBrowsers = new HashSet<string>
{
"org.mozilla.firefox","org.mozilla.firefox_beta","com.microsoft.emmx","com.android.chrome",
"com.chrome.beta","com.android.browser","com.brave.browser","com.opera.browser",
"com.opera.browser.beta","com.opera.mini.native","com.chrome.dev","com.chrome.canary",
"com.google.android.apps.chrome","com.google.android.apps.chrome_dev","com.yandex.browser",
"com.sec.android.app.sbrowser","com.sec.android.app.sbrowser.beta","org.codeaurora.swe.browser",
"com.amazon.cloud9","mark.via.gp","org.bromite.bromite","org.chromium.chrome","com.kiwibrowser.browser",
"com.ecosia.android","com.opera.mini.native.beta","org.mozilla.fennec_aurora","org.mozilla.fennec_fdroid",
"com.qwant.liberty", "com.opera.touch","org.mozilla.fenix","org.mozilla.reference.browser",
"org.mozilla.rocket"
"org.mozilla.firefox",
"org.mozilla.firefox_beta",
"com.microsoft.emmx",
"com.android.chrome",
"com.chrome.beta",
"com.android.browser",
"com.brave.browser",
"com.opera.browser",
"com.opera.browser.beta",
"com.opera.mini.native",
"com.chrome.dev",
"com.chrome.canary",
"com.google.android.apps.chrome",
"com.google.android.apps.chrome_dev",
"com.yandex.browser",
"com.sec.android.app.sbrowser",
"com.sec.android.app.sbrowser.beta",
"org.codeaurora.swe.browser",
"com.amazon.cloud9",
"mark.via.gp",
"org.bromite.bromite",
"org.chromium.chrome",
"com.kiwibrowser.browser",
"com.ecosia.android",
"com.opera.mini.native.beta",
"org.mozilla.fennec_aurora",
"com.qwant.liberty",
"com.opera.touch",
"org.mozilla.fenix",
"org.mozilla.reference.browser",
"org.mozilla.rocket",
};
// The URLs are blacklisted from autofilling
public static HashSet<string> BlacklistedUris = new HashSet<string>
{
"androidapp://android", "androidapp://com.x8bit.bitwarden", "androidapp://com.oneplus.applocker"
"androidapp://android",
"androidapp://com.x8bit.bitwarden",
"androidapp://com.oneplus.applocker",
};
public static async Task<List<FilledItem>> GetFillItemsAsync(Parser parser, ICipherService service)
public static async Task<List<FilledItem>> GetFillItemsAsync(Parser parser, ICipherService cipherService)
{
var items = new List<FilledItem>();
if(parser.FieldCollection.FillableForLogin)
{
var ciphers = await service.GetAllAsync(parser.Uri);
var ciphers = await cipherService.GetAllDecryptedByUrlAsync(parser.Uri);
if(ciphers.Item1.Any() || ciphers.Item2.Any())
{
var allCiphers = ciphers.Item1.ToList();
allCiphers.AddRange(ciphers.Item2.ToList());
foreach(var cipher in allCiphers)
{
items.Add(new FilledItem(cipher));
}
return allCiphers.Select(c => new FilledItem(c)).ToList();
}
}
else if(parser.FieldCollection.FillableForCard)
{
var ciphers = await service.GetAllAsync();
foreach(var cipher in ciphers.Where(c => c.Type == CipherType.Card))
{
items.Add(new FilledItem(cipher));
}
var ciphers = await cipherService.GetAllDecryptedAsync();
return ciphers.Where(c => c.Type == CipherType.Card).Select(c => new FilledItem(c)).ToList();
}
return items;
return new List<FilledItem>();
}
public static FillResponse BuildFillResponse(Context context, Parser parser, List<FilledItem> items, bool locked)
public static FillResponse BuildFillResponse(Parser parser, List<FilledItem> items, bool locked)
{
var responseBuilder = new FillResponse.Builder();
if(items != null && items.Count > 0)
{
foreach(var item in items)
{
var dataset = BuildDataset(context, parser.FieldCollection, item);
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, item);
if(dataset != null)
{
responseBuilder.AddDataset(dataset);
}
}
}
responseBuilder.AddDataset(BuildVaultDataset(context, parser.FieldCollection, parser.Uri, locked));
responseBuilder.AddDataset(BuildVaultDataset(parser.ApplicationContext, parser.FieldCollection,
parser.Uri, locked));
AddSaveInfo(parser, responseBuilder, parser.FieldCollection);
responseBuilder.SetIgnoredIds(parser.FieldCollection.IgnoreAutofillIds.ToArray());
return responseBuilder.Build();
@@ -96,7 +112,7 @@ namespace Bit.Android.Autofill
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem)
{
var datasetBuilder = new Dataset.Builder(
BuildListView(context.PackageName, filledItem.Name, filledItem.Subtitle, filledItem.Icon));
BuildListView(filledItem.Name, filledItem.Subtitle, filledItem.Icon, context));
if(filledItem.ApplyToFields(fields, datasetBuilder))
{
return datasetBuilder.Build();
@@ -128,8 +144,11 @@ namespace Bit.Android.Autofill
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
PendingIntentFlags.CancelCurrent);
var view = BuildListView(context.PackageName, AppResources.AutofillWithBitwarden,
locked ? AppResources.VaultIsLocked : AppResources.GoToMyVault, Resource.Drawable.icon);
var view = BuildListView(
AppResources.AutofillWithBitwarden,
locked ? AppResources.VaultIsLocked : AppResources.GoToMyVault,
Resource.Drawable.icon,
context);
var datasetBuilder = new Dataset.Builder(view);
datasetBuilder.SetAuthentication(pendingIntent.IntentSender);
@@ -139,14 +158,14 @@ namespace Bit.Android.Autofill
{
datasetBuilder.SetValue(autofillId, AutofillValue.ForText("PLACEHOLDER"));
}
return datasetBuilder.Build();
}
public static RemoteViews BuildListView(string packageName, string text, string subtext, int iconId)
public static RemoteViews BuildListView(string text, string subtext, int iconId, Context context)
{
var packageName = context.PackageName;
var view = new RemoteViews(packageName, Resource.Layout.autofill_listitem);
view.SetTextViewText(Resource.Id.text, text);
view.SetTextViewText(Resource.Id.text1, text);
view.SetTextViewText(Resource.Id.text2, subtext);
view.SetImageViewResource(Resource.Id.icon, iconId);
return view;

View File

@@ -5,20 +5,20 @@ using Android.OS;
using Android.Runtime;
using Android.Service.Autofill;
using Android.Widget;
using Bit.App;
using Bit.App.Abstractions;
using Bit.App.Enums;
using Bit.Core;
using Bit.Core.Abstractions;
using Bit.Core.Enums;
using Bit.Core.Utilities;
using System.Collections.Generic;
using System.Linq;
using XLabs.Ioc;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
[Service(Permission = Manifest.Permission.BindAutofillService, Label = "Bitwarden")]
[IntentFilter(new string[] { "android.service.autofill.AutofillService" })]
[MetaData("android.autofill", Resource = "@xml/autofillservice")]
[Register("com.x8bit.bitwarden.Autofill.AutofillService")]
public class AutofillService : global::Android.Service.Autofill.AutofillService
public class AutofillService : Android.Service.Autofill.AutofillService
{
private ICipherService _cipherService;
private ILockService _lockService;
@@ -31,33 +31,32 @@ namespace Bit.Android.Autofill
return;
}
var parser = new Parser(structure);
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
if(!parser.ShouldAutofill)
{
return;
}
if(_lockService == null)
{
_lockService = Resolver.Resolve<ILockService>();
_lockService = ServiceContainer.Resolve<ILockService>("lockService");
}
List<FilledItem> items = null;
var locked = (await _lockService.GetLockTypeAsync(false)) != LockType.None;
var locked = await _lockService.IsLockedAsync();
if(!locked)
{
if(_cipherService == null)
{
_cipherService = Resolver.Resolve<ICipherService>();
_cipherService = ServiceContainer.Resolve<ICipherService>("cipherService");
}
items = await AutofillHelpers.GetFillItemsAsync(parser, _cipherService);
}
// build response
var response = AutofillHelpers.BuildFillResponse(this, parser, items, locked);
var response = AutofillHelpers.BuildFillResponse(parser, items, locked);
callback.OnSuccess(response);
}
@@ -69,7 +68,7 @@ namespace Bit.Android.Autofill
return;
}
var parser = new Parser(structure);
var parser = new Parser(structure, ApplicationContext);
parser.Parse();
var savedItem = parser.FieldCollection.GetSavedItem();

View File

@@ -7,7 +7,7 @@ using static Android.App.Assist.AssistStructure;
using Android.Text;
using static Android.Views.ViewStructure;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class Field
{
@@ -86,6 +86,69 @@ namespace Bit.Android.Autofill
public HtmlInfo HtmlInfo { get; private set; }
public ViewNode Node { get; private set; }
public bool ValueIsNull()
{
return TextValue == null && DateValue == null && ToggleValue == null;
}
public override bool Equals(object obj)
{
if(this == obj)
{
return true;
}
if(obj == null || GetType() != obj.GetType())
{
return false;
}
var field = obj as Field;
if(TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
{
return false;
}
if(DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
{
return false;
}
return ToggleValue != null ? ToggleValue.Equals(field.ToggleValue) : field.ToggleValue == null;
}
public override int GetHashCode()
{
var result = TextValue != null ? TextValue.GetHashCode() : 0;
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
return result;
}
private static List<string> FilterForSupportedHints(string[] hints)
{
return hints?.Where(h => IsValidHint(h)).ToList() ?? new List<string>();
}
private static bool IsValidHint(string hint)
{
switch(hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
case View.AutofillHintCreditCardExpirationMonth:
case View.AutofillHintCreditCardExpirationYear:
case View.AutofillHintCreditCardNumber:
case View.AutofillHintCreditCardSecurityCode:
case View.AutofillHintEmailAddress:
case View.AutofillHintPhone:
case View.AutofillHintName:
case View.AutofillHintPassword:
case View.AutofillHintPostalAddress:
case View.AutofillHintPostalCode:
case View.AutofillHintUsername:
return true;
default:
return false;
}
}
private void UpdateSaveTypeFromHints()
{
SaveType = SaveDataType.Generic;
@@ -128,72 +191,5 @@ namespace Bit.Android.Autofill
}
}
}
public bool ValueIsNull()
{
return TextValue == null && DateValue == null && ToggleValue == null;
}
public override bool Equals(object obj)
{
if(this == obj)
{
return true;
}
if(obj == null || GetType() != obj.GetType())
{
return false;
}
var field = obj as Field;
if(TextValue != null ? !TextValue.Equals(field.TextValue) : field.TextValue != null)
{
return false;
}
if(DateValue != null ? !DateValue.Equals(field.DateValue) : field.DateValue != null)
{
return false;
}
return ToggleValue != null ? ToggleValue.Equals(field.ToggleValue) : field.ToggleValue == null;
}
public override int GetHashCode()
{
var result = TextValue != null ? TextValue.GetHashCode() : 0;
result = 31 * result + (DateValue != null ? DateValue.GetHashCode() : 0);
result = 31 * result + (ToggleValue != null ? ToggleValue.GetHashCode() : 0);
return result;
}
private static List<string> FilterForSupportedHints(string[] hints)
{
return hints?.Where(h => IsValidHint(h)).ToList() ?? new List<string>();
}
private static bool IsValidHint(string hint)
{
switch(hint)
{
case View.AutofillHintCreditCardExpirationDate:
case View.AutofillHintCreditCardExpirationDay:
case View.AutofillHintCreditCardExpirationMonth:
case View.AutofillHintCreditCardExpirationYear:
case View.AutofillHintCreditCardNumber:
case View.AutofillHintCreditCardSecurityCode:
case View.AutofillHintEmailAddress:
case View.AutofillHintPhone:
case View.AutofillHintName:
case View.AutofillHintPassword:
case View.AutofillHintPostalAddress:
case View.AutofillHintPostalCode:
case View.AutofillHintUsername:
return true;
default:
return false;
}
}
}
}

View File

@@ -5,7 +5,7 @@ using System.Linq;
using Android.Text;
using Android.Views;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class FieldCollection
{
@@ -47,7 +47,6 @@ namespace Bit.Android.Autofill
{
return _passwordFields;
}
if(Hints.Any())
{
_passwordFields = new List<Field>();
@@ -64,7 +63,6 @@ namespace Bit.Android.Autofill
_passwordFields = Fields.Where(f => FieldHasPasswordTerms(f)).ToList();
}
}
return _passwordFields;
}
}
@@ -77,7 +75,6 @@ namespace Bit.Android.Autofill
{
return _usernameFields;
}
_usernameFields = new List<Field>();
if(Hints.Any())
{
@@ -102,20 +99,29 @@ namespace Bit.Android.Autofill
}
}
}
return _usernameFields;
}
}
public bool FillableForLogin => FocusedHintsContain(
new string[] { View.AutofillHintUsername, View.AutofillHintEmailAddress, View.AutofillHintPassword }) ||
UsernameFields.Any(f => f.Focused) || PasswordFields.Any(f => f.Focused);
public bool FillableForCard => FocusedHintsContain(
new string[] { View.AutofillHintCreditCardNumber, View.AutofillHintCreditCardExpirationMonth,
View.AutofillHintCreditCardExpirationYear, View.AutofillHintCreditCardSecurityCode});
public bool FillableForIdentity => FocusedHintsContain(
new string[] { View.AutofillHintName, View.AutofillHintPhone, View.AutofillHintPostalAddress,
View.AutofillHintPostalCode });
public bool FillableForLogin => FocusedHintsContain(new string[] {
View.AutofillHintUsername,
View.AutofillHintEmailAddress,
View.AutofillHintPassword
}) || UsernameFields.Any(f => f.Focused) || PasswordFields.Any(f => f.Focused);
public bool FillableForCard => FocusedHintsContain(new string[] {
View.AutofillHintCreditCardNumber,
View.AutofillHintCreditCardExpirationMonth,
View.AutofillHintCreditCardExpirationYear,
View.AutofillHintCreditCardSecurityCode
});
public bool FillableForIdentity => FocusedHintsContain(new string[] {
View.AutofillHintName,
View.AutofillHintPhone,
View.AutofillHintPostalAddress,
View.AutofillHintPostalCode
});
public bool Fillable => FillableForLogin || FillableForCard || FillableForIdentity;
@@ -127,7 +133,6 @@ namespace Bit.Android.Autofill
}
_passwordFields = _usernameFields = null;
FieldTrackingIds.Add(field.TrackingId);
Fields.Add(field);
AutofillIds.Add(field.AutofillId);
@@ -141,12 +146,10 @@ namespace Bit.Android.Autofill
{
FocusedHints.Add(hint);
}
if(!HintToFieldsMap.ContainsKey(hint))
{
HintToFieldsMap.Add(hint, new List<Field>());
}
HintToFieldsMap[hint].Add(field);
}
}
@@ -164,7 +167,7 @@ namespace Bit.Android.Autofill
var savedItem = new SavedItem
{
Type = App.Enums.CipherType.Login,
Type = Core.Enums.CipherType.Login,
Login = new SavedItem.LoginItem
{
Password = GetFieldValue(passwordField)
@@ -173,14 +176,13 @@ namespace Bit.Android.Autofill
var usernameField = Fields.TakeWhile(f => f.AutofillId != passwordField.AutofillId).LastOrDefault();
savedItem.Login.Username = GetFieldValue(usernameField);
return savedItem;
}
else if(SaveType == SaveDataType.CreditCard)
{
var savedItem = new SavedItem
{
Type = App.Enums.CipherType.Card,
Type = Core.Enums.CipherType.Card,
Card = new SavedItem.CardItem
{
Number = GetFieldValue(View.AutofillHintCreditCardNumber),
@@ -190,10 +192,8 @@ namespace Bit.Android.Autofill
Code = GetFieldValue(View.AutofillHintCreditCardSecurityCode)
}
};
return savedItem;
}
return null;
}
@@ -224,7 +224,6 @@ namespace Bit.Android.Autofill
}
return fieldList.Select(f => f.AutofillId).ToArray();
}
return new AutofillId[0];
}
@@ -238,7 +237,6 @@ namespace Bit.Android.Autofill
{
return HintToFieldsMap[View.AutofillHintCreditCardNumber].Select(f => f.AutofillId).ToArray();
}
return new AutofillId[0];
}
@@ -260,7 +258,6 @@ namespace Bit.Android.Autofill
}
}
}
return null;
}
@@ -270,7 +267,6 @@ namespace Bit.Android.Autofill
{
return null;
}
if(!string.IsNullOrWhiteSpace(field.TextValue))
{
if(field.AutofillType == AutofillType.List && field.ListValue.HasValue && monthValue)
@@ -294,7 +290,6 @@ namespace Bit.Android.Autofill
{
return field.ToggleValue.Value.ToString();
}
return null;
}
@@ -340,7 +335,6 @@ namespace Bit.Android.Autofill
{
return false;
}
var lowerValue = value.ToLowerInvariant();
return terms.Any(t => lowerValue.Contains(t));
}

View File

@@ -1,107 +1,56 @@
using System;
using Android.Service.Autofill;
using Android.Service.Autofill;
using Android.Views.Autofill;
using System.Linq;
using Bit.App.Models;
using Bit.App.Enums;
using Bit.Core.Enums;
using Android.Views;
using Bit.Core.Models.View;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class FilledItem
{
private Lazy<string> _password;
private Lazy<string> _cardName;
private string _password;
private string _cardName;
private string _cardNumber;
private Lazy<string> _cardExpMonth;
private Lazy<string> _cardExpYear;
private Lazy<string> _cardCode;
private Lazy<string> _idPhone;
private Lazy<string> _idEmail;
private Lazy<string> _idUsername;
private Lazy<string> _idAddress;
private Lazy<string> _idPostalCode;
private string _cardExpMonth;
private string _cardExpYear;
private string _cardCode;
private string _idPhone;
private string _idEmail;
private string _idUsername;
private string _idAddress;
private string _idPostalCode;
public FilledItem(Cipher cipher)
public FilledItem(CipherView cipher)
{
Name = cipher.Name?.Decrypt(cipher.OrganizationId) ?? "--";
Name = cipher.Name;
Type = cipher.Type;
Subtitle = cipher.SubTitle;
switch(Type)
{
case CipherType.Login:
Subtitle = cipher.Login.Username?.Decrypt(cipher.OrganizationId) ?? string.Empty;
Icon = Resource.Drawable.login;
_password = new Lazy<string>(() => cipher.Login.Password?.Decrypt(cipher.OrganizationId));
_password = cipher.Login.Password;
break;
case CipherType.Card:
Subtitle = cipher.Card.Brand?.Decrypt(cipher.OrganizationId);
_cardNumber = cipher.Card.Number?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(_cardNumber) && _cardNumber.Length >= 4)
{
if(!string.IsNullOrWhiteSpace(_cardNumber))
{
Subtitle += ", ";
}
Subtitle += ("*" + _cardNumber.Substring(_cardNumber.Length - 4));
}
_cardNumber = cipher.Card.Number;
Icon = Resource.Drawable.card;
_cardName = new Lazy<string>(() => cipher.Card.CardholderName?.Decrypt(cipher.OrganizationId));
_cardCode = new Lazy<string>(() => cipher.Card.Code?.Decrypt(cipher.OrganizationId));
_cardExpMonth = new Lazy<string>(() => cipher.Card.ExpMonth?.Decrypt(cipher.OrganizationId));
_cardExpYear = new Lazy<string>(() => cipher.Card.ExpYear?.Decrypt(cipher.OrganizationId));
_cardName = cipher.Card.CardholderName;
_cardCode = cipher.Card.Code;
_cardExpMonth = cipher.Card.ExpMonth;
_cardExpYear = cipher.Card.ExpYear;
break;
case CipherType.Identity:
var firstName = cipher.Identity?.FirstName?.Decrypt(cipher.OrganizationId) ?? " ";
var lastName = cipher.Identity?.LastName?.Decrypt(cipher.OrganizationId) ?? " ";
Subtitle = " ";
if(!string.IsNullOrWhiteSpace(firstName))
{
Subtitle = firstName;
}
if(!string.IsNullOrWhiteSpace(lastName))
{
if(!string.IsNullOrWhiteSpace(Subtitle))
{
Subtitle += " ";
}
Subtitle += lastName;
}
Icon = Resource.Drawable.id;
_idPhone = new Lazy<string>(() => cipher.Identity.Phone?.Decrypt(cipher.OrganizationId));
_idEmail = new Lazy<string>(() => cipher.Identity.Email?.Decrypt(cipher.OrganizationId));
_idUsername = new Lazy<string>(() => cipher.Identity.Username?.Decrypt(cipher.OrganizationId));
_idAddress = new Lazy<string>(() =>
{
var address = cipher.Identity.Address1?.Decrypt(cipher.OrganizationId);
var address2 = cipher.Identity.Address2?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(address2))
{
if(!string.IsNullOrWhiteSpace(address))
{
address += ", ";
}
address += address2;
}
var address3 = cipher.Identity.Address3?.Decrypt(cipher.OrganizationId);
if(!string.IsNullOrWhiteSpace(address3))
{
if(!string.IsNullOrWhiteSpace(address))
{
address += ", ";
}
address += address3;
}
return address;
});
_idPostalCode = new Lazy<string>(() => cipher.Identity.PostalCode?.Decrypt(cipher.OrganizationId));
_idPhone = cipher.Identity.Phone;
_idEmail = cipher.Identity.Email;
_idUsername = cipher.Identity.Username;
_idAddress = cipher.Identity.FullAddress;
_idPostalCode = cipher.Identity.PostalCode;
break;
default:
Icon = Resource.Drawable.login;
break;
}
}
@@ -121,11 +70,11 @@ namespace Bit.Android.Autofill
var setValues = false;
if(Type == CipherType.Login)
{
if(fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password.Value))
if(fieldCollection.PasswordFields.Any() && !string.IsNullOrWhiteSpace(_password))
{
foreach(var f in fieldCollection.PasswordFields)
{
var val = ApplyValue(f, _password.Value);
var val = ApplyValue(f, _password);
if(val != null)
{
setValues = true;
@@ -133,7 +82,6 @@ namespace Bit.Android.Autofill
}
}
}
if(fieldCollection.UsernameFields.Any() && !string.IsNullOrWhiteSpace(Subtitle))
{
foreach(var f in fieldCollection.UsernameFields)
@@ -149,68 +97,73 @@ namespace Bit.Android.Autofill
}
else if(Type == CipherType.Card)
{
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardNumber,
new Lazy<string>(() => _cardNumber)))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardNumber,
_cardNumber))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardSecurityCode, _cardCode))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardSecurityCode,
_cardCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardExpirationMonth, _cardExpMonth, true))
if(ApplyValue(datasetBuilder, fieldCollection,
Android.Views.View.AutofillHintCreditCardExpirationMonth, _cardExpMonth, true))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintCreditCardExpirationYear, _cardExpYear))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintCreditCardExpirationYear,
_cardExpYear))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintName, _cardName))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, _cardName))
{
setValues = true;
}
}
else if(Type == CipherType.Identity)
{
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPhone, _idPhone))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPhone, _idPhone))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintEmailAddress, _idEmail))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintEmailAddress, _idEmail))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintUsername, _idUsername))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintUsername,
_idUsername))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPostalAddress, _idAddress))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalAddress,
_idAddress))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintPostalCode, _idPostalCode))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintPostalCode,
_idPostalCode))
{
setValues = true;
}
if(ApplyValue(datasetBuilder, fieldCollection, View.AutofillHintName, new Lazy<string>(() => Subtitle)))
if(ApplyValue(datasetBuilder, fieldCollection, Android.Views.View.AutofillHintName, Subtitle))
{
setValues = true;
}
}
return setValues;
}
private static bool ApplyValue(Dataset.Builder builder, FieldCollection fieldCollection,
string hint, Lazy<string> value, bool monthValue = false)
string hint, string value, bool monthValue = false)
{
bool setValues = false;
if(fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value.Value))
if(fieldCollection.HintToFieldsMap.ContainsKey(hint) && !string.IsNullOrWhiteSpace(value))
{
foreach(var f in fieldCollection.HintToFieldsMap[hint])
{
var val = ApplyValue(f, value.Value, monthValue);
var val = ApplyValue(f, value, monthValue);
if(val != null)
{
setValues = true;
@@ -245,7 +198,6 @@ namespace Bit.Android.Autofill
return AutofillValue.ForList(monthIndex - 1);
}
}
for(var i = 0; i < field.AutofillOptions.Count; i++)
{
if(field.AutofillOptions[i].Equals(value))
@@ -266,7 +218,6 @@ namespace Bit.Android.Autofill
default:
break;
}
return null;
}
}

View File

@@ -1,29 +1,31 @@
using static Android.App.Assist.AssistStructure;
using Android.App.Assist;
using Bit.App;
using System.Collections.Generic;
using Bit.Core;
using Android.Content;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class Parser
{
public static HashSet<string> ExcludedPackageIds = new HashSet<string>
public static HashSet<string> _excludedPackageIds = new HashSet<string>
{
"android"
};
private readonly AssistStructure _structure;
private string _uri;
private string _packageName;
private string _webDomain;
public Parser(AssistStructure structure)
public Parser(AssistStructure structure, Context applicationContext)
{
_structure = structure;
ApplicationContext = applicationContext;
}
public Context ApplicationContext { get; set; }
public FieldCollection FieldCollection { get; private set; } = new FieldCollection();
public string Uri
{
get
@@ -32,12 +34,12 @@ namespace Bit.Android.Autofill
{
return _uri;
}
if(string.IsNullOrWhiteSpace(WebDomain) && string.IsNullOrWhiteSpace(PackageName))
var webDomainNull = string.IsNullOrWhiteSpace(WebDomain);
if(webDomainNull && string.IsNullOrWhiteSpace(PackageName))
{
_uri = null;
}
else if(!string.IsNullOrWhiteSpace(WebDomain))
else if(!webDomainNull)
{
_uri = string.Concat("http://", WebDomain);
}
@@ -45,10 +47,10 @@ namespace Bit.Android.Autofill
{
_uri = string.Concat(Constants.AndroidAppProtocol, PackageName);
}
return _uri;
}
}
public string PackageName
{
get => _packageName;
@@ -58,10 +60,10 @@ namespace Bit.Android.Autofill
{
_packageName = _uri = null;
}
_packageName = value;
}
}
public string WebDomain
{
get => _webDomain;
@@ -71,19 +73,12 @@ namespace Bit.Android.Autofill
{
_webDomain = _uri = null;
}
_webDomain = value;
}
}
public bool ShouldAutofill
{
get
{
return !string.IsNullOrWhiteSpace(Uri) && !AutofillHelpers.BlacklistedUris.Contains(Uri) &&
FieldCollection != null && FieldCollection.Fillable;
}
}
public bool ShouldAutofill => !string.IsNullOrWhiteSpace(Uri) &&
!AutofillHelpers.BlacklistedUris.Contains(Uri) && FieldCollection != null && FieldCollection.Fillable;
public void Parse()
{
@@ -92,7 +87,6 @@ namespace Bit.Android.Autofill
var node = _structure.GetWindowNodeAt(i);
ParseNode(node.RootViewNode);
}
if(!AutofillHelpers.TrustedBrowsers.Contains(PackageName) &&
!AutofillHelpers.CompatBrowsers.Contains(PackageName))
{
@@ -123,7 +117,7 @@ namespace Bit.Android.Autofill
private void SetPackageAndDomain(ViewNode node)
{
if(string.IsNullOrWhiteSpace(PackageName) && !string.IsNullOrWhiteSpace(node.IdPackage) &&
!ExcludedPackageIds.Contains(node.IdPackage))
!_excludedPackageIds.Contains(node.IdPackage))
{
PackageName = node.IdPackage;
}
@@ -133,4 +127,4 @@ namespace Bit.Android.Autofill
}
}
}
}
}

View File

@@ -1,6 +1,6 @@
using Bit.App.Enums;
using Bit.Core.Enums;
namespace Bit.Android.Autofill
namespace Bit.Droid.Autofill
{
public class SavedItem
{