diff --git a/Directory.Packages.props b/Directory.Packages.props
index 0f31e32..806b335 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -8,6 +8,7 @@
+
diff --git a/src/AppServices/AppServices.csproj b/src/AppServices/AppServices.csproj
index abb3a5a..7813edf 100644
--- a/src/AppServices/AppServices.csproj
+++ b/src/AppServices/AppServices.csproj
@@ -11,6 +11,7 @@
+
@@ -22,7 +23,6 @@
-
diff --git a/src/AppServices/Notifications/NotificationService.cs b/src/AppServices/Notifications/NotificationService.cs
index 3c99644..e204d44 100644
--- a/src/AppServices/Notifications/NotificationService.cs
+++ b/src/AppServices/Notifications/NotificationService.cs
@@ -1,5 +1,5 @@
using GaEpd.EmailService;
-using GaEpd.EmailService.Repository;
+using GaEpd.EmailService.EmailLogRepository;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using MyApp.AppServices.ErrorLogging;
@@ -39,7 +39,7 @@ public async Task SendNotificationAsync(Template template, s
Message message;
try
{
- message = Message.Create(subject, recipientEmail, settings.DefaultSender, textBody, htmlBody);
+ message = Message.Create(subject, recipientEmail, textBody, htmlBody);
}
catch (Exception e)
{
@@ -47,7 +47,7 @@ public async Task SendNotificationAsync(Template template, s
return NotificationResult.FailureResult($"{FailurePrefix} An error occurred when generating the email.");
}
- if (settings.SaveEmail) await repository.InsertAsync(EmailLog.Create(message), token).ConfigureAwait(false);
+ if (settings.EnableEmailLog) await repository.InsertAsync(message, token).ConfigureAwait(false);
if (settings is { EnableEmail: false, EnableEmailAuditing: false })
{
@@ -56,7 +56,7 @@ public async Task SendNotificationAsync(Template template, s
try
{
- await emailService.SendEmailAsync(message, settings, token).ConfigureAwait(false);
+ _ = emailService.SendEmailAsync(message, token).ConfigureAwait(false);
}
catch (Exception e)
{
diff --git a/src/AppServices/RegisterServices/AutoMapperProfiles.cs b/src/AppServices/RegisterServices/AutoMapperProfiles.cs
index a14fa6a..14c9142 100644
--- a/src/AppServices/RegisterServices/AutoMapperProfiles.cs
+++ b/src/AppServices/RegisterServices/AutoMapperProfiles.cs
@@ -5,9 +5,7 @@ namespace MyApp.AppServices.RegisterServices;
public static class AutoMapperProfiles
{
- public static void AddAutoMapperProfiles(this IServiceCollection services)
- {
- // Add AutoMapper profiles
+ // Add AutoMapper profiles
+ public static IServiceCollection AddAutoMapperProfiles(this IServiceCollection services) =>
services.AddAutoMapper(expression => expression.AddProfile());
- }
}
diff --git a/src/AppServices/RegisterServices/RegisterAppServices.cs b/src/AppServices/RegisterServices/RegisterAppServices.cs
index d4fbd0e..2ce28d3 100644
--- a/src/AppServices/RegisterServices/RegisterAppServices.cs
+++ b/src/AppServices/RegisterServices/RegisterAppServices.cs
@@ -14,7 +14,7 @@ namespace MyApp.AppServices.RegisterServices;
public static class RegisterAppServices
{
- public static void AddAppServices(this IServiceCollection services)
+ public static IServiceCollection AddAppServices(this IServiceCollection services)
{
// Work Entries
services.AddScoped();
@@ -27,8 +27,7 @@ public static void AddAppServices(this IServiceCollection services)
services.AddScoped();
services.AddScoped();
- // Email
- services.AddTransient();
+ // Notifications
services.AddScoped();
// Offices
@@ -37,5 +36,7 @@ public static void AddAppServices(this IServiceCollection services)
// Data Export
services.AddScoped();
+
+ return services;
}
}
diff --git a/src/AppServices/RegisterServices/Validators.cs b/src/AppServices/RegisterServices/Validators.cs
index c75bd03..4732837 100644
--- a/src/AppServices/RegisterServices/Validators.cs
+++ b/src/AppServices/RegisterServices/Validators.cs
@@ -6,6 +6,6 @@ namespace MyApp.AppServices.RegisterServices;
public static class Validators
{
// Add all validators
- public static void AddValidators(this IServiceCollection services) =>
+ public static IServiceCollection AddValidators(this IServiceCollection services) =>
services.AddValidatorsFromAssemblyContaining(typeof(Validators));
}
diff --git a/src/EfRepository/DbContext/AppDbContext.cs b/src/EfRepository/DbContext/AppDbContext.cs
index 7cc33f1..f05b445 100644
--- a/src/EfRepository/DbContext/AppDbContext.cs
+++ b/src/EfRepository/DbContext/AppDbContext.cs
@@ -1,4 +1,4 @@
-using GaEpd.EmailService.Repository;
+using GaEpd.EmailService.EmailLogRepository;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using MyApp.Domain.Entities.EntryActions;
diff --git a/src/EfRepository/Repositories/EmailLogRepository.cs b/src/EfRepository/Repositories/EmailLogRepository.cs
index da9334b..10fe66c 100644
--- a/src/EfRepository/Repositories/EmailLogRepository.cs
+++ b/src/EfRepository/Repositories/EmailLogRepository.cs
@@ -1,12 +1,19 @@
-using GaEpd.EmailService.Repository;
+using GaEpd.EmailService;
+using GaEpd.EmailService.EmailLogRepository;
+using Microsoft.Extensions.Configuration;
using MyApp.EfRepository.DbContext;
namespace MyApp.EfRepository.Repositories;
-public sealed class EmailLogRepository(AppDbContext dbContext) : IEmailLogRepository
+public sealed class EmailLogRepository(AppDbContext dbContext, IConfiguration configuration) : IEmailLogRepository
{
- public async Task InsertAsync(EmailLog emailLog, CancellationToken token = default)
+ public async Task InsertAsync(Message message, CancellationToken token = default)
{
+ var settings = new EmailServiceSettings();
+ configuration.GetSection(nameof(EmailServiceSettings)).Bind(settings);
+ if (!settings.EnableEmailLog) return;
+
+ var emailLog = EmailLog.Create(message);
await dbContext.EmailLogs.AddAsync(emailLog, token).ConfigureAwait(false);
await dbContext.SaveChangesAsync(token).ConfigureAwait(false);
}
diff --git a/src/EmailService/EmailService.cs b/src/EmailService/EmailService.cs
deleted file mode 100644
index e269fb5..0000000
--- a/src/EmailService/EmailService.cs
+++ /dev/null
@@ -1,65 +0,0 @@
-using GaEpd.EmailService.Utilities;
-using MailKit.Net.Smtp;
-using MailKit.Security;
-using MimeKit;
-
-namespace GaEpd.EmailService;
-
-public class EmailService : IEmailService
-{
- public async Task SendEmailAsync(Message message, EmailServiceSettings settings, CancellationToken token = default)
- {
- if (settings is { EnableEmail: false, EnableEmailAuditing: false }) return;
-
- var emailMessage = new MimeMessage();
- emailMessage.From.Add(new MailboxAddress(string.Empty, message.Sender));
- emailMessage.Cc.AddRange(message.CopyRecipients.Select(address => new MailboxAddress(string.Empty, address)));
- emailMessage.Subject = message.Subject;
-
- if (settings.EnableEmail && message.Recipients.Count > 0)
- {
- emailMessage.To.AddRange(message.Recipients.Select(address => new MailboxAddress(string.Empty, address)));
-
- var builder = new BodyBuilder
- {
- TextBody = message.TextBody,
- HtmlBody = message.HtmlBody
- };
- emailMessage.Body = builder.ToMessageBody();
-
- await SendEmailMessageAsync(emailMessage, settings, token).ConfigureAwait(false);
- }
-
- if (settings is { EnableEmailAuditing: true, AuditEmailRecipients.Count: > 0 })
- {
- emailMessage.Cc.Clear();
- emailMessage.To.Clear();
- emailMessage.To.AddRange(settings.AuditEmailRecipients
- .Select(address => new MailboxAddress(string.Empty, address)));
-
- const string auditText = "This is a copy of the original email for auditing purposes. Original recipient: ";
- var auditBuilder = new BodyBuilder
- {
- TextBody = string.Concat(auditText, message.Recipients.ConcatWithSeparator(", "), Environment.NewLine,
- Environment.NewLine, message.TextBody),
- HtmlBody = string.Concat($"{auditText}{message.Recipients.ConcatWithSeparator(", ")}
",
- message.HtmlBody)
- };
- emailMessage.Body = auditBuilder.ToMessageBody();
-
- await SendEmailMessageAsync(emailMessage, settings, token).ConfigureAwait(false);
- }
- }
-
- private static async Task SendEmailMessageAsync(MimeMessage emailMessage, EmailServiceSettings settings,
- CancellationToken token)
- {
- if (!Enum.TryParse(settings.SecureSocketOption, out SecureSocketOptions secureSocketOption))
- secureSocketOption = SecureSocketOptions.Auto;
- using var client = new SmtpClient();
- await client.ConnectAsync(settings.SmtpHost, settings.SmtpPort, secureSocketOption, token)
- .ConfigureAwait(false);
- await client.SendAsync(emailMessage, token).ConfigureAwait(false);
- await client.DisconnectAsync(true, token).ConfigureAwait(false);
- }
-}
diff --git a/src/EmailService/EmailService.csproj b/src/EmailService/EmailService.csproj
deleted file mode 100644
index d09bc66..0000000
--- a/src/EmailService/EmailService.csproj
+++ /dev/null
@@ -1,16 +0,0 @@
-
-
-
- net9.0
- enable
- enable
- GaEpd.EmailService
-
-
-
-
-
-
-
-
-
diff --git a/src/EmailService/EmailService.csproj.DotSettings b/src/EmailService/EmailService.csproj.DotSettings
deleted file mode 100644
index 89316e4..0000000
--- a/src/EmailService/EmailService.csproj.DotSettings
+++ /dev/null
@@ -1,2 +0,0 @@
-
- Library
\ No newline at end of file
diff --git a/src/EmailService/EmailServiceSettings.cs b/src/EmailService/EmailServiceSettings.cs
deleted file mode 100644
index d4b2533..0000000
--- a/src/EmailService/EmailServiceSettings.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-namespace GaEpd.EmailService;
-
-public class EmailServiceSettings
-{
- public bool EnableEmail { get; init; }
- public bool SaveEmail { get; init; }
- public string SmtpHost { get; init; } = null!;
- public int SmtpPort { get; init; }
- public string DefaultSender { get; init; } = null!;
- public string SecureSocketOption { get; init; } = null!;
- public bool EnableEmailAuditing { get; init; }
- public List AuditEmailRecipients { get; init; } = null!;
-}
diff --git a/src/EmailService/IEmailService.cs b/src/EmailService/IEmailService.cs
deleted file mode 100644
index e96a1ac..0000000
--- a/src/EmailService/IEmailService.cs
+++ /dev/null
@@ -1,6 +0,0 @@
-namespace GaEpd.EmailService;
-
-public interface IEmailService
-{
- Task SendEmailAsync(Message message, EmailServiceSettings settings, CancellationToken token = default);
-}
diff --git a/src/EmailService/Message.cs b/src/EmailService/Message.cs
deleted file mode 100644
index 3b9e6b9..0000000
--- a/src/EmailService/Message.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-namespace GaEpd.EmailService;
-
-public record Message
-{
- public string Sender { get; private set; } = string.Empty;
- public string Subject { get; private set; } = string.Empty;
- public List Recipients { get; } = [];
- public List CopyRecipients { get; } = [];
- public string? TextBody { get; private set; }
- public string? HtmlBody { get; private set; }
-
- public static Message Create(string subject, string recipient, string sender, string? textBody, string? htmlBody,
- IEnumerable? copyRecipients = null) =>
- Create(subject, [recipient], sender, textBody, htmlBody, copyRecipients);
-
- public static Message Create(string subject, ICollection recipients, string sender, string? textBody,
- string? htmlBody, IEnumerable? copyRecipients = null)
- {
- if(string.IsNullOrWhiteSpace(subject))
- throw new ArgumentException("A subject must be provided.", nameof(subject));
-
- if (recipients.Count == 0)
- throw new ArgumentException("At least one recipient must be specified.", nameof(recipients));
-
- if (recipients.Any(string.IsNullOrEmpty))
- throw new ArgumentException("Recipient cannot be null, empty, or white space.", nameof(recipients));
-
- if (string.IsNullOrEmpty(htmlBody) && string.IsNullOrEmpty(textBody))
- throw new ArgumentException("Either a plaintext or HTML body must be provided.", nameof(htmlBody));
-
- var message = new Message
- {
- Sender = sender,
- Subject = subject,
- TextBody = textBody,
- HtmlBody = htmlBody,
- };
-
- message.Recipients.AddRange(recipients);
- if (copyRecipients != null) message.CopyRecipients.AddRange(copyRecipients);
-
- return message;
- }
-}
diff --git a/src/EmailService/Properties/AssemblyInfo.cs b/src/EmailService/Properties/AssemblyInfo.cs
deleted file mode 100644
index 948f7d1..0000000
--- a/src/EmailService/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-using System.Runtime.CompilerServices;
-
-[assembly: InternalsVisibleTo("EmailServiceTests")]
diff --git a/src/EmailService/Repository/EmailLog.cs b/src/EmailService/Repository/EmailLog.cs
deleted file mode 100644
index 1e27152..0000000
--- a/src/EmailService/Repository/EmailLog.cs
+++ /dev/null
@@ -1,42 +0,0 @@
-using GaEpd.EmailService.Utilities;
-using System.ComponentModel.DataAnnotations;
-
-namespace GaEpd.EmailService.Repository;
-
-public record EmailLog
-{
- [Key]
- public required Guid Id { get; init; }
-
- public DateTimeOffset? CreatedAt { get; init; }
-
- [StringLength(200)]
- public required string Sender { get; init; }
-
- [StringLength(200)]
- public required string Subject { get; init; }
-
- [StringLength(2000)]
- public required string Recipients { get; init; }
-
- [StringLength(2000)]
- public string? CopyRecipients { get; init; }
-
- [StringLength(15_000)]
- public string? TextBody { get; init; }
-
- [StringLength(20_000)]
- public string? HtmlBody { get; init; }
-
- public static EmailLog Create(Message message) => new()
- {
- Id = Guid.NewGuid(),
- Sender = message.Sender.Truncate(200),
- Subject = message.Subject.Truncate(200),
- Recipients = message.Recipients.ConcatWithSeparator(",").Truncate(2000),
- CopyRecipients = message.CopyRecipients.ConcatWithSeparator(",").Truncate(2000),
- TextBody = message.TextBody.Truncate(15_000),
- HtmlBody = message.HtmlBody.Truncate(20_000),
- CreatedAt = DateTimeOffset.Now,
- };
-}
diff --git a/src/EmailService/Repository/IEmailLogRepository.cs b/src/EmailService/Repository/IEmailLogRepository.cs
deleted file mode 100644
index 5953609..0000000
--- a/src/EmailService/Repository/IEmailLogRepository.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-namespace GaEpd.EmailService.Repository;
-
-public interface IEmailLogRepository : IDisposable, IAsyncDisposable
-{
- ///
- /// Inserts a new .
- ///
- /// The Email Log to insert.
- ///
- ///
- Task InsertAsync(EmailLog emailLog, CancellationToken token = default);
-}
diff --git a/src/EmailService/Utilities/StringExtensions.cs b/src/EmailService/Utilities/StringExtensions.cs
deleted file mode 100644
index 4d6ae1a..0000000
--- a/src/EmailService/Utilities/StringExtensions.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using System.Diagnostics.CodeAnalysis;
-
-namespace GaEpd.EmailService.Utilities;
-
-internal static class StringExtensions
-{
- public static string ConcatWithSeparator(this IEnumerable items, string separator = " ") =>
- string.Join(separator, items.Where(s => !string.IsNullOrEmpty(s)));
-
- [return: NotNullIfNotNull(nameof(value))]
- public static string? Truncate(this string? value, int maxLength, string suffix = "…")
- {
- if (maxLength < 0) throw new ArgumentException("maxLength must not be negative.", nameof(maxLength));
- if (value is null) return null;
- if (string.IsNullOrEmpty(value) || maxLength == 0) return string.Empty;
- if (value.Length <= maxLength) return value;
- return maxLength < suffix.Length
- ? value[..maxLength]
- : $"{value[..(maxLength - suffix.Length)]}{suffix}";
- }
-}
diff --git a/src/LocalRepository/Repositories/LocalEmailLogRepository.cs b/src/LocalRepository/Repositories/LocalEmailLogRepository.cs
index 77d6945..10e61bc 100644
--- a/src/LocalRepository/Repositories/LocalEmailLogRepository.cs
+++ b/src/LocalRepository/Repositories/LocalEmailLogRepository.cs
@@ -1,10 +1,11 @@
-using GaEpd.EmailService.Repository;
+using GaEpd.EmailService;
+using GaEpd.EmailService.EmailLogRepository;
namespace MyApp.LocalRepository.Repositories;
public sealed class LocalEmailLogRepository : IEmailLogRepository
{
- public Task InsertAsync(EmailLog emailLog, CancellationToken token = default) => Task.CompletedTask;
+ public Task InsertAsync(Message message, CancellationToken token = default) => Task.CompletedTask;
public void Dispose()
{
diff --git a/src/WebApp/Platform/AppConfiguration/DataPersistence.cs b/src/WebApp/Platform/AppConfiguration/DataPersistence.cs
index b1e8eed..717ea95 100644
--- a/src/WebApp/Platform/AppConfiguration/DataPersistence.cs
+++ b/src/WebApp/Platform/AppConfiguration/DataPersistence.cs
@@ -1,4 +1,4 @@
-using GaEpd.EmailService.Repository;
+using GaEpd.EmailService.EmailLogRepository;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics;
using MyApp.Domain.Entities.EntryActions;
@@ -15,20 +15,22 @@ namespace MyApp.WebApp.Platform.AppConfiguration;
public static class DataPersistence
{
- public static void AddDataPersistence(this IServiceCollection services, ConfigurationManager configuration,
+ public static IServiceCollection AddDataPersistence(this IServiceCollection services,
+ ConfigurationManager configuration,
IWebHostEnvironment environment)
{
// When configured, use in-memory data; otherwise use a SQL Server database.
if (AppSettings.DevSettings.UseInMemoryData)
{
// Use in-memory data for all repositories.
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
- services.AddSingleton();
+ services
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton()
+ .AddSingleton();
- return;
+ return services;
}
// When in-memory data is disabled, use a database connection.
@@ -47,7 +49,7 @@ public static void AddDataPersistence(this IServiceCollection services, Configur
dbBuilder
.UseSqlServer(connectionString, sqlServerOpts => sqlServerOpts.EnableRetryOnFailure())
.ConfigureWarnings(builder => builder.Throw(RelationalEventId.MultipleCollectionIncludeWarning));
-
+
if (environment.IsDevelopment()) dbBuilder.EnableSensitiveDataLogging();
});
@@ -57,10 +59,13 @@ public static void AddDataPersistence(this IServiceCollection services, Configur
}
// Repositories
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
- services.AddScoped();
+ services
+ .AddScoped()
+ .AddScoped()
+ .AddScoped()
+ .AddScoped()
+ .AddScoped();
+
+ return services;
}
}
diff --git a/src/WebApp/Program.cs b/src/WebApp/Program.cs
index 2612545..bc8813a 100644
--- a/src/WebApp/Program.cs
+++ b/src/WebApp/Program.cs
@@ -1,3 +1,4 @@
+using GaEpd.EmailService.Utilities;
using GaEpd.FileService;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.OpenApi.Models;
@@ -43,7 +44,8 @@
// https://gaepdit.github.io/web-apps/use-https.html#how-to-enable-hsts
if (!isDevelopment)
{
- builder.Services.AddHsts(options => options.MaxAge = TimeSpan.FromMinutes(300))
+ builder.Services
+ .AddHsts(options => options.MaxAge = TimeSpan.FromMinutes(300))
.AddHttpsRedirection(options =>
{
options.HttpsPort = 443;
@@ -52,32 +54,38 @@
}
// Configure application monitoring.
-builder.Services.AddTransient();
-builder.Services.AddSingleton(provider =>
-{
- var client = new RaygunClient(provider.GetService()!, provider.GetService()!);
- client.SendingMessage += (_, eventArgs) => eventArgs.Message.Details.Tags.Add(builder.Environment.EnvironmentName);
- return client;
-});
-builder.Services.AddRaygun(opts =>
-{
- opts.ApiKey = AppSettings.RaygunSettings.ApiKey;
- opts.ApplicationVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3);
- opts.ExcludeErrorsFromLocal = AppSettings.RaygunSettings.ExcludeErrorsFromLocal;
- opts.IgnoreFormFieldNames = ["*Password"];
- opts.EnvironmentVariables.Add("ASPNETCORE_*");
-});
-builder.Services.AddRaygunUserProvider();
-builder.Services.AddHttpContextAccessor(); // needed by RaygunScriptPartial
+builder.Services
+ .AddTransient()
+ .AddSingleton(provider =>
+ {
+ var client = new RaygunClient(provider.GetService()!,
+ provider.GetService()!);
+ client.SendingMessage += (_, eventArgs) =>
+ eventArgs.Message.Details.Tags.Add(builder.Environment.EnvironmentName);
+ return client;
+ })
+ .AddRaygun(opts =>
+ {
+ opts.ApiKey = AppSettings.RaygunSettings.ApiKey;
+ opts.ApplicationVersion = Assembly.GetEntryAssembly()?.GetName().Version?.ToString(3);
+ opts.ExcludeErrorsFromLocal = AppSettings.RaygunSettings.ExcludeErrorsFromLocal;
+ opts.IgnoreFormFieldNames = ["*Password"];
+ opts.EnvironmentVariables.Add("ASPNETCORE_*");
+ })
+ .AddRaygunUserProvider()
+ .AddHttpContextAccessor(); // needed by RaygunScriptPartial
// Add app services.
-builder.Services.AddAutoMapperProfiles();
-builder.Services.AddAppServices();
-builder.Services.AddValidators();
+builder.Services
+ .AddAutoMapperProfiles()
+ .AddAppServices()
+ .AddEmailService()
+ .AddValidators();
// Add data stores.
-builder.Services.AddDataPersistence(builder.Configuration, builder.Environment);
-builder.Services.AddFileServices(builder.Configuration);
+builder.Services
+ .AddDataPersistence(builder.Configuration, builder.Environment)
+ .AddFileServices(builder.Configuration);
// Initialize database.
builder.Services.AddHostedService();
@@ -117,14 +125,14 @@
// Configure security HTTP headers
if (!app.Environment.IsDevelopment() || AppSettings.DevSettings.UseSecurityHeadersInDev)
{
- app.UseHsts();
- app.UseSecurityHeaders(policyCollection => policyCollection.AddSecurityHeaderPolicies());
+ app.UseHsts().UseSecurityHeaders(policyCollection => policyCollection.AddSecurityHeaderPolicies());
}
if (!string.IsNullOrEmpty(AppSettings.RaygunSettings.ApiKey)) app.UseRaygun();
// Configure the application pipeline.
-app.UseStatusCodePagesWithReExecute("/Error/{0}")
+app
+ .UseStatusCodePagesWithReExecute("/Error/{0}")
.UseHttpsRedirection()
.UseWebOptimizer()
.UseStaticFiles()
@@ -133,7 +141,8 @@
.UseAuthorization();
// Configure API documentation.
-app.UseSwagger(options => { options.RouteTemplate = "api-docs/{documentName}/openapi.json"; })
+app
+ .UseSwagger(options => { options.RouteTemplate = "api-docs/{documentName}/openapi.json"; })
.UseSwaggerUI(options =>
{
options.SwaggerEndpoint($"{apiVersion}/openapi.json", $"{apiTitle} {apiVersion}");
diff --git a/src/WebApp/appsettings.json b/src/WebApp/appsettings.json
index 0ef1bac..586f472 100644
--- a/src/WebApp/appsettings.json
+++ b/src/WebApp/appsettings.json
@@ -40,15 +40,16 @@
},
"EmailServiceSettings": {
"EnableEmail": false,
- "SaveEmail": true,
"SmtpHost": "localhost",
"SmtpPort": 25,
- "DefaultSender": "App.Emailer@email.invalid",
+ "DefaultSenderName": "EPD-IT",
+ "DefaultSenderEmail": "App.Emailer@email.invalid",
"SecureSocketOption": "None",
"EnableEmailAuditing": false,
"AuditEmailRecipients": [
"Audit.Recipient@email.invalid"
- ]
+ ],
+ "EnableEmailLog": true
},
"DevSettings": {
"UseDevSettings": true,
diff --git a/template-app.sln b/template-app.sln
index a3605ea..52f8eed 100644
--- a/template-app.sln
+++ b/template-app.sln
@@ -27,8 +27,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LocalRepositoryTests", "tes
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebAppTests", "tests\WebAppTests\WebAppTests.csproj", "{0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EmailService", "src\EmailService\EmailService.csproj", "{1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -82,10 +80,6 @@ Global
{0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0C0DFDC9-DB51-4C14-91F8-30E9FC66E32C}.Release|Any CPU.Build.0 = Release|Any CPU
- {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {1D7EE75A-3FA5-4BC7-B11D-4E6EABA19BC9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{13FAE9CA-FE4A-447E-8957-037E5DAD845B} = {DB76F5B0-EC9D-4144-91AA-46D5679152A3}
diff --git a/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs b/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs
index 332f44e..b68ed37 100644
--- a/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs
+++ b/tests/AppServicesTests/Permissions/AuthorizationServiceBuilder.cs
@@ -8,8 +8,7 @@ public static class AuthorizationServiceBuilder
public static IAuthorizationService BuildAuthorizationService(Action setupServices)
{
var services = new ServiceCollection();
- services.AddAuthorization();
- services.AddLogging();
+ services.AddAuthorization().AddLogging();
setupServices.Invoke(services);
return services.BuildServiceProvider().GetRequiredService();
}
diff --git a/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs b/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs
index 4af8605..90d3abb 100644
--- a/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs
+++ b/tests/AppServicesTests/Permissions/PolicyTests/ActiveUserPolicy.cs
@@ -13,8 +13,7 @@ public class ActiveUserPolicy
[SetUp]
public void SetUp() => _authorization = AuthorizationServiceBuilder.BuildAuthorizationService(collection =>
- collection.AddAuthorizationBuilder()
- .AddPolicy(nameof(Policies.ActiveUser), Policies.ActiveUser));
+ collection.AddAuthorizationBuilder().AddPolicy(nameof(Policies.ActiveUser), Policies.ActiveUser));
[Test]
public async Task WhenActiveAndAuthenticated_Succeeds()