PM-4404 Added CreationDate to Fido2Credential objects and updated the UI bindings accordingly (#2832)

This commit is contained in:
Federico Maccaroni 2023-10-19 17:46:26 -03:00 committed by GitHub
parent 72de17bd1d
commit 142c3145f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 52 additions and 14 deletions

View file

@ -12,6 +12,7 @@
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors" xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields" xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore" xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore"
xmlns:appResources="clr-namespace:Bit.App.Resources"
x:DataType="pages:CipherAddEditPageViewModel" x:DataType="pages:CipherAddEditPageViewModel"
x:Name="_page" x:Name="_page"
Title="{Binding PageTitle}"> Title="{Binding PageTitle}">
@ -28,6 +29,8 @@
<u:InverseBoolConverter x:Key="inverseBool" /> <u:InverseBoolConverter x:Key="inverseBool" />
<u:StringHasValueConverter x:Key="stringHasValue" /> <u:StringHasValueConverter x:Key="stringHasValue" />
<u:IsNotNullConverter x:Key="notNull" /> <u:IsNotNullConverter x:Key="notNull" />
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static appResources:AppResources.CreatedXY}" />
<ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1" <ToolbarItem Text="{u:I18n Cancel}" Clicked="Close_Clicked" Order="Primary" Priority="-1"
x:Key="closeItem" x:Name="_closeItem" /> x:Key="closeItem" x:Name="_closeItem" />
<ToolbarItem Text="{u:I18n Collections}" <ToolbarItem Text="{u:I18n Collections}"
@ -229,7 +232,7 @@
Margin="0,10,0,0" Margin="0,10,0,0"
IsVisible="{Binding ShowPasskeyInfo}"/> IsVisible="{Binding ShowPasskeyInfo}"/>
<Entry <Entry
Text="{Binding CreationDate}" Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
IsEnabled="False" IsEnabled="False"
StyleClass="box-value,text-muted" StyleClass="box-value,text-muted"
IsVisible="{Binding ShowPasskeyInfo}" /> IsVisible="{Binding ShowPasskeyInfo}" />

View file

@ -11,6 +11,7 @@
xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors" xmlns:dts="clr-namespace:Bit.App.Lists.DataTemplateSelectors"
xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields" xmlns:il="clr-namespace:Bit.App.Lists.ItemLayouts.CustomFields"
xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore" xmlns:core="clr-namespace:Bit.Core;assembly=BitwardenCore"
xmlns:appResources="clr-namespace:Bit.App.Resources"
x:DataType="pages:CipherDetailsPageViewModel" x:DataType="pages:CipherDetailsPageViewModel"
x:Name="_page" x:Name="_page"
Title="{Binding PageTitle}"> Title="{Binding PageTitle}">
@ -23,6 +24,7 @@
<u:InverseBoolConverter x:Key="inverseBool" /> <u:InverseBoolConverter x:Key="inverseBool" />
<u:StringHasValueConverter x:Key="stringHasValue" /> <u:StringHasValueConverter x:Key="stringHasValue" />
<u:IsNotNullConverter x:Key="notNull" /> <u:IsNotNullConverter x:Key="notNull" />
<u:DateTimeConverter x:Key="dateTime" Format="{x:Static appResources:AppResources.CreatedXY}" />
<ToolbarItem Text="{u:I18n Collections}" <ToolbarItem Text="{u:I18n Collections}"
x:Key="collectionsItem" x:Key="collectionsItem"
x:Name="_collectionsItem" x:Name="_collectionsItem"
@ -201,10 +203,10 @@
Margin="0,10,0,0" Margin="0,10,0,0"
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}}"/> IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}}"/>
<Entry <Entry
Text="{Binding CreationDate}" Text="{Binding Cipher.Login.MainFido2Credential.CreationDate, Mode=OneWay, Converter={StaticResource dateTime}, FallbackValue=''}"
IsEnabled="False" IsEnabled="False"
StyleClass="box-value,text-muted" StyleClass="box-value,text-muted"
IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}}" /> IsVisible="{Binding Cipher.Login.MainFido2Credential, Converter={StaticResource notNull}, FallbackValue=False}" />
<Grid StyleClass="box-row" <Grid StyleClass="box-row"
IsVisible="{Binding ShowTotp}" IsVisible="{Binding ShowTotp}"
AutomationId="ItemRow"> AutomationId="ItemRow">

