diff --git a/GUIs.Test.TestGUI/frmEmail.vb b/GUIs.Test.TestGUI/frmEmail.vb index fb6089a5..af9c10d4 100644 --- a/GUIs.Test.TestGUI/frmEmail.vb +++ b/GUIs.Test.TestGUI/frmEmail.vb @@ -13,7 +13,7 @@ Public Class frmEmail Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click - Dim oResult = Email.Test_Login(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL) + Dim oResult = Email.Test_Login(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS) If oResult = True Then AddLog($"Connection to {txtServer.Text} successful.") @@ -23,7 +23,7 @@ Public Class frmEmail End Sub Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click - Dim oMessages = Email.Get_Messages(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL, "Inbox") + Dim oMessages = Email.Get_Messages(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS, "Inbox") AddLog($"Found {oMessages.Count} Messages!") For Each oMessage In oMessages @@ -37,7 +37,7 @@ Public Class frmEmail Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click Dim oMessageId As String = txtMessageID.Text - Dim oMail As IMail = Email.Get_Message(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSL, oMessageId, "Inbox") + Dim oMail As IMail = Email.Get_Message(txtServer.Text, txtUser.Text, txtPassword.Text, Email2.EmailSecurity.SSLTLS, oMessageId, "Inbox") Dim oFilename As String = IO.Path.GetTempFileName oMail.Save(oFilename) diff --git a/Modules.Messaging/Email2.vb b/Modules.Messaging/Email2.vb index d0245e10..6a29ccb9 100644 --- a/Modules.Messaging/Email2.vb +++ b/Modules.Messaging/Email2.vb @@ -3,11 +3,14 @@ Imports DigitalData.Modules.Filesystem Imports Limilabs.Mail Imports Limilabs.Client.IMAP Imports Limilabs.Mail.MIME +Imports System.IO +Imports Limilabs.Mail.MSG Public Class Email2 Private ReadOnly Logger As Logger Private ReadOnly LogConfig As LogConfig Private ReadOnly FileEx As Filesystem.File + Private ReadOnly MailBuilder As New MailBuilder() Public Sub New(pLogConfig As LogConfig) LogConfig = pLogConfig @@ -16,21 +19,49 @@ Public Class Email2 End Sub Public Enum EmailSecurity - SSL + SSLTLS STARTTLS End Enum Private Function Get_PortForSecurityOption(pSecurity As EmailSecurity) As Integer - Select Case pSecurity - Case EmailSecurity.SSL - Return 993 + If pSecurity = EmailSecurity.STARTTLS Then + Return 143 + Else ' EmailSecurity.SSL + Return 993 + End If + End Function - Case EmailSecurity.STARTTLS - Return 143 + Private Function New_Connection(pIMAP As Imap, pServer As String, pUsername As String, pPassword As String, pPort As Integer, pSecurity As EmailSecurity) As Boolean + Try + Logger.Debug("Connecting to IMAP server [{0}]", pServer) - Case Else - Return 0 - End Select + Dim oPort As Integer = pPort + If oPort = 0 Then + oPort = Get_PortForSecurityOption(pSecurity) + End If + Logger.Debug("Using Port [{0}] for connection", oPort) + + If pSecurity = EmailSecurity.STARTTLS Then + Logger.Debug("Using STARTTLS as Security Option") + pIMAP.Connect(pServer, oPort) + pIMAP.StartTLS() + Else + Logger.Debug("Using SSL/TLS as Security Option") + pIMAP.ConnectSSL(pServer, oPort) + End If + Logger.Debug("Connection to IMAP Server [{0}] established!", pServer) + + Logger.Debug("Logging in with user [{0}]", pUsername) + pIMAP.UseBestLogin(pUsername, pPassword) + + Return True + + Catch ex As Exception + Logger.Warn("Could not connect to server [{0}] with user [{1}]", pServer, pUsername) + Logger.Error(ex) + Return False + + End Try End Function Public Function Test_Login(pServer As String, pUsername As String, pPassword As String, pSecurity As EmailSecurity, Optional pFolder As String = "Inbox", Optional pPort As Integer = 0) As Boolean @@ -38,30 +69,15 @@ Public Class Email2 Try Using oClient As New Imap() - Logger.Debug("Connecting to IMAP server [{0}]", pServer) + If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then + Logger.Debug("Fetching Inbox") + Dim oStatus As FolderStatus = oClient.SelectInbox() + + Logger.Debug("Test finished!") + oClient.Close() - Dim oPort As Integer = pPort - If oPort = 0 Then - oPort = Get_PortForSecurityOption(pSecurity) End If - If pSecurity = EmailSecurity.SSL Then - oClient.ConnectSSL(pServer, oPort) - ElseIf pSecurity = EmailSecurity.STARTTLS Then - oClient.Connect(pServer, oPort) - oClient.StartTLS() - Else - Throw New ArgumentOutOfRangeException("Security") - End If - - Logger.Debug("Logging in with user [{0}]", pUsername) - oClient.UseBestLogin(pUsername, pPassword) - - Logger.Debug("Fetching Inbox") - Dim oStatus As FolderStatus = oClient.SelectInbox() - - Logger.Debug("Test finished!") - oClient.Close() End Using Return True @@ -80,46 +96,27 @@ Public Class Email2 Try Using oClient As New Imap() - Logger.Debug("Connecting to IMAP server [{0}]", pServer) + If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then + Logger.Debug("Fetching Folder [{0}]", pFolder) + Dim oStatus As FolderStatus = oClient.Select(pFolder) - Dim oPort As Integer = pPort - If oPort = 0 Then - oPort = Get_PortForSecurityOption(pSecurity) + Logger.Debug("Fetching Unseen UUIDs") + Dim oUUIDs As List(Of Long) = oClient.Search(Flag.Unseen) + Dim oMailBuilder As New MailBuilder() + + Logger.Debug("Fetching Unseen Mails") + For Each oUUID As Long In oUUIDs + Dim oEmlFile As Byte() = oClient.GetMessageByUID(oUUID) + Dim oEmail As IMail = oMailBuilder.CreateFromEml(oEmlFile) + oMails.Add(oEmail) + + Next + + Logger.Debug("Emails fetched!") + oClient.Close() End If - If pSecurity = EmailSecurity.SSL Then - oClient.ConnectSSL(pServer, oPort) - - ElseIf pSecurity = EmailSecurity.STARTTLS Then - oClient.Connect(pServer, oPort) - oClient.StartTLS() - - Else - Throw New ArgumentOutOfRangeException("Security") - - End If - - Logger.Debug("Logging in with user [{0}]", pUsername) - oClient.UseBestLogin(pUsername, pPassword) - - Logger.Debug("Fetching Folder [{0}]", pFolder) - Dim oStatus As FolderStatus = oClient.Select(pFolder) - - Logger.Debug("Fetching Unseen UUIDs") - Dim oUUIDs As List(Of Long) = oClient.Search(Flag.Unseen) - Dim oMailBuilder As New MailBuilder() - - Logger.Debug("Fetching Unseen Mails") - For Each oUUID As Long In oUUIDs - Dim oEmlFile As Byte() = oClient.GetMessageByUID(oUUID) - Dim oEmail As IMail = oMailBuilder.CreateFromEml(oEmlFile) - oMails.Add(oEmail) - - Next - - Logger.Debug("Emails fetched!") - oClient.Close() End Using Return oMails @@ -139,50 +136,27 @@ Public Class Email2 Try Using oClient As New Imap() - Logger.Debug("Connecting to IMAP server [{0}]", pServer) + If New_Connection(oClient, pServer, pUsername, pPassword, pPort, pSecurity) Then + Logger.Debug("Fetching Folder [{0}]", pFolder) + Dim oStatus As FolderStatus = oClient.Select(pFolder) - Dim oPort As Integer = pPort - If oPort = 0 Then - oPort = Get_PortForSecurityOption(pSecurity) + Logger.Debug("Fetching UUIDs") + Dim oUUIDs As List(Of Long) = oClient.Search(Flag.All) + Logger.Debug("Fetching Mails") + Dim oInfos As List(Of MessageInfo) = oClient.GetMessageInfoByUID(oUUIDs) - End If + Dim oMailInfo = oInfos.Where(Function(i) i.Envelope.MessageID = pMessageId).FirstOrDefault() - If pSecurity = EmailSecurity.SSL Then - oClient.ConnectSSL(pServer, oPort) - - ElseIf pSecurity = EmailSecurity.STARTTLS Then - oClient.Connect(pServer, oPort) - oClient.StartTLS() - - Else - Throw New ArgumentOutOfRangeException("Security") - - End If - - Logger.Debug("Logging in with user [{0}]", pUsername) - oClient.UseBestLogin(pUsername, pPassword) - - Logger.Debug("Fetching Inbox") - Dim oStatus As FolderStatus = oClient.Select(pFolder) - - Logger.Debug("Fetching UUIDs") - Dim oUUIDs As List(Of Long) = oClient.Search(Flag.All) - Dim oMailBuilder As New MailBuilder() - - Dim oInfos As List(Of MessageInfo) = oClient.GetMessageInfoByUID(oUUIDs) - - Logger.Debug("Fetching Unseen Mails") - For Each oInfo As MessageInfo In oInfos - If oInfo.Envelope.MessageID = pMessageId Then - Dim oMailData As Byte() = oClient.GetMessageByUID(oInfo.UID) - oMail = oMailBuilder.CreateFromEml(oMailData) - - Exit For + If oMailInfo IsNot Nothing Then + Dim oMailData As Byte() = oClient.GetMessageByUID(oMailInfo.UID) + oMail = MailBuilder.CreateFromEml(oMailData) End If - Next - Logger.Debug("Emails fetched!") - oClient.Close() + Logger.Debug("Emails fetched!") + oClient.Close() + + End If + End Using Return oMail @@ -190,16 +164,16 @@ Public Class Email2 Catch ex As Exception Logger.Warn("Login failed for server [{0}:{1}] with user [{2}]!", pServer, pPort, pUsername) Logger.Error(ex) - Return New List(Of IMail) + + Return Nothing End Try End Function - Public Function Remove_AttachmentsFromEmail(pFileName As String) As String + Public Function Remove_AttachmentsFromEmail(pFileName As String, Optional pSuffix As String = "") As String Try - Dim oTempFileName As String = IO.Path.GetTempFileName() - Dim oMailBuilder As New MailBuilder() - Dim oMail = oMailBuilder.CreateFromEmlFile(pFileName) + Dim oTempFileName As String = Path.Combine(Path.GetTempPath(), AddFilenameSuffix(pFileName, pSuffix)) + Dim oMail = MailBuilder.CreateFromEmlFile(pFileName) oMail.RemoveAttachments() oMail.Save(oTempFileName) @@ -215,8 +189,7 @@ Public Class Email2 Public Function Save_AttachmentsToDisk(pFileName As String) As List(Of String) Try Dim oAttachmentPaths As New List(Of String) - Dim oMailBuilder As New MailBuilder() - Dim oMail = oMailBuilder.CreateFromEmlFile(pFileName) + Dim oMail = MailBuilder.CreateFromEmlFile(pFileName) Dim oTempPath As String = IO.Path.GetTempPath() If oMail.Attachments.Count = 0 Then @@ -238,4 +211,56 @@ Public Class Email2 Return New List(Of String) End Try End Function + + Public Function ConvertMsgToEml(pEmailFileName As String) As String + Dim oInfo As New FileInfo(pEmailFileName) + + If oInfo.Extension.ToUpper = ".EML" Then + Return pEmailFileName + + ElseIf oInfo.Extension.ToUpper = ".MSG" Then + Return DoConvertMsgToEmlFile(pEmailFileName) + + Else + Return Nothing + + End If + End Function + + Private Function DoConvertMsgToEmlFile(pMsgFile As String) As String + Try + Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pMsgFile) + Dim oEmlPath As String = $"{oFileNameWithoutExtension}.eml" + + Using oConverter As New MsgConverter(pMsgFile) + Dim oEmail As IMail = oConverter.CreateMessage() + Dim oData As Byte() = oEmail.Render() + + oEmail.Save(oEmlPath) + End Using + + Return oEmlPath + + Catch ex As Exception + Return Nothing + + End Try + End Function + + Private Function GetTempFileNameWithExtension(pExtension As String) As String + Dim oTempFileName As String = IO.Path.GetTempFileName() + Dim oInfo As New IO.FileInfo(oTempFileName) + Dim oExtension As String = IIf(pExtension.StartsWith("."), pExtension, $".{pExtension}") + Dim oNewFileName = IO.Path.Combine(oInfo.DirectoryName, oInfo.Name.Replace(oInfo.Extension, oExtension)) + + Return oNewFileName + End Function + + Private Function AddFilenameSuffix(pFilename As String, pSuffix As String) + Dim oFileInfo As New FileInfo(pFilename) + Dim oExtension As String = oFileInfo.Extension + Dim oFileNameWithoutExtension = Path.GetFileNameWithoutExtension(pFilename) + + Return $"{oFileNameWithoutExtension}{pSuffix}{oExtension}" + End Function End Class