Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 4 additions & 10 deletions Core/Models/Account.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.ComponentModel;
using Upsilon.Apps.Passkey.Core.Utils;
using Upsilon.Apps.Passkey.Interfaces;
using Upsilon.Apps.Passkey.Interfaces.Enums;
using Upsilon.Apps.Passkey.Interfaces.Models;

namespace Upsilon.Apps.Passkey.Core.Models
{
Expand All @@ -19,7 +19,6 @@ string IAccount.Label
{
get => Database.Get(Label);
set => Label = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(Label),
needsReview: false,
oldValue: Label,
Expand All @@ -31,7 +30,6 @@ string[] IAccount.Identifiers
{
get => Database.Get(Identifiers);
set => Identifiers = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(Identifiers),
needsReview: true,
oldValue: Identifiers,
Expand All @@ -50,7 +48,7 @@ string IAccount.Password
Dictionary<DateTime, string> oldPasswords = Passwords.CloneWith(Database.SerializationCenter);
Passwords[DateTime.Now] = Password = value;

if (_service != null)
if (_service is not null)
{
if (Service.User.NumberOfOldPasswordToKeep != 0)
{
Expand All @@ -67,7 +65,6 @@ string IAccount.Password
}

_ = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(Password),
needsReview: true,
oldValue: oldPasswords,
Expand All @@ -84,7 +81,6 @@ string IAccount.Notes
{
get => Database.Get(Notes);
set => Notes = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(Notes),
needsReview: false,
oldValue: Notes,
Expand All @@ -96,7 +92,6 @@ int IAccount.PasswordUpdateReminderDelay
{
get => Database.Get(PasswordUpdateReminderDelay);
set => PasswordUpdateReminderDelay = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(PasswordUpdateReminderDelay),
needsReview: false,
oldValue: PasswordUpdateReminderDelay,
Expand All @@ -108,7 +103,6 @@ AccountOption IAccount.Options
{
get => Database.Get(Options);
set => Options = Database.AutoSave.UpdateValue(ItemId,
itemName: ToString(),
fieldName: nameof(Options),
needsReview: false,
oldValue: Options,
Expand Down Expand Up @@ -157,7 +151,7 @@ public void Apply(Change change)
{
switch (change.ActionType)
{
case Change.Type.Update:
case LogEventType.ItemUpdated:
switch (change.FieldName)
{
case nameof(Label):
Expand All @@ -184,7 +178,7 @@ public void Apply(Change change)
}
break;
default:
throw new InvalidEnumArgumentException(nameof(change.ActionType), (int)change.ActionType, typeof(Change.Type));
throw new InvalidEnumArgumentException(nameof(change.ActionType), (int)change.ActionType, typeof(LogEventType));
}
}

Expand Down
75 changes: 40 additions & 35 deletions Core/Models/AutoSave.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Upsilon.Apps.Passkey.Core.Utils;
using Upsilon.Apps.Passkey.Interfaces.Enums;

namespace Upsilon.Apps.Passkey.Core.Models
{
Expand All @@ -13,7 +14,6 @@ internal Database Database
public Dictionary<string, List<Change>> Changes { get; set; } = [];

internal T UpdateValue<T>(string itemId,
string itemName,
string fieldName,
bool needsReview,
T oldValue,
Expand All @@ -23,53 +23,45 @@ internal T UpdateValue<T>(string itemId,
if (Database.SerializationCenter.AreDifferent(oldValue, newValue))
{
_addChange(itemId,
itemName,
string.Empty,
fieldName,
oldValue.SerializeWith(Database.SerializationCenter),
newValue.SerializeWith(Database.SerializationCenter),
readableValue,
needsReview,
Change.Type.Update);
LogEventType.ItemUpdated);
}

return newValue;
}

internal T AddValue<T>(string itemId,
string itemName,
string containerName,
string readableValue,
bool needsReview,
T value) where T : notnull
{
_addChange(itemId, itemName, containerName, string.Empty, value.SerializeWith(Database.SerializationCenter), string.Empty, needsReview, Change.Type.Add);
_addChange(itemId, string.Empty, value.SerializeWith(Database.SerializationCenter), readableValue, needsReview, LogEventType.ItemAdded);

return value;
}

internal T DeleteValue<T>(string itemId,
string itemName,
string containerName,
string readableValue,
bool needsReview,
T value) where T : notnull
{
_addChange(itemId, itemName, containerName, string.Empty, value.SerializeWith(Database.SerializationCenter), string.Empty, needsReview, Change.Type.Delete);
_addChange(itemId, string.Empty, value.SerializeWith(Database.SerializationCenter), readableValue, needsReview, LogEventType.ItemDeleted);

return value;
}

private void _addChange(string itemId,
string itemName,
string containerName,
string fieldName,
string newValue,
string readableValue,
bool needsReview,
Change.Type action)
LogEventType action)
{
_addChange(itemId,
itemName,
containerName,
fieldName,
null,
newValue,
Expand All @@ -79,14 +71,12 @@ private void _addChange(string itemId,
}

private void _addChange(string itemId,
string itemName,
string containerName,
string fieldName,
string? oldValue,
string newValue,
string readableValue,
bool needsReview,
Change.Type action)
LogEventType action)
{
string changeKey = $"{itemId}\t{fieldName}";
if (!Changes.ContainsKey(changeKey))
Expand All @@ -106,26 +96,44 @@ private void _addChange(string itemId,

_mergeChanges(changeKey, currentChange);

if (Database.AutoSaveFileLocker == null)
Database.FileLocker.Save(this, Database.AutoSaveFileEntry, Database.Passkeys);

if (itemId == Database.User?.ItemId)
{
Database.AutoSaveFileLocker = new(Database.CryptographyCenter, Database.SerializationCenter, Database.AutoSaveFile, FileMode.OpenOrCreate);
if (Database.User is not null)
{
itemId = Database.User.ToString();
}
}
else if (itemId.StartsWith('S'))
{
Service? s = Database.User?.Services.FirstOrDefault(x => x.ItemId == itemId);

Database.AutoSaveFileLocker.Save(this, Database.Passkeys);
string logMessage = action switch
if (s is not null)
{
itemId = s.ToString();
}
}
else if (itemId.StartsWith('A'))
{
Change.Type.Add => $"{itemName} has been added to {containerName}",
Change.Type.Delete => $"{itemName} has been removed from {containerName}",
_ => $"{itemName}'s {fieldName.ToSentenceCase().ToLower()} has been {(string.IsNullOrWhiteSpace(readableValue) ? $"updated" : $"set to {readableValue}")}",
};
Database.Logs.AddLog(logMessage, needsReview);
Account? a = Database.User?.Services.SelectMany(x => x.Accounts).FirstOrDefault(x => x.ItemId == itemId);

if (a is not null)
{
itemId = a.ToString();
}
}

Database.Logs.AddLog(data: [itemId, fieldName, readableValue],
eventType: action,
needsReview);
}

private void _mergeChanges(string changeKey, Change currentChange)
{
Change? lastUpdate = Changes[changeKey].LastOrDefault(x => x.ActionType == Change.Type.Update);
Change? lastUpdate = Changes[changeKey].LastOrDefault(x => x.ActionType == LogEventType.ItemUpdated);

if (currentChange.ActionType != Change.Type.Update
if (currentChange.ActionType != LogEventType.ItemUpdated
|| lastUpdate is null)
{
Changes[changeKey].Add(currentChange);
Expand All @@ -147,7 +155,7 @@ private void _mergeChanges(string changeKey, Change currentChange)

internal void ApplyChanges(bool deleteFile)
{
List<Change> changes = Changes.Values.SelectMany(x => x).OrderBy(x => x.Index).ToList();
List<Change> changes = [.. Changes.Values.SelectMany(x => x).OrderBy(x => x.Index)];

foreach (Change change in changes)
{
Expand All @@ -170,13 +178,10 @@ internal void Clear(bool deleteFile)
{
Changes.Clear();

Database.AutoSaveFileLocker?.Dispose();
Database.AutoSaveFileLocker = null;

if (deleteFile
&& File.Exists(Database.AutoSaveFile))
&& Database.FileLocker.Exists(Database.AutoSaveFileEntry))
{
File.Delete(Database.AutoSaveFile);
Database.FileLocker.Delete(Database.AutoSaveFileEntry);
}
}
}
Expand Down
14 changes: 4 additions & 10 deletions Core/Models/Change.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
namespace Upsilon.Apps.Passkey.Core.Models
using Upsilon.Apps.Passkey.Interfaces.Enums;

namespace Upsilon.Apps.Passkey.Core.Models
{
internal sealed class Change
{
public enum Type
{
None = 0,
Update = 1,
Add = 2,
Delete = 3,
}

public long Index { get; set; } = long.MaxValue;
public Type ActionType { get; set; } = Type.None;
public LogEventType ActionType { get; set; } = LogEventType.None;
public string ItemId { get; set; } = string.Empty;
public string FieldName { get; set; } = string.Empty;
public string? OldValue { get; set; } = null;
Expand Down
Loading