View file

@ -7,6 +7,8 @@ namespace Bit.App.Utilities
{ {
public class DateTimeConverter : IValueConverter public class DateTimeConverter : IValueConverter
{ {
public string Format { get; set; } = "{0} {1}";
private readonly ILocalizeService _localizeService; private readonly ILocalizeService _localizeService;
public DateTimeConverter() public DateTimeConverter()
@ -26,7 +28,7 @@ namespace Bit.App.Utilities
return string.Empty; return string.Empty;
} }
var d = ((DateTime)value).ToLocalTime(); var d = ((DateTime)value).ToLocalTime();
return string.Format("{0} {1}", return string.Format(Format,
_localizeService.GetLocaleShortDate(d), _localizeService.GetLocaleShortDate(d),
_localizeService.GetLocaleShortTime(d)); _localizeService.GetLocaleShortTime(d));
} }

View file

@ -1,4 +1,5 @@
using Bit.Core.Models.Domain; using System;
using Bit.Core.Models.Domain;
namespace Bit.Core.Models.Api namespace Bit.Core.Models.Api
{ {
@ -21,6 +22,7 @@ namespace Bit.Core.Models.Api
UserHandle = fido2Key.UserHandle?.EncryptedString; UserHandle = fido2Key.UserHandle?.EncryptedString;
UserName = fido2Key.UserName?.EncryptedString; UserName = fido2Key.UserName?.EncryptedString;
Counter = fido2Key.Counter?.EncryptedString; Counter = fido2Key.Counter?.EncryptedString;
CreationDate = fido2Key.CreationDate;
} }
public string CredentialId { get; set; } public string CredentialId { get; set; }
@ -34,5 +36,6 @@ namespace Bit.Core.Models.Api
public string UserHandle { get; set; } public string UserHandle { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
public string Counter { get; set; } public string Counter { get; set; }
public DateTime CreationDate { get; set; }
} }
} }

View file

@ -1,4 +1,5 @@
using Bit.Core.Models.Api; using System;
using Bit.Core.Models.Api;
namespace Bit.Core.Models.Data namespace Bit.Core.Models.Data
{ {
@ -19,6 +20,7 @@ namespace Bit.Core.Models.Data
UserHandle = apiData.UserHandle; UserHandle = apiData.UserHandle;
UserName = apiData.UserName; UserName = apiData.UserName;
Counter = apiData.Counter; Counter = apiData.Counter;
CreationDate = apiData.CreationDate;
} }
public string CredentialId { get; set; } public string CredentialId { get; set; }
@ -32,5 +34,6 @@ namespace Bit.Core.Models.Data
public string UserHandle { get; set; } public string UserHandle { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
public string Counter { get; set; } public string Counter { get; set; }
public DateTime CreationDate { get; set; }
} }
} }

View file

