diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml
index b7876f8d..e955bda6 100644
--- a/.github/workflows/dotnet.yml
+++ b/.github/workflows/dotnet.yml
@@ -25,4 +25,40 @@ jobs:
run: dotnet test ./Src/UnitTests/CoravelUnitTests/CoravelUnitTests.csproj
- name: Integration Tests
run: dotnet test ./Src/IntegrationTests/Tests/Tests.csproj
+ build_and_tests_on_dotnet_7:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 7.0.x
+ - name: Restore dependencies
+ run: dotnet restore ./Src/All.sln
+ - name: Build
+ run: dotnet build ./Src/All.sln
+ - name: Mailer Tests
+ run: dotnet test ./Src/UnitTests/MailerUnitTests/MailerUnitTests.csproj
+ - name: Unit Tests
+ run: dotnet test ./Src/UnitTests/CoravelUnitTests/CoravelUnitTests.csproj
+ - name: Integration Tests
+ run: dotnet test ./Src/IntegrationTests/Tests/Tests.csproj
+ build_and_tests_on_dotnet_8:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v3
+ - name: Setup .NET
+ uses: actions/setup-dotnet@v3
+ with:
+ dotnet-version: 8.0.x
+ - name: Restore dependencies
+ run: dotnet restore ./Src/All.sln
+ - name: Build
+ run: dotnet build ./Src/All.sln
+ - name: Mailer Tests
+ run: dotnet test ./Src/UnitTests/MailerUnitTests/MailerUnitTests.csproj
+ - name: Unit Tests
+ run: dotnet test ./Src/UnitTests/CoravelUnitTests/CoravelUnitTests.csproj
+ - name: Integration Tests
+ run: dotnet test ./Src/IntegrationTests/Tests/Tests.csproj
diff --git a/Demo/Demo.csproj b/Demo/Demo.csproj
index 646d419e..b7b5041f 100644
--- a/Demo/Demo.csproj
+++ b/Demo/Demo.csproj
@@ -3,11 +3,12 @@
net6.0
Linux
+ True
-
+
@@ -15,8 +16,7 @@
-
-
+
diff --git a/Demo/Startup.cs b/Demo/Startup.cs
index ccd89b95..75b821d4 100644
--- a/Demo/Startup.cs
+++ b/Demo/Startup.cs
@@ -34,7 +34,8 @@ public void ConfigureServices(IServiceCollection services)
options.MinimumSameSitePolicy = SameSiteMode.None;
});
- services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
+ services.AddMvc(options => { options.EnableEndpointRouting = false; }).AddRazorRuntimeCompilation();
+ services.AddControllersWithViews();
// Coravel Scheduling
services.AddScheduler();
@@ -68,19 +69,19 @@ public void Configure(IApplicationBuilder app, IHostingEnvironment env)
else
{
app.UseExceptionHandler("/Home/Error");
- app.UseHsts();
+ // app.UseHsts();
}
- app.UseHttpsRedirection();
+ // app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
- // app.UseMvc(routes =>
- // {
- // routes.MapRoute(
- // name: "default",
- // template: "{controller=Home}/{action=Index}/{id?}");
- // });
+ app.UseMvc(routes =>
+ {
+ routes.MapRoute(
+ name: "default",
+ template: "{controller=Home}/{action=Index}/{id?}");
+ });
IEventRegistration registration = app.ApplicationServices.ConfigureEvents();
diff --git a/DocsV2/docs/Mailing/README.md b/DocsV2/docs/Mailing/README.md
index 49bffebc..c062139c 100644
--- a/DocsV2/docs/Mailing/README.md
+++ b/DocsV2/docs/Mailing/README.md
@@ -102,7 +102,8 @@ async Task SendMailCustomAsync(
MailRecipient replyTo,
IEnumerable cc,
IEnumerable bcc,
- IEnumerable attachments = null
+ IEnumerable attachments = null,
+ MailRecipient sender = null
)
{
// Custom logic for sending an email.
@@ -111,6 +112,10 @@ async Task SendMailCustomAsync(
services.AddCustomMailer(this.Configuration, SendMailCustomAsync);
```
+:::warn
+Breaking changes to this method signature are more likely than other as this is the signature that the Mailer's internals use. If a new version of the Mailer causes your code to stop compiling sucessfully, it's probably this signature that needs to be updated. Luckliy, it's usually a quick change in 1 spot.
+:::
+
### Built-In View Templates
Coravel's mailer comes with some pre-built e-mail friendly razor templates! This means you don't have to worry about
@@ -134,7 +139,7 @@ What about static content like the mail footer and logo? Coravel's got you cover
In your `appsettings.json`, you may add the following global values that will populate when using Coravel's built-in templates:
-```
+```json
"Coravel": {
"Mail": {
/* Your app's logo that will be shown at the top of your e-mails. */
@@ -195,35 +200,53 @@ You can then call various methods like `To` and `From` to configure the recipien
### From
-To specify who the sender of the email is, use the `From()` method:
+To specify who the email is from, use the `From()` method:
-`From("test@test.com")`
+```csharp
+From("test@test.com")
+```
You may also supply an instance of `Coravel.Mailer.Mail.MailRecipient` to include the address and sender name:
-`From(new MailRecipient(email, name))`
+```csharp
+From(new MailRecipient(email, name))
+```
-### Send To Recipient
+You can set a global from address by setting it in `appsettings.json`:
-Using the `To()` method, you can supply the recipient's e-mail address and name.
-
-#### Address
+```json
+ "Coravel": {
+ "Mail": {
+ "From":{
+ "Address": "global@from.com",
+ "Name": "My Company"
+ }
+ }
+ }
+```
-Using an e-mail address in a `string`:
+### To
-`To("test@test.com")`
+Using the `To()` method, you can supply the recipient's e-mail address and name.
-#### Multiple Addresses
+Or, using an e-mail address in a `string`:
-You can pass`IEnumerable` to the `To()` method.
+```csharp
+To("test@test.com")
+```
-#### MailRecipient
+You can also pass:
+- `To(IEnumerable)`
+- `To(MailRecipient)`
+- `To(IEnumerable)`
-Pass an instance of `MailRecipient` to the `To()` method.
+### Sender
-#### Multiple MailRecipients
+To specify the sender of the email (different from the `From` address), use the `Sender()` method:
-Pass an `IEnumerable` to the `To()` method.
+```csharp
+Sender("test@test.com")
+```
#### Attachments
@@ -261,18 +284,16 @@ Further methods, which all accept either `IEnumerable` or `IEnumerable 👈 Make sure it's this SDK.
- Exe
- netcoreapp3.1
True 👈 Add this too.
```
diff --git a/Samples/EFCoreSample/test.csproj b/Samples/EFCoreSample/test.csproj
index 877225ad..5da47bb0 100644
--- a/Samples/EFCoreSample/test.csproj
+++ b/Samples/EFCoreSample/test.csproj
@@ -13,7 +13,6 @@
-
diff --git a/Samples/QueueWithCancellationTokens/QueueWithCancellationTokens.csproj b/Samples/QueueWithCancellationTokens/QueueWithCancellationTokens.csproj
index d26720ab..a48099d1 100644
--- a/Samples/QueueWithCancellationTokens/QueueWithCancellationTokens.csproj
+++ b/Samples/QueueWithCancellationTokens/QueueWithCancellationTokens.csproj
@@ -6,7 +6,6 @@
-
diff --git a/Src/Coravel.Mailer/Coravel.Mailer.csproj b/Src/Coravel.Mailer/Coravel.Mailer.csproj
index b0ea54b4..5a6b8305 100644
--- a/Src/Coravel.Mailer/Coravel.Mailer.csproj
+++ b/Src/Coravel.Mailer/Coravel.Mailer.csproj
@@ -17,10 +17,17 @@
true
true
$(NoWarn);1591
+ ./readme.md
+ ./logo.png
+
+
+
+
+
diff --git a/Src/Coravel.Mailer/Mail/Interfaces/IMailer.cs b/Src/Coravel.Mailer/Mail/Interfaces/IMailer.cs
index 1cdc37b5..87c52b11 100644
--- a/Src/Coravel.Mailer/Mail/Interfaces/IMailer.cs
+++ b/Src/Coravel.Mailer/Mail/Interfaces/IMailer.cs
@@ -7,6 +7,6 @@ public interface IMailer
{
Task RenderAsync(Mailable mailable);
Task SendAsync(Mailable mailable);
- Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null);
+ Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null);
}
}
\ No newline at end of file
diff --git a/Src/Coravel.Mailer/Mail/Mailable.cs b/Src/Coravel.Mailer/Mail/Mailable.cs
index 3c7a3caa..3b8722ed 100644
--- a/Src/Coravel.Mailer/Mail/Mailable.cs
+++ b/Src/Coravel.Mailer/Mail/Mailable.cs
@@ -17,6 +17,11 @@ public class Mailable
///
private MailRecipient _from;
+ ///
+ /// The email sender.
+ ///
+ private MailRecipient _sender;
+
///
/// Recipients of the message.
///
@@ -73,6 +78,15 @@ public Mailable From(MailRecipient recipient)
public Mailable From(string email) =>
this.From(new MailRecipient(email));
+ public Mailable Sender(MailRecipient recipient)
+ {
+ this._sender = recipient;
+ return this;
+ }
+
+ public Mailable Sender(string email) =>
+ this.Sender(new MailRecipient(email));
+
public Mailable To(IEnumerable recipients)
{
this._to = recipients;
@@ -175,7 +189,8 @@ await mailer.SendAsync(
this._replyTo,
this._cc,
this._bcc,
- this._attachments
+ this._attachments,
+ sender: this._sender
).ConfigureAwait(false);
}
diff --git a/Src/Coravel.Mailer/Mail/Mailers/AssertMailer.cs b/Src/Coravel.Mailer/Mail/Mailers/AssertMailer.cs
index 86b0b039..0eeb6be9 100644
--- a/Src/Coravel.Mailer/Mail/Mailers/AssertMailer.cs
+++ b/Src/Coravel.Mailer/Mail/Mailers/AssertMailer.cs
@@ -13,6 +13,7 @@ public class Data
public string subject { get; set; }
public IEnumerable to { get; set; }
public MailRecipient from { get; set; }
+ public MailRecipient sender { get; set; }
public MailRecipient replyTo { get; set; }
public IEnumerable cc { get; set; }
public IEnumerable bcc { get; set; }
@@ -26,7 +27,7 @@ public AssertMailer(Action assertAction)
this._assertAction = assertAction;
}
- public Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ public Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments, MailRecipient sender = null)
{
this._assertAction(new Data
{
@@ -37,7 +38,8 @@ public Task SendAsync(string message, string subject, IEnumerable
replyTo = replyTo,
cc = cc,
bcc = bcc,
- attachments = attachments
+ attachments = attachments,
+ sender = sender
});
return Task.CompletedTask;
}
diff --git a/Src/Coravel.Mailer/Mail/Mailers/CustomMailer.cs b/Src/Coravel.Mailer/Mail/Mailers/CustomMailer.cs
index 7a003075..3cec413a 100644
--- a/Src/Coravel.Mailer/Mail/Mailers/CustomMailer.cs
+++ b/Src/Coravel.Mailer/Mail/Mailers/CustomMailer.cs
@@ -7,7 +7,7 @@ namespace Coravel.Mailer.Mail.Mailers
{
public class CustomMailer : IMailer
{
- public delegate Task SendAsyncFunc(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null);
+ public delegate Task SendAsyncFunc(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null);
private RazorRenderer _renderer;
private SendAsyncFunc _sendAsyncFunc;
private MailRecipient _globalFrom;
@@ -25,10 +25,10 @@ public Task RenderAsync(Mailable mailable) =>
public async Task SendAsync(Mailable mailable) =>
await mailable.SendAsync(this._renderer, this);
- public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments, MailRecipient sender = null)
{
await this._sendAsyncFunc(
- message, subject, to, this._globalFrom ?? from, replyTo, cc, bcc, attachments
+ message, subject, to, from ?? this._globalFrom, replyTo, cc, bcc, attachments, sender: sender
);
}
}
diff --git a/Src/Coravel.Mailer/Mail/Mailers/FileLogMailer.cs b/Src/Coravel.Mailer/Mail/Mailers/FileLogMailer.cs
index 3d1a1b89..5cfd6a65 100644
--- a/Src/Coravel.Mailer/Mail/Mailers/FileLogMailer.cs
+++ b/Src/Coravel.Mailer/Mail/Mailers/FileLogMailer.cs
@@ -27,9 +27,9 @@ public async Task RenderAsync(Mailable mailable)
return await mailable.RenderAsync(this._renderer, this);
}
- public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null)
+ public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
- from = this._globalFrom ?? from;
+ from = from ?? this._globalFrom;
using (var writer = File.CreateText(FilePath))
{
@@ -38,6 +38,7 @@ await writer.WriteAsync($@"
Subject: {subject}
To: {CommaSeparated(to)}
From: {DisplayAddress(from)}
+Sender: { (sender is null ? "N/A" : DisplayAddress(sender)) }
ReplyTo: {DisplayAddress(replyTo)}
Cc: {CommaSeparated(cc)}
Bcc: {CommaSeparated(bcc)}
diff --git a/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs b/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs
index 19fe6d4f..bb10c956 100644
--- a/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs
+++ b/Src/Coravel.Mailer/Mail/Mailers/SmtpMailer.cs
@@ -50,11 +50,12 @@ public async Task SendAsync(Mailable mailable)
await mailable.SendAsync(this._renderer, this);
}
- public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null)
+ public async Task SendAsync(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
var mail = new MimeMessage();
this.SetFrom(@from, mail);
+ SetSender(sender, mail);
SetRecipients(to, mail);
SetCc(cc, mail);
SetBcc(bcc, mail);
@@ -121,7 +122,17 @@ private static void SetRecipients(IEnumerable to, MimeMessage mai
private void SetFrom(MailRecipient @from, MimeMessage mail)
{
- mail.From.Add(AsMailboxAddress(this._globalFrom ?? @from));
+ mail.From.Add(AsMailboxAddress(@from ?? this._globalFrom));
+ }
+
+ private static void SetSender(MailRecipient sender, MimeMessage mail)
+ {
+ if(sender is null)
+ {
+ return;
+ }
+
+ mail.Sender = AsMailboxAddress(sender);
}
private static void SetReplyTo(MailRecipient replyTo, MimeMessage mail)
diff --git a/Src/Coravel.Mailer/logo.png b/Src/Coravel.Mailer/logo.png
new file mode 100644
index 00000000..028229b3
Binary files /dev/null and b/Src/Coravel.Mailer/logo.png differ
diff --git a/Src/Coravel.Mailer/readme.md b/Src/Coravel.Mailer/readme.md
new file mode 100644
index 00000000..9b30e87b
--- /dev/null
+++ b/Src/Coravel.Mailer/readme.md
@@ -0,0 +1,29 @@
+Coravel makes advanced application features accessible and easy-to-use by giving you a simple,
+expressive and straightforward syntax - helping developers get their .NET Core applications up-and-running fast without compromising code quality.
+
+This is the mailer specific package for Coravel.
+
+## Features:
+
+E-mails are not as easy as they should be. Luckily for you, Coravel solves this by offering:
+
+- Built-in e-mail friendly razor templates
+- Simple and flexible mailing API
+- Render your e-mails for visual testing
+- Drivers supporting SMTP, local log file or BYOM ("bring your own mailer") driver
+- Quick and simple configuration via `appsettings.json`
+- And more!
+
+## Official Documentation
+
+[You can view the official docs here.](https://docs.coravel.net/Installation/)
+
+## Coravel Pro
+
+If you are building a .NET Core application with EF Core, then you might want to look into [Coravel Pro](https://www.pro.coravel.net/). It is an admin panel & tools to make maintaining and managing your .NET Core app a breeze!
+
+- Visual job scheduling & management
+- Scaffold a CRUD UI for managing your EF Core entities
+- Easily configure a dashboard to show health metrics (or whatever you want)
+- Build custom tablular reports of your data
+- And more!
\ No newline at end of file
diff --git a/Src/IntegrationTests/TestMvcApp/appsettings.json b/Src/IntegrationTests/TestMvcApp/appsettings.json
index def9159a..13ba4530 100644
--- a/Src/IntegrationTests/TestMvcApp/appsettings.json
+++ b/Src/IntegrationTests/TestMvcApp/appsettings.json
@@ -4,5 +4,12 @@
"Default": "Warning"
}
},
- "AllowedHosts": "*"
+ "AllowedHosts": "*",
+ "Coravel": {
+ "Mail": {
+ "From":{
+ "Address": "global@from.com"
+ }
+ }
+ }
}
diff --git a/Src/UnitTests/MailerUnitTests/Mail/CustomMailerTests.cs b/Src/UnitTests/MailerUnitTests/Mail/CustomMailerTests.cs
index 3576197c..ec1e6798 100644
--- a/Src/UnitTests/MailerUnitTests/Mail/CustomMailerTests.cs
+++ b/Src/UnitTests/MailerUnitTests/Mail/CustomMailerTests.cs
@@ -15,7 +15,7 @@ public class CustomMailerTests
[Fact]
public async Task CustomMailerSucessful()
{
- async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
Assert.Equal("test", subject);
Assert.Equal("from@test.com", from.Email);
@@ -41,7 +41,7 @@ await mailer.SendAsync(
[Fact]
public async Task CustomMailer_GlobalFrom()
{
- async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
Assert.Equal("global@test.com", from.Email);
Assert.Equal("Global", from.Name);
@@ -57,7 +57,32 @@ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
+ {
+ Assert.Equal("from@test.com", from.Email);
+ Assert.Null(from.Name);
+ await Task.CompletedTask;
+ };
+
+ var mailer = new CustomMailer(
+ null, // We aren't rendering anything, so it's null.
+ SendMailCustom,
+ new MailRecipient("global@test.com", "Global")
+ );
+
+ await mailer.SendAsync(
+ new GenericHtmlMailable()
+ .Subject("test")
+ .From("from@test.com") // Should override the global from.
.To("to@test.com")
.Html("test")
);
@@ -66,7 +91,7 @@ await mailer.SendAsync(
[Fact]
public async Task CustomMailer_Render()
{
- async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
await Task.CompletedTask;
};
@@ -92,7 +117,7 @@ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments)
+ async Task SendMailCustom(string message, string subject, IEnumerable to, MailRecipient from, MailRecipient replyTo, IEnumerable cc, IEnumerable bcc, IEnumerable attachments = null, MailRecipient sender = null)
{
Assert.Equal(2, attachments.Count());
Assert.Equal("Attachment 2", attachments.Skip(1).Single().Name);