save password history changes

This commit is contained in:
Kyle Spearrin 2018-07-30 16:15:36 -04:00
parent 4d08ce90cc
commit a9a33ad71e
5 changed files with 62 additions and 11 deletions

View File

@ -13,7 +13,7 @@ namespace Bit.App.Models.Api
Uris = cipher.Login.Uris?.Select(u => new LoginUriType(u));
Username = cipher.Login.Username?.EncryptedString;
Password = cipher.Login.Password?.EncryptedString;
PasswordRevisionDate = cipher.Login.PasswordRevisionDate;
Totp = cipher.Login.Totp?.EncryptedString;
}

View File

@ -20,6 +20,11 @@ namespace Bit.App.Models.Api
Fields = cipher.Fields.Select(f => new FieldType(f));
}
if(cipher.PasswordHistory != null)
{
PasswordHistory = cipher.PasswordHistory.Select(h => new PasswordHistoryRequest(h));
}
switch(Type)
{
case CipherType.Login:
@ -46,7 +51,7 @@ namespace Bit.App.Models.Api
public string Name { get; set; }
public string Notes { get; set; }
public IEnumerable<FieldType> Fields { get; set; }
public IEnumerable<PasswordHistoryResponse> PasswordHistory { get; set; }
public IEnumerable<PasswordHistoryRequest> PasswordHistory { get; set; }
public LoginType Login { get; set; }
public CardType Card { get; set; }

View File

@ -2,6 +2,12 @@
{
public class PasswordHistoryRequest
{
public PasswordHistoryRequest(PasswordHistory ph)
{
Password = ph.Password?.EncryptedString;
LastUsedDate = ph.LastUsedDate;
}
public string Password { get; set; }
public System.DateTime LastUsedDate { get; set; }
}

View File

@ -23,6 +23,8 @@ namespace Bit.App.Pages
private readonly IDeviceInfoService _deviceInfo;
private readonly IGoogleAnalyticsService _googleAnalyticsService;
private DateTime? _lastAction;
private string _originalLoginPassword = null;
private List<Tuple<string, string>> _originalHiddenFields = new List<Tuple<string, string>>();
public VaultEditCipherPage(string cipherId)
{
@ -169,7 +171,7 @@ namespace Bit.App.Pages
// Types
if(Cipher.Type == CipherType.Login)
{
LoginTotpCell = new FormEntryCell(AppResources.AuthenticatorKey,
LoginTotpCell = new FormEntryCell(AppResources.AuthenticatorKey,
button1: _deviceInfo.HasCamera ? "camera.png" : null);
LoginTotpCell.Entry.Text = Cipher.Login?.Totp?.Decrypt(Cipher.OrganizationId);
LoginTotpCell.Entry.DisableAutocapitalize = true;
@ -179,7 +181,8 @@ namespace Bit.App.Pages
LoginPasswordCell = new FormEntryCell(AppResources.Password, isPassword: true,
nextElement: LoginTotpCell.Entry, button1: "eye.png", button2: "refresh_alt.png");
LoginPasswordCell.Entry.Text = Cipher.Login?.Password?.Decrypt(Cipher.OrganizationId);
LoginPasswordCell.Entry.Text = _originalLoginPassword =
Cipher.Login?.Password?.Decrypt(Cipher.OrganizationId);
LoginPasswordCell.Entry.DisableAutocapitalize = true;
LoginPasswordCell.Entry.Autocorrect = false;
LoginPasswordCell.Entry.FontFamily =
@ -211,7 +214,7 @@ namespace Bit.App.Pages
foreach(var uri in Cipher.Login.Uris)
{
var value = uri.Uri?.Decrypt(Cipher.OrganizationId);
UrisSection.Insert(UrisSection.Count - 1,
UrisSection.Insert(UrisSection.Count - 1,
Helpers.MakeUriCell(value, uri.Match, UrisSection, this));
}
}
@ -415,6 +418,11 @@ namespace Bit.App.Pages
{
FieldsSection.Add(cell);
}
if(!string.IsNullOrWhiteSpace(label) && !string.IsNullOrWhiteSpace(value) &&
field.Type == FieldType.Hidden)
{
_originalHiddenFields.Add(new Tuple<string, string>(label, value));
}
}
}
AddFieldCell = new ExtendedTextCell
@ -491,7 +499,8 @@ namespace Bit.App.Pages
Cipher.Notes = string.IsNullOrWhiteSpace(NotesCell.Editor.Text) ? null :
NotesCell.Editor.Text.Encrypt(Cipher.OrganizationId);
Cipher.Favorite = FavoriteCell.On;
var passwordHistory = Cipher.PasswordHistory?.ToList() ?? new List<PasswordHistory>();
switch(Cipher.Type)
{
case CipherType.Login:
@ -505,6 +514,18 @@ namespace Bit.App.Pages
LoginTotpCell.Entry.Text.Encrypt(Cipher.OrganizationId),
};
if(!string.IsNullOrWhiteSpace(_originalLoginPassword) &&
LoginPasswordCell.Entry.Text != _originalLoginPassword)
{
var now = DateTime.UtcNow;
passwordHistory.Insert(0, new PasswordHistory
{
LastUsedDate = now,
Password = _originalLoginPassword.Encrypt(Cipher.OrganizationId),
});
Cipher.Login.PasswordRevisionDate = now;
}
Helpers.ProcessUrisSectionForSave(UrisSection, Cipher);
break;
case CipherType.SecureNote:
@ -639,7 +660,18 @@ namespace Bit.App.Pages
Cipher.FolderId = null;
}
Helpers.ProcessFieldsSectionForSave(FieldsSection, Cipher);
var hiddenFields = Helpers.ProcessFieldsSectionForSave(FieldsSection, Cipher);
var changedFields = _originalHiddenFields.Where(of =>
hiddenFields.Any(f => f.Item1 == of.Item1 && f.Item2 != of.Item2));
foreach(var cf in changedFields)
{
passwordHistory.Insert(0, new PasswordHistory
{
LastUsedDate = DateTime.UtcNow,
Password = (cf.Item1 + ": " + cf.Item2).Encrypt(Cipher.OrganizationId),
});
}
Cipher.PasswordHistory = (passwordHistory?.Count ?? 0) > 0 ? passwordHistory : null;
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
var saveTask = await _cipherService.SaveAsync(Cipher);
@ -714,7 +746,7 @@ namespace Bit.App.Pages
CardExpYearCell?.InitEvents();
CardNameCell?.InitEvents();
CardNumberCell?.InitEvents();
if (CardCodeCell?.Button1 != null)
if(CardCodeCell?.Button1 != null)
{
CardCodeCell.Button1.Clicked += CardCodeButton_Clicked;
}
@ -798,7 +830,7 @@ namespace Bit.App.Pages
CardExpYearCell?.Dispose();
CardNameCell?.Dispose();
CardNumberCell?.Dispose();
if (CardCodeCell?.Button1 != null)
if(CardCodeCell?.Button1 != null)
{
CardCodeCell.Button1.Clicked -= CardCodeButton_Clicked;
}
@ -826,7 +858,7 @@ namespace Bit.App.Pages
default:
break;
}
Helpers.DisposeSectionEvents(FieldsSection);
Helpers.DisposeSectionEvents(UrisSection);
}

