aboutsummaryrefslogtreecommitdiff
path: root/Transactional Emails/Transactions/EmailTransactionValidator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Transactional Emails/Transactions/EmailTransactionValidator.cs')
-rw-r--r--Transactional Emails/Transactions/EmailTransactionValidator.cs109
1 files changed, 109 insertions, 0 deletions
diff --git a/Transactional Emails/Transactions/EmailTransactionValidator.cs b/Transactional Emails/Transactions/EmailTransactionValidator.cs
new file mode 100644
index 0000000..09571bf
--- /dev/null
+++ b/Transactional Emails/Transactions/EmailTransactionValidator.cs
@@ -0,0 +1,109 @@
+using FluentValidation;
+
+using VNLib.Plugins.Extensions.Validation;
+
+
+namespace Emails.Transactional.Transactions
+{
+ internal class EmailTransactionValidator : AbstractValidator<EmailTransaction>
+ {
+ public const int MAX_SUBJECT_LEN = 50;
+ public EmailTransactionValidator()
+ {
+ //Catch to make sure user-id is set
+ RuleFor(static t => t.UserId)
+ .NotEmpty();
+ //validate from addres/name
+ RuleFor(static t => t.FromName)
+ .NotEmpty()
+ .WithName("from_name")
+ .AlphaNumericOnly()
+ .WithName("from_name");
+ RuleFor(static t => t.From)
+ .NotEmpty()
+ .EmailAddress()
+ .WithName("from");
+
+ //Rule names must be their json propery name, so clients can properly log errors
+ //must include a template id
+ RuleFor(static t => t.TemplateId)
+ .NotEmpty()
+ .MaximumLength(200)
+ .WithName("template_id");
+
+ //From address must not be empty
+ RuleFor(static t => t.From)
+ .NotEmpty()
+ .EmailAddress();
+ //Subject is required alpha num
+ RuleFor(static t => t.Subject)
+ .NotEmpty()
+ .AlphaNumericOnly()
+ .MaximumLength(MAX_SUBJECT_LEN)
+ .WithName("subject");
+
+ //To address must not be empty, and must be valid email addresses
+ RuleFor(static t => t.ToAddresses)
+ .NotEmpty()
+ .ChildRules(static to => {
+ //Check keys (address)
+ to.RuleForEach(static b => b.Keys)
+ .NotEmpty()
+ .EmailAddress()
+ .WithName("to");
+
+ //Check values (names)
+ to.RuleForEach(static b => b.Values)
+ .NotEmpty()
+ .AlphaNumericOnly()
+ .WithName("to_name");
+ })
+ .WithName("to");
+ //Check bcc addresses, allowed to be empty
+ RuleFor(static t => t.BccAddresses)
+ .ChildRules(static bcc => {
+ //Check keys (address)
+ bcc.RuleForEach(static b => b.Keys)
+ .NotEmpty()
+ .EmailAddress()
+ .WithName("bcc");
+
+ //Check values (names)
+ bcc.RuleForEach(static b => b.Values)
+ .NotEmpty()
+ .AlphaNumericOnly()
+ .WithName("bcc_names");
+ })
+ .When(static t => t.BccAddresses != null)
+ .WithName("bcc");
+ //Check cc, also allowed to be empty
+ RuleFor(static t => t.CcAddresses)
+ .ChildRules(static cc => {
+ //Check keys (names)
+ cc.RuleForEach(static b => b.Keys)
+ .NotEmpty()
+ .EmailAddress()
+ .WithName("cc");
+
+ //Check values (addresses)
+ cc.RuleForEach(static b => b.Values)
+ .NotEmpty()
+ .AlphaNumericOnly()
+ .WithName("cc_names");
+ })
+ .When(static t => t.BccAddresses != null)
+ .WithName("cc");
+
+ RuleFor(static t => t.ReplyTo)
+ //Allow the reply to email to be empty, if its not, then validate the address
+ .EmailAddress()
+ .When(static t => t.BccAddresses != null)
+ .WithName("reply_to");
+
+ //Make sure a variable table is defined
+ RuleFor(static t => t.Variables)
+ .NotNull()
+ .WithName("variables");
+ }
+ }
+}