mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 23:25:45 +03:00
switch to main activity when locked
This commit is contained in:
parent
322b251def
commit
8c89b0e587
4 changed files with 94 additions and 36 deletions
|
@ -58,12 +58,14 @@ namespace Bit.Android.Autofill
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FillResponse BuildAuthResponse(Context context, FieldCollection fields)
|
public static FillResponse BuildAuthResponse(Context context, FieldCollection fields, string uri)
|
||||||
{
|
{
|
||||||
var responseBuilder = new FillResponse.Builder();
|
var responseBuilder = new FillResponse.Builder();
|
||||||
var view = BuildListView(context.PackageName, "Autofill with bitwarden",
|
var view = BuildListView(context.PackageName, "Autofill with bitwarden",
|
||||||
"Vault locked", Resource.Drawable.icon);
|
"Vault locked", Resource.Drawable.icon);
|
||||||
var intent = new Intent(context, typeof(AuthActivity));
|
var intent = new Intent(context, typeof(MainActivity));
|
||||||
|
intent.PutExtra("uri", uri);
|
||||||
|
intent.PutExtra("autofillFramework", true);
|
||||||
var pendingIntent = PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent);
|
var pendingIntent = PendingIntent.GetActivity(context, 0, intent, PendingIntentFlags.CancelCurrent);
|
||||||
responseBuilder.SetAuthentication(fields.AutofillIds.ToArray(), pendingIntent.IntentSender, view);
|
responseBuilder.SetAuthentication(fields.AutofillIds.ToArray(), pendingIntent.IntentSender, view);
|
||||||
return responseBuilder.Build();
|
return responseBuilder.Build();
|
||||||
|
|
|
@ -4,9 +4,7 @@ using Android.Content;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Runtime;
|
using Android.Runtime;
|
||||||
using Android.Service.Autofill;
|
using Android.Service.Autofill;
|
||||||
using Android.Views;
|
|
||||||
using Bit.App.Abstractions;
|
using Bit.App.Abstractions;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using XLabs.Ioc;
|
using XLabs.Ioc;
|
||||||
|
|
||||||
|
@ -42,9 +40,10 @@ namespace Bit.Android.Autofill
|
||||||
_lockService = Resolver.Resolve<ILockService>();
|
_lockService = Resolver.Resolve<ILockService>();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(true) // if locked
|
var isLocked = (await _lockService.GetLockTypeAsync(false)) != App.Enums.LockType.None;
|
||||||
|
if(isLocked)
|
||||||
{
|
{
|
||||||
var authResponse = AutofillHelpers.BuildAuthResponse(this, parser.FieldCollection);
|
var authResponse = AutofillHelpers.BuildAuthResponse(this, parser.FieldCollection, parser.Uri);
|
||||||
callback.OnSuccess(authResponse);
|
callback.OnSuccess(authResponse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,45 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using Android.Service.Autofill;
|
using Android.Service.Autofill;
|
||||||
using Android.Views;
|
|
||||||
using Android.Views.Autofill;
|
using Android.Views.Autofill;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Android.Text;
|
using Android.Text;
|
||||||
using Bit.App.Models;
|
using Bit.App.Models;
|
||||||
using Bit.App.Enums;
|
using Bit.App.Enums;
|
||||||
|
using Bit.App.Models.Page;
|
||||||
|
|
||||||
namespace Bit.Android.Autofill
|
namespace Bit.Android.Autofill
|
||||||
{
|
{
|
||||||
public class CipherFilledItem : IFilledItem
|
public class CipherFilledItem : IFilledItem
|
||||||
{
|
{
|
||||||
private readonly Cipher _cipher;
|
private Lazy<string> _password;
|
||||||
|
|
||||||
public CipherFilledItem(Cipher cipher)
|
public CipherFilledItem(Cipher cipher)
|
||||||
{
|
{
|
||||||
_cipher = cipher;
|
|
||||||
Name = cipher.Name?.Decrypt() ?? "--";
|
Name = cipher.Name?.Decrypt() ?? "--";
|
||||||
|
Type = cipher.Type;
|
||||||
|
|
||||||
switch(cipher.Type)
|
switch(Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
Subtitle = _cipher.Login.Username?.Decrypt() ?? string.Empty;
|
Subtitle = cipher.Login.Username?.Decrypt() ?? string.Empty;
|
||||||
|
_password = new Lazy<string>(() => cipher.Login.Password?.Decrypt());
|
||||||
|
Icon = Resource.Drawable.login;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public CipherFilledItem(VaultListPageModel.Cipher cipher)
|
||||||
|
{
|
||||||
|
Name = cipher.Name ?? "--";
|
||||||
|
Type = cipher.Type;
|
||||||
|
|
||||||
|
switch(Type)
|
||||||
|
{
|
||||||
|
case CipherType.Login:
|
||||||
|
Subtitle = cipher.LoginUsername ?? string.Empty;
|
||||||
|
_password = cipher.LoginPassword;
|
||||||
Icon = Resource.Drawable.login;
|
Icon = Resource.Drawable.login;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -33,10 +50,11 @@ namespace Bit.Android.Autofill
|
||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Subtitle { get; set; } = string.Empty;
|
public string Subtitle { get; set; } = string.Empty;
|
||||||
public int Icon { get; set; } = Resource.Drawable.login;
|
public int Icon { get; set; } = Resource.Drawable.login;
|
||||||
|
public CipherType Type { get; set; }
|
||||||
|
|
||||||
public bool ApplyToFields(FieldCollection fieldCollection, Dataset.Builder datasetBuilder)
|
public bool ApplyToFields(FieldCollection fieldCollection, Dataset.Builder datasetBuilder)
|
||||||
{
|
{
|
||||||
if(_cipher.Type == CipherType.Login && _cipher.Login != null)
|
if(Type == CipherType.Login)
|
||||||
{
|
{
|
||||||
var passwordField = fieldCollection.Fields.FirstOrDefault(
|
var passwordField = fieldCollection.Fields.FirstOrDefault(
|
||||||
f => f.InputType.HasFlag(InputTypes.TextVariationPassword));
|
f => f.InputType.HasFlag(InputTypes.TextVariationPassword));
|
||||||
|
@ -51,13 +69,12 @@ namespace Bit.Android.Autofill
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var password = _cipher.Login.Password?.Decrypt();
|
if(string.IsNullOrWhiteSpace(_password.Value))
|
||||||
if(string.IsNullOrWhiteSpace(password))
|
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
datasetBuilder.SetValue(passwordField.AutofillId, AutofillValue.ForText(password));
|
datasetBuilder.SetValue(passwordField.AutofillId, AutofillValue.ForText(_password.Value));
|
||||||
|
|
||||||
var usernameField = fieldCollection.Fields.TakeWhile(f => f.Id != passwordField.Id).LastOrDefault();
|
var usernameField = fieldCollection.Fields.TakeWhile(f => f.Id != passwordField.Id).LastOrDefault();
|
||||||
if(usernameField != null)
|
if(usernameField != null)
|
||||||
|
|
|
@ -19,6 +19,10 @@ using Android.Nfc;
|
||||||
using Android.Views.InputMethods;
|
using Android.Views.InputMethods;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using Android.Views.Autofill;
|
||||||
|
using Android.App.Assist;
|
||||||
|
using Bit.Android.Autofill;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Bit.Android
|
namespace Bit.Android
|
||||||
{
|
{
|
||||||
|
@ -131,35 +135,71 @@ namespace Bit.Android
|
||||||
|
|
||||||
private void ReturnCredentials(VaultListPageModel.Cipher cipher)
|
private void ReturnCredentials(VaultListPageModel.Cipher cipher)
|
||||||
{
|
{
|
||||||
Intent data = new Intent();
|
if(Intent.GetBooleanExtra("autofillFramework", false))
|
||||||
if(cipher == null)
|
|
||||||
{
|
{
|
||||||
data.PutExtra("canceled", "true");
|
if(cipher == null)
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
var isPremium = Resolver.Resolve<ITokenService>()?.TokenPremium ?? false;
|
|
||||||
var autoCopyEnabled = !_settings.GetValueOrDefault(Constants.SettingDisableTotpCopy, false);
|
|
||||||
if(isPremium && autoCopyEnabled && _deviceActionService != null && cipher.LoginTotp?.Value != null)
|
|
||||||
{
|
{
|
||||||
_deviceActionService.CopyToClipboard(App.Utilities.Crypto.Totp(cipher.LoginTotp.Value));
|
SetResult(Result.Canceled);
|
||||||
|
Finish();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
data.PutExtra("uri", cipher.LoginUri);
|
var structure = Intent.GetParcelableExtra(AutofillManager.ExtraAssistStructure) as AssistStructure;
|
||||||
data.PutExtra("username", cipher.LoginUsername);
|
if(structure == null)
|
||||||
data.PutExtra("password", cipher.LoginPassword?.Value ?? null);
|
{
|
||||||
}
|
SetResult(Result.Canceled);
|
||||||
|
Finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(Parent == null)
|
var parser = new Parser(structure);
|
||||||
{
|
parser.ParseForFill();
|
||||||
SetResult(Result.Ok, data);
|
if(!parser.FieldCollection.Fields.Any() || string.IsNullOrWhiteSpace(parser.Uri))
|
||||||
|
{
|
||||||
|
SetResult(Result.Canceled);
|
||||||
|
Finish();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var items = new List<IFilledItem> { new CipherFilledItem(cipher) };
|
||||||
|
var response = AutofillHelpers.BuildFillResponse(this, parser.FieldCollection, items);
|
||||||
|
var replyIntent = new Intent();
|
||||||
|
replyIntent.PutExtra(AutofillManager.ExtraAuthenticationResult, response);
|
||||||
|
SetResult(Result.Ok, replyIntent);
|
||||||
|
Finish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Parent.SetResult(Result.Ok, data);
|
var data = new Intent();
|
||||||
}
|
if(cipher == null)
|
||||||
|
{
|
||||||
|
data.PutExtra("canceled", "true");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var isPremium = Resolver.Resolve<ITokenService>()?.TokenPremium ?? false;
|
||||||
|
var autoCopyEnabled = !_settings.GetValueOrDefault(Constants.SettingDisableTotpCopy, false);
|
||||||
|
if(isPremium && autoCopyEnabled && _deviceActionService != null && cipher.LoginTotp?.Value != null)
|
||||||
|
{
|
||||||
|
_deviceActionService.CopyToClipboard(App.Utilities.Crypto.Totp(cipher.LoginTotp.Value));
|
||||||
|
}
|
||||||
|
|
||||||
Finish();
|
data.PutExtra("uri", cipher.LoginUri);
|
||||||
|
data.PutExtra("username", cipher.LoginUsername);
|
||||||
|
data.PutExtra("password", cipher.LoginPassword?.Value ?? null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Parent == null)
|
||||||
|
{
|
||||||
|
SetResult(Result.Ok, data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Parent.SetResult(Result.Ok, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Finish();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnPause()
|
protected override void OnPause()
|
||||||
|
|
Loading…
Reference in a new issue