From cf61753032cbea8984b3b81a1cf568461e2e822a Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:36:48 +0330 Subject: [PATCH 1/6] Use proxy in sending email, if needed --- docker-compose.yml | 3 ++ .../otp/app/{controller => }/OTPController.kt | 2 +- .../app/{controller => }/TOTPController.kt | 2 +- .../opex/otp/app/config/PostgresConfig.kt | 2 + .../otp/app/service/message/EmailSender.kt | 15 ++++++- .../otp/app/conttroller/OTPControllerIT.kt | 38 +++++++++++++++++ .../src/test/resources/application.yml | 42 +++++++++++++++++++ otp/pom.xml | 23 ++++++++++ .../postgres/dao/CurrencyRepositoryV2.kt | 3 +- 9 files changed, 126 insertions(+), 4 deletions(-) rename otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/{controller => }/OTPController.kt (98%) rename otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/{controller => }/TOTPController.kt (97%) create mode 100644 otp/otp-app/src/test/kotlin/co/nilin/opex/otp/app/conttroller/OTPControllerIT.kt create mode 100644 otp/otp-app/src/test/resources/application.yml diff --git a/docker-compose.yml b/docker-compose.yml index 6aebfa640..63535e6e2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -546,6 +546,9 @@ services: - SMTP_USER=${SMTP_USER} - SMTP_PASS=${SMTP_PASS} - SMTP_FROM=${SMTP_FROM} + - SMTP_SOCKS_HOST=${SMTP_SOCKS_HOST} + - SMTP_SOCKS_PORT=${SMTP_SOCKS_PORT} + - SMTP_PROXY_ENABLED=${SMTP_PROXY_ENABLED} - TOKEN_ISSUER_URL=${KC_ISSUER_URL} - OTP_CODE_RESPONSE_ENABLED=${OTP_CODE_RESPONSE_ENABLED} depends_on: diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt similarity index 98% rename from otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt rename to otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt index 0b44a084b..d8ed08e89 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt @@ -1,4 +1,4 @@ -package co.nilin.opex.otp.app.controller +package co.nilin.opex.otp.app import co.nilin.opex.common.OpexError import co.nilin.opex.otp.app.data.NewOTPRequest diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt similarity index 97% rename from otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt rename to otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt index 115db992e..2bda1376c 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt @@ -1,4 +1,4 @@ -package co.nilin.opex.otp.app.controller +package co.nilin.opex.otp.app import co.nilin.opex.otp.app.data.SetupTOTPRequest import co.nilin.opex.otp.app.data.SetupTOTPResponse diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/config/PostgresConfig.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/config/PostgresConfig.kt index 0c554085b..94cc7cc4a 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/config/PostgresConfig.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/config/PostgresConfig.kt @@ -2,12 +2,14 @@ package co.nilin.opex.otp.app.config import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Configuration +import org.springframework.context.annotation.Profile import org.springframework.core.io.Resource import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories import org.springframework.r2dbc.core.DatabaseClient @Configuration @EnableR2dbcRepositories(basePackages = ["co.nilin.opex"]) +@Profile("!test") class PostgresConfig( db: DatabaseClient, @Value("classpath:schema.sql") private val schemaResource: Resource diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt index e9912bfb4..effaec97e 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt @@ -7,6 +7,8 @@ import jakarta.mail.internet.InternetAddress import jakarta.mail.internet.MimeMessage import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Component +import java.net.Authenticator +import java.net.PasswordAuthentication @Component class EmailSender( @@ -19,7 +21,13 @@ class EmailSender( @Value("\${otp.email.password}") private val password: String, @Value("\${otp.email.from}") - private val from: String + private val from: String, + @Value("\${otp.email.proxy.enabled}") + private val proxyIsEnabled: Boolean, + @Value("\${otp.email.proxy.host}") + private val proxyHost: String?, + @Value("\${otp.email.proxy.port}") + private val proxyPort: String? ) : MessageSender { private val logger by LoggerDelegate() @@ -34,6 +42,11 @@ class EmailSender( properties["mail.smtp.starttls.enable"] = "true" properties["mail.smtp.from"] = from properties["mail.smtp.ssl.protocols"] = "TLSv1.2" + if (proxyIsEnabled) { + properties["mail.smtp.socks.host"] = proxyHost + properties["mail.smtp.socks.port"] = proxyPort + } + val session = Session.getDefaultInstance(properties) return try { diff --git a/otp/otp-app/src/test/kotlin/co/nilin/opex/otp/app/conttroller/OTPControllerIT.kt b/otp/otp-app/src/test/kotlin/co/nilin/opex/otp/app/conttroller/OTPControllerIT.kt new file mode 100644 index 000000000..c83c6a29e --- /dev/null +++ b/otp/otp-app/src/test/kotlin/co/nilin/opex/otp/app/conttroller/OTPControllerIT.kt @@ -0,0 +1,38 @@ +package co.nilin.opex.otp.app.conttroller + + +import co.nilin.opex.otp.app.service.message.EmailSender +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Disabled +import org.junit.jupiter.api.Test + + +class EmailSenderIT { + @Disabled("Manual test: requires real SMTP + proxy") + @Test + fun `should send email via real smtp`() = runBlocking { + + val sender = EmailSender( + host = requireEnv("SMTP_HOST"), + port = requireEnv("SMTP_PORT"), + username = requireEnv("SMTP_USER"), + password = requireEnv("SMTP_PASS"), + from = requireEnv("SMTP_FROM"), + proxyIsEnabled = true, + proxyHost = requireEnv("SMTP_SOCKS_HOST"), + proxyPort = requireEnv("SMTP_SOCKS_PORT") + ) + + val result = sender.send( + receiver = requireEnv("SMTP_RECEIVER"), + message = "

Integration Test

", + metadata = emptyMap() + ) + + Assertions.assertTrue(result) + } + + private fun requireEnv(key: String): String = + System.getenv(key) ?: error("Missing env: $key") +} \ No newline at end of file diff --git a/otp/otp-app/src/test/resources/application.yml b/otp/otp-app/src/test/resources/application.yml new file mode 100644 index 000000000..909266384 --- /dev/null +++ b/otp/otp-app/src/test/resources/application.yml @@ -0,0 +1,42 @@ +spring: + main: + web-application-type: none + + # 🚫 disable everything noisy + autoconfigure: + exclude: + - org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration + - org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration + - org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration + + cloud: + consul: + enabled: false + config: + enabled: false + + vault: + enabled: false + + kafka: + bootstrap-servers: "" +otp: + response-enabled: ${OTP_CODE_RESPONSE_ENABLED:false} + sms: + provider: + url: ${SMS_PROVIDER_URL} + api-key: ${SMS_PROVIDER_API_KEY} + template: ${SMS_PROVIDER_TEMPLATE} + email: + host: ${SMTP_HOST} + port: ${SMTP_PORT} + username: ${SMTP_USER} + password: ${SMTP_PASS} + from: ${SMTP_FROM} + proxy: + enabled: ${SMTP_PROXY_ENABLED:false} + host: ${SMTP_PROXY_HOST} + port: ${SMTP_PROXY_PORT} + custom-message: + enabled: ${CUSTOM_MESSAGE_ENABLED:false} + base-url: ${CUSTOM_MESSAGE_URL} \ No newline at end of file diff --git a/otp/pom.xml b/otp/pom.xml index 0266dd847..712576203 100644 --- a/otp/pom.xml +++ b/otp/pom.xml @@ -33,6 +33,29 @@ logbook-spring-boot-webflux-autoconfigure 3.9.0 + + org.testcontainers + junit-jupiter + 1.18.0 + test + + + org.springframework.boot + spring-boot-starter-test + test + + + org.mockito + mockito-core + + + + + org.mockito + mockito-core + 5.4.0 + test + diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt index 731d5a384..3c835916c 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt @@ -1,5 +1,6 @@ package co.nilin.opex.wallet.ports.postgres.dao +import co.nilin.opex.common.data.UserLanguage import co.nilin.opex.wallet.core.inout.CurrencyPrecision import co.nilin.opex.wallet.ports.postgres.dto.CurrencyView import co.nilin.opex.wallet.ports.postgres.model.CurrencyModel @@ -44,7 +45,7 @@ interface CurrencyRepositoryV2 : ReactiveCrudRepository { fun fetchCurrency( uuid: String? = null, symbol: String? = null, - lang: String? = null + lang: String? = UserLanguage.safeValueOf(null).name ): Mono? From b363d0c3148a1ebf3d9eeb73789944d9777ef5d3 Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:37:52 +0330 Subject: [PATCH 2/6] Move OTP controllers --- .../co/nilin/opex/otp/app/{ => controller}/OTPController.kt | 2 +- .../co/nilin/opex/otp/app/{ => controller}/TOTPController.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) rename otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/{ => controller}/OTPController.kt (98%) rename otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/{ => controller}/TOTPController.kt (97%) diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt similarity index 98% rename from otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt rename to otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt index d8ed08e89..0b44a084b 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/OTPController.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/OTPController.kt @@ -1,4 +1,4 @@ -package co.nilin.opex.otp.app +package co.nilin.opex.otp.app.controller import co.nilin.opex.common.OpexError import co.nilin.opex.otp.app.data.NewOTPRequest diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt similarity index 97% rename from otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt rename to otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt index 2bda1376c..115db992e 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/TOTPController.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/controller/TOTPController.kt @@ -1,4 +1,4 @@ -package co.nilin.opex.otp.app +package co.nilin.opex.otp.app.controller import co.nilin.opex.otp.app.data.SetupTOTPRequest import co.nilin.opex.otp.app.data.SetupTOTPResponse From 38ec903b05f8bedca633430037480b921660c5fe Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:39:44 +0330 Subject: [PATCH 3/6] Remove unused packages --- .../co/nilin/opex/otp/app/service/message/EmailSender.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt index effaec97e..402e72c93 100644 --- a/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt +++ b/otp/otp-app/src/main/kotlin/co/nilin/opex/otp/app/service/message/EmailSender.kt @@ -7,8 +7,7 @@ import jakarta.mail.internet.InternetAddress import jakarta.mail.internet.MimeMessage import org.springframework.beans.factory.annotation.Value import org.springframework.stereotype.Component -import java.net.Authenticator -import java.net.PasswordAuthentication + @Component class EmailSender( From 7a59b7a66dde6917fa65778c84018e9d61f1383f Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:40:34 +0330 Subject: [PATCH 4/6] Revert currency changes --- .../opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt index 3c835916c..4931a675f 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt @@ -45,7 +45,7 @@ interface CurrencyRepositoryV2 : ReactiveCrudRepository { fun fetchCurrency( uuid: String? = null, symbol: String? = null, - lang: String? = UserLanguage.safeValueOf(null).name + lang: String?, ): Mono? From 49cc37ee9760327c46b4eaaff0955647d0bc3b22 Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:41:03 +0330 Subject: [PATCH 5/6] Revert currency changes --- .../opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt index 4931a675f..9769d05ab 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt @@ -45,7 +45,7 @@ interface CurrencyRepositoryV2 : ReactiveCrudRepository { fun fetchCurrency( uuid: String? = null, symbol: String? = null, - lang: String?, + lang: String? = null ): Mono? From b2d37cafc8424a6ed5b34a328369a61b813c0dc9 Mon Sep 17 00:00:00 2001 From: fatemeh imanipour Date: Mon, 4 May 2026 20:41:27 +0330 Subject: [PATCH 6/6] Revert currency changes --- .../nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt index 9769d05ab..731d5a384 100644 --- a/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt +++ b/wallet/wallet-ports/wallet-persister-postgres/src/main/kotlin/co/nilin/opex/wallet/ports/postgres/dao/CurrencyRepositoryV2.kt @@ -1,6 +1,5 @@ package co.nilin.opex.wallet.ports.postgres.dao -import co.nilin.opex.common.data.UserLanguage import co.nilin.opex.wallet.core.inout.CurrencyPrecision import co.nilin.opex.wallet.ports.postgres.dto.CurrencyView import co.nilin.opex.wallet.ports.postgres.model.CurrencyModel