From c88287ec64c2acd1dd247575732fd2a514b99056 Mon Sep 17 00:00:00 2001 From: Federico Maccaroni Date: Wed, 17 Apr 2024 19:10:53 -0300 Subject: [PATCH] PM-7258 Updated Android Credential creation details on description to be localized and passed the user email for further details. (#3162) --- .../Autofill/CredentialProviderService.cs | 57 +++++++++++++------ .../Localization/AppResources.Designer.cs | 29 +++++++--- .../Resources/Localization/AppResources.resx | 6 ++ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/src/App/Platforms/Android/Autofill/CredentialProviderService.cs b/src/App/Platforms/Android/Autofill/CredentialProviderService.cs index 00e415017..9be7377f8 100644 --- a/src/App/Platforms/Android/Autofill/CredentialProviderService.cs +++ b/src/App/Platforms/Android/Autofill/CredentialProviderService.cs @@ -25,20 +25,26 @@ namespace Bit.Droid.Autofill public const int UniqueCreateRequestCode = 94556024; private readonly LazyResolve _vaultTimeoutService = new LazyResolve(); + private readonly LazyResolve _stateService = new LazyResolve(); private readonly LazyResolve _logger = new LazyResolve(); - public override void OnBeginCreateCredentialRequest(BeginCreateCredentialRequest request, + public override async void OnBeginCreateCredentialRequest(BeginCreateCredentialRequest request, CancellationSignal cancellationSignal, IOutcomeReceiver callback) { - var response = ProcessCreateCredentialsRequestAsync(request); - if (response != null) + try { - callback.OnResult(response); - } - else - { - callback.OnError("Error creating credential"); + var response = await ProcessCreateCredentialsRequestAsync(request); + if (response != null) + { + await MainThread.InvokeOnMainThreadAsync(() => callback.OnResult(response)); + return; + } } + catch (Exception ex) + { + _logger.Value.Exception(ex); + } + MainThread.BeginInvokeOnMainThread(() => callback.OnError(AppResources.ErrorCreatingPasskey)); } public override async void OnBeginGetCredentialRequest(BeginGetCredentialRequest request, @@ -70,16 +76,16 @@ namespace Bit.Droid.Autofill catch (GetCredentialException e) { _logger.Value.Exception(e); - callback.OnError(e.ErrorMessage ?? "Error getting credentials"); + callback.OnError(e.ErrorMessage ?? AppResources.ErrorReadingPasskey); } catch (Exception e) { - _logger.Value.Exception(e); - throw; + _logger.Value.Exception(e); + callback.OnError(AppResources.ErrorReadingPasskey); } } - private BeginCreateCredentialResponse ProcessCreateCredentialsRequestAsync( + private async Task ProcessCreateCredentialsRequestAsync( BeginCreateCredentialRequest request) { if (request == null) { return null; } @@ -92,22 +98,25 @@ namespace Bit.Droid.Autofill } else if (request is BeginCreatePublicKeyCredentialRequest beginCreatePublicKeyCredentialRequest) { - return HandleCreatePasskeyQuery(beginCreatePublicKeyCredentialRequest); + return await HandleCreatePasskeyQueryAsync(beginCreatePublicKeyCredentialRequest); } return null; } - private BeginCreateCredentialResponse HandleCreatePasskeyQuery(BeginCreatePublicKeyCredentialRequest optionRequest) + private async Task HandleCreatePasskeyQueryAsync(BeginCreatePublicKeyCredentialRequest optionRequest) { var intent = new Intent(ApplicationContext, typeof(MainActivity)); intent.PutExtra(CredentialProviderConstants.Fido2CredentialAction, CredentialProviderConstants.Fido2CredentialCreate); var pendingIntent = PendingIntent.GetActivity(ApplicationContext, UniqueCreateRequestCode, intent, AndroidHelpers.AddPendingIntentMutabilityFlag(PendingIntentFlags.UpdateCurrent, true)); - //TODO: i81n needs to be done - var createEntryBuilder = new CreateEntry.Builder("Bitwarden Vault", pendingIntent) - .SetDescription("Your passkey will be saved securely to the Bitwarden Vault. You can use it from any other device for sign-in in the future.") + var userEmail = await GetSafeActiveAccountEmailAsync(); + + var createEntryBuilder = new CreateEntry.Builder(userEmail ?? AppResources.Bitwarden, pendingIntent) + .SetDescription(userEmail != null + ? string.Format(AppResources.YourPasskeyWillBeSavedToYourBitwardenVaultForX, userEmail) + : AppResources.YourPasskeyWillBeSavedToYourBitwardenVault) .Build(); var createCredentialResponse = new BeginCreateCredentialResponse.Builder() @@ -141,5 +150,19 @@ namespace Bit.Droid.Autofill { callback.OnResult(null); } + + private async Task GetSafeActiveAccountEmailAsync() + { + try + { + return await _stateService.Value.GetEmailAsync(); + } + catch (Exception ex) + { + // if it throws to get the user's email then we log and continue showing a more generic message + _logger.Value.Exception(ex); + return null; + } + } } } diff --git a/src/Core/Resources/Localization/AppResources.Designer.cs b/src/Core/Resources/Localization/AppResources.Designer.cs index a8251192b..3cecec4a9 100644 --- a/src/Core/Resources/Localization/AppResources.Designer.cs +++ b/src/Core/Resources/Localization/AppResources.Designer.cs @@ -1,7 +1,6 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // This code was generated by a tool. -// Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. @@ -14,12 +13,10 @@ namespace Bit.Core.Resources.Localization { /// /// A strongly-typed resource class, for looking up localized strings, etc. + /// This class was generated by MSBuild using the GenerateResource task. + /// To add or remove a member, edit your .resx file then rerun MSBuild. /// - // This class was auto-generated by the StronglyTypedResourceBuilder - // class via a tool like ResGen or Visual Studio. - // To add or remove a member, edit your .ResX file then rerun ResGen - // with the /str option, or rebuild your VS project. - [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Build.Tasks.StronglyTypedResourceBuilder", "15.1.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] public class AppResources { @@ -8084,6 +8081,24 @@ namespace Bit.Core.Resources.Localization { } } + /// + /// Looks up a localized string similar to Your passkey will be saved to your Bitwarden vault. + /// + public static string YourPasskeyWillBeSavedToYourBitwardenVault { + get { + return ResourceManager.GetString("YourPasskeyWillBeSavedToYourBitwardenVault", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Your passkey will be saved to your Bitwarden vault for {0}. + /// + public static string YourPasskeyWillBeSavedToYourBitwardenVaultForX { + get { + return ResourceManager.GetString("YourPasskeyWillBeSavedToYourBitwardenVaultForX", resourceCulture); + } + } + /// /// Looks up a localized string similar to Your request has been sent to your admin.. /// diff --git a/src/Core/Resources/Localization/AppResources.resx b/src/Core/Resources/Localization/AppResources.resx index 2b1f5218e..4d82ba0f7 100644 --- a/src/Core/Resources/Localization/AppResources.resx +++ b/src/Core/Resources/Localization/AppResources.resx @@ -2969,4 +2969,10 @@ Do you want to switch to this account? 3. Select "Bitwarden" to use for passwords and passkeys + + Your passkey will be saved to your Bitwarden vault + + + Your passkey will be saved to your Bitwarden vault for {0} +