private void SaveIcsAttachment(MailDraftData draft, MimeMessage mimeMessage) { if (string.IsNullOrEmpty(draft.CalendarIcs)) { return; } try { var icsAttachment = mimeMessage.Attachments.FirstOrDefault( a => a.ContentType.IsMimeType("application", "ics")); if (icsAttachment == null) { return; } var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(draft.CalendarIcs))) { engine.AttachmentEngine .AttachFileToDraft(draft.Mailbox.TenantId, draft.Mailbox.UserId, draft.Id, icsAttachment.ContentType.Name, memStream, memStream.Length); } } catch (Exception ex) { Log.Warn(string.Format("Problem with attach ICAL to message. mailId={0} Exception:\r\n{1}\r\n", draft.Id, ex)); } }
private void SendMailNotification(MailDraftData draft) { try { var state = 0; if (!string.IsNullOrEmpty(draft.CalendarIcs)) { switch (draft.CalendarMethod) { case Defines.ICAL_REQUEST: state = 1; break; case Defines.ICAL_REPLY: state = 2; break; case Defines.ICAL_CANCEL: state = 3; break; } } // send success notification _signalrServiceClient.SendMailNotification(draft.Mailbox.TenantId, draft.Mailbox.UserId, state); } catch (Exception ex) { Log.ErrorFormat("Unexpected error with wcf signalrServiceClient: {0}, {1}", ex.Message, ex.StackTrace); } }
public static void ChangeEmbeddedAttachmentLinks(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } var baseAttachmentFolder = MailStoragePathCombiner.GetMessageDirectory(draft.Mailbox.UserId, draft.StreamId); var doc = new HtmlDocument(); doc.LoadHtml(draft.HtmlBody); var linkNodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'" + baseAttachmentFolder + "'))]"); if (linkNodes == null) { return; } foreach (var linkNode in linkNodes) { var link = linkNode.Attributes["src"].Value; log.InfoFormat("ChangeEmbededAttachmentLinks() Embeded attachment link for changing to cid: {0}", link); var fileLink = HttpUtility.UrlDecode(link.Substring(baseAttachmentFolder.Length)); var fileName = Path.GetFileName(fileLink); var attach = CreateEmbbededAttachment(fileName, link, fileLink, draft.Mailbox.UserId, draft.Mailbox.TenantId, draft.Mailbox.MailBoxId, draft.StreamId); draft.AttachmentsEmbedded.Add(attach); linkNode.SetAttributeValue("src", "cid:" + attach.contentId); log.InfoFormat("ChangeEmbededAttachmentLinks() Attachment cid: {0}", attach.contentId); } draft.HtmlBody = doc.DocumentNode.OuterHtml; }
private void SetDraftSending(MailDraftData draft) { var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); engine.ChainEngine.SetConversationsFolder(new List <int> { draft.Id }, FolderType.Sending); }
public static void ChangeAllImagesLinksToEmbedded(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } try { var doc = new HtmlDocument(); doc.LoadHtml(draft.HtmlBody); var linkNodes = doc.DocumentNode.SelectNodes("//img[@src]"); if (linkNodes == null) { return; } foreach (var linkNode in linkNodes) { var link = linkNode.Attributes["src"].Value; log.InfoFormat("ChangeAllImagesLinksToEmbedded() Link to img link: {0}", link); var fileName = Path.GetFileName(link); var data = StorageManager.LoadLinkData(link, log); if (!data.Any()) { continue; } var attach = new MailAttachmentData { fileName = fileName, storedName = fileName, contentId = link.GetMd5(), data = data }; log.InfoFormat("ChangeAllImagesLinksToEmbedded() Embedded img link contentId: {0}", attach.contentId); linkNode.SetAttributeValue("src", "cid:" + attach.contentId); if (draft.AttachmentsEmbedded.All(x => x.contentId != attach.contentId)) { draft.AttachmentsEmbedded.Add(attach); } } draft.HtmlBody = doc.DocumentNode.OuterHtml; } catch (Exception ex) { log.ErrorFormat("ChangeAllImagesLinksToEmbedded(): Exception: {0}", ex.ToString()); } }
public static void ChangeEmbeddedAttachmentLinks(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } var baseAttachmentFolder = MailStoragePathCombiner.GetMessageDirectory(draft.Mailbox.UserId, draft.StreamId); var doc = new HtmlDocument(); doc.LoadHtml(draft.HtmlBody); var linkNodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'" + baseAttachmentFolder + "') or @x-mail-embedded)]"); if (linkNodes == null) { return; } foreach (var linkNode in linkNodes) { var link = linkNode.Attributes["src"].Value; log.InfoFormat("ChangeEmbededAttachmentLinks() Embeded attachment link for changing to cid: {0}", link); var isExternal = link.IndexOf(baseAttachmentFolder) == -1; var fileLink = isExternal ? link : HttpUtility.UrlDecode(link.Substring(baseAttachmentFolder.Length)); var fileName = Path.GetFileName(fileLink); var attach = CreateEmbbededAttachment(fileName, link, fileLink, draft.Mailbox.UserId, draft.Mailbox.TenantId, draft.Mailbox.MailBoxId, draft.StreamId); if (isExternal) { using (var webClient = new WebClient()) { //webClient.Headers.Add("Authorization", GetPartnerAuthHeader(actionUrl)); try { attach.data = webClient.DownloadData(fileLink); } catch (WebException we) { log.Error(we); continue; } } } draft.AttachmentsEmbedded.Add(attach); linkNode.SetAttributeValue("src", "cid:" + attach.contentId); log.InfoFormat("ChangeEmbededAttachmentLinks() Attachment cid: {0}", attach.contentId); } draft.HtmlBody = doc.DocumentNode.OuterHtml; }
public static void ChangeSmileLinks(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } var baseSmileUrl = MailStoragePathCombiner.GetEditorSmileBaseUrl(); var doc = new HtmlDocument(); doc.LoadHtml(draft.HtmlBody); var linkNodes = doc.DocumentNode.SelectNodes("//img[@src and (contains(@src,'" + baseSmileUrl + "'))]"); if (linkNodes == null) { return; } foreach (var linkNode in linkNodes) { var link = linkNode.Attributes["src"].Value; log.InfoFormat("ChangeSmileLinks() Link to smile: {0}", link); var fileName = Path.GetFileName(link); var data = StorageManager.LoadLinkData(link, log); if (!data.Any()) { continue; } var attach = new MailAttachmentData { fileName = fileName, storedName = fileName, contentId = link.GetMd5(), data = data }; log.InfoFormat("ChangeSmileLinks() Embedded smile contentId: {0}", attach.contentId); linkNode.SetAttributeValue("src", "cid:" + attach.contentId); if (draft.AttachmentsEmbedded.All(x => x.contentId != attach.contentId)) { draft.AttachmentsEmbedded.Add(attach); } } draft.HtmlBody = doc.DocumentNode.OuterHtml; }
private void SendMailErrorNotification(MailDraftData draft) { try { // send success notification _signalrServiceClient.SendMailNotification(draft.Mailbox.TenantId, draft.Mailbox.UserId, -1); } catch (Exception ex) { Log.ErrorFormat("Unexpected error with wcf signalrServiceClient: {0}, {1}", ex.Message, ex.StackTrace); } }
public static void ChangeUrlProxyLinks(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } try { draft.HtmlBody = HtmlSanitizer.RemoveProxyHttpUrls(draft.HtmlBody); } catch (Exception ex) { log.ErrorFormat("ChangeUrlProxyLinks(): Exception: {0}", ex.ToString()); } }
private void ReleaseSendingDraftOnFailure(MailDraftData draft) { var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); using (var daoFactory = new DaoFactory()) { using (var tx = daoFactory.DbManager.BeginTransaction(IsolationLevel.ReadUncommitted)) { var listObjects = engine.ChainEngine.GetChainedMessagesInfo(daoFactory, new List <int> { draft.Id }); if (!listObjects.Any()) { return; } engine.MessageEngine.SetFolder(daoFactory, listObjects, FolderType.Draft); tx.Commit(); } } }
private void SendMailNotification(MailDraftData draft) { try { MailNotificationState state = 0; if (!string.IsNullOrEmpty(draft.CalendarIcs)) { switch (draft.CalendarMethod) { case Defines.ICAL_REQUEST: state = MailNotificationState.SentIcalRequest; break; case Defines.ICAL_REPLY: state = MailNotificationState.SentIcalResponse; break; case Defines.ICAL_CANCEL: state = MailNotificationState.SentIcalCancel; break; } } if (draft.IsReceipt) { state = MailNotificationState.ReadingConfirmed; } // send success notification _signalrServiceClient.SendMailNotification(draft.Mailbox.TenantId, draft.Mailbox.UserId, state); } catch (Exception ex) { Log.ErrorFormat("Unexpected error with wcf signalrServiceClient: {0}, {1}", ex.Message, ex.StackTrace); } }
private void AddNotificationAlertToMailbox(MailDraftData draft, Exception exOnSanding) { try { var sbMessage = new StringBuilder(1024); sbMessage .AppendFormat("<div style=\"max-width:500px;font: normal 12px Arial, Tahoma,sans-serif;\"><p style=\"color:gray;font: normal 12px Arial, Tahoma,sans-serif;\">{0}</p>", DaemonLabels.AutomaticMessageLabel) .AppendFormat("<p style=\"font: normal 12px Arial, Tahoma,sans-serif;\">{0}</p>", DaemonLabels.MessageIdentificator .Replace("{subject}", draft.Subject) .Replace("{date}", DateTime.Now.ToString(CultureInfo.InvariantCulture))) .AppendFormat("<div><p style=\"font: normal 12px Arial, Tahoma,sans-serif;\">{0}:</p><ul style=\"color:#333;font: normal 12px Arial, Tahoma,sans-serif;\">", DaemonLabels.RecipientsLabel); draft.To.ForEach(rcpt => sbMessage.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); draft.Cc.ForEach(rcpt => sbMessage.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); draft.Bcc.ForEach(rcpt => sbMessage.AppendFormat("<li>{0}</li>", HttpUtility.HtmlEncode(rcpt))); sbMessage .AppendFormat("</ul>") .AppendFormat("<p style=\"font: normal 12px Arial, Tahoma,sans-serif;\">{0}</p>", DaemonLabels.RecommendationsLabel .Replace("{account_name}", "<b>" + draft.From + "</b>")) .AppendFormat( "<a id=\"delivery_failure_button\" mailid={0} class=\"button blue\" style=\"margin-right:8px;\">{1}</a></div>", draft.Id, DaemonLabels.TryAgainButtonLabel) .AppendFormat("<p style=\"font: normal 12px Arial, Tahoma,sans-serif;\">{0}</p>", DaemonLabels.FaqInformationLabel .Replace("{url_begin}", "<a id=\"delivery_failure_faq_link\" target=\"blank\" href=\"#\" class=\"link underline\">") .Replace("{url_end}", "</a>")); const int max_length = 300; var smtpResponse = string.IsNullOrEmpty(exOnSanding.Message) ? "no response" : exOnSanding.Message.Length > max_length ? exOnSanding.Message.Substring(0, max_length) : exOnSanding.Message; sbMessage.AppendFormat("<p style=\"color:gray;font: normal 12px Arial, Tahoma,sans-serif;\">{0}: \"{1}\"</p></div>", DaemonLabels.ReasonLabel, smtpResponse); draft.Mailbox.Name = ""; var messageDelivery = new MailDraftData(0, draft.Mailbox, DaemonLabels.DaemonEmail, new List <string>() { draft.From }, new List <string>(), new List <string>(), DaemonLabels.SubjectLabel, MailUtil.CreateStreamId(), "", true, new List <int>(), sbMessage.ToString(), MailUtil.CreateStreamId(), new List <MailAttachmentData>()); // SaveToDraft To Inbox var notifyMessageItem = messageDelivery.ToMailMessage(); notifyMessageItem.ChainId = notifyMessageItem.MimeMessageId; notifyMessageItem.IsNew = true; MessageEngine.StoreMailBody(draft.Mailbox, notifyMessageItem, Log); var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); var mailDaemonMessageid = engine.MessageEngine.MailSave(draft.Mailbox, notifyMessageItem, 0, FolderType.Inbox, FolderType.Inbox, null, string.Empty, string.Empty, false); engine.AlertEngine.CreateDeliveryFailureAlert( draft.Mailbox.TenantId, draft.Mailbox.UserId, draft.Mailbox.MailBoxId, draft.Subject, draft.From, draft.Id, mailDaemonMessageid); } catch (Exception exError) { Log.ErrorFormat("AddNotificationAlertToMailbox() in MailboxId={0} failed with exception:\r\n{1}", draft.Mailbox.MailBoxId, exError.ToString()); } }
public static void ChangeAttachedFileLinksAddresses(this MailDraftData draft, ILog log = null) { if (log == null) { log = new NullLog(); } var doc = new HtmlDocument(); doc.LoadHtml(draft.HtmlBody); var linkNodes = doc.DocumentNode.SelectNodes("//a[contains(@class,'mailmessage-filelink-link')]"); if (linkNodes == null) { return; } var fileStorageService = new FileStorageServiceController(); var setLinks = new List <Tuple <string, string> >(); foreach (var linkNode in linkNodes) { var fileId = linkNode.Attributes["data-fileid"].Value; var objectId = "file_" + fileId; linkNode.Attributes["class"].Remove(); // 'mailmessage-filelink-link' linkNode.Attributes["data-fileid"].Remove(); // 'data-fileid' var setLink = setLinks.SingleOrDefault(x => x.Item1 == fileId); if (setLink != null) { linkNode.SetAttributeValue("href", setLink.Item2); log.InfoFormat("ChangeAttachedFileLinks() Change file link href: {0}", fileId); continue; } var aceCollection = new AceCollection { Entries = new ItemList <string> { objectId }, Aces = new ItemList <AceWrapper> { new AceWrapper { SubjectId = FileConstant.ShareLinkId, SubjectGroup = true, Share = draft.FileLinksShareMode } } }; fileStorageService.SetAceObject(aceCollection, false); log.InfoFormat("ChangeAttachedFileLinks() Set public accees to file: {0}", fileId); var sharedInfo = fileStorageService.GetSharedInfo(new ItemList <string> { objectId }) .Find(r => r.SubjectId == FileConstant.ShareLinkId); linkNode.SetAttributeValue("href", sharedInfo.Link); log.InfoFormat("ChangeAttachedFileLinks() Change file link href: {0}", fileId); setLinks.Add(new Tuple <string, string>(fileId, sharedInfo.Link)); } linkNodes = doc.DocumentNode.SelectNodes("//div[contains(@class,'mailmessage-filelink')]"); foreach (var linkNode in linkNodes) { linkNode.Attributes["class"].Remove(); } draft.HtmlBody = doc.DocumentNode.OuterHtml; }
private static MimeEntity ToMimeMessageBody(MailDraftData draft) { string textBody; MailUtil.TryExtractTextFromHtml(draft.HtmlBody, out textBody); MultipartAlternative alternative = null; MimeEntity body = null; if (!string.IsNullOrEmpty(textBody)) { var textPart = new TextPart("plain") { Text = textBody, ContentTransferEncoding = ContentEncoding.QuotedPrintable }; if (!string.IsNullOrEmpty(draft.HtmlBody)) { alternative = new MultipartAlternative { textPart }; body = alternative; } else { body = textPart; } } if (!string.IsNullOrEmpty(draft.HtmlBody)) { var htmlPart = new TextPart("html") { Text = draft.HtmlBody, ContentTransferEncoding = ContentEncoding.QuotedPrintable }; MimeEntity html; if (draft.AttachmentsEmbedded.Any()) { htmlPart.ContentTransferEncoding = ContentEncoding.Base64; var related = new MultipartRelated { Root = htmlPart }; related.Root.ContentId = null; foreach (var emb in draft.AttachmentsEmbedded) { var linkedResource = ConvertToMimePart(emb, emb.contentId); related.Add(linkedResource); } html = related; } else { html = htmlPart; } if (alternative != null) { alternative.Add(html); } else { body = html; } } if (!string.IsNullOrEmpty(draft.CalendarIcs)) { var calendarPart = new TextPart("calendar") { Text = draft.CalendarIcs, ContentTransferEncoding = ContentEncoding.QuotedPrintable }; calendarPart.ContentType.Parameters.Add("method", draft.CalendarMethod); if (alternative != null) { alternative.Add(calendarPart); } else { body = calendarPart; } } if (draft.Attachments.Any() || !string.IsNullOrEmpty(draft.CalendarIcs)) { var mixed = new Multipart("mixed"); if (body != null) { mixed.Add(body); } foreach (var att in draft.Attachments) { var attachment = ConvertToMimePart(att); mixed.Add(attachment); } if (!string.IsNullOrEmpty(draft.CalendarIcs)) { var filename = "calendar.ics"; switch (draft.CalendarMethod) { case Defines.ICAL_REQUEST: filename = "invite.ics"; break; case Defines.ICAL_REPLY: filename = "reply.ics"; break; case Defines.ICAL_CANCEL: filename = "cancel.ics"; break; } var contentType = new ContentType("application", "ics"); contentType.Parameters.Add("method", draft.CalendarMethod); contentType.Parameters.Add("name", filename); var calendarResource = new MimePart(contentType) { ContentDisposition = new ContentDisposition(ContentDisposition.Attachment), ContentTransferEncoding = ContentEncoding.Base64, FileName = filename }; var data = Encoding.UTF8.GetBytes(draft.CalendarIcs); var ms = new MemoryStream(data); calendarResource.Content = new MimeContent(ms); mixed.Add(calendarResource); } body = mixed; } if (body != null) { return(body); } return(new TextPart("plain") { Text = string.Empty }); }
public static MimeMessage ToMimeMessage(this MailDraftData draft) { var mimeMessage = new MimeMessage { Date = DateTime.UtcNow, Subject = !string.IsNullOrEmpty(draft.Subject) ? draft.Subject : "", MessageId = draft.MimeMessageId }; var from = MailboxAddress.Parse(ParserOptions.Default, draft.From); mimeMessage.From.Add(from); if (draft.To.Any()) { mimeMessage.To.AddRange(draft.To.ConvertAll(MailboxAddress.Parse)); } if (draft.Cc.Any()) { mimeMessage.Cc.AddRange(draft.Cc.ConvertAll(MailboxAddress.Parse)); } if (draft.Bcc.Any()) { mimeMessage.Bcc.AddRange(draft.Bcc.ConvertAll(MailboxAddress.Parse)); } if (draft.Important) { mimeMessage.Importance = MessageImportance.High; } if (!string.IsNullOrEmpty(draft.MimeReplyToId)) { mimeMessage.InReplyTo = draft.MimeReplyToId; } mimeMessage.Body = ToMimeMessageBody(draft); if (draft.IsAutogenerated) { mimeMessage.Headers.Add("Auto-Submitted", "auto-generated"); } if (draft.IsAutoreplied) { mimeMessage.Headers.Add("Auto-Submitted", "auto-replied"); } if (draft.RequestReceipt) { mimeMessage.Headers[HeaderId.ReturnReceiptTo] = from.ToString(true); } if (draft.RequestRead) { mimeMessage.Headers[HeaderId.DispositionNotificationTo] = from.ToString(true); } return(mimeMessage); }
public virtual MailMessage Save( int id, string from, List <string> to, List <string> cc, List <string> bcc, string mimeReplyToId, bool importance, string subject, List <int> tags, string body, List <MailAttachmentData> attachments, string calendarIcs, DeliveryFailureMessageTranslates translates = null) { var mailAddress = new MailAddress(from); var engine = new EngineFactory(Tenant, User); var accounts = engine.AccountEngine.GetAccountInfoList().ToAccountData(); var account = accounts.FirstOrDefault(a => a.Email.ToLower().Equals(mailAddress.Address)); if (account == null) { throw new ArgumentException("Mailbox not found"); } if (account.IsGroup) { throw new InvalidOperationException("Saving emails from a group address is forbidden"); } var mbox = engine.MailboxEngine.GetMailboxData( new СoncreteUserMailboxExp(account.MailboxId, Tenant, User)); if (mbox == null) { throw new ArgumentException("No such mailbox"); } string mimeMessageId, streamId; var previousMailboxId = mbox.MailBoxId; if (id > 0) { var message = engine.MessageEngine.GetMessage(id, new MailMessage.Options { LoadImages = false, LoadBody = true, NeedProxyHttp = Defines.NeedProxyHttp, NeedSanitizer = false }); if (message.Folder != FolderType.Draft) { throw new InvalidOperationException("Saving emails is permitted only in the Drafts folder"); } if (message.HtmlBody.Length > Defines.MaximumMessageBodySize) { throw new InvalidOperationException("Message body exceeded limit (" + Defines.MaximumMessageBodySize / 1024 + " KB)"); } mimeMessageId = message.MimeMessageId; streamId = message.StreamId; previousMailboxId = message.MailboxId; } else { mimeMessageId = MailUtil.CreateMessageId(); streamId = MailUtil.CreateStreamId(); } var fromAddress = MailUtil.CreateFullEmail(mbox.Name, mbox.EMail.Address); var compose = new MailDraftData(id, mbox, fromAddress, to, cc, bcc, subject, mimeMessageId, mimeReplyToId, importance, tags, body, streamId, attachments, calendarIcs) { PreviousMailboxId = previousMailboxId }; DaemonLabels = translates ?? DeliveryFailureMessageTranslates.Defauilt; return(Save(compose)); }
public long Send(int id, string from, List <string> to, List <string> cc, List <string> bcc, string mimeReplyToId, bool importance, string subject, List <int> tags, string body, List <MailAttachmentData> attachments, Files.Core.Security.FileShare fileLinksShareMode, string calendarIcs, bool isAutoreply, bool requestReceipt, bool requestRead, DeliveryFailureMessageTranslates translates = null) { if (id < 1) { id = 0; } if (string.IsNullOrEmpty(from)) { throw new ArgumentNullException("from"); } if (!to.Any()) { throw new ArgumentNullException("to"); } var mailAddress = new MailAddress(from); var engine = new EngineFactory(Tenant, User); var accounts = engine.AccountEngine.GetAccountInfoList().ToAccountData(); var account = accounts.FirstOrDefault(a => a.Email.ToLower().Equals(mailAddress.Address)); if (account == null) { throw new ArgumentException("Mailbox not found"); } if (account.IsGroup) { throw new InvalidOperationException("Sending emails from a group address is forbidden"); } var mbox = engine.MailboxEngine.GetMailboxData( new СoncreteUserMailboxExp(account.MailboxId, Tenant, User)); if (mbox == null) { throw new ArgumentException("No such mailbox"); } if (!mbox.Enabled) { throw new InvalidOperationException("Sending emails from a disabled account is forbidden"); } string mimeMessageId, streamId; var previousMailboxId = mbox.MailBoxId; if (id > 0) { var message = engine.MessageEngine.GetMessage(id, new MailMessage.Options { LoadImages = false, LoadBody = true, NeedProxyHttp = Defines.NeedProxyHttp, NeedSanitizer = false }); if (message.Folder != FolderType.Draft && message.Folder != FolderType.Templates) { throw new InvalidOperationException("Sending emails is permitted only in the Drafts folder"); } if (message.HtmlBody.Length > Defines.MaximumMessageBodySize) { throw new InvalidOperationException("Message body exceeded limit (" + Defines.MaximumMessageBodySize / 1024 + " KB)"); } mimeMessageId = message.MimeMessageId; streamId = message.StreamId; foreach (var attachment in attachments) { attachment.streamId = streamId; } previousMailboxId = message.MailboxId; } else { mimeMessageId = MailUtil.CreateMessageId(); streamId = MailUtil.CreateStreamId(); } var fromAddress = MailUtil.CreateFullEmail(mbox.Name, mailAddress.Address); var draft = new MailDraftData(id, mbox, fromAddress, to, cc, bcc, subject, mimeMessageId, mimeReplyToId, importance, tags, body, streamId, attachments, calendarIcs) { FileLinksShareMode = fileLinksShareMode, PreviousMailboxId = previousMailboxId, RequestReceipt = requestReceipt, RequestRead = requestRead, IsAutogenerated = !string.IsNullOrEmpty(calendarIcs), IsAutoreplied = isAutoreply }; DaemonLabels = translates ?? DeliveryFailureMessageTranslates.Defauilt; return(Send(draft)); }
public bool SimpleSend( string from, List <string> to, string subject, string body, bool isReceipt, DeliveryFailureMessageTranslates translates = null) { if (!to.Any()) { throw new ArgumentNullException("to"); } if (string.IsNullOrEmpty(from)) { throw new ArgumentNullException("from"); } var mailAddress = new MailAddress(from); var engine = new EngineFactory(Tenant, User); var accounts = engine.AccountEngine.GetAccountInfoList().ToAccountData(); var account = accounts.FirstOrDefault(a => a.Email.ToLower().Equals(mailAddress.Address)); if (account == null) { throw new ArgumentException("Mailbox not found"); } if (account.IsGroup) { throw new InvalidOperationException("Sending emails from a group address is forbidden"); } var mbox = engine.MailboxEngine.GetMailboxData( new СoncreteUserMailboxExp(account.MailboxId, Tenant, User)); if (mbox == null) { throw new ArgumentException("No such mailbox"); } if (!mbox.Enabled) { throw new InvalidOperationException("Sending emails from a disabled account is forbidden"); } var previousMailboxId = mbox.MailBoxId; var mimeMessageId = MailUtil.CreateMessageId(); var streamId = MailUtil.CreateStreamId(); var fromAddress = MailUtil.CreateFullEmail(mbox.Name, mailAddress.Address); var draft = new MailDraftData(0, mbox, fromAddress, to, new List <string>(), new List <string>(), subject, mimeMessageId, string.Empty, false, new List <int>(), body, streamId, new List <MailAttachmentData>(), string.Empty) { FileLinksShareMode = (Files.Core.Security.FileShare)FileShare.None, PreviousMailboxId = previousMailboxId, RequestReceipt = false, RequestRead = false, IsAutogenerated = false, IsAutoreplied = false, IsReceipt = isReceipt }; DaemonLabels = translates ?? DeliveryFailureMessageTranslates.Defauilt; var scheme = HttpContext.Current == null ? Uri.UriSchemeHttp : HttpContext.Current.Request.GetUrlRewriter().Scheme; var currentUrl = HttpContext.Current != null?HttpContext.Current.Request.GetUrlRewriter().ToString() : null; Task.Run(() => { try { if (HttpContext.Current == null && !WorkContext.IsMono) { HttpContext.Current = new HttpContext( new HttpRequest("hack", currentUrl, string.Empty), new HttpResponse(new StringWriter())); } CoreContext.TenantManager.SetCurrentTenant(draft.Mailbox.TenantId); SecurityContext.CurrentUser = new Guid(draft.Mailbox.UserId); draft.ChangeEmbeddedAttachmentLinks(Log); var mimeMessage = draft.ToMimeMessage(); using (var mc = new MailClient(draft.Mailbox, CancellationToken.None, certificatePermit: draft.Mailbox.IsTeamlab || _sslCertificatePermit, log: Log, enableDsn: draft.RequestReceipt)) { mc.Send(mimeMessage, false); } Log.Info($"User {draft.Mailbox.UserId} sent a read confirmation to {string.Join(",", draft.To)} from {draft.From}"); SendMailNotification(draft); } catch (Exception ex) { Log.ErrorFormat("Mail->Send failed: Exception: {0}", ex.ToString()); SendMailErrorNotification(draft, MailNotificationState.SendReceiptError); } }); return(true); }
private void ReleaseSendingDraftOnSuccess(MailDraftData draft, MailMessage message) { var engine = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId); using (var daoFactory = new DaoFactory()) { var db = daoFactory.DbManager; using (var tx = db.BeginTransaction(IsolationLevel.ReadUncommitted)) { // message was correctly send - lets update its chains id var draftChainId = message.ChainId; // before moving message from draft to sent folder - lets recalculate its correct chain id var chainInfo = engine.MessageEngine.DetectChain(daoFactory, draft.Mailbox, message.MimeMessageId, message.MimeReplyToId, message.Subject); message.ChainId = chainInfo.Id; if (message.ChainId.Equals(message.MimeMessageId)) { message.MimeReplyToId = null; } var daoMailInfo = daoFactory.CreateMailInfoDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); if (!draftChainId.Equals(message.ChainId)) { daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageId(message.Id) .Build(), MailTable.Columns.ChainId, message.ChainId); engine.ChainEngine.UpdateChain(daoFactory, draftChainId, FolderType.Sending, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); var daoCrmLink = daoFactory.CreateCrmLinkDao(draft.Mailbox.TenantId, draft.Mailbox.UserId); daoCrmLink.UpdateCrmLinkedChainId(draftChainId, draft.Mailbox.MailBoxId, message.ChainId); } engine.ChainEngine.UpdateChain(daoFactory, message.ChainId, FolderType.Sending, null, draft.Mailbox.MailBoxId, draft.Mailbox.TenantId, draft.Mailbox.UserId); var listObjects = engine.ChainEngine.GetChainedMessagesInfo(daoFactory, new List <int> { draft.Id }); if (!listObjects.Any()) { return; } engine.MessageEngine.SetFolder(daoFactory, listObjects, FolderType.Sent); daoMailInfo.SetFieldValue( SimpleMessagesExp.CreateBuilder(Tenant, User) .SetMessageId(draft.Id) .Build(), MailTable.Columns.FolderRestore, FolderType.Sent); tx.Commit(); } } }
public long Send(MailDraftData draft) { if (string.IsNullOrEmpty(draft.HtmlBody)) { draft.HtmlBody = EMPTY_HTML_BODY; } var message = Save(draft); if (message.Id <= 0) { throw new ArgumentException(string.Format("DraftManager-Send: Invalid message.Id = {0}", message.Id)); } ValidateAddresses(DraftFieldTypes.From, new List <string> { draft.From }, true); message.ToList = ValidateAddresses(DraftFieldTypes.To, draft.To, true); message.CcList = ValidateAddresses(DraftFieldTypes.Cc, draft.Cc, false); message.BccList = ValidateAddresses(DraftFieldTypes.Bcc, draft.Bcc, false); var scheme = HttpContext.Current == null ? Uri.UriSchemeHttp : HttpContext.Current.Request.GetUrlRewriter().Scheme; SetDraftSending(draft); Task.Run(() => { try { CoreContext.TenantManager.SetCurrentTenant(draft.Mailbox.TenantId); SecurityContext.AuthenticateMe(new Guid(draft.Mailbox.UserId)); draft.ChangeEmbeddedAttachmentLinks(Log); draft.ChangeSmileLinks(Log); draft.ChangeAttachedFileLinksAddresses(Log); draft.ChangeAttachedFileLinksImages(Log); if (!string.IsNullOrEmpty(draft.CalendarIcs)) { draft.ChangeAllImagesLinksToEmbedded(Log); } draft.ChangeUrlProxyLinks(Log); var mimeMessage = draft.ToMimeMessage(); using (var mc = new MailClient(draft.Mailbox, CancellationToken.None, certificatePermit: draft.Mailbox.IsTeamlab || _sslCertificatePermit, log: Log, enableDsn: draft.RequestReceipt)) { mc.Send(mimeMessage, draft.Mailbox.Imap && !DisableImapSendSyncServers.Contains(draft.Mailbox.Server)); } try { SaveIcsAttachment(draft, mimeMessage); SendMailNotification(draft); ReleaseSendingDraftOnSuccess(draft, message); var factory = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId, Log); factory.CrmLinkEngine.AddRelationshipEventForLinkedAccounts(draft.Mailbox, message, scheme); factory.EmailInEngine.SaveEmailInData(draft.Mailbox, message, scheme); SaveFrequentlyContactedAddress(draft.Mailbox.TenantId, draft.Mailbox.UserId, mimeMessage, scheme); var filters = factory.FilterEngine.GetList(); if (filters.Any()) { factory.FilterEngine.ApplyFilters(message, draft.Mailbox, new MailFolder(FolderType.Sent, ""), filters); } factory.IndexEngine.Update(new List <MailWrapper> { message.ToMailWrapper(draft.Mailbox.TenantId, new Guid(draft.Mailbox.UserId)) }); } catch (Exception ex) { Log.ErrorFormat("Unexpected Error in Send() Id = {0}\r\nException: {1}", message.Id, ex.ToString()); } } catch (Exception ex) { Log.ErrorFormat("Mail->Send failed: Exception: {0}", ex.ToString()); AddNotificationAlertToMailbox(draft, ex); ReleaseSendingDraftOnFailure(draft); SendMailErrorNotification(draft); } finally { if (draft.IsAutoreplied) { var engineFactory = new EngineFactory(draft.Mailbox.TenantId, draft.Mailbox.UserId, Log); engineFactory .AutoreplyEngine .SaveAutoreplyHistory(draft.Mailbox, message); } } }); return(message.Id); }