mirror of
https://github.com/bitwarden/mobile.git
synced 2024-12-25 16:47:55 +01:00
save password history changes
This commit is contained in:
parent
4d08ce90cc
commit
a9a33ad71e
@ -13,7 +13,7 @@ namespace Bit.App.Models.Api
|
|||||||
Uris = cipher.Login.Uris?.Select(u => new LoginUriType(u));
|
Uris = cipher.Login.Uris?.Select(u => new LoginUriType(u));
|
||||||
Username = cipher.Login.Username?.EncryptedString;
|
Username = cipher.Login.Username?.EncryptedString;
|
||||||
Password = cipher.Login.Password?.EncryptedString;
|
Password = cipher.Login.Password?.EncryptedString;
|
||||||
|
PasswordRevisionDate = cipher.Login.PasswordRevisionDate;
|
||||||
Totp = cipher.Login.Totp?.EncryptedString;
|
Totp = cipher.Login.Totp?.EncryptedString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,11 @@ namespace Bit.App.Models.Api
|
|||||||
Fields = cipher.Fields.Select(f => new FieldType(f));
|
Fields = cipher.Fields.Select(f => new FieldType(f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(cipher.PasswordHistory != null)
|
||||||
|
{
|
||||||
|
PasswordHistory = cipher.PasswordHistory.Select(h => new PasswordHistoryRequest(h));
|
||||||
|
}
|
||||||
|
|
||||||
switch(Type)
|
switch(Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
@ -46,7 +51,7 @@ namespace Bit.App.Models.Api
|
|||||||
public string Name { get; set; }
|
public string Name { get; set; }
|
||||||
public string Notes { get; set; }
|
public string Notes { get; set; }
|
||||||
public IEnumerable<FieldType> Fields { 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 LoginType Login { get; set; }
|
||||||
public CardType Card { get; set; }
|
public CardType Card { get; set; }
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
{
|
{
|
||||||
public class PasswordHistoryRequest
|
public class PasswordHistoryRequest
|
||||||
{
|
{
|
||||||
|
public PasswordHistoryRequest(PasswordHistory ph)
|
||||||
|
{
|
||||||
|
Password = ph.Password?.EncryptedString;
|
||||||
|
LastUsedDate = ph.LastUsedDate;
|
||||||
|
}
|
||||||
|
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public System.DateTime LastUsedDate { get; set; }
|
public System.DateTime LastUsedDate { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@ namespace Bit.App.Pages
|
|||||||
private readonly IDeviceInfoService _deviceInfo;
|
private readonly IDeviceInfoService _deviceInfo;
|
||||||
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
private readonly IGoogleAnalyticsService _googleAnalyticsService;
|
||||||
private DateTime? _lastAction;
|
private DateTime? _lastAction;
|
||||||
|
private string _originalLoginPassword = null;
|
||||||
|
private List<Tuple<string, string>> _originalHiddenFields = new List<Tuple<string, string>>();
|
||||||
|
|
||||||
public VaultEditCipherPage(string cipherId)
|
public VaultEditCipherPage(string cipherId)
|
||||||
{
|
{
|
||||||
@ -179,7 +181,8 @@ namespace Bit.App.Pages
|
|||||||
|
|
||||||
LoginPasswordCell = new FormEntryCell(AppResources.Password, isPassword: true,
|
LoginPasswordCell = new FormEntryCell(AppResources.Password, isPassword: true,
|
||||||
nextElement: LoginTotpCell.Entry, button1: "eye.png", button2: "refresh_alt.png");
|
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.DisableAutocapitalize = true;
|
||||||
LoginPasswordCell.Entry.Autocorrect = false;
|
LoginPasswordCell.Entry.Autocorrect = false;
|
||||||
LoginPasswordCell.Entry.FontFamily =
|
LoginPasswordCell.Entry.FontFamily =
|
||||||
@ -415,6 +418,11 @@ namespace Bit.App.Pages
|
|||||||
{
|
{
|
||||||
FieldsSection.Add(cell);
|
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
|
AddFieldCell = new ExtendedTextCell
|
||||||
@ -492,6 +500,7 @@ namespace Bit.App.Pages
|
|||||||
NotesCell.Editor.Text.Encrypt(Cipher.OrganizationId);
|
NotesCell.Editor.Text.Encrypt(Cipher.OrganizationId);
|
||||||
Cipher.Favorite = FavoriteCell.On;
|
Cipher.Favorite = FavoriteCell.On;
|
||||||
|
|
||||||
|
var passwordHistory = Cipher.PasswordHistory?.ToList() ?? new List<PasswordHistory>();
|
||||||
switch(Cipher.Type)
|
switch(Cipher.Type)
|
||||||
{
|
{
|
||||||
case CipherType.Login:
|
case CipherType.Login:
|
||||||
@ -505,6 +514,18 @@ namespace Bit.App.Pages
|
|||||||
LoginTotpCell.Entry.Text.Encrypt(Cipher.OrganizationId),
|
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);
|
Helpers.ProcessUrisSectionForSave(UrisSection, Cipher);
|
||||||
break;
|
break;
|
||||||
case CipherType.SecureNote:
|
case CipherType.SecureNote:
|
||||||
@ -639,7 +660,18 @@ namespace Bit.App.Pages
|
|||||||
Cipher.FolderId = null;
|
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);
|
await _deviceActionService.ShowLoadingAsync(AppResources.Saving);
|
||||||
var saveTask = await _cipherService.SaveAsync(Cipher);
|
var saveTask = await _cipherService.SaveAsync(Cipher);
|
||||||
@ -714,7 +746,7 @@ namespace Bit.App.Pages
|
|||||||
CardExpYearCell?.InitEvents();
|
CardExpYearCell?.InitEvents();
|
||||||
CardNameCell?.InitEvents();
|
CardNameCell?.InitEvents();
|
||||||
CardNumberCell?.InitEvents();
|
CardNumberCell?.InitEvents();
|
||||||
if (CardCodeCell?.Button1 != null)
|
if(CardCodeCell?.Button1 != null)
|
||||||
{
|
{
|
||||||
CardCodeCell.Button1.Clicked += CardCodeButton_Clicked;
|
CardCodeCell.Button1.Clicked += CardCodeButton_Clicked;
|
||||||
}
|
}
|
||||||
@ -798,7 +830,7 @@ namespace Bit.App.Pages
|
|||||||
CardExpYearCell?.Dispose();
|
CardExpYearCell?.Dispose();
|
||||||
CardNameCell?.Dispose();
|
CardNameCell?.Dispose();
|
||||||
CardNumberCell?.Dispose();
|
CardNumberCell?.Dispose();
|
||||||
if (CardCodeCell?.Button1 != null)
|
if(CardCodeCell?.Button1 != null)
|
||||||
{
|
{
|
||||||
CardCodeCell.Button1.Clicked -= CardCodeButton_Clicked;
|
CardCodeCell.Button1.Clicked -= CardCodeButton_Clicked;
|
||||||
}
|
}
|
||||||
|
@ -331,8 +331,9 @@ namespace Bit.App.Utilities
|
|||||||
return cell;
|
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)
|
if(fieldsSection != null && fieldsSection.Count > 0)
|
||||||
{
|
{
|
||||||
var fields = new List<Field>();
|
var fields = new List<Field>();
|
||||||
@ -348,6 +349,12 @@ namespace Bit.App.Utilities
|
|||||||
entryCell.Entry.Text.Encrypt(cipher.OrganizationId),
|
entryCell.Entry.Text.Encrypt(cipher.OrganizationId),
|
||||||
Type = entryCell.Entry.IsPassword ? FieldType.Hidden : FieldType.Text
|
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)
|
else if(cell is FormSwitchCell switchCell)
|
||||||
{
|
{
|
||||||
@ -368,6 +375,7 @@ namespace Bit.App.Utilities
|
|||||||
{
|
{
|
||||||
cipher.Fields = null;
|
cipher.Fields = null;
|
||||||
}
|
}
|
||||||
|
return hiddenFieldValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FormEntryCell MakeUriCell(string value, UriMatchType? match, TableSection urisSection, Page page)
|
public static FormEntryCell MakeUriCell(string value, UriMatchType? match, TableSection urisSection, Page page)
|
||||||
|
Loading…
Reference in New Issue
Block a user