mirror of
https://github.com/bitwarden/android.git
synced 2024-12-25 18:38:27 +03:00
Add support for hidden passwords (#920)
* Add support for hidden passwords * Hide TOTP, hide hidden fields. * Change _cipher to Cipher.
This commit is contained in:
parent
e64fb39c32
commit
52ca84946b
10 changed files with 39 additions and 13 deletions
|
@ -112,9 +112,11 @@
|
||||||
StyleClass="box-value"
|
StyleClass="box-value"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="{Binding PasswordFieldColSpan}"
|
||||||
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
|
IsPassword="{Binding ShowPassword, Converter={StaticResource inverseBool}}"
|
||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
IsTextPredictionEnabled="False" />
|
IsTextPredictionEnabled="False"
|
||||||
|
IsEnabled="{Binding Cipher.ViewPassword}"/>
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text=""
|
Text=""
|
||||||
|
@ -123,7 +125,8 @@
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n CheckPassword}" />
|
AutomationProperties.Name="{u:I18n CheckPassword}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text="{Binding ShowPasswordIcon}"
|
Text="{Binding ShowPasswordIcon}"
|
||||||
|
@ -132,7 +135,8 @@
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
|
AutomationProperties.Name="{u:I18n ToggleVisibility}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text=""
|
Text=""
|
||||||
|
@ -141,7 +145,8 @@
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n GeneratePassword}" />
|
AutomationProperties.Name="{u:I18n GeneratePassword}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<Grid StyleClass="box-row, box-row-input">
|
<Grid StyleClass="box-row, box-row-input">
|
||||||
|
@ -163,9 +168,12 @@
|
||||||
Text="{Binding Cipher.Login.Totp}"
|
Text="{Binding Cipher.Login.Totp}"
|
||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
IsTextPredictionEnabled="False"
|
IsTextPredictionEnabled="False"
|
||||||
|
IsPassword="{Binding Cipher.ViewPassword, Converter={StaticResource inverseBool}}"
|
||||||
|
IsEnabled="{Binding Cipher.ViewPassword}"
|
||||||
StyleClass="box-value"
|
StyleClass="box-value"
|
||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Grid.Column="0" />
|
Grid.Column="0"
|
||||||
|
Grid.ColumnSpan="{Binding TotpColumnSpan}" />
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text=""
|
Text=""
|
||||||
|
@ -173,6 +181,7 @@
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n ScanQrTitle}" />
|
AutomationProperties.Name="{u:I18n ScanQrTitle}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
|
@ -562,6 +571,7 @@
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
IsVisible="{Binding IsHiddenType}"
|
IsVisible="{Binding IsHiddenType}"
|
||||||
IsPassword="{Binding ShowHiddenValue, Converter={StaticResource inverseBool}}"
|
IsPassword="{Binding ShowHiddenValue, Converter={StaticResource inverseBool}}"
|
||||||
|
IsEnabled="{Binding ShowViewHidden}"
|
||||||
IsSpellCheckEnabled="False"
|
IsSpellCheckEnabled="False"
|
||||||
IsTextPredictionEnabled="False">
|
IsTextPredictionEnabled="False">
|
||||||
<Entry.Keyboard>
|
<Entry.Keyboard>
|
||||||
|
@ -582,7 +592,7 @@
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text="{Binding ShowHiddenValueIcon}"
|
Text="{Binding ShowHiddenValueIcon}"
|
||||||
Command="{Binding ToggleHiddenValueCommand}"
|
Command="{Binding ToggleHiddenValueCommand}"
|
||||||
IsVisible="{Binding IsHiddenType}"
|
IsVisible="{Binding ShowViewHidden}"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
|
|
|
@ -274,6 +274,8 @@ namespace Bit.App.Pages
|
||||||
public bool ShowAttachments => Cipher.HasAttachments;
|
public bool ShowAttachments => Cipher.HasAttachments;
|
||||||
public string ShowPasswordIcon => ShowPassword ? "" : "";
|
public string ShowPasswordIcon => ShowPassword ? "" : "";
|
||||||
public string ShowCardCodeIcon => ShowCardCode ? "" : "";
|
public string ShowCardCodeIcon => ShowCardCode ? "" : "";
|
||||||
|
public int PasswordFieldColSpan => Cipher.ViewPassword ? 1 : 4;
|
||||||
|
public int TotpColumnSpan => Cipher.ViewPassword ? 1 : 2;
|
||||||
|
|
||||||
public void Init()
|
public void Init()
|
||||||
{
|
{
|
||||||
|
@ -631,7 +633,8 @@ namespace Bit.App.Pages
|
||||||
Fields.Add(new AddEditPageFieldViewModel(Cipher, new FieldView
|
Fields.Add(new AddEditPageFieldViewModel(Cipher, new FieldView
|
||||||
{
|
{
|
||||||
Type = type,
|
Type = type,
|
||||||
Name = string.IsNullOrWhiteSpace(name) ? null : name
|
Name = string.IsNullOrWhiteSpace(name) ? null : name,
|
||||||
|
NewField = true,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -818,6 +821,7 @@ namespace Bit.App.Pages
|
||||||
public bool IsTextType => _field.Type == FieldType.Text;
|
public bool IsTextType => _field.Type == FieldType.Text;
|
||||||
public bool IsBooleanType => _field.Type == FieldType.Boolean;
|
public bool IsBooleanType => _field.Type == FieldType.Boolean;
|
||||||
public bool IsHiddenType => _field.Type == FieldType.Hidden;
|
public bool IsHiddenType => _field.Type == FieldType.Hidden;
|
||||||
|
public bool ShowViewHidden => IsHiddenType && (_cipher.ViewPassword || _field.NewField);
|
||||||
|
|
||||||
public void ToggleHiddenValue()
|
public void ToggleHiddenValue()
|
||||||
{
|
{
|
||||||
|
|
|
@ -134,7 +134,8 @@
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n CheckPassword}" />
|
AutomationProperties.Name="{u:I18n CheckPassword}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text="{Binding ShowPasswordIcon}"
|
Text="{Binding ShowPasswordIcon}"
|
||||||
|
@ -143,7 +144,8 @@
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n ToggleVisibility}" />
|
AutomationProperties.Name="{u:I18n ToggleVisibility}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
<controls:FaButton
|
<controls:FaButton
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text=""
|
Text=""
|
||||||
|
@ -153,7 +155,8 @@
|
||||||
Grid.Column="3"
|
Grid.Column="3"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
AutomationProperties.IsInAccessibleTree="True"
|
AutomationProperties.IsInAccessibleTree="True"
|
||||||
AutomationProperties.Name="{u:I18n CopyPassword}" />
|
AutomationProperties.Name="{u:I18n CopyPassword}"
|
||||||
|
IsVisible="{Binding Cipher.ViewPassword}" />
|
||||||
</Grid>
|
</Grid>
|
||||||
<BoxView StyleClass="box-row-separator"
|
<BoxView StyleClass="box-row-separator"
|
||||||
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}" />
|
IsVisible="{Binding Cipher.Login.Password, Converter={StaticResource stringHasValue}}" />
|
||||||
|
@ -570,7 +573,7 @@
|
||||||
StyleClass="box-row-button, box-row-button-platform"
|
StyleClass="box-row-button, box-row-button-platform"
|
||||||
Text="{Binding ShowHiddenValueIcon}"
|
Text="{Binding ShowHiddenValueIcon}"
|
||||||
Command="{Binding ToggleHiddenValueCommand}"
|
Command="{Binding ToggleHiddenValueCommand}"
|
||||||
IsVisible="{Binding IsHiddenType}"
|
IsVisible="{Binding ShowViewHidden}"
|
||||||
Grid.Row="0"
|
Grid.Row="0"
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Grid.RowSpan="2"
|
Grid.RowSpan="2"
|
||||||
|
|
|
@ -684,8 +684,9 @@ namespace Bit.App.Pages
|
||||||
public bool IsTextType => _field.Type == Core.Enums.FieldType.Text;
|
public bool IsTextType => _field.Type == Core.Enums.FieldType.Text;
|
||||||
public bool IsBooleanType => _field.Type == Core.Enums.FieldType.Boolean;
|
public bool IsBooleanType => _field.Type == Core.Enums.FieldType.Boolean;
|
||||||
public bool IsHiddenType => _field.Type == Core.Enums.FieldType.Hidden;
|
public bool IsHiddenType => _field.Type == Core.Enums.FieldType.Hidden;
|
||||||
|
public bool ShowViewHidden => IsHiddenType && _cipher.ViewPassword;
|
||||||
public bool ShowCopyButton => _field.Type != Core.Enums.FieldType.Boolean &&
|
public bool ShowCopyButton => _field.Type != Core.Enums.FieldType.Boolean &&
|
||||||
!string.IsNullOrWhiteSpace(_field.Value);
|
!string.IsNullOrWhiteSpace(_field.Value) && !(IsHiddenType && !_cipher.ViewPassword);
|
||||||
|
|
||||||
public void ToggleHiddenValue()
|
public void ToggleHiddenValue()
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace Bit.App.Utilities
|
||||||
{
|
{
|
||||||
options.Add(AppResources.CopyUsername);
|
options.Add(AppResources.CopyUsername);
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrWhiteSpace(cipher.Login.Password))
|
if (!string.IsNullOrWhiteSpace(cipher.Login.Password) && cipher.ViewPassword)
|
||||||
{
|
{
|
||||||
options.Add(AppResources.CopyPassword);
|
options.Add(AppResources.CopyPassword);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ namespace Bit.Core.Models.Data
|
||||||
FolderId = response.FolderId;
|
FolderId = response.FolderId;
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
Edit = response.Edit;
|
Edit = response.Edit;
|
||||||
|
ViewPassword = response.ViewPassword;
|
||||||
OrganizationUseTotp = response.OrganizationUseTotp;
|
OrganizationUseTotp = response.OrganizationUseTotp;
|
||||||
Favorite = response.Favorite;
|
Favorite = response.Favorite;
|
||||||
RevisionDate = response.RevisionDate;
|
RevisionDate = response.RevisionDate;
|
||||||
|
@ -53,6 +54,7 @@ namespace Bit.Core.Models.Data
|
||||||
public string FolderId { get; set; }
|
public string FolderId { get; set; }
|
||||||
public string UserId { get; set; }
|
public string UserId { get; set; }
|
||||||
public bool Edit { get; set; }
|
public bool Edit { get; set; }
|
||||||
|
public bool ViewPassword { get; set; }
|
||||||
public bool OrganizationUseTotp { get; set; }
|
public bool OrganizationUseTotp { get; set; }
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace Bit.Core.Models.Domain
|
||||||
Favorite = obj.Favorite;
|
Favorite = obj.Favorite;
|
||||||
OrganizationUseTotp = obj.OrganizationUseTotp;
|
OrganizationUseTotp = obj.OrganizationUseTotp;
|
||||||
Edit = obj.Edit;
|
Edit = obj.Edit;
|
||||||
|
ViewPassword = obj.ViewPassword;
|
||||||
RevisionDate = obj.RevisionDate;
|
RevisionDate = obj.RevisionDate;
|
||||||
CollectionIds = obj.CollectionIds != null ? new HashSet<string>(obj.CollectionIds) : null;
|
CollectionIds = obj.CollectionIds != null ? new HashSet<string>(obj.CollectionIds) : null;
|
||||||
LocalData = localData;
|
LocalData = localData;
|
||||||
|
@ -63,6 +64,7 @@ namespace Bit.Core.Models.Domain
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
public bool OrganizationUseTotp { get; set; }
|
public bool OrganizationUseTotp { get; set; }
|
||||||
public bool Edit { get; set; }
|
public bool Edit { get; set; }
|
||||||
|
public bool ViewPassword { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
public Dictionary<string, object> LocalData { get; set; }
|
public Dictionary<string, object> LocalData { get; set; }
|
||||||
public Login Login { get; set; }
|
public Login Login { get; set; }
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace Bit.Core.Models.Response
|
||||||
public SecureNoteApi SecureNote { get; set; }
|
public SecureNoteApi SecureNote { get; set; }
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
public bool Edit { get; set; }
|
public bool Edit { get; set; }
|
||||||
|
public bool ViewPassword { get; set; } = true; // Fallback for old server versions
|
||||||
public bool OrganizationUseTotp { get; set; }
|
public bool OrganizationUseTotp { get; set; }
|
||||||
public DateTime RevisionDate { get; set; }
|
public DateTime RevisionDate { get; set; }
|
||||||
public List<AttachmentResponse> Attachments { get; set; }
|
public List<AttachmentResponse> Attachments { get; set; }
|
||||||
|
|
|
@ -18,6 +18,7 @@ namespace Bit.Core.Models.View
|
||||||
Favorite = c.Favorite;
|
Favorite = c.Favorite;
|
||||||
OrganizationUseTotp = c.OrganizationUseTotp;
|
OrganizationUseTotp = c.OrganizationUseTotp;
|
||||||
Edit = c.Edit;
|
Edit = c.Edit;
|
||||||
|
ViewPassword = c.ViewPassword;
|
||||||
Type = c.Type;
|
Type = c.Type;
|
||||||
LocalData = c.LocalData;
|
LocalData = c.LocalData;
|
||||||
CollectionIds = c.CollectionIds;
|
CollectionIds = c.CollectionIds;
|
||||||
|
@ -34,6 +35,7 @@ namespace Bit.Core.Models.View
|
||||||
public bool Favorite { get; set; }
|
public bool Favorite { get; set; }
|
||||||
public bool OrganizationUseTotp { get; set; }
|
public bool OrganizationUseTotp { get; set; }
|
||||||
public bool Edit { get; set; }
|
public bool Edit { get; set; }
|
||||||
|
public bool ViewPassword { get; set; }
|
||||||
public Dictionary<string, object> LocalData { get; set; }
|
public Dictionary<string, object> LocalData { get; set; }
|
||||||
public LoginView Login { get; set; }
|
public LoginView Login { get; set; }
|
||||||
public IdentityView Identity { get; set; }
|
public IdentityView Identity { get; set; }
|
||||||
|
|
|
@ -16,5 +16,6 @@ namespace Bit.Core.Models.View
|
||||||
public string Value { get; set; }
|
public string Value { get; set; }
|
||||||
public FieldType Type { get; set; }
|
public FieldType Type { get; set; }
|
||||||
public string MaskedValue => Value != null ? "••••••••" : null;
|
public string MaskedValue => Value != null ? "••••••••" : null;
|
||||||
|
public bool NewField { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue