Redirect emails to dev address in non-production; fix PAID stamp color

- EmailService: add RedirectIfNonProd() mirroring SmsService pattern;
  reads SendGrid:DevRedirectEmail and redirects all outbound email in
  non-production so real customers are never contacted on local/dev
- appsettings.json: set DevRedirectEmail to spouliot@scppowdercoating.com
- PdfService: revert Opacity() (not in QuestPDF 2024.12.3); use
  Colors.Green.Lighten2 for stamp + border to achieve lighter look

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 16:32:01 -04:00
parent 14d6c82839
commit b8057295ec
3 changed files with 23 additions and 5 deletions
@@ -175,16 +175,15 @@ public class PdfService : IPdfService
container
.AlignCenter()
.AlignMiddle()
.Opacity(0.35f)
.Rotate(-45f)
.Border(3)
.BorderColor(Colors.Green.Darken2)
.Border(2)
.BorderColor(Colors.Green.Lighten2)
.PaddingVertical(10)
.PaddingHorizontal(20)
.Text("PAID")
.FontSize(52)
.Bold()
.FontColor(Colors.Green.Darken2);
.FontColor(Colors.Green.Lighten2);
}
/// <summary>
@@ -47,6 +47,8 @@ public class EmailService : IEmailService
if (!_hostEnvironment.IsProduction())
subject = $"[{_hostEnvironment.EnvironmentName}] {subject}";
(toEmail, toName) = RedirectIfNonProd(toEmail, toName);
var fromEmail = _configuration["SendGrid:FromEmail"] ?? "noreply@example.com";
var fromName = _configuration["SendGrid:FromName"] ?? "Powder Coating";
@@ -104,6 +106,8 @@ public class EmailService : IEmailService
if (!_hostEnvironment.IsProduction())
subject = $"[{_hostEnvironment.EnvironmentName}] {subject}";
(toEmail, toName) = RedirectIfNonProd(toEmail, toName);
var fromEmail = _configuration["SendGrid:FromEmail"] ?? "noreply@example.com";
var fromName = _configuration["SendGrid:FromName"] ?? "Powder Coating";
@@ -138,6 +142,20 @@ public class EmailService : IEmailService
}
}
/// <summary>
/// In non-production environments, redirects outbound email to <c>SendGrid:DevRedirectEmail</c>
/// so real customers are never contacted outside of production. Double-gated on environment
/// name AND the config value so a misconfigured prod deploy can't accidentally redirect.
/// </summary>
private (string email, string name) RedirectIfNonProd(string toEmail, string toName)
{
if (_hostEnvironment.IsProduction()) return (toEmail, toName);
var devEmail = _configuration["SendGrid:DevRedirectEmail"];
if (string.IsNullOrWhiteSpace(devEmail)) return (toEmail, toName);
_logger.LogWarning("Non-production environment: redirecting email from {Original} to dev address {Dev}", toEmail, devEmail);
return (devEmail, $"[DEV → {toName} <{toEmail}>]");
}
/// <summary>
/// Sends the built SendGrid message and interprets the HTTP response. Extracted so both
/// send methods share identical dispatch and logging logic.
+2 -1
View File
@@ -45,7 +45,8 @@
"SendGrid": {
"ApiKey": "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",
"FromEmail": "spouliot@scppowdercoating.com",
"FromName": "Powder Coating App Staff"
"FromName": "Powder Coating App Staff",
"DevRedirectEmail": "spouliot@scppowdercoating.com"
},
"Twilio": {
"AccountSid": "your-twilio-account-sid",