diff --git a/pom.xml b/pom.xml
index ffe74404..4c727f1b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.iemr.common-API
common-api
- 3.8.2
+ 3.12.0
war
Common-API
diff --git a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java
index e411b9ef..3b60c78b 100644
--- a/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java
+++ b/src/main/java/com/iemr/common/service/users/IEMRAdminUserServiceImpl.java
@@ -26,6 +26,7 @@
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
+import java.util.concurrent.CompletableFuture;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@@ -469,7 +470,7 @@ public int setForgetPassword(User user, String loginpass, String transactionId,
int count = 0;
try {
if (isAdmin != null && isAdmin == true) {
- updateCTIPasswordForUserV1(user.getUserID(), loginpass);
+ updateCTIPasswordInBackground(user.getUserID(), loginpass);
loginpass = securePassword.generateStrongPassword(loginpass);
count = iEMRUserRepositoryCustom.updateSetForgetPassword(user.getUserID(), loginpass);
} else {
@@ -477,7 +478,7 @@ public int setForgetPassword(User user, String loginpass, String transactionId,
.getSessionObjectForChangePassword((user.getUserID().toString() + user.getUserName()));
if (tokenFromRedis.equalsIgnoreCase(transactionId)) {
- updateCTIPasswordForUserV1(user.getUserID(), loginpass);
+ updateCTIPasswordInBackground(user.getUserID(), loginpass);
loginpass = securePassword.generateStrongPassword(loginpass);
count = iEMRUserRepositoryCustom.updateSetForgetPassword(user.getUserID(), loginpass);
// Deleting transaction Id
@@ -600,6 +601,15 @@ public void updateCTIPasswordForUser(Long userID, String password) {
}
}
+ /**
+ * Sends the new password to the CTI server without making the user wait: called from this class, so the
+ * {@code @Async} of updateCTIPasswordForUserV1 is not applied (no proxy) and an unreachable CTI server held the
+ * password screen until the network timeout - before the password was even saved.
+ */
+ void updateCTIPasswordInBackground(Long userID, String password) {
+ CompletableFuture.runAsync(() -> updateCTIPasswordForUserV1(userID, password));
+ }
+
@Async
public void updateCTIPasswordForUserV1(Long userID, String password) {
try {
diff --git a/src/test/java/com/iemr/common/service/users/IEMRAdminUserServiceImplTest.java b/src/test/java/com/iemr/common/service/users/IEMRAdminUserServiceImplTest.java
index de282b52..a896327f 100644
--- a/src/test/java/com/iemr/common/service/users/IEMRAdminUserServiceImplTest.java
+++ b/src/test/java/com/iemr/common/service/users/IEMRAdminUserServiceImplTest.java
@@ -374,6 +374,28 @@ void testSetForgetPassword_ValidTransaction() throws Exception {
assertEquals(1, result);
}
+ @Test
+ void testSetForgetPassword_DoesNotWaitForCtiServer() throws Exception {
+ // Given: the CTI server does not answer until released
+ java.util.concurrent.CountDownLatch ctiReleased = new java.util.concurrent.CountDownLatch(1);
+ when(iEMRUserRepositoryCustom.findUserByUserID(1L)).thenReturn(testUser);
+ when(ctiService.addUpdateUserData(anyString(), anyString())).thenAnswer(invocation -> {
+ ctiReleased.await(10, java.util.concurrent.TimeUnit.SECONDS);
+ return new OutputResponse();
+ });
+ when(securePassword.generateStrongPassword("newpassword")).thenReturn("hashedNewPassword");
+ when(iEMRUserRepositoryCustom.updateSetForgetPassword(1L, "hashedNewPassword")).thenReturn(1);
+
+ // When: the password is saved without waiting for CTI
+ int result = assertTimeoutPreemptively(java.time.Duration.ofSeconds(2),
+ () -> userService.setForgetPassword(testUser, "newpassword", "token123", true));
+
+ // Then: saved, and CTI is still updated in the background
+ assertEquals(1, result);
+ ctiReleased.countDown();
+ verify(ctiService, timeout(2000)).addUpdateUserData(anyString(), eq("127.0.0.1"));
+ }
+
@Test
void testSetForgetPassword_InvalidTransaction() throws Exception {
// Given