mirror of
https://github.com/bitwarden/mobile.git
synced 2024-12-24 16:38:22 +01:00
[Linked fields] Add Linked Field as a custom field type (#1563)
* Add linked fields support * Fix style, don't show linked field if Secure Note * Finish basic linked fields for Login * Use Field.LinkedId to store linked field info * Reset Linked Custom Fields if cipherType changes * Refactor to use ItemView class * Use enum for LinkedId * Detect if no linkedFieldOptions
This commit is contained in:
parent
3cb8adeeff
commit
90b62d61ae
@ -656,6 +656,16 @@
|
||||
</Keyboard>
|
||||
</Entry.Keyboard>
|
||||
</controls:MonoEntry>
|
||||
<StackLayout
|
||||
StyleClass="box-row, box-row-input"
|
||||
IsVisible="{Binding IsLinkedType}">
|
||||
<Picker
|
||||
x:Name="_linkedFieldOptionPicker"
|
||||
ItemsSource="{Binding LinkedFieldOptions, Mode=OneTime}"
|
||||
SelectedIndex="{Binding LinkedFieldOptionSelectedIndex}"
|
||||
ItemDisplayBinding="{Binding Key}"
|
||||
StyleClass="box-value" />
|
||||
</StackLayout>
|
||||
<Switch
|
||||
IsToggled="{Binding BooleanValue}"
|
||||
Grid.Row="0"
|
||||
|
@ -64,13 +64,6 @@ namespace Bit.App.Pages
|
||||
new KeyValuePair<UriMatchType?, string>(UriMatchType.Exact, AppResources.Exact),
|
||||
new KeyValuePair<UriMatchType?, string>(UriMatchType.Never, AppResources.Never)
|
||||
};
|
||||
private List<KeyValuePair<FieldType, string>> _fieldTypeOptions =
|
||||
new List<KeyValuePair<FieldType, string>>
|
||||
{
|
||||
new KeyValuePair<FieldType, string>(FieldType.Text, AppResources.FieldTypeText),
|
||||
new KeyValuePair<FieldType, string>(FieldType.Hidden, AppResources.FieldTypeHidden),
|
||||
new KeyValuePair<FieldType, string>(FieldType.Boolean, AppResources.FieldTypeBoolean)
|
||||
};
|
||||
|
||||
public AddEditPageViewModel()
|
||||
{
|
||||
@ -667,8 +660,20 @@ namespace Bit.App.Pages
|
||||
|
||||
public async void AddField()
|
||||
{
|
||||
var fieldTypeOptions = new List<KeyValuePair<FieldType, string>>
|
||||
{
|
||||
new KeyValuePair<FieldType, string>(FieldType.Text, AppResources.FieldTypeText),
|
||||
new KeyValuePair<FieldType, string>(FieldType.Hidden, AppResources.FieldTypeHidden),
|
||||
new KeyValuePair<FieldType, string>(FieldType.Boolean, AppResources.FieldTypeBoolean),
|
||||
};
|
||||
|
||||
if (Cipher.LinkedFieldOptions != null)
|
||||
{
|
||||
fieldTypeOptions.Add(new KeyValuePair<FieldType, string>(FieldType.Linked, AppResources.FieldTypeLinked));
|
||||
}
|
||||
|
||||
var typeSelection = await Page.DisplayActionSheet(AppResources.SelectTypeField, AppResources.Cancel, null,
|
||||
_fieldTypeOptions.Select(f => f.Value).ToArray());
|
||||
fieldTypeOptions.Select(f => f.Value).ToArray());
|
||||
if (typeSelection != null && typeSelection != AppResources.Cancel)
|
||||
{
|
||||
var name = await _deviceActionService.DisplayPromptAync(AppResources.CustomFieldName);
|
||||
@ -680,7 +685,7 @@ namespace Bit.App.Pages
|
||||
{
|
||||
Fields = new ExtendedObservableCollection<AddEditPageFieldViewModel>();
|
||||
}
|
||||
var type = _fieldTypeOptions.FirstOrDefault(f => f.Value == typeSelection).Key;
|
||||
var type = fieldTypeOptions.FirstOrDefault(f => f.Value == typeSelection).Key;
|
||||
Fields.Add(new AddEditPageFieldViewModel(Cipher, new FieldView
|
||||
{
|
||||
Type = type,
|
||||
@ -746,6 +751,12 @@ namespace Bit.App.Pages
|
||||
{
|
||||
Cipher.Type = TypeOptions[TypeSelectedIndex].Value;
|
||||
TriggerCipherChanged();
|
||||
|
||||
// Linked Custom Fields only apply to a specific item type
|
||||
foreach (var field in Fields.Where(f => f.IsLinkedType).ToList())
|
||||
{
|
||||
Fields.Remove(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -850,23 +861,29 @@ namespace Bit.App.Pages
|
||||
|
||||
public class AddEditPageFieldViewModel : ExtendedViewModel
|
||||
{
|
||||
private II18nService _i18nService;
|
||||
private FieldView _field;
|
||||
private CipherView _cipher;
|
||||
private bool _showHiddenValue;
|
||||
private bool _booleanValue;
|
||||
private int _linkedFieldOptionSelectedIndex;
|
||||
private string[] _additionalFieldProperties = new string[]
|
||||
{
|
||||
nameof(IsBooleanType),
|
||||
nameof(IsHiddenType),
|
||||
nameof(IsTextType),
|
||||
nameof(IsLinkedType),
|
||||
};
|
||||
|
||||
public AddEditPageFieldViewModel(CipherView cipher, FieldView field)
|
||||
{
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_cipher = cipher;
|
||||
Field = field;
|
||||
ToggleHiddenValueCommand = new Command(ToggleHiddenValue);
|
||||
BooleanValue = IsBooleanType && field.Value == "true";
|
||||
LinkedFieldOptionSelectedIndex = !Field.LinkedId.HasValue ? 0 :
|
||||
LinkedFieldOptions.FindIndex(lfo => lfo.Value == Field.LinkedId.Value);
|
||||
}
|
||||
|
||||
public FieldView Field
|
||||
@ -898,12 +915,32 @@ namespace Bit.App.Pages
|
||||
}
|
||||
}
|
||||
|
||||
public int LinkedFieldOptionSelectedIndex
|
||||
{
|
||||
get => _linkedFieldOptionSelectedIndex;
|
||||
set
|
||||
{
|
||||
if (SetProperty(ref _linkedFieldOptionSelectedIndex, value))
|
||||
{
|
||||
LinkedFieldValueChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions
|
||||
{
|
||||
get => _cipher.LinkedFieldOptions
|
||||
.Select(kvp => new KeyValuePair<string, LinkedIdType>(_i18nService.T(kvp.Key), kvp.Value))
|
||||
.ToList();
|
||||
}
|
||||
|
||||
public Command ToggleHiddenValueCommand { get; set; }
|
||||
|
||||
public string ShowHiddenValueIcon => _showHiddenValue ? "" : "";
|
||||
public bool IsTextType => _field.Type == FieldType.Text;
|
||||
public bool IsBooleanType => _field.Type == FieldType.Boolean;
|
||||
public bool IsHiddenType => _field.Type == FieldType.Hidden;
|
||||
public bool IsLinkedType => _field.Type == FieldType.Linked;
|
||||
public bool ShowViewHidden => IsHiddenType && (_cipher.ViewPassword || _field.NewField);
|
||||
|
||||
public void ToggleHiddenValue()
|
||||
@ -920,5 +957,14 @@ namespace Bit.App.Pages
|
||||
{
|
||||
TriggerPropertyChanged(nameof(Field), _additionalFieldProperties);
|
||||
}
|
||||
|
||||
private void LinkedFieldValueChanged()
|
||||
{
|
||||
if (Field != null && LinkedFieldOptionSelectedIndex > -1)
|
||||
{
|
||||
Field.LinkedId = LinkedFieldOptions.Find(lfo =>
|
||||
lfo.Value == LinkedFieldOptions[LinkedFieldOptionSelectedIndex].Value).Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -561,6 +561,12 @@
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
IsVisible="{Binding IsTextType}" />
|
||||
<controls:FaLabel
|
||||
Text="{Binding ValueText, Mode=OneWay}"
|
||||
StyleClass="box-value"
|
||||
Grid.Row="1"
|
||||
Grid.Column="0"
|
||||
IsVisible="{Binding IsLinkedType}" />
|
||||
<controls:FaLabel
|
||||
Text="{Binding ValueText, Mode=OneWay}"
|
||||
StyleClass="box-value"
|
||||
|
@ -704,6 +704,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public class ViewPageFieldViewModel : ExtendedViewModel
|
||||
{
|
||||
private II18nService _i18nService;
|
||||
private ViewPageViewModel _vm;
|
||||
private FieldView _field;
|
||||
private CipherView _cipher;
|
||||
@ -711,6 +712,7 @@ namespace Bit.App.Pages
|
||||
|
||||
public ViewPageFieldViewModel(ViewPageViewModel vm, CipherView cipher, FieldView field)
|
||||
{
|
||||
_i18nService = ServiceContainer.Resolve<II18nService>("i18nService");
|
||||
_vm = vm;
|
||||
_cipher = cipher;
|
||||
Field = field;
|
||||
@ -741,16 +743,38 @@ namespace Bit.App.Pages
|
||||
});
|
||||
}
|
||||
|
||||
public string ValueText
|
||||
{
|
||||
get
|
||||
{
|
||||
if (IsBooleanType)
|
||||
{
|
||||
return _field.Value == "true" ? "" : "";
|
||||
}
|
||||
else if (IsLinkedType)
|
||||
{
|
||||
var i18nKey = _cipher.LinkedFieldI18nKey(Field.LinkedId.GetValueOrDefault());
|
||||
return " " + _i18nService.T(i18nKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _field.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Command ToggleHiddenValueCommand { get; set; }
|
||||
|
||||
public string ValueText => IsBooleanType ? (_field.Value == "true" ? "" : "") : _field.Value;
|
||||
public string ShowHiddenValueIcon => _showHiddenValue ? "" : "";
|
||||
public bool IsTextType => _field.Type == Core.Enums.FieldType.Text;
|
||||
public bool IsBooleanType => _field.Type == Core.Enums.FieldType.Boolean;
|
||||
public bool IsHiddenType => _field.Type == Core.Enums.FieldType.Hidden;
|
||||
public bool IsLinkedType => _field.Type == Core.Enums.FieldType.Linked;
|
||||
public bool ShowViewHidden => IsHiddenType && _cipher.ViewPassword;
|
||||
public bool ShowCopyButton => _field.Type != Core.Enums.FieldType.Boolean &&
|
||||
!string.IsNullOrWhiteSpace(_field.Value) && !(IsHiddenType && !_cipher.ViewPassword);
|
||||
!string.IsNullOrWhiteSpace(_field.Value) &&
|
||||
!(IsHiddenType && !_cipher.ViewPassword) &&
|
||||
_field.Type != FieldType.Linked;
|
||||
|
||||
public async void ToggleHiddenValue()
|
||||
{
|
||||
|
16
src/App/Resources/AppResources.Designer.cs
generated
16
src/App/Resources/AppResources.Designer.cs
generated
@ -1,6 +1,7 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 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.
|
||||
@ -9,9 +10,10 @@
|
||||
|
||||
namespace Bit.App.Resources {
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
public class AppResources {
|
||||
@ -1779,6 +1781,12 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
public static string FullName {
|
||||
get {
|
||||
return ResourceManager.GetString("FullName", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string LicenseNumber {
|
||||
get {
|
||||
return ResourceManager.GetString("LicenseNumber", resourceCulture);
|
||||
@ -2025,6 +2033,12 @@ namespace Bit.App.Resources {
|
||||
}
|
||||
}
|
||||
|
||||
public static string FieldTypeLinked {
|
||||
get {
|
||||
return ResourceManager.GetString("FieldTypeLinked", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
public static string FieldTypeText {
|
||||
get {
|
||||
return ResourceManager.GetString("FieldTypeText", resourceCulture);
|
||||
|
@ -1059,6 +1059,9 @@
|
||||
<data name="LastName" xml:space="preserve">
|
||||
<value>Last Name</value>
|
||||
</data>
|
||||
<data name="FullName" xml:space="preserve">
|
||||
<value>Full Name</value>
|
||||
</data>
|
||||
<data name="LicenseNumber" xml:space="preserve">
|
||||
<value>License Number</value>
|
||||
</data>
|
||||
@ -1183,6 +1186,9 @@
|
||||
<data name="FieldTypeHidden" xml:space="preserve">
|
||||
<value>Hidden</value>
|
||||
</data>
|
||||
<data name="FieldTypeLinked" xml:space="preserve">
|
||||
<value>Linked</value>
|
||||
</data>
|
||||
<data name="FieldTypeText" xml:space="preserve">
|
||||
<value>Text</value>
|
||||
</data>
|
||||
|
@ -4,6 +4,7 @@
|
||||
{
|
||||
Text = 0,
|
||||
Hidden = 1,
|
||||
Boolean = 2
|
||||
Boolean = 2,
|
||||
Linked = 3,
|
||||
}
|
||||
}
|
||||
|
38
src/Core/Enums/LinkedIdType.cs
Normal file
38
src/Core/Enums/LinkedIdType.cs
Normal file
@ -0,0 +1,38 @@
|
||||
namespace Bit.Core.Enums {
|
||||
|
||||
public enum LinkedIdType: int
|
||||
{
|
||||
// Login
|
||||
Login_Username = 100,
|
||||
Login_Password = 101,
|
||||
|
||||
// Card
|
||||
Card_CardholderName = 300,
|
||||
Card_ExpMonth = 301,
|
||||
Card_ExpYear = 302,
|
||||
Card_Code = 303,
|
||||
Card_Brand = 304,
|
||||
Card_Number = 305,
|
||||
|
||||
// Identity
|
||||
Identity_Title = 400,
|
||||
Identity_MiddleName = 401,
|
||||
Identity_Address1 = 402,
|
||||
Identity_Address2 = 403,
|
||||
Identity_Address3 = 404,
|
||||
Identity_City = 405,
|
||||
Identity_State = 406,
|
||||
Identity_PostalCode = 407,
|
||||
Identity_Country = 408,
|
||||
Identity_Company = 409,
|
||||
Identity_Email = 410,
|
||||
Identity_Phone = 411,
|
||||
Identity_Ssn = 412,
|
||||
Identity_Username = 413,
|
||||
Identity_PassportNumber = 414,
|
||||
Identity_LicenseNumber = 415,
|
||||
Identity_FirstName = 416,
|
||||
Identity_LastName = 417,
|
||||
Identity_FullName = 418,
|
||||
}
|
||||
}
|
@ -7,5 +7,6 @@ namespace Bit.Core.Models.Api
|
||||
public FieldType Type { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public LinkedIdType? LinkedId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -12,10 +12,12 @@ namespace Bit.Core.Models.Data
|
||||
Type = data.Type;
|
||||
Name = data.Name;
|
||||
Value = data.Value;
|
||||
LinkedId = data.LinkedId;
|
||||
}
|
||||
|
||||
public FieldType Type { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
public LinkedIdType? LinkedId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -19,12 +19,14 @@ namespace Bit.Core.Models.Domain
|
||||
public Field(FieldData obj, bool alreadyEncrypted = false)
|
||||
{
|
||||
Type = obj.Type;
|
||||
LinkedId = obj.LinkedId;
|
||||
BuildDomainModel(this, obj, _map, alreadyEncrypted);
|
||||
}
|
||||
|
||||
public EncString Name { get; set; }
|
||||
public EncString Value { get; set; }
|
||||
public FieldType Type { get; set; }
|
||||
public LinkedIdType? LinkedId { get; set; }
|
||||
|
||||
public Task<FieldView> DecryptAsync(string orgId)
|
||||
{
|
||||
@ -38,10 +40,12 @@ namespace Bit.Core.Models.Domain
|
||||
{
|
||||
"Name",
|
||||
"Value",
|
||||
"Type"
|
||||
"Type",
|
||||
"LinkedId"
|
||||
}, new HashSet<string>
|
||||
{
|
||||
"Type"
|
||||
"Type",
|
||||
"LinkedId"
|
||||
});
|
||||
return f;
|
||||
}
|
||||
|
@ -81,7 +81,8 @@ namespace Bit.Core.Models.Request
|
||||
{
|
||||
Type = f.Type,
|
||||
Name = f.Name?.EncryptedString,
|
||||
Value = f.Value?.EncryptedString
|
||||
Value = f.Value?.EncryptedString,
|
||||
LinkedId = f.LinkedId,
|
||||
}).ToList();
|
||||
|
||||
PasswordHistory = cipher.PasswordHistory?.Select(ph => new PasswordHistoryRequest
|
||||
|
@ -1,9 +1,11 @@
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Enums;
|
||||
using System.Collections.Generic;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public class CardView : View
|
||||
public class CardView : ItemView
|
||||
{
|
||||
private string _brand;
|
||||
private string _number;
|
||||
@ -40,7 +42,7 @@ namespace Bit.Core.Models.View
|
||||
}
|
||||
}
|
||||
|
||||
public string SubTitle
|
||||
public override string SubTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -82,6 +84,19 @@ namespace Bit.Core.Models.View
|
||||
}
|
||||
}
|
||||
|
||||
public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions
|
||||
{
|
||||
get => new List<KeyValuePair<string, LinkedIdType>>()
|
||||
{
|
||||
new KeyValuePair<string, LinkedIdType>("CardholderName", LinkedIdType.Card_CardholderName),
|
||||
new KeyValuePair<string, LinkedIdType>("ExpirationMonth", LinkedIdType.Card_ExpMonth),
|
||||
new KeyValuePair<string, LinkedIdType>("ExpirationYear", LinkedIdType.Card_ExpYear),
|
||||
new KeyValuePair<string, LinkedIdType>("SecurityCode", LinkedIdType.Card_Code),
|
||||
new KeyValuePair<string, LinkedIdType>("Brand", LinkedIdType.Card_Brand),
|
||||
new KeyValuePair<string, LinkedIdType>("Number", LinkedIdType.Card_Number),
|
||||
};
|
||||
}
|
||||
|
||||
private string FormatYear(string year)
|
||||
{
|
||||
return year.Length == 2 ? string.Concat("20", year) : year;
|
||||
|
@ -50,20 +50,20 @@ namespace Bit.Core.Models.View
|
||||
public DateTime? DeletedDate { get; set; }
|
||||
public CipherRepromptType Reprompt { get; set; }
|
||||
|
||||
public string SubTitle
|
||||
public ItemView Item
|
||||
{
|
||||
get
|
||||
{
|
||||
switch (Type)
|
||||
{
|
||||
case CipherType.Login:
|
||||
return Login.SubTitle;
|
||||
return Login;
|
||||
case CipherType.SecureNote:
|
||||
return SecureNote.SubTitle;
|
||||
return SecureNote;
|
||||
case CipherType.Card:
|
||||
return Card.SubTitle;
|
||||
return Card;
|
||||
case CipherType.Identity:
|
||||
return Identity.SubTitle;
|
||||
return Identity;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@ -71,6 +71,8 @@ namespace Bit.Core.Models.View
|
||||
}
|
||||
}
|
||||
|
||||
public List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions => Item.LinkedFieldOptions;
|
||||
public string SubTitle => Item.SubTitle;
|
||||
public bool Shared => OrganizationId != null;
|
||||
public bool HasPasswordHistory => PasswordHistory?.Any() ?? false;
|
||||
public bool HasAttachments => Attachments?.Any() ?? false;
|
||||
@ -102,5 +104,11 @@ namespace Bit.Core.Models.View
|
||||
}
|
||||
}
|
||||
public bool IsDeleted => DeletedDate.HasValue;
|
||||
|
||||
public string LinkedFieldI18nKey(LinkedIdType id)
|
||||
{
|
||||
return LinkedFieldOptions.Find(lfo => lfo.Value == id).Key;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@ namespace Bit.Core.Models.View
|
||||
public FieldView(Field f)
|
||||
{
|
||||
Type = f.Type;
|
||||
LinkedId = f.LinkedId;
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
@ -17,5 +18,6 @@ namespace Bit.Core.Models.View
|
||||
public FieldType Type { get; set; }
|
||||
public string MaskedValue => Value != null ? "••••••••" : null;
|
||||
public bool NewField { get; set; }
|
||||
public LinkedIdType? LinkedId { get; set; }
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Enums;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public class IdentityView : View
|
||||
public class IdentityView : ItemView
|
||||
{
|
||||
private string _firstName;
|
||||
private string _lastName;
|
||||
@ -47,7 +49,7 @@ namespace Bit.Core.Models.View
|
||||
public string PassportNumber { get; set; }
|
||||
public string LicenseNumber { get; set; }
|
||||
|
||||
public string SubTitle
|
||||
public override string SubTitle
|
||||
{
|
||||
get
|
||||
{
|
||||
@ -141,5 +143,31 @@ namespace Bit.Core.Models.View
|
||||
return string.Format("{0}, {1}, {2}", city, state, postalCode);
|
||||
}
|
||||
}
|
||||
|
||||
public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions
|
||||
{
|
||||
get => new List<KeyValuePair<string, LinkedIdType>>()
|
||||
{
|
||||
new KeyValuePair<string, LinkedIdType>("Title", LinkedIdType.Identity_Title),
|
||||
new KeyValuePair<string, LinkedIdType>("MiddleName", LinkedIdType.Identity_MiddleName),
|
||||
new KeyValuePair<string, LinkedIdType>("Address1", LinkedIdType.Identity_Address1),
|
||||
new KeyValuePair<string, LinkedIdType>("Address2", LinkedIdType.Identity_Address2),
|
||||
new KeyValuePair<string, LinkedIdType>("Address3", LinkedIdType.Identity_Address3),
|
||||
new KeyValuePair<string, LinkedIdType>("CityTown", LinkedIdType.Identity_City),
|
||||
new KeyValuePair<string, LinkedIdType>("StateProvince", LinkedIdType.Identity_State),
|
||||
new KeyValuePair<string, LinkedIdType>("ZipPostalCode", LinkedIdType.Identity_PostalCode),
|
||||
new KeyValuePair<string, LinkedIdType>("Country", LinkedIdType.Identity_Country),
|
||||
new KeyValuePair<string, LinkedIdType>("Company", LinkedIdType.Identity_Company),
|
||||
new KeyValuePair<string, LinkedIdType>("Email", LinkedIdType.Identity_Email),
|
||||
new KeyValuePair<string, LinkedIdType>("Phone", LinkedIdType.Identity_Phone),
|
||||
new KeyValuePair<string, LinkedIdType>("SSN", LinkedIdType.Identity_Ssn),
|
||||
new KeyValuePair<string, LinkedIdType>("Username", LinkedIdType.Identity_Username),
|
||||
new KeyValuePair<string, LinkedIdType>("PassportNumber", LinkedIdType.Identity_PassportNumber),
|
||||
new KeyValuePair<string, LinkedIdType>("LicenseNumber", LinkedIdType.Identity_LicenseNumber),
|
||||
new KeyValuePair<string, LinkedIdType>("FirstName", LinkedIdType.Identity_FirstName),
|
||||
new KeyValuePair<string, LinkedIdType>("LastName", LinkedIdType.Identity_LastName),
|
||||
new KeyValuePair<string, LinkedIdType>("FullName", LinkedIdType.Identity_FullName),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
14
src/Core/Models/View/ItemView.cs
Normal file
14
src/Core/Models/View/ItemView.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System.Collections.Generic;
|
||||
using Bit.Core.Enums;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public abstract class ItemView : View
|
||||
{
|
||||
public ItemView() { }
|
||||
|
||||
public abstract string SubTitle { get; }
|
||||
|
||||
public abstract List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions { get; }
|
||||
}
|
||||
}
|
@ -1,11 +1,12 @@
|
||||
using Bit.Core.Models.Domain;
|
||||
using Bit.Core.Enums;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public class LoginView : View
|
||||
public class LoginView : ItemView
|
||||
{
|
||||
public LoginView() { }
|
||||
|
||||
@ -21,9 +22,18 @@ namespace Bit.Core.Models.View
|
||||
public List<LoginUriView> Uris { get; set; }
|
||||
public string Uri => HasUris ? Uris[0].Uri : null;
|
||||
public string MaskedPassword => Password != null ? "••••••••" : null;
|
||||
public string SubTitle => Username;
|
||||
public override string SubTitle => Username;
|
||||
public bool CanLaunch => HasUris && Uris.Any(u => u.CanLaunch);
|
||||
public string LaunchUri => HasUris ? Uris.FirstOrDefault(u => u.CanLaunch)?.LaunchUri : null;
|
||||
public bool HasUris => (Uris?.Count ?? 0) > 0;
|
||||
|
||||
public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions
|
||||
{
|
||||
get => new List<KeyValuePair<string, LinkedIdType>>()
|
||||
{
|
||||
new KeyValuePair<string, LinkedIdType>("Username", LinkedIdType.Login_Username),
|
||||
new KeyValuePair<string, LinkedIdType>("Password", LinkedIdType.Login_Password),
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,10 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Domain;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Bit.Core.Models.View
|
||||
{
|
||||
public class SecureNoteView : View
|
||||
public class SecureNoteView : ItemView
|
||||
{
|
||||
public SecureNoteView() { }
|
||||
|
||||
@ -13,6 +14,7 @@ namespace Bit.Core.Models.View
|
||||
}
|
||||
|
||||
public SecureNoteType Type { get; set; }
|
||||
public string SubTitle => null;
|
||||
public override string SubTitle => null;
|
||||
public override List<KeyValuePair<string, LinkedIdType>> LinkedFieldOptions => null;
|
||||
}
|
||||
}
|
||||
|
@ -1190,7 +1190,8 @@ namespace Bit.Core.Services
|
||||
{
|
||||
var field = new Field
|
||||
{
|
||||
Type = model.Type
|
||||
Type = model.Type,
|
||||
LinkedId = model.LinkedId,
|
||||
};
|
||||
// normalize boolean type field values
|
||||
if (model.Type == FieldType.Boolean && model.Value != "true")
|
||||
|
Loading…
Reference in New Issue
Block a user