From 22cc534f4f5578bf89c3f26961f9ef5342ef3ca2 Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 20 Oct 2026 10:03:22 +0530 Subject: [PATCH 1/2] chore: set Common-API version to 3.12.0 Co-Authored-By: Claude Opus 5.5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 From 2701b015faf89cea53ac120b324a7618fb5762ab Mon Sep 17 00:00:00 2001 From: vishwab1 Date: Tue, 20 Oct 2026 10:03:22 +0530 Subject: [PATCH 2/2] fix(user): do not wait for the CTI server when a password is set setForgetPassword called updateCTIPasswordForUserV1 from the same class, so its @Async was not applied: an unreachable CTI server held the password screen until the network timeout, before the password was saved (camp laptops cannot reach the call-centre CTI server). The CTI update now runs in the background; the password is saved and the user continues immediately. Co-Authored-By: Claude Opus 5.5 --- .../users/IEMRAdminUserServiceImpl.java | 14 ++++++++++-- .../users/IEMRAdminUserServiceImplTest.java | 22 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) 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