diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..a9d2e74 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM mcr.microsoft.com/dotnet/sdk:10.0-bookworm-slim AS build +WORKDIR /src + +COPY ["LiteCharmsMessaging/LiteCharmsMessaging.csproj", "LiteCharmsMessaging/"] +RUN dotnet restore "LiteCharmsMessaging/LiteCharmsMessaging.csproj" + +COPY . . + +WORKDIR "/src/LiteCharmsMessaging" +RUN dotnet build "LiteCharmsMessaging.csproj" -c Release -o /app/build +RUN dotnet publish "LiteCharmsMessaging.csproj" -c Release -o /app/publish /p:UseAppHost=false + +FROM mcr.microsoft.com/dotnet/aspnet:10.0-bookworm-slim AS final +WORKDIR /app + +COPY --from=build /app/publish . + +EXPOSE 8080 + +ENTRYPOINT ["dotnet", "LiteCharmsMessaging.dll"] \ No newline at end of file diff --git a/LiteCharmsMessaging.slnx b/LiteCharmsMessaging.slnx new file mode 100644 index 0000000..79f4651 --- /dev/null +++ b/LiteCharmsMessaging.slnx @@ -0,0 +1,3 @@ + + + diff --git a/LiteCharmsMessaging/EmailRequest.cs b/LiteCharmsMessaging/EmailRequest.cs new file mode 100644 index 0000000..5d429fe --- /dev/null +++ b/LiteCharmsMessaging/EmailRequest.cs @@ -0,0 +1 @@ +public sealed record EmailRequest(string HtmlBody, string? From, string? To); \ No newline at end of file diff --git a/LiteCharmsMessaging/LiteCharmsMessaging.csproj b/LiteCharmsMessaging/LiteCharmsMessaging.csproj new file mode 100644 index 0000000..b13823c --- /dev/null +++ b/LiteCharmsMessaging/LiteCharmsMessaging.csproj @@ -0,0 +1,15 @@ + + + + net10.0 + enable + enable + + + + + + + + + diff --git a/LiteCharmsMessaging/Program.cs b/LiteCharmsMessaging/Program.cs new file mode 100644 index 0000000..af5d2c1 --- /dev/null +++ b/LiteCharmsMessaging/Program.cs @@ -0,0 +1,63 @@ +using Microsoft.AspNetCore.Mvc; +using MimeKit; +using SmtpClient = MailKit.Net.Smtp.SmtpClient; + +var builder = WebApplication.CreateBuilder(args); + +var allowedOrigins = builder.Configuration.GetSection("CorsSettings:AllowedOrigins").Get() ?? Array.Empty(); + +builder.Services.AddCors(options => +{ + options.AddPolicy("AllowStrictOrigins", policy => + { + policy.WithOrigins(allowedOrigins) + .AllowAnyHeader() + .AllowAnyMethod(); + }); +}); + +var app = builder.Build(); + +app.UseCors("AllowStrictOrigins"); + +app.MapPost("/api/send-email", async ([FromBody] EmailRequest request, IConfiguration config) => +{ + try + { + var message = new MimeMessage(); + + var defaultFrom = config["SmtpSettings:DefaultFrom"]; + var defaultTo = config["SmtpSettings:DefaultTo"]; + + var fromAddress = string.IsNullOrWhiteSpace(request.From) ? defaultFrom : request.From; + var toAddress = string.IsNullOrWhiteSpace(request.To) ? defaultTo : request.To; + + message.From.Add(MailboxAddress.Parse(fromAddress!)); + message.To.Add(MailboxAddress.Parse(toAddress!)); + message.Subject = "New message from LiteCharms"; + + var bodyBuilder = new BodyBuilder { HtmlBody = request.HtmlBody }; + message.Body = bodyBuilder.ToMessageBody(); + + using var client = new SmtpClient(); + + var host = config["SmtpSettings:Host"]; + var port = config.GetValue("SmtpSettings:Port"); + var useSsl = config.GetValue("SmtpSettings:UseSsl"); + var username = config["SmtpSettings:Username"]; + var password = config["SmtpSettings:Password"]; + + await client.ConnectAsync(host!, port, useSsl); + await client.AuthenticateAsync(username!, password!); + await client.SendAsync(message); + await client.DisconnectAsync(true); + + return Results.Ok(new { success = true, message = "Email dispatched successfully." }); + } + catch (Exception ex) + { + return Results.Problem(detail: ex.Message, statusCode: 500); + } +}); + +app.Run(); diff --git a/LiteCharmsMessaging/Properties/launchSettings.json b/LiteCharmsMessaging/Properties/launchSettings.json new file mode 100644 index 0000000..65c9126 --- /dev/null +++ b/LiteCharmsMessaging/Properties/launchSettings.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "http://localhost:5295", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "applicationUrl": "https://localhost:7212;http://localhost:5295", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/LiteCharmsMessaging/appsettings.json b/LiteCharmsMessaging/appsettings.json new file mode 100644 index 0000000..09c80f2 --- /dev/null +++ b/LiteCharmsMessaging/appsettings.json @@ -0,0 +1,26 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "SmtpSettings": { + "Host": "mail.litecharms.co.za", + "Port": 465, + "UseSsl": true, + "Username": "contact@litecharms.co.za", + "Password": "YPPUzCl%TL$GD*x7f", + "DefaultFrom": "LiteCharms ", + "DefaultTo": "contact@litecharms.co.za" + }, + "CorsSettings": { + "AllowedOrigins": [ + "https://litecharms.co.za", + "https://www.litecharms.co.za", + "https://localhost:7212", + "http://localhost:5295" + ] + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d60da48 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,12 @@ +services: + api: + container_name: litecharms-messaging-api + build: + context: . + dockerfile: Dockerfile + restart: unless-stopped + ports: + - "8090:8080" + environment: + - ASPNETCORE_ENVIRONMENT=${ASPNETCORE_ENVIRONMENT} + - SmtpSettings__Password=${SMTP_PASSWORD} \ No newline at end of file