diff --git a/obp-api/pom.xml b/obp-api/pom.xml
index 1227da21a..92bf9c7df 100644
--- a/obp-api/pom.xml
+++ b/obp-api/pom.xml
@@ -101,6 +101,12 @@
commons-text
1.10.0
+
+
+ org.apache.commons
+ commons-email
+ 1.5
+
org.postgresql
postgresql
diff --git a/obp-api/src/main/scala/code/api/util/CommonsEmailWrapper.scala b/obp-api/src/main/scala/code/api/util/CommonsEmailWrapper.scala
new file mode 100644
index 000000000..bd695b819
--- /dev/null
+++ b/obp-api/src/main/scala/code/api/util/CommonsEmailWrapper.scala
@@ -0,0 +1,201 @@
+package code.api.util
+
+import org.apache.commons.mail.{Email, SimpleEmail, HtmlEmail, MultiPartEmail, EmailAttachment, DefaultAuthenticator}
+import java.io.File
+import java.net.URL
+import code.util.Helper.MdcLoggable
+import net.liftweb.common.{Box, Empty, Full}
+import net.liftweb.util.Helpers.now
+
+/**
+ * Apache Commons Email Wrapper for OBP-API
+ * This wrapper provides a simple interface to send emails using Apache Commons Email
+ * instead of Lift Web's Mailer
+ */
+object CommonsEmailWrapper extends MdcLoggable {
+
+ /**
+ * Email configuration case class
+ */
+ case class EmailConfig(
+ smtpHost: String,
+ smtpPort: Int,
+ username: String,
+ password: String,
+ useTLS: Boolean = true,
+ useSSL: Boolean = false,
+ debug: Boolean = false
+ )
+
+ /**
+ * Email content case class
+ */
+ case class EmailContent(
+ from: String,
+ to: List[String],
+ cc: List[String] = List.empty,
+ bcc: List[String] = List.empty,
+ subject: String,
+ textContent: Option[String] = None,
+ htmlContent: Option[String] = None,
+ attachments: List[EmailAttachment] = List.empty
+ )
+
+ /**
+ * Send simple text email
+ */
+ def sendTextEmail(config: EmailConfig, content: EmailContent): Box[String] = {
+ try {
+ logger.info(s"Sending text email from ${content.from} to ${content.to.mkString(", ")}")
+
+ val email = new SimpleEmail()
+ configureEmail(email, config, content)
+
+ // Set text content
+ content.textContent match {
+ case Some(text) => email.setMsg(text)
+ case None => email.setMsg("")
+ }
+
+ val messageId = email.send()
+ logger.info(s"Email sent successfully with Message-ID: $messageId")
+ Full(messageId)
+ } catch {
+ case e: Exception =>
+ logger.error(s"Failed to send text email: ${e.getMessage}", e)
+ Empty
+ }
+ }
+
+ /**
+ * Send HTML email
+ */
+ def sendHtmlEmail(config: EmailConfig, content: EmailContent): Box[String] = {
+ try {
+ logger.info(s"Sending HTML email from ${content.from} to ${content.to.mkString(", ")}")
+
+ val email = new HtmlEmail()
+ configureEmail(email, config, content)
+
+ // Set HTML content
+ content.htmlContent match {
+ case Some(html) => email.setHtmlMsg(html)
+ case None => email.setHtmlMsg("No content")
+ }
+
+ // Set text content as fallback
+ content.textContent.foreach(email.setTextMsg)
+
+ val messageId = email.send()
+ logger.info(s"HTML email sent successfully with Message-ID: $messageId")
+ Full(messageId)
+ } catch {
+ case e: Exception =>
+ logger.error(s"Failed to send HTML email: ${e.getMessage}", e)
+ Empty
+ }
+ }
+
+ /**
+ * Send email with attachments
+ */
+ def sendEmailWithAttachments(config: EmailConfig, content: EmailContent): Box[String] = {
+ try {
+ logger.info(s"Sending email with attachments from ${content.from} to ${content.to.mkString(", ")}")
+
+ val email = new MultiPartEmail()
+ configureEmail(email, config, content)
+
+ // Set text content
+ content.textContent.foreach(email.setMsg)
+
+ // Add attachments
+ content.attachments.foreach(email.attach)
+
+ val messageId = email.send()
+ logger.info(s"Email with attachments sent successfully with Message-ID: $messageId")
+ Full(messageId)
+ } catch {
+ case e: Exception =>
+ logger.error(s"Failed to send email with attachments: ${e.getMessage}", e)
+ Empty
+ }
+ }
+
+ /**
+ * Configure email with common settings
+ */
+ private def configureEmail(email: Email, config: EmailConfig, content: EmailContent): Unit = {
+ // SMTP Configuration
+ email.setHostName(config.smtpHost)
+ email.setSmtpPort(config.smtpPort)
+ email.setAuthenticator(new DefaultAuthenticator(config.username, config.password))
+ email.setSSLOnConnect(config.useSSL)
+ email.setStartTLSEnabled(config.useTLS)
+ email.setDebug(config.debug)
+
+ // Set charset
+ email.setCharset("UTF-8")
+
+ // Set sender
+ email.setFrom(content.from)
+
+ // Set recipients
+ content.to.foreach(email.addTo)
+ content.cc.foreach(email.addCc)
+ content.bcc.foreach(email.addBcc)
+
+ // Set subject
+ email.setSubject(content.subject)
+ }
+
+ /**
+ * Create email attachment from file
+ */
+ def createFileAttachment(filePath: String, name: Option[String] = None): EmailAttachment = {
+ val attachment = new EmailAttachment()
+ attachment.setPath(filePath)
+ attachment.setDisposition(EmailAttachment.ATTACHMENT)
+ name.foreach(attachment.setName)
+ attachment
+ }
+
+ /**
+ * Create email attachment from URL
+ */
+ def createUrlAttachment(url: String, name: String): EmailAttachment = {
+ val attachment = new EmailAttachment()
+ attachment.setURL(new URL(url))
+ attachment.setDisposition(EmailAttachment.ATTACHMENT)
+ attachment.setName(name)
+ attachment
+ }
+
+ /**
+ * Test MailHog configuration, this for testing
+ */
+ def testMailHogConfig(): Unit = {
+ val config = EmailConfig(
+ smtpHost = "localhost",
+ smtpPort = 1025,
+ username = "",
+ password = "",
+ useTLS = false,
+ debug = true
+ )
+
+ val content = EmailContent(
+ from = "test@localhost",
+ to = List("receive@mailhog.local"),
+ subject = "Test MailHog with Apache Commons Email",
+ textContent = Some("This is a test email sent to MailHog using Apache Commons Email wrapper.")
+ )
+
+ logger.info("Testing MailHog configuration with Apache Commons Email...")
+
+ sendTextEmail(config, content) match {
+ case Full(messageId) => logger.info(s"MailHog email sent successfully: $messageId")
+ case Empty => logger.error("Failed to send MailHog email")
+ }
+ }
+}
\ No newline at end of file
diff --git a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
index c2e98117b..70ae47c69 100644
--- a/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
+++ b/obp-api/src/main/scala/code/api/v4_0_0/APIMethods400.scala
@@ -83,8 +83,8 @@ import net.liftweb.json.JsonDSL._
import net.liftweb.json.Serialization.write
import net.liftweb.json._
import net.liftweb.util.Helpers.{now, tryo}
-import net.liftweb.util.Mailer.{From, PlainMailBodyType, Subject, To, XHTMLMailBodyType}
-import net.liftweb.util.{Helpers, Mailer, StringHelpers}
+import net.liftweb.util.{Helpers, StringHelpers}
+import code.api.util.CommonsEmailWrapper._
import org.apache.commons.lang3.StringUtils
import java.net.URLEncoder
@@ -3368,7 +3368,30 @@ trait APIMethods400 extends MdcLoggable {
.replace(WebUIPlaceholder.activateYourAccount, link)
logger.debug(s"customHtmlText: ${customHtmlText}")
logger.debug(s"Before send user invitation by email. Purpose: ${UserInvitationPurpose.DEVELOPER}")
- Mailer.sendMail(From(from), Subject(subject), To(invitation.email), PlainMailBodyType(customText), XHTMLMailBodyType(XML.loadString(customHtmlText)))
+
+ // Use Apache Commons Email wrapper instead of Lift Mailer
+ val emailConfig = EmailConfig(
+ smtpHost = APIUtil.getPropsValue("mail.smtp.host", "localhost"),
+ smtpPort = APIUtil.getPropsValue("mail.smtp.port", "1025").toInt,
+ username = APIUtil.getPropsValue("mail.smtp.user", ""),
+ password = APIUtil.getPropsValue("mail.smtp.password", ""),
+ useTLS = APIUtil.getPropsValue("mail.smtp.starttls.enable", "false").toBoolean,
+ debug = APIUtil.getPropsValue("mail.debug", "false").toBoolean
+ )
+
+ val emailContent = EmailContent(
+ from = from,
+ to = List(invitation.email),
+ subject = subject,
+ textContent = Some(customText),
+ htmlContent = Some(customHtmlText)
+ )
+
+ sendHtmlEmail(emailConfig, emailContent) match {
+ case Full(messageId) => logger.debug(s"Email sent successfully with Message-ID: $messageId")
+ case Empty => logger.error("Failed to send user invitation email")
+ }
+
logger.debug(s"After send user invitation by email. Purpose: ${UserInvitationPurpose.DEVELOPER}")
} else {
val subject = getWebUiPropsValue("webui_customer_user_invitation_email_subject", "Welcome to the API Playground")
@@ -3380,7 +3403,30 @@ trait APIMethods400 extends MdcLoggable {
.replace(WebUIPlaceholder.activateYourAccount, link)
logger.debug(s"customHtmlText: ${customHtmlText}")
logger.debug(s"Before send user invitation by email.")
- Mailer.sendMail(From(from), Subject(subject), To(invitation.email), PlainMailBodyType(customText), XHTMLMailBodyType(XML.loadString(customHtmlText)))
+
+ // Use Apache Commons Email wrapper instead of Lift Mailer
+ val emailConfig = EmailConfig(
+ smtpHost = APIUtil.getPropsValue("mail.smtp.host", "localhost"),
+ smtpPort = APIUtil.getPropsValue("mail.smtp.port", "1025").toInt,
+ username = APIUtil.getPropsValue("mail.smtp.user", ""),
+ password = APIUtil.getPropsValue("mail.smtp.password", ""),
+ useTLS = APIUtil.getPropsValue("mail.smtp.starttls.enable", "false").toBoolean,
+ debug = APIUtil.getPropsValue("mail.debug", "false").toBoolean
+ )
+
+ val emailContent = EmailContent(
+ from = from,
+ to = List(invitation.email),
+ subject = subject,
+ textContent = Some(customText),
+ htmlContent = Some(customHtmlText)
+ )
+
+ sendHtmlEmail(emailConfig, emailContent) match {
+ case Full(messageId) => logger.debug(s"Email sent successfully with Message-ID: $messageId")
+ case Empty => logger.error("Failed to send user invitation email")
+ }
+
logger.debug(s"After send user invitation by email.")
}
(JSONFactory400.createUserInvitationJson(invitation), HttpCode.`201`(callContext))