@ -1,4 +1,6 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Models.View; using Bit.Core.Models.View;
@ -7,7 +9,7 @@ namespace Bit.Core.Models.Domain
{ {
public class Fido2Credential : Domain public class Fido2Credential : Domain
{ {
public static HashSet<string> EncryptableProperties => new HashSet<string> public static HashSet<string> EncryptablePropertiesToMap => new HashSet<string>
{ {
nameof(CredentialId), nameof(CredentialId),
nameof(Discoverable), nameof(Discoverable),
@ -22,11 +24,18 @@ namespace Bit.Core.Models.Domain
nameof(Counter) nameof(Counter)
}; };
public static HashSet<string> NonEncryptablePropertiesToMap => new HashSet<string>
{
nameof(CreationDate)
};
public static HashSet<string> AllPropertiesToMap => new HashSet<string>(EncryptablePropertiesToMap.Concat(NonEncryptablePropertiesToMap));
public Fido2Credential() { } public Fido2Credential() { }
public Fido2Credential(Fido2CredentialData data, bool alreadyEncrypted = false) public Fido2Credential(Fido2CredentialData data, bool alreadyEncrypted = false)
{ {
BuildDomainModel(this, data, EncryptableProperties, alreadyEncrypted); BuildDomainModel(this, data, AllPropertiesToMap, alreadyEncrypted, NonEncryptablePropertiesToMap);
} }
public EncString CredentialId { get; set; } public EncString CredentialId { get; set; }
@ -40,16 +49,17 @@ namespace Bit.Core.Models.Domain
public EncString UserHandle { get; set; } public EncString UserHandle { get; set; }
public EncString UserName { get; set; } public EncString UserName { get; set; }
public EncString Counter { get; set; } public EncString Counter { get; set; }
public DateTime CreationDate { get; set; }
public async Task<Fido2CredentialView> DecryptAsync(string orgId, SymmetricCryptoKey key = null) public async Task<Fido2CredentialView> DecryptAsync(string orgId, SymmetricCryptoKey key = null)
{ {
return await DecryptObjAsync(new Fido2CredentialView(), this, EncryptableProperties, orgId, key); return await DecryptObjAsync(new Fido2CredentialView(this), this, EncryptablePropertiesToMap, orgId, key);
} }
public Fido2CredentialData ToFido2CredentialData() public Fido2CredentialData ToFido2CredentialData()
{ {
var data = new Fido2CredentialData(); var data = new Fido2CredentialData();
BuildDataModel(this, data, EncryptableProperties); BuildDataModel(this, data, AllPropertiesToMap, NonEncryptablePropertiesToMap);
return data; return data;
} }
} }

View file

@ -1,10 +1,21 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Domain;
namespace Bit.Core.Models.View namespace Bit.Core.Models.View
{ {
public class Fido2CredentialView : ItemView, ILaunchableView public class Fido2CredentialView : ItemView, ILaunchableView
{ {
public Fido2CredentialView()
{
}
public Fido2CredentialView(Fido2Credential fido2Credential)
{
CreationDate = fido2Credential.CreationDate;
}
public string CredentialId { get; set; } public string CredentialId { get; set; }
public string Discoverable { get; set; } public string Discoverable { get; set; }
public string KeyType { get; set; } = Constants.DefaultFido2CredentialType; public string KeyType { get; set; } = Constants.DefaultFido2CredentialType;
@ -16,6 +27,7 @@ namespace Bit.Core.Models.View
public string UserHandle { get; set; } public string UserHandle { get; set; }
public string UserName { get; set; } public string UserName { get; set; }
public string Counter { get; set; } public string Counter { get; set; }
public DateTime CreationDate { get; set; }
public override string SubTitle => UserName; public override string SubTitle => UserName;
public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions => new List<KeyValuePair<string, LinkedIdType>>(); public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions => new List<KeyValuePair<string, LinkedIdType>>();

View file

@ -1161,8 +1161,11 @@ namespace Bit.Core.Services
cipher.Login.Fido2Credentials = new List<Fido2Credential>(); cipher.Login.Fido2Credentials = new List<Fido2Credential>();
foreach (var fido2Credential in model.Login.Fido2Credentials) foreach (var fido2Credential in model.Login.Fido2Credentials)
{ {
var fido2CredentialDomain = new Fido2Credential(); var fido2CredentialDomain = new Fido2Credential
await EncryptObjPropertyAsync(fido2Credential, fido2CredentialDomain, Fido2Credential.EncryptableProperties, key); {
CreationDate = fido2Credential.CreationDate
};
await EncryptObjPropertyAsync(fido2Credential, fido2CredentialDomain, Fido2Credential.EncryptablePropertiesToMap, key);
cipher.Login.Fido2Credentials.Add(fido2CredentialDomain); cipher.Login.Fido2Credentials.Add(fido2CredentialDomain);
} }
} }