Improve alias capability model and Outlook alias sync
This commit is contained in:
@@ -128,6 +128,10 @@ public static class GoogleIntegratorExtensions
|
||||
ReplyToAddress = a.ReplyToAddress,
|
||||
AliasSenderName = a.DisplayName,
|
||||
IsVerified = a.VerificationStatus == "accepted" || a.IsDefault.GetValueOrDefault(),
|
||||
Source = AliasSource.ProviderDiscovered,
|
||||
SendCapability = a.VerificationStatus == "accepted" || a.IsDefault.GetValueOrDefault()
|
||||
? AliasSendCapability.Confirmed
|
||||
: AliasSendCapability.Unknown,
|
||||
}).ToList();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@ public interface IDefaultChangeProcessor
|
||||
Task<bool> MapLocalDraftAsync(Guid accountId, Guid localDraftCopyUniqueId, string newMailCopyId, string newDraftId, string newThreadId);
|
||||
Task UpdateFolderLastSyncDateAsync(Guid folderId);
|
||||
Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases);
|
||||
Task UpdateAliasSendCapabilityAsync(Guid accountId, string aliasAddress, AliasSendCapability capability);
|
||||
// Calendar
|
||||
Task<List<AccountCalendar>> GetAccountCalendarsAsync(Guid accountId);
|
||||
|
||||
@@ -200,6 +201,9 @@ public class DefaultChangeProcessor(IDatabaseService databaseService,
|
||||
public Task UpdateRemoteAliasInformationAsync(MailAccount account, List<RemoteAccountAlias> remoteAccountAliases)
|
||||
=> AccountService.UpdateRemoteAliasInformationAsync(account, remoteAccountAliases);
|
||||
|
||||
public Task UpdateAliasSendCapabilityAsync(Guid accountId, string aliasAddress, AliasSendCapability capability)
|
||||
=> AccountService.UpdateAliasSendCapabilityAsync(accountId, aliasAddress, capability);
|
||||
|
||||
public Task<List<AccountCalendar>> GetAccountCalendarsAsync(Guid accountId)
|
||||
=> CalendarService.GetAccountCalendarsAsync(accountId);
|
||||
|
||||
|
||||
@@ -1405,6 +1405,69 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
return new ProfileInformation(displayNameAndAddress.Item1, profilePictureData, displayNameAndAddress.Item2);
|
||||
}
|
||||
|
||||
protected override async Task SynchronizeAliasesAsync()
|
||||
{
|
||||
var userInfo = await _graphClient.Me.GetAsync((config) =>
|
||||
{
|
||||
config.QueryParameters.Select = ["mail", "proxyAddresses"];
|
||||
}).ConfigureAwait(false);
|
||||
|
||||
var remoteAliases = GetRemoteAliases(userInfo);
|
||||
await _outlookChangeProcessor.UpdateRemoteAliasInformationAsync(Account, remoteAliases).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private List<RemoteAccountAlias> GetRemoteAliases(User userInfo)
|
||||
{
|
||||
var aliases = new Dictionary<string, RemoteAccountAlias>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
void AddAlias(string address)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(address))
|
||||
return;
|
||||
|
||||
var normalizedAddress = address.Trim();
|
||||
var isAccountAddress = normalizedAddress.Equals(Account.Address, StringComparison.OrdinalIgnoreCase);
|
||||
var capability = isAccountAddress ? AliasSendCapability.Confirmed : AliasSendCapability.Unknown;
|
||||
|
||||
if (aliases.TryGetValue(normalizedAddress, out var existingAlias))
|
||||
{
|
||||
existingAlias.IsPrimary |= isAccountAddress;
|
||||
existingAlias.IsRootAlias |= isAccountAddress;
|
||||
|
||||
if (capability == AliasSendCapability.Confirmed)
|
||||
existingAlias.SendCapability = AliasSendCapability.Confirmed;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
aliases[normalizedAddress] = new RemoteAccountAlias
|
||||
{
|
||||
AliasAddress = normalizedAddress,
|
||||
ReplyToAddress = normalizedAddress,
|
||||
IsPrimary = isAccountAddress,
|
||||
IsRootAlias = isAccountAddress,
|
||||
IsVerified = capability == AliasSendCapability.Confirmed,
|
||||
Source = AliasSource.ProviderDiscovered,
|
||||
SendCapability = capability
|
||||
};
|
||||
}
|
||||
|
||||
AddAlias(userInfo?.Mail);
|
||||
|
||||
foreach (var proxyAddress in userInfo?.ProxyAddresses ?? [])
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(proxyAddress) ||
|
||||
!proxyAddress.StartsWith("smtp:", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
AddAlias(proxyAddress["smtp:".Length..]);
|
||||
}
|
||||
|
||||
return aliases.Values.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// POST requests are handled differently in batches in Graph SDK.
|
||||
/// Batch basically ignores the step's coontent-type and body.
|
||||
@@ -1959,6 +2022,16 @@ public class OutlookSynchronizer : WinoSynchronizer<RequestInformation, Message,
|
||||
var errorJson = JsonNode.Parse(content);
|
||||
var errorCode = errorJson["error"]["code"].GetValue<string>();
|
||||
var errorMessage = errorJson["error"]["message"].GetValue<string>();
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.Forbidden &&
|
||||
string.Equals(errorCode, "ErrorSendAsDenied", StringComparison.OrdinalIgnoreCase) &&
|
||||
bundle?.UIChangeRequest is SendDraftRequest sendDraftRequest)
|
||||
{
|
||||
var sendingAlias = sendDraftRequest.Request.SendingAlias?.AliasAddress ?? Account.Address;
|
||||
await _outlookChangeProcessor.UpdateAliasSendCapabilityAsync(Account.Id, sendingAlias, AliasSendCapability.Denied).ConfigureAwait(false);
|
||||
errorMessage = string.Format(Translator.Exception_AliasSendDenied_Message, sendingAlias);
|
||||
}
|
||||
|
||||
var errorString = $"[{response.StatusCode}] {errorCode} - {errorMessage}\n";
|
||||
|
||||
// Create error context
|
||||
|
||||
Reference in New Issue
Block a user