Пример #1
0
        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));
            }
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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;
        }
Пример #4
0
        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);
        }
Пример #5
0
        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());
            }
        }
Пример #6
0
        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;
        }
Пример #7
0
        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;
        }
Пример #8
0
 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);
     }
 }
Пример #9
0
        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());
            }
        }
Пример #10
0
        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();
                }
            }
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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());
            }
        }
Пример #13
0
        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;
        }
Пример #14
0
        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
            });
        }
Пример #15
0
        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);
        }
Пример #16
0
        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));
        }
Пример #17
0
        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));
        }
Пример #18
0
        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);
        }
Пример #19
0
        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();
                }
            }
        }
Пример #20
0
        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);
        }