Full trust Wino Server implementation. (#295)

* Separation of messages. Introducing Wino.Messages library.

* Wino.Server and Wino.Packaging projects. Enabling full trust for UWP and app service connection manager basics.

* Remove debug code.

* Enable generating assembly info to deal with unsupported os platform warnings.

* Fix server-client connection.

* UIMessage communication. Single instancing for server and re-connection mechanism on suspension.

* Removed IWinoSynchronizerFactory from UWP project.

* Removal of background task service from core.

* Delegating changes to UI and triggering new background synchronization.

* Fix build error.

* Moved core lib messages to Messaging project.

* Better client-server communication. Handling of requests in the server. New synchronizer factory in the server.

* WAM broker and MSAL token caching for OutlookAuthenticator. Handling account creation for Outlook.

* WinoServerResponse basics.

* Delegating protocol activation for Gmail authenticator.

* Adding margin to searchbox to match action bar width.

* Move libraries into lib folder.

* Storing base64 encoded mime on draft creation instead of MimeMessage object. Fixes serialization/deserialization issue with S.T.Json

* Scrollbar adjustments

* WınoExpander for thread expander layout ıssue.

* Handling synchronizer state changes.

* Double init on background activation.

* FIxing packaging issues and new Wino Mail launcher protocol for activation from full thrust process.

* Remove debug deserialization.

* Remove debug code.

* Making sure the server connection is established when the app is launched.

* Thrust -> Trust string replacement...

* Rename package to Wino Mail

* Enable translated values in the server.

* Fixed an issue where toast activation can't find the clicked mail after the folder is initialized.

* Revert debug code.

* Change server background sync to every 3 minute and Inbox only synchronization.

* Revert google auth changes.

* App preferences page.

* Changing tray icon visibility on preference change.

* Start the server with invisible tray icon if set to invisible.

* Reconnect button on the title bar.

* Handling of toast actions.

* Enable x86 build for server during packaging.

* Get rid of old background tasks and v180 migration.

* Terminate client when Exit clicked in server.

* Introducing SynchronizationSource to prevent notifying UI after server tick synchronization.

* Remove confirmAppClose restricted capability and unused debug code in manifest.

* Closing the reconnect info popup when reconnect is clicked.

* Custom RetryHandler for OutlookSynchronizer and separating client/server logs.

* Running server on Windows startup.

* Fix startup exe.

* Fix for expander list view item paddings.

* Force full sync on app launch instead of Inbox.

* Fix draft creation.

* Fix an issue with custom folder sync logic.

* Reporting back account sync progress from server.

* Fix sending drafts and missing notifications for imap.

* Changing imap folder sync requirements.

* Retain file  count is set to 3.

* Disabled swipe gestures temporarily due to native crash
 with SwipeControl

* Save all attachments implementation.

* Localization for save all attachments button.

* Fix logging dates for logs.

* Fixing ARM64 build.

* Add ARM64 build config to packaging project.

* Comment out OutOfProcPDB for ARM64.

* Hnadling GONE response for Outlook folder synchronization.
This commit is contained in:
Burak Kaan Köse
2024-08-05 00:36:26 +02:00
committed by GitHub
parent 4dc225184d
commit ff77b2b3dc
275 changed files with 4986 additions and 2381 deletions

View File

@@ -1,5 +1,6 @@
using System.Collections.Specialized;
using System.Linq;
using System.Text.Json.Serialization;
using MimeKit;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Enums;
@@ -8,6 +9,7 @@ namespace Wino.Core.Domain.Models.MailItem
{
public class DraftCreationOptions
{
[JsonIgnore]
public MimeMessage ReferenceMimeMessage { get; set; }
public MailCopy ReferenceMailCopy { get; set; }
public DraftCreationReason Reason { get; set; }

View File

@@ -1,23 +1,49 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json.Serialization;
using MimeKit;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Extensions;
namespace Wino.Core.Domain.Models.MailItem
{
public class DraftPreperationRequest : DraftCreationOptions
{
public DraftPreperationRequest(MailAccount account, MailCopy createdLocalDraftCopy, MimeMessage createdLocalDraftMimeMessage)
public DraftPreperationRequest(MailAccount account, MailCopy createdLocalDraftCopy, string base64EncodedMimeMessage)
{
Account = account ?? throw new ArgumentNullException(nameof(account));
CreatedLocalDraftCopy = createdLocalDraftCopy ?? throw new ArgumentNullException(nameof(createdLocalDraftCopy));
CreatedLocalDraftMimeMessage = createdLocalDraftMimeMessage ?? throw new ArgumentNullException(nameof(createdLocalDraftMimeMessage));
// MimeMessage is not serializable with System.Text.Json. Convert to base64 string.
// This is additional work when deserialization needed, but not much to do atm.
Base64LocalDraftMimeMessage = base64EncodedMimeMessage;
}
[JsonConstructor]
private DraftPreperationRequest() { }
public MailCopy CreatedLocalDraftCopy { get; set; }
public MimeMessage CreatedLocalDraftMimeMessage { get; set; }
public string Base64LocalDraftMimeMessage { get; set; }
[JsonIgnore]
private MimeMessage createdLocalDraftMimeMessage;
[JsonIgnore]
public MimeMessage CreatedLocalDraftMimeMessage
{
get
{
if (createdLocalDraftMimeMessage == null)
{
createdLocalDraftMimeMessage = Base64LocalDraftMimeMessage.GetMimeMessageFromBase64();
}
return createdLocalDraftMimeMessage;
}
}
public MailAccount Account { get; }
}
}

View File

@@ -1,7 +1,49 @@
using MimeKit;
using System.Text.Json.Serialization;
using MimeKit;
using Wino.Core.Domain.Entities;
using Wino.Core.Domain.Extensions;
namespace Wino.Core.Domain.Models.MailItem
{
public record SendDraftPreparationRequest(MailCopy MailItem, MimeMessage Mime, MailItemFolder DraftFolder, MailItemFolder SentFolder, MailAccountPreferences AccountPreferences);
public class SendDraftPreparationRequest
{
public MailCopy MailItem { get; set; }
public string Base64MimeMessage { get; set; }
public MailItemFolder SentFolder { get; set; }
public MailItemFolder DraftFolder { get; set; }
public MailAccountPreferences AccountPreferences { get; set; }
public SendDraftPreparationRequest(MailCopy mailItem,
MailItemFolder sentFolder,
MailItemFolder draftFolder,
MailAccountPreferences accountPreferences,
string base64MimeMessage)
{
MailItem = mailItem;
SentFolder = sentFolder;
DraftFolder = draftFolder;
AccountPreferences = accountPreferences;
Base64MimeMessage = base64MimeMessage;
}
[JsonConstructor]
private SendDraftPreparationRequest() { }
[JsonIgnore]
private MimeMessage mime;
[JsonIgnore]
public MimeMessage Mime
{
get
{
if (mime == null)
{
mime = Base64MimeMessage.GetMimeMessageFromBase64();
}
return mime;
}
}
}
}

View File

@@ -1,8 +1,7 @@
using System;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.MailItem;
namespace Wino.Core.Domain.Models.Requests
namespace Wino.Core.Domain.Models.MailItem
{
/// <summary>
/// Defines a single rule for toggling user actions if needed.

View File

@@ -0,0 +1,16 @@
using Newtonsoft.Json;
namespace Wino.Core.Domain.Models.Reader
{
/// <summary>
/// Used to pass messages from the webview to the app.
/// </summary>
public class WebViewMessage
{
[JsonProperty("type")]
public string Type { get; set; }
[JsonProperty("value")]
public string Value { get; set; }
}
}

View File

@@ -1,10 +0,0 @@
namespace Wino.Core.Domain.Models.Requests
{
/// <summary>
/// Interface for all messages to report UI changes from synchronizers to UI.
/// None of these messages can't run a code that manipulates database.
/// They are sent either from processor or view models to signal some other
/// parts of the application.
/// </summary>
public interface IUIMessage;
}

View File

@@ -0,0 +1,18 @@
using System;
using Wino.Core.Domain.Interfaces;
namespace Wino.Core.Domain.Models.Requests
{
/// <summary>
/// Encapsulates request to queue and account for synchronizer.
/// </summary>
/// <param name="AccountId"><inheritdoc/></param>
/// <param name="Request"></param>
/// <param name="Request">Prepared request for the server.</param>
/// <param name="AccountId">Whihc account to execute this request for.</param>
public record ServerRequestPackage(Guid AccountId, IRequestBase Request) : IClientMessage
{
public override string ToString() => $"Server Package: {Request.GetType().Name}";
}
}

View File

@@ -1,9 +0,0 @@
namespace Wino.Core.Domain.Models.Requests
{
// Used to pass messages from the webview to the app.
public class WebViewMessage
{
public string type { get; set; }
public string value { get; set; }
}
}

View File

@@ -0,0 +1,42 @@
using Wino.Core.Domain.Exceptions;
namespace Wino.Core.Domain.Models.Server
{
/// <summary>
/// Encapsulates responses from the Wino server.
/// Exceptions are stored separately in the Message and StackTrace properties due to serialization issues.
/// </summary>
/// <typeparam name="T">Type of the expected response.</typeparam>
public class WinoServerResponse<T>
{
public bool IsSuccess { get; set; }
public string Message { get; set; }
public T Data { get; set; }
// protected WinoServerResponse() { }
public static WinoServerResponse<T> CreateSuccessResponse(T data)
{
return new WinoServerResponse<T>
{
IsSuccess = true,
Data = data
};
}
public static WinoServerResponse<T> CreateErrorResponse(string message)
{
return new WinoServerResponse<T>
{
IsSuccess = false,
Message = message
};
}
public void ThrowIfFailed()
{
if (!IsSuccess)
throw new WinoServerException(Message);
}
}
}

View File

@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
namespace Wino.Core.Domain.Models.Synchronization
{
@@ -27,11 +26,6 @@ namespace Wino.Core.Domain.Models.Synchronization
/// </summary>
public List<Guid> SynchronizationFolderIds { get; set; }
/// <summary>
/// A listener to be notified about the progress of the synchronization.
/// </summary>
public ISynchronizationProgress ProgressListener { get; set; }
/// <summary>
/// When doing a linked inbox synchronization, we must ignore reporting completion to the caller for each folder.
/// This Id will help tracking that. Id is unique, but this one can be the same for all sync requests

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.MailItem;
@@ -6,8 +7,14 @@ namespace Wino.Core.Domain.Models.Synchronization
{
public class SynchronizationResult
{
protected SynchronizationResult() { }
public SynchronizationResult() { }
/// <summary>
/// Gets the new downloaded messages from synchronization.
/// Server will create notifications for these messages.
/// It's ignored in serialization. Client should not react to this.
/// </summary>
[JsonIgnore]
public IEnumerable<IMailItem> DownloadedMessages { get; set; } = new List<IMailItem>();
public SynchronizationCompletedState CompletedState { get; set; }