public Task SendEmailAsync(EmailMessage emailMessage, string accountName = null, string id = null, string direction = null) { Email emailObject = new Email(); Guid? emailId = Guid.NewGuid(); if (!string.IsNullOrEmpty(id)) { emailId = Guid.Parse(id); emailObject = _emailRepository.Find(null, q => q.Id == emailId)?.Items?.FirstOrDefault(); if (emailObject == null) { emailObject = new Email() { Id = emailId, Status = StatusType.Unknown.ToString() }; } } Email email = new Email(); if (!string.IsNullOrEmpty(id)) { email.Id = emailId; } //find email settings and determine is email is enabled/disabled var organizationId = Guid.Parse(_organizationManager.GetDefaultOrganization().Id.ToString()); var emailSettings = _emailSettingsRepository.Find(null, s => s.OrganizationId == organizationId).Items.FirstOrDefault(); //check if accountName exists var existingAccount = _emailAccountRepository.Find(null, d => d.Name.ToLower(null) == accountName?.ToLower(null))?.Items?.FirstOrDefault(); if (existingAccount == null) { existingAccount = _emailAccountRepository.Find(null, d => d.IsDefault && !d.IsDisabled).Items.FirstOrDefault(); } //if there are no records in the email settings table for that organization, email should be disabled if (emailSettings == null) { email.Status = StatusType.Blocked.ToString(); email.Reason = "Email disabled. Please configure email settings."; } //if there are email settings but they are disabled, don't send email else if (emailSettings != null && emailSettings.IsEmailDisabled) { email.Status = StatusType.Blocked.ToString(); email.Reason = "Email functionality has been disabled."; } else { if (existingAccount == null && emailSettings != null) { existingAccount = _emailAccountRepository.Find(null, a => a.IsDefault == true && a.IsDisabled == false)?.Items?.FirstOrDefault(); if (existingAccount == null) { email.Status = StatusType.Failed.ToString(); email.Reason = $"Account '{accountName}' could be found."; } if (existingAccount != null && existingAccount.IsDisabled == true) { email.Status = StatusType.Blocked.ToString(); email.Reason = $"Account '{accountName}' has been disabled."; } } //set from email address else if (existingAccount != null) { EmailAddress fromEmailAddress = new EmailAddress(existingAccount.FromName, existingAccount.FromEmailAddress); List <EmailAddress> emailAddresses = new List <EmailAddress>(); foreach (EmailAddress emailAddress in emailMessage.From) { if (!string.IsNullOrEmpty(emailAddress.Address)) { emailAddresses.Add(emailAddress); } } emailMessage.From.Clear(); foreach (EmailAddress emailAddress in emailAddresses) { emailMessage.From.Add(emailAddress); } emailMessage.From.Add(fromEmailAddress); } //remove email addresses in to, cc, and bcc lists with domains that are blocked or not allowed List <EmailAddress> toList = new List <EmailAddress>(); List <EmailAddress> ccList = new List <EmailAddress>(); List <EmailAddress> bccList = new List <EmailAddress>(); if (string.IsNullOrEmpty(emailSettings.AllowedDomains)) { if (!string.IsNullOrEmpty(emailSettings.BlockedDomains)) { //remove any email address that is in blocked domain IEnumerable <string>?denyList = (new List <string>(emailSettings?.BlockedDomains?.Split(','))).Select(s => s.ToLowerInvariant().Trim()); foreach (EmailAddress address in emailMessage.To) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (!denyList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { toList.Add(address); } } } emailMessage.To.Clear(); emailMessage.To = toList; foreach (EmailAddress address in emailMessage.CC) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (!denyList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { ccList.Add(address); } } } emailMessage.CC.Clear(); emailMessage.CC = ccList; foreach (EmailAddress address in emailMessage.Bcc) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (!denyList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { bccList.Add(address); } } } emailMessage.Bcc.Clear(); emailMessage.Bcc = bccList; } } else { if (!string.IsNullOrEmpty(emailSettings.AllowedDomains)) { //remove any email address that is not on white list IEnumerable <string> allowList = (new List <string>(emailSettings.AllowedDomains.Split(','))).Select(s => s.ToLowerInvariant().Trim()); foreach (EmailAddress address in emailMessage.To) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (allowList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { toList.Add(address); } } } emailMessage.To.Clear(); emailMessage.To = toList; foreach (EmailAddress address in emailMessage.CC) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (allowList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { ccList.Add(address); } } } emailMessage.CC.Clear(); emailMessage.CC = ccList; foreach (EmailAddress address in emailMessage.Bcc) { if (!string.IsNullOrEmpty(address.Address)) { MailboxAddress mailAddress = new MailboxAddress(address.Address); if (allowList.Contains(mailAddress.Address.Split("@")[1].ToLowerInvariant())) { bccList.Add(address); } } } emailMessage.Bcc.Clear(); emailMessage.Bcc = bccList; } } if (emailMessage.To.Count == 0) { email.Status = StatusType.Blocked.ToString(); email.Reason = "No email addresses to send email to."; } //add any necessary additional email addresses (administrators, etc.) if (!string.IsNullOrEmpty(emailSettings.AddToAddress)) { foreach (string toAddress in emailSettings.AddToAddress.Split(',')) { EmailAddress emailAddress = new EmailAddress(toAddress, toAddress); emailMessage.To.Add(emailAddress); } } if (!string.IsNullOrEmpty(emailSettings.AddCCAddress)) { foreach (string CCAddress in emailSettings.AddCCAddress.Split(',')) { EmailAddress emailAddress = new EmailAddress(CCAddress, CCAddress); emailMessage.CC.Add(emailAddress); } } if (!string.IsNullOrEmpty(emailSettings.AddBCCAddress)) { foreach (string BCCAddress in emailSettings.AddBCCAddress.Split(',')) { EmailAddress emailAddress = new EmailAddress(BCCAddress); emailMessage.Bcc.Add(emailAddress); } } //add subject and body prefixes/suffixes if (!string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && !string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailSettings.SubjectAddPrefix, emailMessage.Subject, emailSettings.SubjectAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailSettings.SubjectAddPrefix, emailMessage.Subject); } if (string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && !string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailMessage.Subject, emailSettings.SubjectAddSuffix); } else { emailMessage.Subject = emailMessage.Subject; } //check if email message body is html or plaintext if (emailMessage.IsBodyHtml) { if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailSettings.BodyAddPrefix, emailMessage.Body, emailSettings.BodyAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailSettings.BodyAddPrefix, emailMessage.Body); } if (string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailMessage.Body, emailSettings.BodyAddSuffix); } else { emailMessage.Body = emailMessage.Body; } } else { if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailSettings.BodyAddPrefix, emailMessage.PlainTextBody, emailSettings.BodyAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailSettings.BodyAddPrefix, emailMessage.PlainTextBody); } if (string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailMessage.PlainTextBody, emailSettings.BodyAddSuffix); } else { emailMessage.PlainTextBody = emailMessage.Body; } } //send email ISendEmailChore sendEmailChore = null; if (existingAccount != null) { if (existingAccount.Provider == "SMTP") { sendEmailChore = new SmtpSendEmailChore(existingAccount, emailSettings); } else if (existingAccount.Provider == "Azure") { sendEmailChore = new AzureSendEmailChore(emailSettings, existingAccount); } } if (sendEmailChore != null) { try { if (email.Status != StatusType.Blocked.ToString() || email.Status != StatusType.Failed.ToString()) { sendEmailChore.SendEmail(emailMessage); email.Status = StatusType.Sent.ToString(); email.Reason = "Email was sent successfully."; } } catch (Exception ex) { email.Status = StatusType.Failed.ToString(); email.Reason = "Error: " + ex.Message; } } else { email.Status = StatusType.Failed.ToString(); email.Reason = "Email failed to send."; } } //log email and its status if (existingAccount != null) { email.EmailAccountId = Guid.Parse(existingAccount.Id.ToString()); } email.SentOnUTC = DateTime.UtcNow; string newEmailMessage = Regex.Replace(emailMessage.Body, @"(<sensitive(\s|\S)*?<\/sensitive>)", "NULL"); email.EmailObjectJson = newEmailMessage; List <string> nameList = new List <string>(); List <string> emailList = new List <string>(); foreach (EmailAddress address in emailMessage.From) { nameList.Add(address.Name); emailList.Add(address.Address); } email.SenderName = JsonConvert.SerializeObject(nameList); email.SenderAddress = JsonConvert.SerializeObject(emailList); email.SenderUserId = _applicationUser?.PersonId; if (string.IsNullOrEmpty(direction)) { email.Direction = Direction.Unknown.ToString(); } else { email.Direction = direction; } //TODO: add logic to next two lines of code to allow for assignment of these Guids email.ConversationId = null; email.ReplyToEmailId = null; if (emailObject.Status == StatusType.Unknown.ToString()) { email.Id = emailObject.Id; email.CreatedOn = DateTime.UtcNow; email.CreatedBy = _httpContextAccessor.HttpContext.User.Identity.Name; _emailRepository.Add(email); } else if (email.Id != null && email.Id != emailId) { email.CreatedOn = DateTime.UtcNow; email.CreatedBy = _httpContextAccessor.HttpContext.User.Identity.Name; _emailRepository.Add(email); } else { emailObject.EmailAccountId = email.EmailAccountId; emailObject.SentOnUTC = email.SentOnUTC; emailObject.EmailObjectJson = email.EmailObjectJson; emailObject.SenderName = email.SenderName; emailObject.SenderAddress = email.SenderAddress; emailObject.SenderUserId = email.SenderUserId; emailObject.Direction = email.Direction; emailObject.ConversationId = email.ConversationId; emailObject.ReplyToEmailId = email.ReplyToEmailId; emailObject.Status = email.Status; emailObject.Reason = email.Reason; _emailRepository.Update(emailObject); } return(Task.CompletedTask); }
public Task SendEmailAsync(EmailMessage emailMessage, string accountName = "") { EmailLog emailLog = new EmailLog(); //Find Email Settings and determine is email is enabled/disabled var organizationId = Guid.Parse(_organizationManager.GetDefaultOrganization().Id.ToString()); var emailSettings = _emailSettingsRepository.Find(null, s => s.OrganizationId == organizationId).Items.FirstOrDefault(); // If there are NO records in the Email Settings table for that Organization, email should be disabled if (emailSettings == null) { emailLog.Status = StatusType.Blocked.ToString(); emailLog.Reason = "Email disabled. Please configure email settings."; } if (emailSettings != null && emailSettings.IsEmailDisabled) { emailLog.Status = StatusType.Blocked.ToString(); emailLog.Reason = "Email functionality has been disabled."; } //Check if accountName exists var existingAccount = _emailAccountRepository.Find(null, d => d.Name.ToLower(null) == accountName.ToLower(null))?.Items?.FirstOrDefault(); if (existingAccount == null && emailSettings != null) { existingAccount = _emailAccountRepository.Find(null, a => a.IsDefault == true && a.IsDisabled == false)?.Items?.FirstOrDefault(); if (existingAccount == null) { emailLog.Status = StatusType.Failed.ToString(); } emailLog.Reason = $"Account '{accountName}' could be found."; if (existingAccount != null && existingAccount.IsDisabled == true) { emailLog.Status = StatusType.Blocked.ToString(); } emailLog.Reason = $"Account '{accountName}' has been disabled."; } //Set From Email Address if (existingAccount != null) { EmailAddress fromEmailAddress = new EmailAddress(existingAccount.FromName, existingAccount.FromEmailAddress); List <EmailAddress> emailAddresses = new List <EmailAddress>(); foreach (EmailAddress emailAddress in emailMessage.From) { if (!string.IsNullOrEmpty(emailAddress.Address)) { emailAddresses.Add(emailAddress); } } emailMessage.From.Clear(); foreach (EmailAddress emailAddress in emailAddresses) { emailMessage.From.Add(emailAddress); } emailMessage.From.Add(fromEmailAddress); } //Remove email addresses in to, cc, and bcc lists with domains that are blocked or not allowed List <EmailAddress> toList = new List <EmailAddress>(); List <EmailAddress> ccList = new List <EmailAddress>(); List <EmailAddress> bccList = new List <EmailAddress>(); if (string.IsNullOrEmpty(emailSettings.AllowedDomains)) { //Remove any email address that is in blocked domain IEnumerable <string>?denyList = (new List <string>(emailSettings?.BlockedDomains?.Split(','))).Select(s => s.ToLowerInvariant().Trim()); foreach (EmailAddress address in emailMessage.To) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (!denyList.Contains(mailAddress.Host.ToLowerInvariant())) { toList.Add(address); } } } emailMessage.To.Clear(); emailMessage.To = toList; foreach (EmailAddress address in emailMessage.CC) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (!denyList.Contains(mailAddress.Host.ToLowerInvariant())) { ccList.Add(address); } } } emailMessage.CC.Clear(); emailMessage.CC = ccList; foreach (EmailAddress address in emailMessage.Bcc) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (!denyList.Contains(mailAddress.Host.ToLowerInvariant())) { bccList.Add(address); } } } emailMessage.Bcc.Clear(); emailMessage.Bcc = bccList; } else { //Remove any email address that is not on white list IEnumerable <string> allowList = (new List <string>(emailSettings.AllowedDomains.Split(','))).Select(s => s.ToLowerInvariant().Trim()); foreach (EmailAddress address in emailMessage.To) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (allowList.Contains(mailAddress.Host.ToLowerInvariant())) { toList.Add(address); } } } emailMessage.To.Clear(); emailMessage.To = toList; foreach (EmailAddress address in emailMessage.CC) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (allowList.Contains(mailAddress.Host.ToLowerInvariant())) { ccList.Add(address); } } } emailMessage.CC.Clear(); emailMessage.CC = ccList; foreach (EmailAddress address in emailMessage.Bcc) { if (!string.IsNullOrEmpty(address.Address)) { MailAddress mailAddress = new MailAddress(address.Address); if (allowList.Contains(mailAddress.Host.ToLowerInvariant())) { bccList.Add(address); } } } emailMessage.Bcc.Clear(); emailMessage.Bcc = bccList; } if (emailMessage.To.Count == 0) { emailLog.Status = StatusType.Blocked.ToString(); } emailLog.Reason = "No email addresses to send email to."; //Add any necessary additional email addresses (Administrators, etc.) if (!string.IsNullOrEmpty(emailSettings.AddToAddress)) { foreach (string toAddress in emailSettings.AddToAddress.Split(',')) { EmailAddress email = new EmailAddress(toAddress, toAddress); emailMessage.To.Add(email); } } if (!string.IsNullOrEmpty(emailSettings.AddCCAddress)) { foreach (string CCAddress in emailSettings.AddCCAddress.Split(',')) { EmailAddress email = new EmailAddress(CCAddress, CCAddress); emailMessage.CC.Add(email); } } if (!string.IsNullOrEmpty(emailSettings.AddBCCAddress)) { foreach (string BCCAddress in emailSettings.AddBCCAddress.Split(',')) { EmailAddress email = new EmailAddress(BCCAddress); emailMessage.Bcc.Add(email); } } //Add Subject and Body Prefixes/Suffixes if (!string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && !string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailSettings.SubjectAddPrefix, emailMessage.Subject, emailSettings.SubjectAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailSettings.SubjectAddPrefix, emailMessage.Subject); } if (string.IsNullOrEmpty(emailSettings.SubjectAddPrefix) && !string.IsNullOrEmpty(emailSettings.SubjectAddSuffix)) { emailMessage.Subject = string.Concat(emailMessage.Subject, emailSettings.SubjectAddSuffix); } else { emailMessage.Subject = emailMessage.Subject; } //Check if Email Message body is html or plaintext //emailMessage.IsBodyHtml = true; if (emailMessage.IsBodyHtml) { if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailSettings.BodyAddPrefix, emailMessage.Body, emailSettings.BodyAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailSettings.BodyAddPrefix, emailMessage.Body); } if (string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.Body = string.Concat(emailMessage.Body, emailSettings.BodyAddSuffix); } else { emailMessage.Body = emailMessage.Body; } } else { if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailSettings.BodyAddPrefix, emailMessage.PlainTextBody, emailSettings.BodyAddSuffix); } if (!string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailSettings.BodyAddPrefix, emailMessage.PlainTextBody); } if (string.IsNullOrEmpty(emailSettings.BodyAddPrefix) && !string.IsNullOrEmpty(emailSettings.BodyAddSuffix)) { emailMessage.PlainTextBody = string.Concat(emailMessage.PlainTextBody, emailSettings.BodyAddSuffix); } else { emailMessage.PlainTextBody = emailMessage.Body; } } //Send email ISendEmailChore sendEmailChore = null; if (existingAccount != null) { if (existingAccount.Provider == "SMTP") { sendEmailChore = new SmtpSendEmailChore(existingAccount, emailSettings); } else if (existingAccount.Provider == "Azure") { sendEmailChore = new AzureSendEmailChore(emailSettings, existingAccount); } } if (sendEmailChore != null) { try { if (emailLog.Status != StatusType.Blocked.ToString() || emailLog.Status != StatusType.Failed.ToString()) { ; } { sendEmailChore.SendEmail(emailMessage); emailLog.Status = StatusType.Sent.ToString(); emailLog.Reason = "Email was sent successfully."; } } catch (Exception ex) { emailLog.Status = StatusType.Failed.ToString(); emailLog.Reason = "Error: " + ex.Message; } } else { emailLog.Status = StatusType.Failed.ToString(); emailLog.Reason = "Email failed to send."; } //Log email and its status emailLog.Id = Guid.NewGuid(); if (existingAccount != null) { emailLog.EmailAccountId = Guid.Parse(existingAccount.Id.ToString()); } emailLog.SentOnUTC = DateTime.UtcNow; string newEmailMessage = Regex.Replace(emailMessage.Body, @"(<sensitive(\s|\S)*?<\/sensitive>)", "NULL"); emailLog.EmailObjectJson = JsonConvert.SerializeObject(newEmailMessage); List <string> nameList = new List <string>(); List <string> emailList = new List <string>(); foreach (EmailAddress address in emailMessage.From) { nameList.Add(address.Name); emailList.Add(address.Address); } emailLog.SenderName = JsonConvert.SerializeObject(nameList); emailLog.SenderAddress = JsonConvert.SerializeObject(emailList); emailLog.CreatedOn = DateTime.UtcNow; emailLog.CreatedBy = applicationUser?.UserName; emailLog.SenderUserId = applicationUser?.PersonId; _emailLogRepository.Add(emailLog); return(Task.CompletedTask); }