Skip to content
Closed
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
5 changes: 2 additions & 3 deletions src/Senders/FluentEmail.Graph/FluentEmail.Graph.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Graph" Version="3.22.0" />
<PackageReference Include="Microsoft.Graph.Auth" Version="1.0.0-preview.5" />
<PackageReference Include="Microsoft.Identity.Client" Version="4.25.0" />
<PackageReference Include="Microsoft.Graph" Version="5.105.0" />
<PackageReference Include="Azure.Identity" Version="1.21.0" />
</ItemGroup>

<ItemGroup>
Expand Down
33 changes: 14 additions & 19 deletions src/Senders/FluentEmail.Graph/GraphSender.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
using FluentEmail.Core;
using Azure.Identity;
using FluentEmail.Core;
using FluentEmail.Core.Interfaces;
using FluentEmail.Core.Models;
using Microsoft.Graph;
using Microsoft.Graph.Auth;
using Microsoft.Identity.Client;
using Microsoft.Graph.Models;
using Microsoft.Graph.Users.Item.SendMail;
using System;
using System.Collections.Generic;
using System.IO;
Expand All @@ -19,9 +20,7 @@ public class GraphSender : ISender
private readonly string _graphSecret;
private bool _saveSent;

private ClientCredentialProvider _authProvider;
private GraphServiceClient _graphClient;
private IConfidentialClientApplication _clientApp;

public GraphSender(
string GraphEmailAppId,
Expand All @@ -34,15 +33,8 @@ public GraphSender(
_graphSecret = GraphEmailSecret;
_saveSent = SaveSentItems;

_clientApp = ConfidentialClientApplicationBuilder
.Create(_appId)
.WithTenantId(_tenantId)
.WithClientSecret(_graphSecret)
.Build();

_authProvider = new ClientCredentialProvider(_clientApp);

_graphClient = new GraphServiceClient(_authProvider);
var credential = new ClientSecretCredential(_tenantId, _appId, _graphSecret);
_graphClient = new GraphServiceClient(credential);
}

public SendResponse Send(IFluentEmail email, CancellationToken? token = null)
Expand Down Expand Up @@ -77,7 +69,7 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
email.Data.ToAddresses.ForEach(r => toRecipients.Add(new Recipient
{
EmailAddress = new EmailAddress
{
{
Address = r.EmailAddress.ToString(),
Name = r.Name
}
Expand Down Expand Up @@ -120,7 +112,7 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?

if(email.Data.Attachments != null && email.Data.Attachments.Count > 0)
{
message.Attachments = new MessageAttachmentsCollectionPage();
message.Attachments = new List<Microsoft.Graph.Models.Attachment>();

email.Data.Attachments.ForEach(a =>
{
Expand Down Expand Up @@ -154,9 +146,12 @@ public async Task<SendResponse> SendAsync(IFluentEmail email, CancellationToken?
try
{
await _graphClient.Users[email.Data.FromAddress.EmailAddress]
.SendMail(message, _saveSent)
.Request()
.PostAsync();
.SendMail
.PostAsync(new SendMailPostRequestBody
{
Message = message,
SaveToSentItems = _saveSent
}, cancellationToken: token ?? CancellationToken.None);

return new SendResponse
{
Expand Down
6 changes: 4 additions & 2 deletions src/Senders/FluentEmail.MailKit/MailKitSender.cs
Original file line number Diff line number Diff line change
Expand Up @@ -181,11 +181,13 @@ private async Task SaveToPickupDirectory(MimeMessage message, string pickupDirec
}

/// <summary>
/// Create a MimMessage so MailKit can send it
/// Create a MimeMessage so MailKit can send it.
/// Virtual so subclasses can preprocess the message before sending
/// (e.g. DKIM-sign it) — see https://github.com/lukencode/FluentEmail/issues/388
/// </summary>
/// <returns>The mail message.</returns>
/// <param name="email">Email data.</param>
private MimeMessage CreateMailMessage(IFluentEmail email)
protected virtual MimeMessage CreateMailMessage(IFluentEmail email)
{
var data = email.Data;

Expand Down
48 changes: 48 additions & 0 deletions test/FluentEmail.Core.Tests/MailKitSmtpSenderTests.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using FluentEmail.Core;
using FluentEmail.Core.Interfaces;
using FluentEmail.MailKitSmtp;
using MimeKit;
using NUnit.Framework;
using Attachment = FluentEmail.Core.Models.Attachment;

Expand Down Expand Up @@ -119,5 +122,50 @@ public void CanSendHtmlAndPlaintextTogether()

Assert.IsTrue(response.Successful);
}

[Test]
public void CanPreprocessMessageByOverridingCreateMailMessage()
{
var sender = new PreprocessingMailKitSender(new SmtpClientOptions
{
Server = "localhost",
Port = 25,
UseSsl = false,
RequiresAuthentication = false,
UsePickupDirectory = true,
MailPickupDirectory = tempDirectory
});
Email.DefaultSender = sender;

var email = Email
.From(fromEmail)
.To(toEmail)
.Subject(subject)
.Body(body);

var response = email.Send();

Assert.IsTrue(response.Successful);
var eml = Directory.EnumerateFiles(tempDirectory, "*.eml").First();
var content = File.ReadAllText(eml);
Assert.IsTrue(content.Contains("X-Preprocessed: yes"),
"Override of CreateMailMessage should be able to modify the message before sending.");
}

/// <summary>
/// Simulates e.g. DKIM-signing: preprocess the MimeMessage after creation.
/// Possible since CreateMailMessage is protected virtual (issue #388).
/// </summary>
private class PreprocessingMailKitSender : MailKitSender
{
public PreprocessingMailKitSender(SmtpClientOptions options) : base(options) { }

protected override MimeMessage CreateMailMessage(IFluentEmail email)
{
var message = base.CreateMailMessage(email);
message.Headers.Add("X-Preprocessed", "yes");
return message;
}
}
}
}