View File

@ -331,8 +331,9 @@ namespace Bit.App.Utilities
return cell;
}
public static void ProcessFieldsSectionForSave(TableSection fieldsSection, Cipher cipher)
public static List<Tuple<string, string>> ProcessFieldsSectionForSave(TableSection fieldsSection, Cipher cipher)
{
var hiddenFieldValues = new List<Tuple<string, string>>();
if(fieldsSection != null && fieldsSection.Count > 0)
{
var fields = new List<Field>();
@ -348,6 +349,12 @@ namespace Bit.App.Utilities
entryCell.Entry.Text.Encrypt(cipher.OrganizationId),
Type = entryCell.Entry.IsPassword ? FieldType.Hidden : FieldType.Text
});
if(entryCell.Entry.IsPassword && !string.IsNullOrWhiteSpace(entryCell.Label.Text))
{
hiddenFieldValues.Add(new Tuple<string, string>(entryCell.Label.Text,
entryCell.Entry.Text));
}
}
else if(cell is FormSwitchCell switchCell)
{
@ -368,6 +375,7 @@ namespace Bit.App.Utilities
{
cipher.Fields = null;
}
return hiddenFieldValues;
}
public static FormEntryCell MakeUriCell(string value, UriMatchType? match, TableSection urisSection, Page page)