mirror of
https://github.com/bitwarden/mobile
synced 2026-01-07 02:53:56 +00:00
[BEEEP] Support for automatic TOTP token copy via external autofill (Android) (#2220)
* Android: Support for automatic TOTP copy via external autofill * update iOS autofill interface * additional tweaks
This commit is contained in:
10
src/Android/Autofill/AutofillConstants.cs
Normal file
10
src/Android/Autofill/AutofillConstants.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
public class AutofillConstants
|
||||
{
|
||||
public const string AutofillFramework = "autofillFramework";
|
||||
public const string AutofillFrameworkFillType = "autofillFrameworkFillType";
|
||||
public const string AutofillFrameworkUri = "autofillFrameworkUri";
|
||||
public const string AutofillFrameworkCipherId = "autofillFrameworkCipherId";
|
||||
}
|
||||
}
|
||||
42
src/Android/Autofill/AutofillExternalSelectionActivity.cs
Normal file
42
src/Android/Autofill/AutofillExternalSelectionActivity.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System.Threading.Tasks;
|
||||
using Android.App;
|
||||
using Android.Content.PM;
|
||||
using Android.OS;
|
||||
using Bit.Core.Abstractions;
|
||||
using Bit.Core.Utilities;
|
||||
using Bit.Droid.Utilities;
|
||||
|
||||
namespace Bit.Droid.Autofill
|
||||
{
|
||||
[Activity(
|
||||
NoHistory = true,
|
||||
LaunchMode = LaunchMode.SingleTop)]
|
||||
public class AutofillExternalSelectionActivity : Xamarin.Forms.Platform.Android.FormsAppCompatActivity
|
||||
{
|
||||
protected override void OnCreate(Bundle bundle)
|
||||
{
|
||||
Intent?.Validate();
|
||||
base.OnCreate(bundle);
|
||||
|
||||
var cipherId = Intent?.GetStringExtra(AutofillConstants.AutofillFrameworkCipherId);
|
||||
if (string.IsNullOrEmpty(cipherId))
|
||||
{
|
||||
SetResult(Result.Canceled);
|
||||
Finish();
|
||||
return;
|
||||
}
|
||||
|
||||
GetCipherAndPerformAutofillAsync(cipherId).FireAndForget();
|
||||
}
|
||||
|
||||
private async Task GetCipherAndPerformAutofillAsync(string cipherId)
|
||||
{
|
||||
var cipherService = ServiceContainer.Resolve<ICipherService>();
|
||||
var cipher = await cipherService.GetAsync(cipherId);
|
||||
var decCipher = await cipher.DecryptAsync();
|
||||
|
||||
var autofillHandler = ServiceContainer.Resolve<IAutofillHandler>();
|
||||
autofillHandler.Autofill(decCipher);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -207,7 +207,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
}
|
||||
var dataset = BuildDataset(parser.ApplicationContext, parser.FieldCollection, items[i],
|
||||
inlinePresentationSpec);
|
||||
true, inlinePresentationSpec);
|
||||
if (dataset != null)
|
||||
{
|
||||
responseBuilder.AddDataset(dataset);
|
||||
@@ -221,7 +221,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
|
||||
public static Dataset BuildDataset(Context context, FieldCollection fields, FilledItem filledItem,
|
||||
InlinePresentationSpec inlinePresentationSpec = null)
|
||||
bool includeAuthIntent, InlinePresentationSpec inlinePresentationSpec = null)
|
||||
{
|
||||
var overlayPresentation = BuildOverlayPresentation(
|
||||
filledItem.Name,
|
||||
@@ -242,6 +242,15 @@ namespace Bit.Droid.Autofill
|
||||
{
|
||||
datasetBuilder.SetInlinePresentation(inlinePresentation);
|
||||
}
|
||||
if (includeAuthIntent)
|
||||
{
|
||||
var intent = new Intent(context, typeof(AutofillExternalSelectionActivity));
|
||||
intent.PutExtra(AutofillConstants.AutofillFramework, true);
|
||||
intent.PutExtra(AutofillConstants.AutofillFrameworkCipherId, filledItem.Id);
|
||||
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
|
||||
AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.CancelCurrent, true));
|
||||
datasetBuilder.SetAuthentication(pendingIntent?.IntentSender);
|
||||
}
|
||||
if (filledItem.ApplyToFields(fields, datasetBuilder))
|
||||
{
|
||||
return datasetBuilder.Build();
|
||||
@@ -253,25 +262,26 @@ namespace Bit.Droid.Autofill
|
||||
IList<InlinePresentationSpec> inlinePresentationSpecs = null)
|
||||
{
|
||||
var intent = new Intent(context, typeof(MainActivity));
|
||||
intent.PutExtra("autofillFramework", true);
|
||||
intent.PutExtra(AutofillConstants.AutofillFramework, true);
|
||||
if (fields.FillableForLogin)
|
||||
{
|
||||
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Login);
|
||||
intent.PutExtra(AutofillConstants.AutofillFrameworkFillType, (int)CipherType.Login);
|
||||
}
|
||||
else if (fields.FillableForCard)
|
||||
{
|
||||
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Card);
|
||||
intent.PutExtra(AutofillConstants.AutofillFrameworkFillType, (int)CipherType.Card);
|
||||
}
|
||||
else if (fields.FillableForIdentity)
|
||||
{
|
||||
intent.PutExtra("autofillFrameworkFillType", (int)CipherType.Identity);
|
||||
intent.PutExtra(AutofillConstants.AutofillFrameworkFillType, (int)CipherType.Identity);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
intent.PutExtra("autofillFrameworkUri", uri);
|
||||
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent, AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.CancelCurrent, true));
|
||||
intent.PutExtra(AutofillConstants.AutofillFrameworkUri, uri);
|
||||
var pendingIntent = PendingIntent.GetActivity(context, ++_pendingIntentId, intent,
|
||||
AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.CancelCurrent, true));
|
||||
|
||||
var overlayPresentation = BuildOverlayPresentation(
|
||||
AppResources.AutofillWithBitwarden,
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace Bit.Droid.Autofill
|
||||
|
||||
public FilledItem(CipherView cipher)
|
||||
{
|
||||
Id = cipher.Id;
|
||||
Name = cipher.Name;
|
||||
Type = cipher.Type;
|
||||
Subtitle = cipher.SubTitle;
|
||||
@@ -55,6 +56,7 @@ namespace Bit.Droid.Autofill
|
||||
}
|
||||
}
|
||||
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Subtitle { get; set; } = string.Empty;
|
||||
public int Icon { get; set; } = Resource.Drawable.login;
|
||||
|
||||
Reference in New Issue
Block a user